Почему мой tar через ssh (команда через author_keys) портит архив?

С бэкапа я хочу вытащить дампы tgz рабочего сервера. Обе машины работают под управлением Ubuntu 16.04.

Поэтому резервный сервер подключается через ssh и определенный ssh ​​к производственному серверу.

~/.ssh/authorized_keys Файл соответствующего пользователя на производственном сервере должен просто разрешать одну команду и накладывать как можно больше ограничений (надеюсь?):

command="tar -cz --file - --ignore-command-error --ignore-failed-read /dir/ 2>/dev/null | cat",no-agent-forwarding,no-port-forwarding,no-user-rc,no-X11-forwarding ssh-rsa AABLASHKEY comment

где /dir/ каталог для резервного копирования, AABLASSHKEY а также comment "реальные" значения, конечно.

| cat в этом случае требуется, потому что иначе tar в этой версии ubuntu ("tar (GNU tar) 1.28") не будет говорить с stdout, заданным ssh (PTY). Стдерр должен уйти в пустоту (2> /dev/null).Изменить: точка зрения о PTY является заблуждение, см. Ответ @grawity.

На принимающей стороне (backup сервер) Я поднимаю это так:

ssh -i /path/to/key the-user@production-server > dir.tgz

Однако полученный файл отличается по размеру от архива, если я создаю его на сервере, и он не является допустимым архивом (например, gzip: stdin: invalid compressed data--crc error ... gzip: stdin: invalid compressed data--length error). Разница в размере составляет 22 байта.

Если я разрешу резервному серверу любую команду на производительном сервере, сняв ограничения в authorized_keys это работает отлично. В какой момент я скучаю?

Ограничения

  • Я очень хочу использовать tar (не Rsync, Rrsync или что-то в этом роде).
  • Соединение должно быть инициировано резервным сервером
  • Рабочий сервер не должен создавать никаких временных файлов

Решение

Как указал @Grawity в своем ответе (прочитайте его, чтобы очистить некоторые заблуждения), следующую строку в ~.ssh/authorized_keys решает проблему (и работает на Ubuntu 16.04 с данной версией OpenSSH):

command="tar -cz --file - --ignore-command-error --ignore-failed-read /dir/ 2>/dev/null",restrict ssh-rsa ....

Чтобы команда back-up-server не выдавала предупреждений, подключитесь к:

ssh -o RequestTTY=no -i /path/to/key the-user@production-server > dir.tgz

1 ответ

Решение

| cat в этом случае требуется, потому что иначе tar […] не будет говорить с stdout, заданным ssh (PTY).

Нет. Наличие PTY - это точно одна из ваших проблем. Слой tty существует для обработки управляющих символов терминала и совершенно не нужен для других типов данных.

Обычно работает SSH в пакетном режиме (т.е. ssh <host> <cmd>) не будет выделять серверную часть PTY; это обеспечит 8-битный чистый канал. Но когда вы не предоставляете команду на клиенте, вам нужно явно добавить -T или же RequestTTY опция клиента для отключения запроса TTY,

ssh -T theuser @ prod> dir.tgz
ssh -o RequestTTY = no theuser @ prod> dir.tgz

или предоставьте фиктивную команду,

ssh theuser @ prod foo > dir.tgz

или запретить такие запросы с no-pty опция author_keys:

command = "tar -czf - / dir / 2> / dev / null", no-pty, ограничить ssh-rsa ABCDEF

( restrict это недавно добавленный псевдоним, который отключает все переадресации сразу, включая те, которые могут быть добавлены в будущем. Доступно с OpenSSH 7.2. На самом деле, это даже включает в себя no-pty , хотя я перечислил это отдельно для этого ответа.)

Другие вопросы по тегам