Bog BOS: SSH и OpenSSH: принципы работы, установка и настройка
SSH обеспечивает возможность удаленного выполнения команд (вместо telnet, rsh и всего, что над ним построено - rsync, rdist и т.д.) и копирования файлов (вместо rcp, ftp) с аутентификацией клиента и сервера и шифрованием (и сжатием) передаваемых данных (пароли также шифруются). Дополнительно обеспечивается шифрование данных X Windows и перенаправление любых TCP-соединений (а это уже ухудшает безопасность, т.к. позволяет делать туннели в обход firewall). Защищает от атак с подделкой (spoof) IP-адресов (включая source routing), DNS-сервера и маршрутизации, от подслушивания паролей и X аутентификации, от подслушивания и манипуляции данными на промежуточных хостах или локальной сети. SSH не защищает, если атакующий получил права root на вашем хосте или права к домашней директории.
Используемые порты: 22/tcp, 22/udp.
Представляет собой протоколы транспортного уровня, аутентификации и соединения (предполагается стандартизация IETF) и программные средства безопасного доступа к компьютерам по небезопасным каналам связи (telnet, X11, rsh, ftp). Аутентификация производится с использованием ассиметричного шифрования с открытым ключом (SSH1 - RSA, SSH2 - RSA/DSA, благо патент на RSA уже истек). Обмен данными - симметричное шифрование (IDEA - патентованный, DES, triple DES, ARCFOUR - вроде найдена дырка, BLOWFISH - быстрый, CAST128, AES/Rijndael). Целостность переданных данных проверяется с помощью CRC32 в SSH1 (подделывается при атаке типа "man in the middle") или HMAC-SHA1/HMAC-MD5 в SSH2. Протокол транспортного уровня работает поверх TCP, обеспечивает аутентификацию сервера. В качестве ключа используется случайная строка, которую генерирует клиент, шифрует с помощью открытого ключа сервера - его надо откуда-то получить - и передаёт ему (сервер знает свой частный ключ и дешифрует строку, затем передаёт её клиенту, если строка дешифрована правильно, значит сервер настоящий). Протокол аутентификации работает поверх протокола транспортного уровня, обеспечивает аутентификацию клиента для сервера. Протокол соединения - поверх протокола аутентификации, мультиплексирует безопасный канал. Шифрование начинается после аутентификации сервера, но до аутентификации клиента, т.е. паролей в открытом виде не передаётся вовсе. Автоматически производится X11 forwarding (по наличию переменной DISPLAY). Возможно соединение произвольных портов TCP по защищенным каналам. Предусматривается возможность сжатия.
SSH1 и SSH2 - совершенно разные протоколы (использование SSH1 не рекомендуется):
- SSH1 подвержен атаке типа "man in the middle"
- SSH1 поддерживает аутентификацию по .rhosts/hosts.equiv (хотя пользоваться этим не надо)
- SSH1 имеет поддержку разнообразных методов аутентификации клиента (AFS, Kerberos, etc.)
Каждый хост должен иметь не менее одного ключа (м.б. общий для нескольких хостов). Предполагается возможность работы с несколькими алгоритмами с открытым ключом, но пока он один - DSS (Digital Signature Standard).
SSH1: каждый хост имеет RSA ключ хоста (обычно 1024 бит), при запуске sshd генерирует временный (1 час, на диск не записывается) RSA ключ сервера (обычно 768 бит). После соединения клиента, сервер передает ему публичный ключ хоста и публичный ключ сервера. Клиент сверяет публичный ключ хоста со своей базой ключей, затем генерирует случайное число (256 бит) и шифрует его публичными ключами хоста и сервера, после чего отсылает серверу. В дальнейшем это случайное число используется как ключ сессии - с его помощью шифруются все сообщения. Алгоритм шифрования предлагается сервером и выбирается клиентом - 3DES (по умолчанию) или Blowfish (быстрее). Клиент пытается аутентифицировать себя с помощью .rhosts или др. механизма (см. ниже).
SSH2: Каждый хост имеет DSA/RSA ключ хоста. Ключ сервера не генерируется. Аутентификация сервера и ключ сессии обеспечивается с помощью алгоритма Diffie-Hellman. Остаток сессии шифруется симметричым алгоритмом шифрования: Blowfish, 3DES, CAST128, Arcfour, AES (128, 192, 256 бит). Целостность сессии обеспечивается hmac-sha1 или hmac-md5. Аутентификация клиента происходит с помощью публичных ключей или "обычных" паролей или интерактивного обмена с помощью дополнительных средств.
Модели аутентификации сервера:
- клиент имеет локальный файл, определяющий соответствие имени сервера и его открытого ключа
- клиент знает открытый ключ сертификационного агента, который отвечает за проверку имени хоста по его открытому ключу (я не разбирался)
Методы аутентификации клиента:
- SSH1: /etc/hosts.equiv, /etc/shosts.equiv, ~/.rhosts, ~/.shosts
- SSH1: RSA (ssh-keygen создает public/private ключи; открытый (public) ключ (из ~/.ssh/identity.pub) хранится на сервере в ~/.ssh/authorized_keys)
- SSH1: RSA в сочетании с .rhosts (хост клиента аутентифицируется по /etc/ssh_known_hosts, ~/.ssh/known_hosts)
- SSH1: разовые пароли s/key
- SSH1: kerberos
- SSH1, SSH2: пароли (шифруются при пересылке)
- SSH2: DSA (ssh-keygen создает public/private ключи; открытый (public) ключ (из ~/.ssh/dsa_id.pub) хранится на сервере в ~/.ssh/authorized_keys)
- SSH2: RSA (ssh-keygen создает public/private ключи; открытый (public) ключ (из ~/.ssh/rsa_id.pub) хранится на сервере в ~/.ssh/authorized_keys)
- SSH2: интерактивный обмен с помощью дополнительных средств (чтение карточек и т.д.), я это не рассматривал
Если запустить sshd из-под обычного пользователя, то можно будет заходить только под этим пользователем (используя -p для непривилегированного порта).
Для аутентификации клиента по хосту ssh должен использовать привилегированный порт (номер порта менее 1024). Для привязки к привилегированному порту ssh должен иметь права setuid root. Если аутентификация клиента по хосту не предполагается, то эти права можно снять. Чтобы использовать обычный порт надо задать опцию "UsePrivilegedPort no" в конфигурационном файле или командной строке.
Бесплатная реализация протокола SSH для BSD. Портирован под другие OS (версии с буквой "p"). В частности, удалось запустить его под Solaris 2.5 (чего не удалось сделать с оригинальной системой) и Linux 2.2/2.4. Поддерживает протоколы 1.3, 1.5 и 2.0. При желании поддерживает Entropy Gathering Daemon (egd) или PRNGd, PAM и Gnome passphrase. Для установки требуется zlib 1.1.3 и OpenSSL 0.9.5a/0.9.6b. Вывод сообщений на syslog.
Изменения в версиях OpenSSH
- zlib и OpenSSL в Linux Red Hat 7.2/7.1/7.0 штатные (хотя OpenSSL какой-то медленный), для Linux Red Hat 6.2 надо предварительно установить OpenSSL 0.9.6b, должны быть установлены пакеты pam и pam-devel
- получить дистрибутив и разархивировать его
- ./configure --with-ipv4-default --with-pam --with-tcp-wrappers --with-md5-passwords --disable-suid-ssh --with-default-path=...
- make
- make install (при обновлении не заменяются старые ssh_config, sshd_config)
- /usr/local/bin
- ssh (AKA slogin)
- scp
- ssh-add (добавление ключей в хранитель - ssh-agent)
- ssh-agent (хранитель ключей)
- ssh-keygen
- ssh-keyscan
- sftp
- /usr/local/sbin/sshd
- /usr/local/libexec/sftp-server
- /usr/local/man/man1 (ssh.1, scp.1, ssh-add.1, ssh-agent.1, ssh-keygen.1, ssh-keyscan.1, sftp.1)
- /usr/local/man/man8 (sshd.8, sftp-server.8)
- /usr/local/etc
- ssh_config
- sshd_config
- moduli
- ssh_host_key и ssh_host_key.pub (приватная и публичная части RSA ключа хоста длиной 1024 bit для root@полное-имя-хоста; SSH1; при обновлении версии сохраняются старые ключи)
- ssh_host_rsa_key и ssh_host_rsa_key.pub (приватная и публичная части RSA ключа хоста длиной 1024 bit для root@полное-имя-хоста; SSH2; при обновлении версии сохраняются старые ключи)
- ssh_host_dsa_key и ssh_host_dsa_key.pub (приватная и публичная части DSA ключа хоста для root@полное-имя-хоста; SSH2; при обновлении версии сохраняются старые ключи)
- при обновлении версии в связи с изменениями внести исправления в ssh_config, sshd_config; слить ssh_known_hosts и ssh_known_hosts2; слить authorized_keys и authorized_keys2; перезапустить sshd
- /usr/local/bin
- налаживание инфраструктуры
- остановить все лишние сервера (telnet, rsh, ftp)
- поставить zlib и OpenSSL 0.9.6b
- получить дистрибутив и разархивировать его
- добавить /usr/ccs/bin в PATH
- ./configure --with-ipv4-default --without-pam --disable-suid-ssh --with-default-path=...
- make (20 MB)
- make install (при обновлении не заменяются старые ssh_config, sshd_config)
- /usr/local/bin
- ssh (AKA slogin)
- scp
- ssh-add (добавление ключей в хранитель - ssh-agent)
- ssh-agent (хранитель ключей)
- ssh-keygen
- ssh-keyscan
- sftp
- /usr/local/sbin/sshd
- /usr/local/libexec/sftp-server
- /usr/local/man/man1 (ssh.1, scp.1, ssh-add.1, ssh-agent.1, ssh-keygen.1, ssh-keyscan.1, sftp.1)
- /usr/local/man/man8 (sshd.8, sftp-server.8)
- /usr/local/etc
- ssh_config
- sshd_config
- ssh_prng_cmds (как собирается энтропия для встроенного генератора случайных чисел, при обновлении версии сохраняется старая программа)
- moduli
- ssh_host_key и ssh_host_key.pub (приватная и публичная части RSA ключа хоста длиной 1024 bit для root@просто-имя-хоста; SSH1; при обновлении версии сохраняются старые ключи)
- ssh_host_rsa_key и ssh_host_rsa_key.pub (приватная и публичная части RSA ключа хоста длиной 1024 bit для root@просто-имя-хоста; SSH2; при обновлении версии сохраняются старые ключи)
- ssh_host_dsa_key и ssh_host_dsa_key.pub (приватная и публичная части DSA ключа хоста для root@просто-имя-хоста; SSH2; при обновлении версии сохраняются старые ключи)
- при обновлении версии в связи с изменениями внести исправления в ssh_config, sshd_config; слить ssh_known_hosts и ssh_known_hosts2; слить authorized_keys и authorized_keys2; перезапустить sshd
- /usr/local/bin
- налаживание инфраструктуры
- остановить все лишние сервера (telnet, rsh, ftp)
- Установка 2.3.0p1 в RedHat 7.0
- Установка 2.2.0p1 в Solaris 2.5 и RedHat 6.2
Обеспечение безопасности вообще и установка ssh, в частности, - это не просто запуск одной программы, а налаживание инфраструктуры взаимодействия различных компонент. Инфраструктура будет различаться в зависимости от поставленных задач, внешних обстоятельств и личных предпочтений. Например, у меня нет необходимости обеспечивать совместимость с SSH1, поэтому при установке всякая возможность работы в режиме SSH1 была намерено обрезана. Также были обрезаны возможности работы с .rhosts, kerberos.
- устанавливаем OpenSSH на все хосты как было описано выше (здесь же создаются RSA/DSA ключи хостов)
- конфигурируем /usr/local/etc/sshd_config
(права 600) на серверах (я опускаю несущественные параметры)
- AllowUsers список-допущенных-пользователей
- ClientAliveInterval 20
- GatewayPorts no
- HostbasedAuthentication no
- HostKey /usr/local/etc/ssh_host_dsa_key
- IgnoreRhosts yes
- IgnoreUserKnownHosts yes
- KeepAlive yes
- #Port 22
- #ListenAddress 0.0.0.0
- LogLevel INFO
- PasswordAuthentication no
- PermitEmptyPasswords no
- PermitRootLogin no
- PrintMotd no
- Protocol 2
- ReverseMappingCheck yes
- RhostsAuthentication no
- RhostsRSAAuthentication no
- RSAAuthentication no
- StrictModes yes
- Subsystem sftp /usr/local/libexec/sftp-server
- SyslogFacility AUTH
- X11Forwarding yes (если на хосте есть X Windows)
- X11DisplayOffset 10 (если на хосте есть X Windows)
- обеспечение запуска "sshd -u0 -4" при загрузке
- Solaris: /etc/init.d/sshd и линк на него из /etc/rc2.d/S99sshd
- Linux Red Hat: /etc/rc.d/init.d/sshd и линк на него из /etc/rc.d/rc2.d/S98sshd (и rc3.d)
- собираем все ssh_host_dsa_key.pub, формируем из них /usr/local/etc/ssh_known_hosts и копируем на все хосты
- открыть дырки в сетевых экранах для TCP/22
- чтобы PAM в RedHat был счастлив - скопировать /etc/pam.d/login в /etc/pam.d/sshd (убрать nullok, тем более что начиная с RH 7.0 его нет)
- конфигурация клиента /usr/local/etc/ssh_config
- Host *
- Cipher blowfish (самый быстрый)
- Ciphers blowfish-cbc,3des-cbc
- Compression yes (для Fast Ethernet выключить)
- FallBackToRsh no
- ForwardAgent yes
- ForwardX11 yes
- GatewayPorts no
- HostbasedAuthentication no
- IdentityFile ~/.ssh/id_dsa (нет у меня id_rsa)
- KeepAlive yes (клиент не завершается)
- LogLevel INFO
- PasswordAuthentication no
- PreferredAuthentications publickey
- Protocol 2
- RhostsAuthentication no
- RhostsRSAAuthentication no
- RSAAuthentication no
- StrictHostKeyChecking yes
- UsePrivilegedPort no
- UseRsh no
- настройка для интерактивной работы. Т.к. в этом режиме возможно выполнение
любых команд, то вход на другой хост без запроса пароля нежелателен, иначе
взлом одного хоста автоматически ведет к взлому всех остальных. Но и вводить
пароль каждый раз утомительно.
- на клиентском хосте (с вводом парольной фразы подлиннее): ssh-keygen -t dsa -f ~/.ssh/id_dsa
- на сервере в ~/.ssh/authorized_keys (права 600) добавить содержимое файла ~/.ssh/id_dsa.pub с клиентского хоста
- в процедуру начала сеанса на клиентском хосте (.bashrc или .bash_profile
или .profile; только с учетом, что мы сюда попали тоже с помощью ssh) или
вручную
- eval `ssh-agent`
- ssh-add ~/.ssh/id_dsa (здесь будет запрошена парольная фраза, но один раз за сеанс)
- теперь при выдаче ssh парольная фраза (и пароль серверного хоста запрашиваться не будет)
- в конце сеанса (только не .bash_logout) надо выдать "ssh-agent -k"
- Выполнение удаленных команд в пакетном режиме (backup, из cron). Здесь
некому будет вводить пароль или парольную фразу. Но и разрешать выполнять
любую команду с одного хоста на другом тоже не хочется (вскрытие первого хоста
автоматически открывает второй). Для каждой команды, которую надо выполнять в
пакетном режиме с одного хоста на втором (backup) делаем:
- на первом хосте выполнить: ssh-keygen -t dsa -N "" -f ~/.ssh/обозначение-команды
- на втором хосте в ~/.ssh/authorized_keys (права 600) добавить строку (учитывать значение PATH): command="текст команды",no-X11-forwarding,no-port-forwarding,no-pty,no-agent-forwarding<содержимое файла ~/.ssh/обозначение-команды.pub на первом хосте>
- в командный файл (или cron) на первом хосте вставлять команду удаленного выполнения (на stderr выдается ненужное в данном случае сообщение о закрытии соединения; переменные окружения SSH_AUTH_SOCK и SSH_AGENT_PID не должны быть установлены): ssh -i ~/.ssh/обозначение-команды второй-хост
- избавиться от всех telnet, ftp и rsh
- --prefix=куда-устанавливать (/usr/local)
- --with-rsh=имя-файла
- --with-pam (с 2.5.1p1)
- --without-pam (до 2.5.1p1)
- --without-lastlog
- --with-kerberos4=директория
- --with-skey
- --with-tcp-wrappers (libwrap.a есть?)
- --with-md5-passwords (пароли MD5 используются, а PAM - нет)
- --with-default-path=PATH (устанавливает переменную PATH для сессии)
- --with-ipv4-default (использовать IPv4 по умолчанию вместо IPv6)
- --with-egd-pool (до 2.5.2p1)
- --with-prngd-socket (с 2.5.2p1)
- --with-prngd-port (с 2.5.2p1)
- --disable-suid-ssh (с 3.0)
Демон должен быть запущен на сервере (компьютере, на который мы хотим зайти). Запуск предполагается автоматически из /etc/rc... Для каждого входного соединения порождается новый процесс. Параметры передаются либо в управляющем файле (перечитывается по SIGHUP), либо ключами командной строки (имеют приоритет):
- -D (не отсоединяться от терминала при запуске)
- -b bits (число бит ключа сервера (SSH1), по умолчанию 768)
- -d (отладочный режим, использование нескольких ключей увеличивает количество отладочной печати)
- -e (выводить сообщения на stderr вместо syslog)
- -f имя-конфигурационного-файла (/usr/local/etc/sshd_config)
- -g grace-time (сколько ждать пока пользователь вспомнит пароль - 600 секунд)
- -h файл-ключей-хоста (/usr/local/etc/ssh_host_key)
- -i (если запущен из inetd)
- -k keygen-time (интервал регенерации ключа сервера для SSH1, 1 час)
- -p порт (22)
- -q (ничего не посылать на syslog)
- -t (проверка на отсутствие ошибок в конфигурационном файле и ключах)
- -u число (вместо имен хостов, превышающих эту длину, в utmp будет записываться IP-адрес: -u0 вызывает безусловную запись IP-адресов)
- -4 (IPv4)
- -6 (IPv6)
/var/run/sshd.pid - идентификатор головного процесса sshd.
/usr/local/etc/moduli - Diffie-Hellman группы, используемые для аутентификации.
Обеспечение запуска sshd при начальной загрузке: /etc/init.d/sshd в Solaris 2.5 (и ссылка на него /etc/rc2.d/S99sshd) - сделать из соседнего скрипта, /etc/rc.d/init.d/sshd в Linux Red Hat 6.2/7.0/7.1/7.2 (и ссылка на него /etc/rc.d/rc2.d/S98sshd, /etc/rc.d/rc3.d/S98sshd) - взять из rpm.
Права на чтение и запись должны быть только для root. Пустые строки и строки, начинающиеся с "#", считаются комментариями.
- AllowGroups список-имен-групп-через-пробел (вход разрешен только пользователям, чья первичная (начиная с 2.5.1p1 и вторичная) группа входит в этот список; разрешаются ? и *)
- AllowTcpForwarding yes/no (запрещение не увеличивает безопасность - человек просто поставит другую программу)
- AllowUsers список-имен-через-пробел (аналогично AllowGroups)
- AuthorizedKeysFile имя-файла-с-публичным ключом (~/.ssh/authorized_keys)
- Banner сообщение-перед-аутентификацией
- Ciphers (список алгоритмов симметричного шифрования для SSH2: aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour)
- ClientAliveInterval секунд (0, интервал проверки не отвалился ли клиент; по шифрованному каналу)
- ClientAliveCountMax число (3, число неудачных проверок до разрыва сессии)
- DenyGroups список-имен-групп-через-пробел
- DenyUsers список-имен-через-пробел
- GatewayPorts no/yes (разрешать ли удаленным хостам доступ к перенаправленным портам)
- HostbasedAuthentication no/yes (только для SSH2)
- HostKey имя-файла-содержащего-приватный-ключ (/usr/local/etc/ssh_host_key; может быть несколько штук; в файле могут лежать rsa1, rsa и dsa ключи; по умолчанию: /usr/local/etc/ssh_host_key, /usr/local/etc/ssh_host_dsa_key, /usr/local/etc/ssh_host_rsa_key)
- IgnoreRhosts yes/no (не использовать .rhosts и .shosts для аутентификации; /etc/hosts.equiv /etc/shosts.equiv будут использоваться все равно)
- IgnoreUserKnownHosts no/yes (игнорировать ~/.ssh/known_hosts во время аутентификации rhosts+RSA)
- KeepAlive yes/no (использовать механизм регулярных сообщений для проверки разрыва связи; по открытому каналу)
- KerberosAuthentication yes/no
- KerberosOrLocalPasswd yes/no (если аутентификация через kerberos не прошла, то использовать /etc/passwd)
- KeyRegenerationInterval 3600 (интервал регенерации ключа сервера)
- ListenAddress 0.0.0.0 (к каким адресам прислушиваться; команда Port д.б. раньше по тексту; начиная с 2.9p1 порт можно указывать здесь же; можно слушать несколько адресов/портов)
- LoginGraceTime секунд (600, сколько секунд давать пользователю, чтобы вспомнить пароль)
- LogLevel INFO (QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG)
- MACs алгоритмы-проверки-целостности-данных (hmac-md5,hmac-sha1,hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96)
- MaxStartups 10 (максимальное число соединений, ожидающих аутентификации; алгоритм раннего предупреждения перегрузки - 10:30:60, отвергать соединение с вероятностью 30%, если уже есть 10 еще неаутентифицированных соединений, вероятность постепенно возрастает до 100% при 60 соединениях)
- PAMAuthenticationViaKbdInt no/yes (заодно разрешает аутентификацию по паролю)
- PasswordAuthentication yes/no (разрешить аутентификацию по паролю; дается рекомендация - закрыть)
- PermitEmptyPasswords no/yes
- PermitRootLogin yes/no/without-password/forced-commands-only (without-password запрещает только аутентификацию по паролю; при использовании RSA-аутентификации с указанием команды исполнение этой команды разрешается в любом случае; forced-commands-only удобен для backup)
- PidFile имя-файла
- Port 22 (может быть несколько)
- PrintLastLog yes/no
- PrintMotd yes/no (выдавать /etc/motd при входе)
- Protocol 1 (1 2 или 1,2 - поддерживаемые версии протокола)
- PubkeyAuthentication yes/no
- ReverseMappingCheck no/yes (после определения адреса по имени хоста проверять, что обратная зона для этого адреса указывает на тот же самый хост)
- RhostsAuthentication no/yes (разрешить аутентификацию только по .rhosts или /etc/hosts.equiv)
- RhostsRSAAuthentication no/yes (разрешить аутентификацию по .rhosts и RSA аутентификации - требует заполнения ssh_known_hosts)
- RSAAuthentication yes/no (только SSH1)
- ServerKeyBits 768
- SkeyAuthentication yes/no (требует установки PasswordAuthentication)
- StrictModes yes/no (проверять права доступа к файлам с частными паролями при запуске)
- Subsystem (для sftp)
- SyslogFacility AUTH (тип сообщений на syslog: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7)
- UseLogin no/yes (использовать login для интерактивных сессий; для выполнения удаленных команд не используется в любом случае)
- X11DisplayOffset 10 (первый доступный номер дисплея при передаче X11)
- X11Forwarding no/yes (пользователь всегда может установить собственный forwareder)
- XAuthLocation адрес-xauth
/etc/nologin - при наличии этого файла запрещается вход пользователей, кроме root. Содержимое файла выдается в качестве сообщения о причине.
/etc/hosts.allow, /etc/hosts.deny - при компиляции с libwrap используется для контроля доступа как описано в hosts_access(5).
~/.rhosts - на каждой строке пара: хост - пользователь, разделенные пробелом. Данному пользователю с данного хоста разрешается заходить без указания пароля при использовании RhostsAuthentication и RhostsRSAAuthentication (этот же файл используется rlogind и rshd). Чтение и запись только для владельца.
~/.shosts - то же самое, но не используется командами rlogind и rshd.
/etc/hosts.equiv - список хостов, пользователи с которых могут заходить, не указывая паролей под теми же самыми именами. За именем хоста можно указывать имя конкретного пользователя. Право на запись только для root. Отрицание обозначается знаком "-". Обычно используется в сочетании с RSA аутентификацией хоста. Очень не рекомендуется.
/etc/shosts.equiv - аналогично, но не используется командами rsh/rlogin.
~/.ssh/environment - содержит пары вида имя=значение, которые помещаются в окружение при входе.
~/.ssh/rc, /usr/local/etc/sshrc - выполняется /bin/sh при входе после чтения окружения, но до запуска shell или команды.
~/.ssh/authorized_keys (публичные RSA-ключи для SSH1 и публичные RSA/DSA ключи для SSH2) - публичные ключи, разрешенные для RSA аутентификации (SSH1) и аутентификации с помощью публичных ключей (SSH2, PubkeyAuthentication) при использовании данной учетной записи. Чтение и запись только для владельца. На каждой строке - описание одного ключа в виде разделенных пробелами полей (несколько сотен байт!):
- опции (через запятую)
- from="список-шаблонов-через-запятую" (принимать соединения только с хостов, удовлетворяющих одному из шаблонов; спец. символы - ?, * и !)
- command="команда" (при аутентификации по данному ключу запускать только указанную команду, а не то что указано пользователем - например, backup; TCP/IP и X11 надо запрещать дополнительно; обязательно использовать опцию no-pty для бинарной передачи данных)
- no-port-forwarding (запретить TCP/IP forwarding)
- no-X11-forwarding
- environment="имя=значение" (может быть несколько)
- no-agent-forwarding (запретить передачу функции аутентификации внешнему агенту)
- no-pty (запретить запрос pty - интерактивную обработку)
- permitopen="host:port" (ограничить переназначение локального порта: ssh -L)
- ключ
- SSH1: RSA bits, exponent, modulus
- SSH2: тип ключа (ssh-dss или ssh-rsa), кодированный (base64) ключ
- комментарий (имя-пользователя@имя-клиентского-хоста)
/usr/local/etc/ssh_known_hosts, ~/.ssh/known_hosts, - публичные ключи (SSH1/SSH2) для известных хостов. Если пользователь пытается соединиться с незнакомым хостом, публичный ключ хоста добавляется в соответствующий личный файл (у пользователя спрашивается разрешение). Эти же файлы используются при RSA аутентификации по имени хоста. Право на запись только у root (общий файл) или владельца (личный файл). /usr/local/etc/ssh_known_hosts должен быть читаем всеми. Может быть несколько строк с различными ключами для одного хоста. Содержит разделенные пробелами поля:
- список шаблонов (через запятую) имен хостов (при аутентификации клиента шаблон сравнивается с каноническим именем хоста клиента, при аутентификации сервера - с именем, указанным клиентом; спец. символы - ?, * и !)
- RSA bits, exponent, modulus или ssh-dss/ssh-rsa и кодированный в base64 ключ (копируется из /usr/local/etc/ssh_host_[dsa_]key.pub)
- комментарий
/usr/local/etc/ssh_host_key, /usr/local/etc/ssh_host_rsa_key, /usr/local/etc/ssh_host_dsa_key - приватные ключи хоста (право на чтение только для root, иначе sshd не запускается).
/usr/local/etc/ssh_host_key.pub, /usr/local/etc/ssh_host_rsa_key.pub, /usr/local/etc/ssh_host_dsa_key.pub - публичные ключи хоста (чтение для всех, запись только для root). При работе не используются и предназначены для копирования в ssh_known_hosts на удаленный хост.
~/.ssh/identity, ~/.ssh/id_dsa, ~/.ssh/id_rsa - приватный RSA1/DSA2/RSA2 ключ пользователя. Чтение и запись только владельцу. М.б. зашифрован парольной фразой по 3DES.
~/.ssh/identity.pub, ~/.ssh/id_dsa.pub, ~/.ssh/id_rsa.pub - публичный RSA1/DSA2/RSA2 ключ пользователя. Необходимо добавить в ~/.ssh/authorized_keys на все хосты, на которые предполагается заходить с использованием RSA/DSA аутентификации.
ssh-keygen - генерация, преобразование и управление ключами. По умолчанию генерирует RSA ключ (ключ -t позволяет задать тип ключа). При генерации запрашивается парольная фраза для 3DES (рекомендуется 10-30 символов). Забытую парольную фразу восстановить невозможно. Число бит по умолчанию - 1024 (минимум - 512 бит, увеличение длины ключа замедляет работу). Комментарий по умолчанию - имя-пользователя@имя-хоста. Имя файла для хранения публичного ключа образуется из имени файла для частного ключа добавлением суффикса ".pub". Ключ хоста должен иметь пустую парольную фразу.
- ssh-keygen [-t rsa1|dsa|rsa] [-b бит] [-N парольная-фраза] [-C комментарий] [-f имя-файла-записи] [-q]
- ssh-keygen -c [-P парольная-фраза] [-C комментарий] [-f файл-с-ключами] - изменить комментарий
- ssh-keygen -e [-f файл-с-ключами] - читает приватный или публичный ключ в формате OpenSSH и преобразует его в формат SECSH для экспорта в другие реализации SSH
- ssh-keygen -i [-f файл-с-ключами] - читает приватный или публичный ключ в формате SSH2 или SECSH и преобразует его в формат OpenSSH
- ssh-keygen -l [-f файл-с-ключами] - показать fingerprint
- ssh-keygen -B [-f файл-с-ключами] - показать bubblebabble digest
- ssh-keygen -p [-P старая-парольная-фраза] [-N новая-парольная-фраза] [-f файл-с-ключами] - изменить парольную фразу
- ssh-keygen -y [-f файл-с-ключами] - читает приватный OpenSSH DSA ключ и выдает OpenSSH DSA публичный ключ
ssh - telnet, rsh, rlogin в одном флаконе, безопасное соединение с X11-сервером и шифровка произвольного TCP/IP соединения.
Если сервер выделил псевдо-терминал, то клиент может использовать управляющие последовательности (только сразу после <nl>):
- "~." - разорвать соединение
- "~^Z" - приостановить ssh
- "~#" - посмотреть список перенаправленнных соединений
- "~&" - перевести перенаправленное TCP/IP или X11 соединение в фоновый режим (только SSH1) при завершении соединения
- "~R" - запрос на смену ключа сессии (только SSH2)
- "~?" - help
- "~~" - передача символа "тильда"
Вместо тильды можно установить другой escape-символ ключом "-e" или директивой EscapeChar. Если псевдо-терминал не выделен (notty), то передача данных происходит в "прозрачном" режиме.
Если при запуске ssh пользователь использовал X11 (определяется по установленной переменной DISPLAY), то все запросы удаленных программ к X11 серверу перенаправляются по шифруемому каналу и осуществляются с локального хоста к локальному X11 серверу (при этом DISPLAY=удаленный-хост:10.0, а ssh создает proxy-сервер и модифицирует Xauthority так, чтобы реальные куки X11-сервера не были известны ssh-серверу, даже виртуальные куки передаются по сети зашифрованными).
Если использовался агент аутентификации, то соединение с ним также перенаправляется на удаленный хост, если не запрещено ключом или в файле конфигурации.
Ключи (имеют приоритет над файлами конфигурации):
- [-a | -A] (запретить/разрешить перенаправление агента аутентификаци)
- [-b адрес] (позволяет для хоста с несколькими интерфейсами или алиасами использовать конкретный адрес)
- [-c blowfish|3des] (SSH1: алгоритм шифрования: 3des (по умолчанию)- более проверен, blowfish - гораздо быстрее)
- [-c список-алгоритмов-шифрования-через-запятую] (SSH2: алгоритм в начале списка имеет наибольший приоритет; по умолчанию: aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc)
- [-C ] (сжатие stdin, stdout, stderr, X11, TCP/IP порты - zlib)
- [-D локальный-порт] (изобразить из себя SOCKS4 сервер по защищенному каналу)
- [-e символ | ^символ | none ] (escape-символ вместо тильды; none обеспечивает прозрачную передачу данных)
- [-f] (перейти в фоновый режим после запроса пароля или парольной фразы)
- [-F имя-конфигурационного-файла]
- [-g] (разрешать удаленному хосту подсоединяться к локальным перенаправленным портам)
- [-i имя-файла] (файл, хранящий RSA/DSA приватный ключ; по умолчанию - ~/.ssh/identity; может быть несколько; чтобы проделать то же самое в DSA/SSH2 до версии 2.5.2p1 надо писать: -o "IdentityFile2 имя-файла")
- [-k] (запретить перенаправление Kerberos или AFS)
- [-l имя-пользователя]
- [-L локальный-порт:хост:удаленный-порт] (делается LISTEN на локальный порт и если происходит соединение на него, то оно перенаправляется по защищенному каналу на удаленный порт; для перенаправления привилегированных портов надо иметь права root)
- [-m список-алгоритмов-обеспечения-целостности-соединения] (SSH2: hmac-md5,hmac-sha1,hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96)
- [-n] (направить /dev/null на stdin и перейти в фоновый режим)
- [-N] (не выполнять удаленную команду - только перенаправить порт)
- [-o опция] (см. описание файла конфигурации - ~/.ssh/ssh_config, /usr/local/etc/ssh_config)
- [-p порт] (соединиться с указанным хостом на удаленном хосте; по умолчанию - 22)
- [-P] (использовать непривилегированный порт для исходящего соединения, чтобы обойти ограничения сетевого экрана; несовместим с RhostsAuthentication и RhostsRSAAuthentication)
- [-q | -v | -v -v | -v -v -v] (меньше/больше сообщений)
- [-R локальный-порт:хост:удаленный-порт] (делается LISTEN на удаленный порт и если происходит соединение на него, то оно перенаправляется по защищенному каналу на локальный порт)
- [-s] (запуск подсистемы на сервере - например, sftp; имя подсистемы задается последним параметром)
- [-t | -T ] (требовать выделения псевдо-tty / не выделять псевдо-tty)
- [-x | -X ] (запретить/разрешить перенаправление X11)
- [пользователь@]хост
- [команда]
- [-1] (только SSH1)
- [-2] (только SSH2)
- [-4] (только IPv4)
- [-6] (только IPv6)
~/.ssh/config (рекомендуется делать недоступным для всех, кроме владельца), /usr/local/etc/ssh_config (должен быть доступен на чтение всем) - конфигурационные файлы для ssh (личный приоритетнее). Файл разделен на секции директивами Host, секция применяется при работе с хостом, удовлетворяющем шаблону секции (первая подходящая):
- Host шаблоны (следующие опции применимы к хостам, подходящим под один из шаблонов; имя хоста берется из командной строки (т.е. неканоническое); в шаблонах используются символы * и ?)
- BatchMode no|yes (не запрашивать пароль/парольную фразу)
- CheckHostIP yes|no (дополнительно проверять адрес сервера в known_hosts)
- Cipher 3des|blowfish (-c)
- Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc (-c)
- ClearAllForwardings no|yes (сбросить все перенаправления портов, заданные -D, -L или -R)
- Compression no|yes (-C)
- CompressionLevel уровень-сжатия (только для SSH1: как в gzip/zlib - от 1/быстрый до 9/лучший; по умолчанию - 6)
- ConnectionAttempts число-попыток-соединения (по умолчанию - 4; 1 раз в секунду; при неудаче пытается использовать протокол rsh)
- DynamicForward (-D)
- EscapeChar символ|^символ|none (-e, символ для использования вместо тильды)
- FallBackToRsh no|yes (использовать rsh, если сервер не имеет ssh)
- ForwardAgent no|yes (-a/-A, передавать ли запрос к агенту аутентификации на удаленный хост)
- ForwardX11 no|yes (-x/-X)
- GatewayPorts no|yes (-g, разрешать ли удаленным хостам соединяться на перенаправленные локальные порты)
- GlobalKnownHostsFile имя-файла (использовать вместо /usr/local/etc/ssh_known_hosts)
- HostbasedAuthentication yes|no (SSH2: аналог RhostsRSAAuthentication)
- HostKeyAlgorithms ssh-rsa,ssh-dss (SSH2)
- HostKeyAlias (если используется несколько серверов на одном хосте)
- HostName имя-хоста (настоящее имя хоста, на который надо зайти)
- IdentityFile имя-файла (-i, файл, хранящий RSA или DSA приватный ключ; может быть несколько; используются также ключи от агента аутентификации)
- KeepAlive yes | no (позволяет заметить разрыв связи или аварийное завершение на дальнем конце; сервер замечает разрыв, а клиент - нет)
- KerberosAuthentication yes|no
- KerberosTgtPassing yes|no
- LocalForward локальный-порт хост:порт (см. -L; может быть несколько)
- LogLevel INFO (QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG)
- MACs hmac-md5,hmac-sha1,hmac-ripemd160,[email protected],hmac-sha1-96,hmac-md5-96 (SSH2:список алгоритмов обеспечения целостности соединения)
- NumberOfPasswordPrompts 3
- PasswordAuthentication yes | no
- Port 22
- PreferredAuthentications publickey,password,keyboard-interactive (SSH2)
- Protocol список-версий-протокола-в-порядке-предпочтения (2,1)
- ProxyCommand (позволяет использовать дополнительную команду для соединения с сервером)
- PubkeyAuthentication yes|no (SSH2)
- RemoteForward порт хост:порт (см. -R; может быть несколько)
- RhostsAuthentication yes | no (SSH1)
- RhostsRSAAuthentication yes | no (SSH1)
- RSAAuthentication yes | no (SSH1)
- SkeyAuthentication no | yes (новое: переименован в ChallengeResponseAuthentication)
- StrictHostKeyChecking ask | no | yes (не добавлять незнакомые или изменившиеся хосты в know_hosts[2])
- UsePrivilegedPort yes | no (-P)
- User имя-пользователя
- UserKnownHostsFile файл-known_hosts
- UseRsh no | yes (если ssh на хосте нет вовсе)
- XAuthLocation расположение-xauth
При входе на удаленный сервер устанавливаются переменные: DISPLAY, HOME, LOGNAME, MAIL, PATH (определяется при компиляции ssh), SSH_AUTH_SOCK (unix socket для взаимодействия с агентом аутентификации), SSH_CLIENT (ip-адрес клиента, порт клиента, порт сервера), SSH_ORIGINAL_COMMAND, SSH_TTY, TZ, USER, строки из ~/.ssh/environment.
ssh-agent, ssh-add. ssh-agent - держатель приватных ключей для RSA/DSA аутентификации. Запускается в начале сессии и устанавливает переменные окружения (SSH_AGENT_PID, SSH_AUTH_SOCK), с помощью которых остальные программы используют его для автоматической аутентификации ssh. Параметром является имя команды и ее аргументы (например, bash), ssh-agent завершается при завершении команды. Если имя команды не указано, то ssh-agent запускается в фоновом режиме, а на stdout выдаются команды экспортирования необходимых переменных окружения (позволяет избежать порождения лишнего shell). В директории /tmp создается unix сокет для общения других программ из пакета ssh с ssh-agent (его имя записывается в SSH_AUTH_SOCK). root может общаться с вашим агентом аутентификации (интересно, что он может сделать?)!
Приватные ключи добавляются программой ssh-add, которая запрашивает парольную фразу, расшифровывает приватный ключ и посылает его ssh-agent. Если терминал недоступен, но определена переменная DISPLAY, то для ввода парольной фразы используется программа, определенная переменной SSH_ASKPASS. Таким образом парольная фраза запрашивается только один раз за сеанс, а не при каждом вызове ssh/scp/sftp. Т.к, ssh-agent выполняется на персональном компьютере пользователя и может обслуживать запросы при переходе с одного удаленного хоста на другой, то он позволяет избежать необходимости хранить приватный ключ на удаленном компьютере и пересылать парольную фразу по сети.
Опции ssh-agent:
- -c (выдавать на stdout команды в стиле csh)
- -s (выдавать на stdout команды в стиле sh)
- -k (завершить работу агента - по переменной SSH_AGENT_PID)
Опции ssh-add:
- имя файла с приватным ключом (по-умолчанию - ~/.ssh/identity)
- -l (выдать fingerprint приватных ключей, хранящихся в ssh-add)
- -L (выдать публичные ключи, хранящиеся в ssh-add)
- -d (удалить приватный ключ)
- -D (удалить все ключи)
Таким образом можно вставить в .profile (Solaris) или .bashrc (Linux) следующие строки (с предварительной проверкой отсутствия переменных окружения SSH_AGENT_PID (означает, что ssh-agent запущен ранее) и SSH_CLIENT (означает, что мы попали на этот хост по ssh с хоста, на котором скорее всего уже запущен ssh-agent)):
eval `ssh-agent` ssh-add ~/.ssh/id_dsa
Сервер sftp (sftp-server) должен быть описан в опции Subsystem в конфигурационном файле sshd.
Клиентская программа sftp позволяет пересылать файлы в интерактивном режиме подобно FTP однако осуществляет все операции поверх защищенного транспорта ssh, который, собственно, и вызывается. Опции:
- [user@]имя-хоста[:dir/]
- -b имя-файла (читает команды из файла вместо stdin)
- -C (сжатие)
- -F имя-конфигурационного-файла-ssh
- -o опция (передается ssh)
- -v
Пакетный режим позволяет копировать файлы без ручного вмешательства при условии неинтерактивной аутентификации.
sftp [user@]host[:file [file]]
Интерактивные команды (аналогично FTP):
- bye
- cd путь
- lcd путь
- chgrp gid имя-файла
- chmod mode имя-файла
- chown uid имя-файла
- exit
- get [-P] имя-удаленного-файла [имя-локального-файла] (ключ -P позволяет сохранить права и времена)
- help
- lls [опции-ls [имя-файла]]
- lmkdir имя-файла
- ln старое-имя новое-имя
- lpwd
- ls [имя-файла]
- lumask umask
- mkdir имя-файла
- put [-P] имя-локального-файла [имя-удаленного-файла] (ключ -P позволяет сохранить права и времена)
- pwd
- quit
- rename старое-имя новое-имя
- rmdir имя-файла
- rm имя-файла
- symlink старое-имя новое-имя
- ! команда-shell
- ! (выход в shell)
- ?
Мда... Это не wu-ftpd :( Слишком много возможностей и никаких средств для их ограничения со стороны системного администратора. Клиентам это давать нельзя.
scp - копирование файлов между хостами (оба могут быть удаленными). Способы аутентификации аналогичны ssh (может запрашивать пароль или парольную фразу). В действительности, вызывает ssh для организации канала передачи данных. Имя файла записывается в виде: [[user@]host:]file. Опции:
- -c алгоритм-шифрования (передается ssh)
- -i имя-файла (файл с приватным ключом, передается в ssh)
- -o опция (передается ssh)
- -p (сохраняет время модификации, использования и права доступа)
- -r (рекурсивно копировать всю директорию)
- -v
- -B (пакетный режим - не запрашивать пароль или парольную фразу)
- -q
- -C (сжатие)
- -F конфигурационный-файл
- -P port (задает порт сервера, стало быть ключа непривилегированных портов нет?)
- -S программа (использовать вместо ssh)
- -4 (IPv4)
- -6 (IPv6)
mc имеет виртуальную файловую систему для работы с ssh-сервером (fish):
cd /#sh:[пользователь@]хост[/директория]
gFTP - графический клиент (GTK+) для FTP, HTTP и SSH в версии 2.0.10 научился работать с sftp от OpenSSH: надо в параметрах SSH указать использование SFTP subsys и нажать Enter в поле пароля для соединения
ssh-keyscan позволяет собрать публичные ключи хостов, имена хостов задаются в качестве параметров или в файле. Опрос производится параллельно. Опции:
- -t тип-ключа (rsa1, rsa, dsa)
- -T секунд (timeout)
- -f имя-файла (каждая строка содержит имя или адрес хоста)
- -4 (IPv4)
- -6 (IPv6)
- -p удаленный-порт
- -v
По умолчанию собирает ключи rsa1, а если сервер не поддерживает SSH1, то определяет номер версии протокола и номер версии софта, но не выдает публичный ключ хоста (хочет 1.3 GB памяти ;).
Бесплатен только для некоммерческого использования или опробации (1.2.12 был совсем бесплатен). Windows-версия только для опробации. Поставить версии 1.2.30 и 2.3.0 в Solaris мне не удалось, так что разбираться не стал. Хотя SSH 3.0 под W98 оказался вполне совместим с сервером OpenSSH 2.9/3.0 (даже sftp работает).
Протокол SSH поддерживается в стабильной версии Cisco IOS начиная с версии 12.2 причем не во всех моделях (популярные у нас Cisco 1600 и Cisco 2500 не поддерживаются по явно надуманным причинам - IP Plus IPsec 56, c2500-ik8s-l; IP/FW Plus IPSec 56, c2500-ik8os-l; Flash 16 MB; DRAM - 10 MB), только протоколы версий 1 и 1.5 (имеющие "дырку" в дизайне против атак типа "man in the middle"), только в прошивках с шифровкой, имеется множество ограничений на методы аутентификации клиента. Плюс к этому ограничения на экспорт сильной криптографии в США. В общем, вы меня поняли ;)
Sergey E. Bogomolov