Chroot rsync для безопасного сбора бэкапов с удалённых хостов
2019-05-12
Один из способов использования Rsync для синхронизации файлов между машинами, это подключение rsync-клиента к rsync-серверу через ssh-сеанс.
Здесь я описал следующий сценарий выкачивания файлов из удалённого хоста site01.example.com на бэкап-хост:
- На клиенте, которым выступает бэкап-хост, запускаем rsync-клиент:
rsync -avP rbkp@site01.example.com:/backup/ /backup/- Клиент стучится на ssh-порт сервера
site01.example.comот имени пользователя rbkp. - На сервере служба
sshdсоздаёт сеанс для rbkp в подготовленной песочнице. - В контексте сеанса rbkp через
/bin/shначинает выполняться rsync-сервер:rsync --server --sender -vlogDtpre.iLsf . /backup/.
- Происходит синхронизация между rsync-клиентом и rsync-сервером.
Подготавливаем песочницу на удалённом хосте
Создаём скелет песочницы для rsync-сервера, то есть создаём отдельную директорию с небольшим количеством файлов. Подключившийся пользователь, от имени которого запустится rsync --server ..., будет иметь доступ только к содержимому этой директории.
# mkdir -p /mnt/rbkp/{.ssh,backup,bin}
# chmod g+s /mnt/rbkp/backup
- В директории
.sshсоздадим файлauthorized_keysсо строкой идентификатора публичного ключа для ssh-сеанса. - В директории
backupскладируем бэкапы, предназначенные для передачи в архив. - В папке
binлежат бинарники, необходимые для работы rsync-сервера. - В процессе подготовки песочницы появятся ещё две или три директории (
lib, lib64, usr/libи т.д.) с библиотеками, необходимыми для работы бинарников.
Копируем бинарники:
# cp /bin/sh /usr/bin/rsync /mnt/rbkp/bin/
Ищем библиотеки необходимые для работы бинарников и копируем их в соответствующие папки. Для /bin/sh:
# for f in $(ldd /bin/sh | awk '{print $1"\n"$3}' | grep ^/); do echo $f && rsync -aRL $f /mnt/rbkp; done
/lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2
Для /usr/bin/rsync:
# for f in $(ldd /usr/bin/rsync | awk '{print $1"\n"$3}' | grep ^/); do echo $f && rsync -aRL $f /mnt/rbkp; done
/lib/x86_64-linux-gnu/libattr.so.1
/lib/x86_64-linux-gnu/libacl.so.1
/lib/x86_64-linux-gnu/libpopt.so.0
/lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2
В результате выполнения этих команд в песочнице появятся библиотеки, необходимые для работы бинарников.
Создаём пользователя для работы rsync-сервера на удалённом хосте
Создаём пользователя без домашней папки, пароля и с минималистическим командной оболочкой sh:
# adduser --home /mnt/rbkp --no-create-home --disabled-password --shell /bin/sh rbkp
Назначим правильных владельцев на песочницу
# chown -R root:root /mnt/rbkp
# chown -R rbkp:rbkp /mnt/rbkp/.ssh /mnt/rbkp/backup
Настраиваем sshd на удалённом хосте
Подразумевается, что sshd уже настроен на подключение с помощью открытых ключей.
В файл /etc/ssh/sshd_config добавляем блок отвечающий за перемещение пользователя rbkp в песочницу. Перемещение выполняется после проверки ключа ssh.
Match User rbkp
ChrootDirectory /mnt/rbkp
Генерируем ssh-ключи и настраиваем свойства подключения
На бэкап-хосте, в директории для бэкапов, генерируем новые безпарольные ssh-ключи:
ssh-keygen -t ed25519 -a 256 -C rbkp_ed25519_$(date +%Y%m%d) -f rbkp_ed25519_$(date +%Y%m%d)
На удалённом хосте в файл /mnt/rbkp/.ssh/authorized_keys добавляем публичную часть нового ssh-ключа и указываем опции ужесточающие политику подключения:
# cat /mnt/rbkp/.ssh/authorized_keys
command="/bin/rsync --server --sender -vlogDtpre.iLsf . /backup/",no-port-forwarding,no-X11-forwarding,no-user-rc,no-agent-forwarding,no-pty ssh-ed25519 AAAAC3Nza...fDWFH rbkp_ed25519_20190331
Итоги
На бэкап-сервере ставим в крон задачу:
rsync -avP -e'ssh -p22 -irbkp_ed25519_20190331 -oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no' --bwlimit=1M rbkp@site01.example.com:/backup/ /mnt/backup/example.com/
В случае кражи ssh-ключей и информации о параметрах для подключения к удалённому хосту, злоумышленнику будет доступен удалённый просмотр папки /mnt/rbkp/backup (посредством rsync --list-only) и её выкачивание на свою машину. Если права на папку допускают удаление, то информация в этой папке может быть уничтожена.