Зачем шифровать файлы и резервные копии на сервере с помощью GPG?
Шифрование файлов и резервных копий защищает данные, если носитель или канал передачи скомпрометированы: украден диск VDS, скопирован архив бэкапа из стороннего S3-хранилища, перехвачен трафик при выгрузке на удалённый сервер. GPG (GnuPG, реализация OpenPGP) шифрует файлы без сервера ключей и базы данных — достаточно бинарника gpg и файла-ключа. На VDS/VPS и выделенных серверах ZevsHost.net в Германии, США и Франции шифрование бэкапов через GPG обязательно всегда, когда архив покидает сервер: уходит на внешний S3, на FTP резервного хостинга или в другой дата-центр.
GPG поддерживает два режима: симметричное шифрование одним паролем (gpg -c) для разовой защиты файла и асимметричное шифрование парой ключей — публичным и приватным — для автоматических бэкапов без участия человека. Разберём обе схемы ниже.
Как быстро зашифровать файл симметрично: gpg -c и passphrase?
Симметричное шифрование подходит для разовой задачи: передать один архив коллеге, отправить конфиг с секретами, зашифровать снимок базы перед копированием на флешку.
gpg -c --cipher-algo AES256 backup.sql
# спросит passphrase дважды, создаст backup.sql.gpg
gpg -o backup.sql -d backup.sql.gpg
# спросит passphrase для расшифровки
Флаг --cipher-algo AES256 фиксирует алгоритм явно: без него старые версии GPG выбирают CAST5, а он слабее AES256. Пароль здесь вводится интерактивно, поэтому для cron-скрипта нужен файл с паролем и правами 600, иначе его сможет прочитать любой локальный пользователь — подробнее о правах читайте в статье про настройку прав доступа Linux.
Как сгенерировать пару ключей GPG и зашифровать бэкап асимметрично?
Асимметричная схема нужна для автоматических бэкапов: скрипт шифрует архив публичным ключом, а расшифровать его может только тот, у кого есть приватный ключ и пароль от него. Приватный ключ на продакшн-сервере хранить не обязательно — достаточно публичного.
gpg --full-generate-key
# выбрать RSA and RSA, размер ключа 4096
gpg --list-keys
gpg --export -a "backup@zevshost-client.example" > pubkey.asc
gpg --import pubkey.asc
Ключевая пара по умолчанию хранится в ~/.gnupg (для root — в /root/.gnupg). Шифрование бэкапа под ключ получателя:
gpg --encrypt --recipient "backup@zevshost-client.example" backup.tar.gz
# создаст backup.tar.gz.gpg
gpg --output backup.tar.gz -d backup.tar.gz.gpg
Приватный ключ — единственный способ вернуть данные, поэтому его нужно вынести за пределы сервера: на офлайн-носитель или в защищённое хранилище секретов, как описано в статье про хранение секретов в Vault. Если приватный ключ потерян или забыт пароль от него — расшифровать архивы невозможно физически, службы восстановления у GPG нет.
Как автоматизировать GPG в cron без ввода пароля вручную?
Cron-скрипт бэкапа не может ждать интерактивного ввода пароля, поэтому есть рабочие варианты автоматизации. Для симметричного шифрования — файл с паролем и флаги --batch:
umask 077
echo 'мой-длинный-пароль' > /root/.backup_pass
chmod 600 /root/.backup_pass
gpg --batch --yes --passphrase-file /root/.backup_pass -c --cipher-algo AES256 -o backup.tar.gz.gpg backup.tar.gz
Для асимметричного шифрования пароль не нужен в момент архивации: шифрование публичным ключом идёт без passphrase, а gpg-agent нужен только для операций с приватным ключом (расшифровка, подпись).
| Способ | Где хранится секрет | Подходит для cron | Риск при компрометации сервера |
|---|---|---|---|
| gpg -c интерактивно | вводится вручную | нет | низкий |
| --passphrase-file (600) | файл на диске | да | средний |
| gpg-agent + кэш | память агента | да, с оговорками | средний |
| шифрование публичным ключом | приватный ключ не на сервере | да | низкий |
Пример строки в crontab -e для root:
0 3 * * * tar czf - /var/www | gpg --encrypt --recipient "backup@zevshost-client.example" -o /backups/site-$(date +\%F).tar.gz.gpg && find /backups -name '*.gpg' -mtime +14 -delete
Как проверить целостность бэкапа: подпись и verify?
Шифрование само по себе не гарантирует, что файл не был подменён или повреждён при передаче на S3. Для этого GPG умеет подписывать файлы отдельно от шифрования:
gpg --detach-sign --armor backup.tar.gz.gpg
# создаст backup.tar.gz.gpg.asc — файл подписи
gpg --verify backup.tar.gz.gpg.asc backup.tar.gz.gpg
# gpg: Good signature from "..." — файл цел
# gpg: BAD signature — файл изменён или повреждён
В скрипте автоматической проверки удобно комбинировать шифрование и подпись одной командой --encrypt --sign, а проверку выносить отдельным шагом перед выгрузкой на S3. При ответе BAD signature выгрузку нужно останавливать и алертить, а не перезаписывать старый бэкап битым архивом. Общий подход к защите сервера, на котором крутится такой скрипт, — в статье про хардненинг SSH.
Чек-лист: типичные ошибки при работе с GPG на сервере
- Потеря приватного ключа без резервной копии — расшифровать старые бэкапы станет невозможно навсегда.
- Файл с паролем для --passphrase-file лежит с правами 644 вместо 600 и читается любым пользователем сервера.
- Шифрование без --cipher-algo AES256 на старых сборках GPG — используется более слабый алгоритм по умолчанию.
- Приватный ключ хранится на том же сервере, который шифрует бэкапы, — при взломе сервера теряется вся защита.
- Нет отдельной проверки gpg --verify после выгрузки на S3 — повреждённый архив обнаруживается только при восстановлении.
Для сравнения: шифрование файловой системы через LUKS защищает весь диск, но не защищает конкретный файл при выгрузке наружу — про этот вариант читайте в статье о LUKS-шифровании диска. GPG и LUKS закрывают разные сценарии и обычно используются вместе: LUKS — для диска сервера целиком, GPG — для файлов и бэкапов, которые покидают сервер.