Šifrování pg_dump pomocí OpenSSL

Šifrování pg_dump pomocí OpenSSL
« kdy: 14. 05. 2024, 11:12:43 »
Ahoj,

testuji podle tohoto postupu https://www.imagescape.com/blog/encrypted-postgres-backups/ a na posledni chvili jsem si vsiml:

Kód: [Vybrat]
-rw-r--r-- 1 postgres postgres 1.5M May 14 00:00 db1_14.05.24-00_00.sql.gz.ssl
-rw-r--r-- 1 postgres postgres 3.4K May 14 00:29 globals_only.gz.ssl
-rw-r--r-- 1 postgres postgres 1.9G May 14 00:04 db2_14.05.24-00_00.sql.gz.ssl <---
-rw-r--r-- 1 postgres postgres 1.9G May 14 00:29 db3_14.05.24-00_00.sql.gz.ssl <---
-rw-r--r-- 1 postgres postgres  19M May 14 00:29 db4_14.05.24-00_00.sql.gz.ssl
-rw-r--r-- 1 postgres postgres 1.4K May 14 00:29 postgres_14.05.24-00_00.sql.gz.ssl
-rw-r--r-- 1 root     root       88 May 14 00:00 postgres_db_list_grep.txt
-rw-r--r-- 1 postgres postgres  772 May 14 00:00 template0_14.05.24-00_00.sql.gz.ssl
-rw-r--r-- 1 postgres postgres 1.4K May 14 00:00 template1_14.05.24-00_00.sql.gz.ssl
-rw-r--r-- 1 postgres postgres 154M May 14 00:29 db5_14.05.24-00_00.sql.gz.ssl


Prikaz dle toho webu je pouzit:
Kód: [Vybrat]
/usr/bin/pg_dump --create --exclude-schema=XX --exclude-schema=XY $line | gzip -c | openssl smime -encrypt -aes256 -binary -outform DEM -out $PDIR/'$line'_'$OFP'.gz.ssl /SOMEPATH/local_backup/pgdump_backup.pem

Nesifrovana db2 ma 1.8 GB, nesifrovana db3 ma 7.34 GB. Obe sifrovane maji 1.9 GB. Proc? Na info omezeni velikost ciloveho souboru jsem nenarazil.

Pripadne nejaky jiny tip, jakym postupem sifrovat dumpy?

Diky.


Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #1 kdy: 14. 05. 2024, 12:19:26 »
Začal bych tím, že se podíváte na skutečnou velikost souborů v bajtech. Ta velikost nešifrované zálohy, kterou uvádíte, je už po komprimaci? Šifrovaný soubor by měl být stejně velký, jako ten před šifrováním, maximálně tam může být o kousek větší kvůli výplni na velikost bloků.

Co je to za souborový systém? Maximální velikost souboru na FAT16 je 2 GB.

Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #2 kdy: 14. 05. 2024, 12:41:24 »
Ano, uvedene velikosti se tykaji nesifrovaneho i sifrovaneho pg_dump po komprimaci ukladane na ext4.

petersveter

Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #3 kdy: 14. 05. 2024, 13:22:15 »
ono ani rozdiel 1.8 a 1.9 giga mi nepride ok kedze aes je len xor a ratam ze je to obycajny ctr takze maximalne tam prefixne nonce ktora ma tusim 16 bajtov takze tych 100mb navyse je divne same o sebe. Jedine ze by sifroval jednotlive exporty(tzn kazda tabulka ma plno insert into a kazdy je sifrovany zvlast) takze 100MB/16 by bolo asi nejakych 6.5M insertov.

Pri tej db3 to teda nema ziaden zmysel, jedine ze by tam sam implementoval kompresiu zo 7.3 na 1.9 giga. Mozno ma nejaky limit na vysledny sifrovany subor alebo nieco take... len hadam :D pg som nikdy nepouzival.

Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #4 kdy: 14. 05. 2024, 13:32:24 »
Zásadně doporučuji před každým šifrováním, archivováním, zipováním si udělat checksum zdrojového souboru a poté cvičně provést dešifrování, rozbalení a ověřit checksum. Kdybys to udělal, nemusíš se takhle ptát, jestli to je v pořádku.

Pokud zdrojový soubor obsahuje příliš prázdných míst, gzip to naprosto zásadne zredukuje. Samotné šifrování, tak jak ho používáš ti zašifruje i nulové bity a budou zahrnuty ve výsledku.

Tj. v první fázi implementuj kontrolu integrity přes checksumy (sha256 může být dostatečné pro tenhle účel), ověř, že výsledek po rozbalení je shodný se vstupem.

Dále ověř, jestli na redukci velikost má vliv použitý gzip (prostě ho z příkazu vynechej a zašifruj přímo zdrojové soubory).


Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #5 kdy: 14. 05. 2024, 15:07:25 »
Ty checksumy, jak o nich píše Tomáš, bych rovnou trvale ukládal vedle těch zašifrovaných souborů. Ať máte hned vedle po ruce kontrolní součet, proti kterému ověříte dešifrovaný rozbalený soubor, když budete zálohu potřebovat.

