Stránka OpenWRT o overení integrity stiahnutých súborov popisuje tri kroky pre úspešné overenie stiahnutých súborov:

  1. Stiahnite súbory sha256sum a sha256sum.asc
  2. Overte podpis príkazom gpg --with-fingerprint --verify sha256sum.asc sha256sum, uistite sa, že GnuPG príkaz hlási dobrý podpis a že odtlačok zodpovedá tým uvedeným na našej stránke odtlačkov.
  3. Stiahnite obraz firmvéru do rovnakého adresára ako súbor sha256sums a overte jeho kontrolný súčet nasledujúcim príkazom: sha256sum -c --ignore-missing sha256sums

V minulosti obsahovala convenience skript, ktorý bol ale odstránený kvôli bezpečnostným nedostatkom (pozrite históriu wiki stránky). Kroky sú ponechané na používateľa a zdajú sa priamočiare, ale verím, že krátke vysvetlenie neuškodí. Použijem TP-Link MR200v1 ako príklad. Cieľom je písať príkazy tak, aby sa dali automatizovať pomocou bash:

Stiahnutie súborov #

Jednoduchý wget postačí:

url="https://downloads.openwrt.org/snapshots/targets/ramips/mt7620"
sumsFile="sha256sums"

wget "$url/$sumsFile"
wget "$url/$sumsFile.asc"

Súbory je možné pred volaním wget zmazať, pretože robí filestamping (pridáva prírastkové číslo na koniec názvu súboru).

Overenie podpisu #

Overenie podpisu automatizovaným spôsobom pomocou bash je miesto, kde som strávil väčšinu času. Jednoduché spustenie ponúkaného príkazu nestačí:

gpg --with-fingerprint --verify sha256sums.asc sha256sums

Bez akejkoľvek predchádzajúcej práce to vyústi do nasledujúcej chyby:

gpg: Can't check signature: No public key

Existuje niekoľko spôsobov, ako problém obísť, najautomatickejší je použiť možnosť --auto-key-retrieve:

gpg --auto-key-retrieve --with-fingerprint --verify sha256sums.asc

Táto možnosť predpokladá, že kľúče sú zverejnené na kľúčovom serveri. Tiež si všimnite, že gpg môže predpokladať správny názov súboru, ak zodpovedá podpisu, takže sha256sums je možné vynechať. Výstup by mal vyzerať podobne ako tento:

gpg: assuming signed data in 'sha256sums'
gpg: Signature made Sun 04 Apr 2021 03:07:20 CEST
gpg:                using RSA key 6D9278A33A9AB3146262DCECF93525A88B699029
gpg: Good signature from "LEDE Build System (LEDE GnuPG key for unattended build jobs) <lede-adm@lists.infradead.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 54CC 7430 7A2C 6DC9 CE61  8269 CD84 BCED 6264 71F1
     Subkey fingerprint: 6D92 78A3 3A9A B314 6262  DCEC F935 25A8 8B69 9029

Vizuálne zameranie sa na slovo Good je minimálnou požiadavkou prvej časti druhého kroku:

uistite sa, že GnuPG príkaz hlási dobrý podpis

Manuálna navigácia na stránku odtlačkov a kopírovanie-vyhľadávanie-vkladanie v prehliadači pre skutočný odtlačok, napríklad 54CC 7430 7A2C 6DC9 CE61 8269 CD84 BCED 6264 71F1 v tomto príklade, je požadovaná ako druhá časť druhého kroku.

že odtlačok zodpovedá tým uvedeným na našej stránke odtlačkov

Testovanie návratového stavu #

So zameraním na automatizáciu, skutočnosť, že možnosť gpg --verify vracia 0 ak bolo overenie úspešné a 1 ak nie (čo je bežná konvencia), znamená, že testovanie stavu predchádzajúceho príkazu v bash pomocou $? môže byť použité tu:

gpg --auto-key-retrieve --with-fingerprint --verify sha256sums.asc

if [ $? -eq 0 ]; then
   echo "SIGNATURE VERIFIED"
else
   echo "SIGNATURE INVALID, the program will terminate"
   exit 1
fi

Parsovanie odtlačku #

V závislosti od verzie GnuPG, gpg --verify iba vypíše výstup na obrazovku. Na parsovanie výstupu a vykonanie niečoho užitočného s ním v skripte treba pridať aj možnosť --status-fd 1:

