GNU/Linux >> Znalost Linux >  >> Linux

Nahraďte MAC adresu UUID

Následující perl skript používá buď Digest::MD5 nebo Digest::SHA modul pro transformaci MAC adresy na hash pomocí tajné soli. Viz manuálové stránky modulů pro více podrobností o nich. Stojí za zmínku, že Digest::SHA má na výběr několik dalších algoritmů.

Kód je napsán tak, aby usnadnil výběr jiného hashovacího algoritmu – jeden odkomentujte a ostatní okomentujte, abyste si vybrali ten, který vám nejlépe vyhovuje. BTW, výstup z _base64 verze funkcí je o něco kratší než _hex funkce, ale vypadají spíše jako šum linky.

Zjednodušil jsem váš zadaný regulární výraz (neviděl jsem, že by bylo třeba hledat pozadí). Možná to budete muset trochu vyladit, abyste pracovali se svými vstupními daty...neposkytli jste žádný vzorek, takže jsem to jen hádal.

#!/usr/bin/perl

# choose one of the following digest modules:
use Digest::MD5 qw(md5_hex md5_base64);
#use Digest::SHA qw(sha256_hex sha256_base64);

use strict;

my $salt='secret salt phrase';

# store seen MAC addresses in a hash so we only have to calculate the digest
# for them once.  This speed optimisation is only useful if the input file
# is large AND any given MAC address may be seen many times.
my %macs=();

while(<>) {
  if (m/clientMac:\s*([A-Z0-9]{12})/i) {
    my $mac = $1;

    if (!defined($macs{$mac})) {
      # choose one of the following digest conversions:

      #my $uuid = sha256_hex($mac . $salt);
      #my $uuid = sha256_base64($mac . $salt);
      my $uuid = md5_hex($mac . $salt);
      #my $uuid = md5_base64($mac . $salt);

      $macs{$mac} = $uuid;
    };

    s/(clientMac:\s*)$mac/$1$macs{$mac}/gio;
  };
  print;
};

Jak je požadováno v komentáři, zde je příklad, jak provést takovou substituci pomocí sed . Použili jste značku /linux, takže by mělo být bezpečné používat GNU sed s jeho e příznak pro s příkaz:

sed -E 'h;s/.*clientMac":\s"([A-Z0-9]{12}).*/echo secretKey\1|md5sum/e;T
  G;s/(.*)\s*-\n(.*clientMac":\s")[A-Z0-9]{12}(.*)/\2\1\3/' logfile