sha256sum se dá použít pro pokusy a máte u něj jistotu, že to dokážete ověřit i za 10 let (i když tou dobou vám asi budou k ničemu ty zálohy). Pokud chcete něco rychlejšího (u gigových souborů už to bude znatelné), použijte třeba BLAKE3 a utilitu b3sum.

Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #6 kdy: 14. 05. 2024, 15:15:49 »
ono ani rozdiel 1.8 a 1.9 giga mi nepride ok kedze aes je len xor a ratam ze je to obycajny ctr takze maximalne tam prefixne nonce ktora ma tusim 16 bajtov takze tych 100mb navyse je divne same o sebe.

Právě proto je důležitá skutečná velikost v bajtech. Protože rozdíl 1,8 GiB vs 1,9 GiB při zaokrouhlování na desetiny GiB může ve skutečnosti být rozdíl jednoho bajtu, nemusí to být 100 MB. AES je bloková šifra, takže minimálně výplň na násobky velikosti bloku tam být musí.

petersveter

Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #7 kdy: 14. 05. 2024, 20:04:39 »
AES je bloková šifra, takže minimálně výplň na násobky velikosti bloku tam být musí.

Ano, ale to sa tyka iba posledneho bloku. AES pouziva 16, 24 alebo 32 bajtov na kluc, teda 192, 256 alebo 512 bitov. Co tvori velkost bloku, kedze je to XOR,  a jedine co sa tam meni je pocet iteracii. Ak vezmem najbeznejsi aes 256 s 24 bajtami, teda [24]uint8, tak 100M rozdiel znamena ze 104 857 600b/24b=4 369 066,6b samostatne sifrovanych zaznamov s paddingom ktory tuto velkost pridava v *plnej* velkosti. Co je nemozne, takze pocet zanamov bude trochu vecsi. Neviem o tej db nic, ale je kludne mozne ze je tam cez povedzme 5M riadkov ktore su exportovane samostatne ako insert into a kazdy je samostatne zasifrovany. Je to uplne v poriadku vysledok.

Myslim ze problem tu je ta db3 kde skoro 8gb db vyprodukuje ledva 2gb export. Na to sa skor OP pyta. A tam jedine ze je to zasifrovane a potom gzipovane, lenze potom preco db2 tiez nie je mensia/gzipnuta? Myslim ze to je ta zahada.

Neviem aky ma ten export format vobec, kedze s pg nerobim, ale je kludne mozne ze pri istej velkosti(napr 2GB+) ten export robi nejaku optimalizaciu(dodatocna kompresia, ktoru si pri improte sam poriesi) a ide pravdepodobne len o vec nejake cli vlajky s ktorou je to mozne de/aktivovat.

petersveter

Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #8 kdy: 14. 05. 2024, 20:43:46 »
ps: ono samozrejme je mozne ze db2 ma nejake binarne data ktore gzip nevie spracovat a db3 ma naopak primarne take co idu. napriklad ak su v db2 primarne jpeg obrazky ako bloby a v db3 su normalne data ake clovek v db ocakava. vtedy takyto vysledok je mozne ocakavat.

Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #9 kdy: 14. 05. 2024, 20:55:49 »
100M rozdiel
Ten rozdíl nemusí být 100 MB, klidně to může být rozdíl jediného bajtu. Padding na konci posledního bloku to tedy klidně může udělat.

Neviem o tej db nic, ale je kludne mozne ze je tam cez povedzme 5M riadkov ktore su exportovane samostatne ako insert into a kazdy je samostatne zasifrovany. Je to uplne v poriadku vysledok.
Šifrovaný je celý zkomprimovaný soubor.

Myslim ze problem tu je ta db3 kde skoro 8gb db vyprodukuje ledva 2gb export. Na to sa skor OP pyta. A tam jedine ze je to zasifrovane a potom gzipovane, lenze potom preco db2 tiez nie je mensia/gzipnuta? Myslim ze to je ta zahada.
Nesmysl. Za prvé, je to vidět, že je to zkomprimované a pak zašifrované. Za druhé, kdyby to bylo zašifrované a zkomprimované, bude to plus mínus stejně velké. Proto se nikdy nekomprimují šifrovaná data, ale šifrují se komprimovaná data. Podstata šifrování je to, aby výstup připomínal co nejvíce náhodná data – a ta se nedají komprimovat.

Neviem aky ma ten export format vobec, kedze s pg nerobim, ale je kludne mozne ze pri istej velkosti(napr 2GB+) ten export robi nejaku optimalizaciu(dodatocna kompresia, ktoru si pri improte sam poriesi) a ide pravdepodobne len o vec nejake cli vlajky s ktorou je to mozne de/aktivovat.
Výstup je sekvence SQL příkazů, které vytvoří současný stav databáze. Tj. CREATE, INSERT apod. Proto to jde tak dobře komprimovat.