gpg --status-fd 1 --auto-key-retrieve --with-fingerprint --verify sha256sums.asc

Výstup je teraz formátovaný inak:

[GNUPG:] NEWSIG
[GNUPG:] KEY_CONSIDERED 54CC74307A2C6DC9CE618269CD84BCED626471F1 0
[GNUPG:] SIG_ID 5XkMbTUScxodW5F+uzE34LmUBk8 2021-04-04 1617498440
[GNUPG:] KEY_CONSIDERED 54CC74307A2C6DC9CE618269CD84BCED626471F1 0
[GNUPG:] GOODSIG F93525A88B699029 LEDE Build System (LEDE GnuPG key for unattended build jobs) <lede-adm@lists.infradead.org>
[GNUPG:] VALIDSIG 6D9278A33A9AB3146262DCECF93525A88B699029 2021-04-04 1617498440 0 4 0 1 10 00 54CC74307A2C6DC9CE618269CD84BCED626471F1
[GNUPG:] KEY_CONSIDERED 54CC74307A2C6DC9CE618269CD84BCED626471F1 0
[GNUPG:] KEY_CONSIDERED 54CC74307A2C6DC9CE618269CD84BCED626471F1 0
[GNUPG:] TRUST_UNDEFINED 0 pgp
[GNUPG:] VERIFICATION_COMPLIANCE_MODE 23

Príklad grep príkazu na extrahovanie odtlačku primárneho kľúča:

gpgOutput=$(gpg --status-fd 1 --auto-key-retrieve --with-fingerprint --verify sha256sums.asc)
fingerprint=$(gpgOutput | grep -m1 KEY_CONSIDERED | tr -d' ' -f3)
echo $fingerprint

Overenie, že odtlačok zodpovedá publikovanému, je najchúlostivejšia časť, pretože je uverejnený iba na webovej stránke s vlastným formátovaním. Tiež to nie je spoľahlivé, pretože keby sa útočníkom podarilo získať prístup k webovému serveru, kde sú odtlačky zverejnené, mohli by ich nahradiť inými. To si vyžaduje určité kognitívne úsilie zo strany používateľa na výskum, akému zdroju možno dôverovať, ale to je téma na inokedy.

Formátovanie odtlačku #

Všimnite si, že zvyčajne treba odtlačok trochu naformátovať, aby zodpovedal zverejnenému tvaru, napríklad pridaním medzery každé štyri znaky a pridaním ďalšej medzery každých 25 znakov, aby zodpovedal ľudsky čitateľnému výstupu gpg --verify, čo možno urobiť takto:

# formats fingerprint 54CC74307A2C6DC9CE618269CD84BCED626471F1
# to prettier form of 54CC 7430 7A2C 6DC9 CE61  8269 CD84 BCED 6264 71F1
formatted=$(echo "$fingerprint" | sed 's/.\{4\}/& /g' | xargs | sed 's/.\{25\}/& /g')

Príklad kontroly prítomnosti odtlačku na webovej stránke, za predpokladu, že odtlačky tam sú legitímne:

curl -s "$fingerprintUrl" | grep -o "$formatted"

Príkaz grep tiež dodržiava konvenciu návratového stavu, takže rovnaký test s $? možno použiť aj tu, čo poskytuje automatizované riešenie.

Overenie kontrolného súčtu #

Tretí krok. Keď je platnosť kontrolných súčtov overená, možno ich použiť na overenie skutočného obrazového súboru, čo znamená, že všetky predchádzajúce kroky boli len prípravou. Ale keď je všetko pripravené, kroky sú priamočiare:

sumsFile="sha256sums"
url="https://downloads.openwrt.org/snapshots/targets/ramips/mt7620"
imageFile="openwrt-imagebuilder-ramips-mt7620.Linux-x86_64.tar.xz"

wget "$url/$imageFile"
sha256sum -c --ignore-missing "$sumsFile"

Výstup sha256sum hovorí, že obrazový súbor (alebo akýkoľvek iný súbor, ktorého sha256 súčet je uložený v súbore sha256sums) bol stiahnutý neporušený.

openwrt-imagebuilder-ramips-mt7620.Linux-x86_64.tar.xz: OK

Rovnaký test stavu možno použiť aj tu na ďalšiu automatizáciu skriptu. Zdrojové súbory vykonávajúce tieto kroky sú tiež dostupné v repozitári.

Toto je 25. príspevok #100daystooffload.