Vysvětlení:

  • h příkaz uloží řádek do prostoru hold, takže jej můžeme obnovit po zpackání řádku (-;
  • s/.*clientMac":\s"([A-Z0-9]{12}).*/echo secretKey\1|md5sum/e odpovídá celému řádku a skutečnou MAC vloží do () k opětovnému použití při výměně. Nahrazení tvoří příkaz, který se má provést:echo ing MCA spolu se "solí" a potrubím do md5sum . e příznak dělá sed spusťte to v shellu a výsledek vložte znovu do vyrovnávací paměti
  • T větví na konec skriptu, pokud nebyla provedena žádná náhrada. Toto je tisk řádků bez neupravené MAC. Následující řádky se provedou pouze v případě, že byla provedena výměna
  • G připojí původní řádek z vyrovnávací paměti, takže nyní máme md5sum výstup, nový řádek a původní řádek ve vyrovnávací paměti
  • s/(.*)\s*-\n(.*clientMac":\s")[A-Z0-9]{12}(.*)/\2\1\3/ zachytí MD5 v prvním páru () , řádek před MAC ve druhém a zbytek řádku za MAC ve třetím, tedy \2\1\3 nahradí MAC za MD5

Jako alternativní přístup jsem někdy používal jednoduchá čísla řádků jako hodnotu zmatku. Díky tomu je výstup kompaktnější a čitelnější.

Také awk je dobrý nástroj, když potřebujete provádět "chytré" operace s textovým souborem, který má čitelnější jazyk než sed . "Chytrá" operace, kterou je v tomto případě třeba provést, je vyhnout se opětovnému spuštění algoritmu zmatku, když je jakákoli MAC adresa nalezena více než jednou. To může značně urychlit operace, pokud máte tisíce řádků odkazujících na malý počet MAC adres.

V praxi zvažte následující skript, který také zpracovává možné více MAC adres vyskytujících se na libovolném řádku, identifikuje a nahrazuje každý výskyt a na konci pak vytiskne mapovací tabulku:

awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v table='sort -k 1,1n | column -t' -- '
$0 ~ pat {
    for (i=1; i <= NF; i++)
        if (match($i, pat)) {
            if (!($i in cache))
                cache[$i]=NR "." i
            $i = "MAC:" cache[$i]
        }
}
1
END {
    print "---Table: "FILENAME"\nnum MAC" | table
    for (mac in cache)
        print cache[mac], mac | table
}
' file.log

Tabulku na konci lze snadno oddělit od hlavního výstupu dodatečným editačním krokem nebo pouhým vytvořením příkazového řetězce v -v table= argument přesměruje svůj výstup do souboru, jako v -v table='sort -k 1,1n | column -t > table' . Lze jej také zcela odstranit pouhým odstraněním celého END{ … } blokovat.

Jako varianta použití skutečného šifrovacího stroje k výpočtu hodnot zmatku, a tedy bez mapovací tabulky na konci:

awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v crypter='openssl enc -aes-256-cbc -a -pass file:mypassfile' -- '
$0 ~ pat {
    for (i=1; i <= NF; i++)
        if (match($i, pat)) {
            addr = cache[$i]
            if (addr == "") {
                "echo '\''" $i "'\'' | " crypter | getline addr
                cache[$i] = addr
            }
            $i = "MAC:" addr
        }
}
1
' file.log

Zde jsem použil openssl jako šifrovací stroj vybere svůj aes-256-cbc šifra (také s výstupem zakódovaným v base64, aby byl textově přívětivý) a přečtení šifrovacího tajemství ze souboru s názvem mypassfile .

Řetězce zašifrované symetrickou šifrou (jako aes-256-cbc ) lze dešifrovat pomocí znalosti použitého tajemství (obsah mypassfile , které si chcete nechat pro sebe), proto je lze obrátit. Také od openssl standardně používá náhodnou sůl, každý běh produkuje různé hodnoty pro stejný vstup. Nepoužívá se sůl (volba -nosalt ) by bylo openssl produkují stejnou hodnotu pro každý běh, takže jsou méně bezpečné, ale na druhou stranu by produkovaly kratší texty a přitom byly stále zašifrovány.

Totéž awk skript by fungoval pro jiné externí příkazy místo openssl pouhým nahrazením příkazu v -v crypter= argument na awk , pokud externí příkaz, který zvolíte, může přijímat vstup ze stdin a tisknout výstup na stdout.

Řetězce hašované pomocí algoritmů jako MD5 nebo SHA jsou místo toho pouze jednosměrné (tj. nelze je obrátit) a vždy produkují stejnou hodnotu pro stejný vstup, proto byste je chtěli „osolit“, aby vypočítané hodnoty produkované ve výstupu nelze pouze prohledávat přes všechny možné MAC adresy. Můžete přidat náhodnou "sůl" jako v následujícím mírně upraveném skriptu:

awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v crypter='sha256sum' -- '
$0 ~ pat {
    for (i=1; i <= NF; i++)
        if (match($i, pat)) {
            addr = cache[$i]
            if (addr == "") {
                "(dd if=/dev/random bs=16 count=1 2>/dev/null; echo '\''" $i "'\'') | " crypter | getline addr
                cache[$i] = addr
            }
            $i = "MAC:" addr
        }
}
1
' file.log

Tento druhý skript používá 16-bajtovou (pseudo-)náhodnou hodnotu jako „sůl“, takže při každém spuštění se stejnými daty vytváří jinou hash hodnotu.


Linux
  1. Vykonat řadu příkazů jedním sudem?

  2. Nahradit rozsah řádků rozsahem řádků (sed nebo jiné)?

  3. Nahradit řádky odpovídající vzoru řádky z jiného souboru v pořadí?

  1. Nahradit nový řádek nulou?

  2. Získání MAC adresy

  3. Jak nahradit text podobný sedu pythonem?

  1. Jak nahradit soubor v jar příkazovým řádkem v linuxu?

  2. Multi-Line Sed Vyměnit

  3. Nahraďte uživatele gitolite3 za git