Každopdáně problém je zjevně v tom, že jsou data useknutá – a jde o to, zda to dělá aplikace nebo souborový systém. Může to být souborový systém, 2 GiB je limit na velikost souboru FAT16. Ale 2 GiB je zároveň velikost znaménkového intu, takže to může být i problém aplikace.

Proto je potřeba jako první zjistit přesnou velikost souborů v bajtech – zda jsou opravdu oba dva stejně velké a odpovídají tomu 231.


Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #11 kdy: 15. 05. 2024, 09:07:06 »
Presne podle ocekavani, nejdrive se spustil pg_dump, vystup je  .sql.gz, pak se spustil druhy pg_dump, ale vystup sql.gz se rovnou zasifroval:

Kód: [Vybrat]
-rw-r--r-- 1 postgres postgres 2035990520 May 15 00:04 db2_15.05.24-00_00.sql.gz
-rw-r--r-- 1 postgres postgres 2004624114 May 15 00:33 db2_15.05.24-00_00.sql.gz.ssl
-rw-r--r-- 1 postgres postgres 7910422089 May 15 00:28 db3_15.05.24-00_00.sql.gz
-rw-r--r-- 1 postgres postgres 2004624114 May 15 00:58 db3_15.05.24-00_00.sql.gz.ssl


Zkusim kouknout na ty parametry, co poslal NCC1701E. Kazdopadne pokud to tak je, tak je to prasarna od openssl.
« Poslední změna: 15. 05. 2024, 09:09:18 od czechsys »

Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #12 kdy: 15. 05. 2024, 09:25:58 »
Můžete pro šifrování místo openssl zkusit použít GPG. Ale nevybavuju si, jestli jsem někdy měl takhle velké soubory záloh. Používám tam asymetrickou šifru, takže na stroji, který zálohy vyrábí, je jen veřejný klíč – kdyby se tam někdo dostal, dostane se k aktuálním datům, ale nebude mít klíč pro dešifrování všech záloh.

Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #13 kdy: 15. 05. 2024, 10:04:29 »
Tak otestovano s pridanym parametrem -stream:

Kód: [Vybrat]
#cat ./db3_15.05.24-00_00.sql.gz | openssl smime -encrypt -aes256 -binary -stream -outform DEM -out ./encrypted.sql.gz.ssl pgdump_backup.pem
-rw-r--r-- 1 root   root     7910422089 May 15 00:28 db3_15.05.24-00_00.sql.gz
-rw-r--r-- 1 root   root     7918147866 May 15 09:36 encrypted.sql.gz.ssl

Kód: [Vybrat]
#openssl smime -decrypt -in ./encrypted.sql.gz.ssl -binary -inform DEM -inkey ./pgdump_backup_key.pem -out ./decrypted.sql.gz
Error reading S/MIME message
4077734DF87F0000:error:038C0100:memory buffer routines:BUF_MEM_grow_clean:malloc failure:../crypto/buffer/buffer.c:128:
4077734DF87F0000:error:068C0100:asn1 encoding routines:asn1_d2i_read_bio:malloc failure:../crypto/asn1/a_d2i_fp.c:209:

#openssl smime -decrypt -in ./encrypted.sql.gz.ssl -binary -stream -inform DEM -inkey ./pgdump_backup_key.pem -out ./decrypted.sql.gz
Error reading S/MIME message
40073BBB2D7F0000:error:038C0100:memory buffer routines:BUF_MEM_grow_clean:malloc failure:../crypto/buffer/buffer.c:128:
40073BBB2D7F0000:error:068C0100:asn1 encoding routines:asn1_d2i_read_bio:malloc failure:../crypto/asn1/a_d2i_fp.c:209:

#free -h
               total        used        free      shared  buff/cache   available
Mem:            47Gi        13Gi       3.2Gi        11Gi        42Gi        33Gi
Swap:          2.7Gi       1.3Gi       1.4Gi

To je sranda. Tak zpatky na zacatek nekam do praveku...

Re:Šifrování pg_dump pomocí OpenSSL
« Odpověď #14 kdy: 15. 05. 2024, 10:04:54 »
hm, tohle je dost velká prasárna, nikdy jsem se s tím zatím nesetkal, je ale pravda, že velké archivy s openssl nešifruji snad nikde, všude je gpg či jiný nástroj či formát. Dobré vědět!

Přidej si tam ty checksumy, hned by ti to spadlo na validaci, protože rozbalený šifrovaný archiv by měl jiný checksum než originál. Jak psal Filip, checksum si ukládej vedle do souboru. Vyhneš se všem těmhle hidden truncate problémům nebo třeba OOM chybě při šifrování.

U toho db3_15.05.24-00_00.sql.gz to jasně vypadá na oříznutí, aes256 v žádné variantě nesnižuje takhle razantně velikost, výjimkou mohou být nějaké spare blocky na FS či nadměrná alokace, kterou ls může ukazovat.