The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

OpenSSH: настройки, секреты, трюки и советы (ssh faq crypt auth)


<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>
Ключевые слова: ssh, faq, crypt, auth,  (найти похожие документы)
From: OpenBSD.ru Date: Mon, 09 Feb 2009 17:02:14 +0000 (UTC) Subject: OpenSSH: настройки, секреты, трюки и советы Оригинал: http://www.openbsd.ru/docs/ssh-tips.html Некоторые советы взяты из статей "Калейдоскоп тайных знаний" и "Волшебные криптотуннели", опубликованных в июньском и июльском номерах журнала "Хакер" за 2008 год. Авторы статей: Андрей Матвеев и Сергей Яремчук. Коррективы и уточнения введены проектом OpenBSD.ru. За последние несколько лет OpenSSH из набора программ для защищенной системы регистрации, выполнения команд на удаленном хосте и передачи файлов с одной машины на другую превратился в швейцарский армейский нож, просто потрясающий своими возможностями. Используете ли вы хотя бы половину из них? Отключение прослушивания IPv6 адресов По умолчанию sshd(8) слушает как на IPv4 так и на IPv6 адресах. Для того что бы отключить возможность работы по IPv6, необходимо изменить параметр AddressFamily: AddressFamily inet Адрес и порт прослушивания По умолчанию sshd(8) принимает подключения на всех интерфейсах, в чем не всегда есть необходимость. Если не требуется заходить на сервер "из вне", следует ограничить его работу определенным адресом с помощью параметра ListenAddress: # ListenAddress 0.0.0.0 ListenAddress 192.168.1.2 Дополнительно через двоеточие можно указать и номер порта. В данном примере используется значение порта, заданное глобально параметром Port. Ограничение доступа суперпользователя В большинстве дистрибутивов в целях безопасности доступ суперпользователю по SSH закрыт (PermitRootLogin no), и при попытке зарегистрироваться под root получаем сообщение об ошибке. Для выполнения задач, требующих привилегий администратора, приходится заходить под обычным пользователем и использовать su(1) или sudo(8). Красиво выйти из ситуации поможет директива Match. В качестве аргумента ей передается критерий отбора (User, Group, Host, Address), его значение и параметр, который нужно применить. Для примера разрешим подключение под root только с localhost и из доверенной подсети 192.168.5.0/24: PermitRootLogin no Match Host 192.168.5.*,127.0.0.1 PermitRootLogin yes Контроль неудачных подключений Следующие две директивы позволяют контролировать неудачные подключения к серверу: LoginGraceTime 60 MaxStartups 2:50:10 Параметр LoginGraceTime определяет, по истечению какого времени простаивающее подключение будет разорвано (в секундах). Значение по умолчанию 120 явно завышено. Количество параллельных неаутентифицированных подключений к серверу контролируется при помощи MaxStartups. Запись параметра имеет форму "start:rate:full". В нашем случае она означает отключение с вероятностью 50% при наличии двух неаутентифицированных связей, с линейным ростом вероятности до 100% при достижении 10. Контроль за подключениями пользователей Установки в файлах /etc/ssh/sshrc или ~/.ssh/rc позволяют выполнить некоторые действия при регистрации пользователя. Здесь можно использовать любые команды оболочки. Например, отправим администратору на почту уведомление о том, что в систему по SSH зашел пользователь: # vi /etc/ssh/sshrc echo $(date) $SSH_CONNECTION $USER $SSH_TTY | mail -s "ssh login" admin@domain.ru Пример создания резервных копий Генерируем пару ключей (секретный и публичный): $ sudo ssh-keygen -t rsa -C 'remote backup' Generating public/private rsa key pair. Enter file in which to save the key (/home/user/.ssh/id_rsa): /home/user/.ssh/id_rsa_backup Добавляем публичный ключ в список авторизованных ключей на удаленной системе: $ ssh remotehost "umask 077; cat > .ssh/authorized_keys" < .ssh/id_rsa_backup.pub Затем редактируем authorized_keys (ключ '-t' следует использовать при запуске программ, требующих для своей работы наличия псевдотерминала): $ ssh -t remotehost vi .ssh/authorized_keys from="192.168.0.*,212.34.XX.YY",command="cd /work; tar cvf - ./* | bzip2 -9", no-pty,no-agent-forwarding,no-X11-forwarding,no-port-forwarding ssh-rsa AAAA[...] И запускаем процедуру резервного копирования: $ ssh -i .ssh/id_rsa_backup remotehost > ~/backup/work-`date +%d%m%Y`.tar.bz2 2>/dev/null Каталог /work, находящийся на сервере remotehost, будет сохранен в архив ~/backup/work-11052008.tar.bz2. Используем dump в связке с SSH Используя SSH, можно защитить информацию, передаваемую программами, не имеющими встроенных механизмов шифрования соединения. Например, сделаем бэкап с помощью dump(8) на удаленный сервер: $ sudo dump -0au -f - /dev/rwd1a | gzip -9 | ssh remotehost 'dd of=cvs_backup.dump.gz' Поскольку в dump(8) встроена возможность передавать данные по сети с использованием RSH, существует возможность использования и SSH, поскольку его функциональность аналогична: $ ssh remotehost touch /home/user/cvs.dump $ env RSH=`which ssh` sudo -E dump 0f remotehost:/home/user/cvs.dump /cvs Передача файлов и каталогов Передать файл, используя SSH, можно одним из следующих способов: $ cat myfile | ssh remotehost 'cat > myfile' $ tar zcf - ~/coding | ssh remotehost 'cat > coding.tgz' Чтобы рекурсивно отправить весь каталог, набираем: $ scp -r mydir user@host.domain.ru: Вариант копирования каталога с использованием ssh(1) и tar(1) с локального хоста на удаленный: $ tar cf - source | ssh remotehost "(cd /target; tar xpf -)" и с удаленного хоста на локальный: $ ssh remotehost "tar cf - source" | (cd /target; tar xpf -) Безопасный способ получения почты Для безопасного получения почты с помощью fetchmail можно использовать SSH. Для этого в конфигурационном файле ~/.fetchmailrc необходимо указать следующее: poll localhost with protocol pop3 and port 8110:preconnect "ssh -f -q -C user@213.167.XX.YY \ -L 8110:213.167.XX.YY:110 sleep 10" password noIdea; Забираем почту: $ fetchmail 1 message for user at localhost (8062 octets). reading message user@localhost.domain.ru:1 of 1 (8062 octets)....... flushed Почтовый шлюз Настроим 192.168.1.1 на перенаправление входящей и исходящей почты по шифрованному каналу для клиентов из 192.168.1.0/24 на mail.domain.ru: $ vi .ssh/config Host mail Hostname mail.domain.ru LocalForward 192.168.1.1:8025 mail.domain.ru:25 LocalForward 192.168.1.1:8110 mail.domain.ru:110 LocalForward 192.168.1.1:8143 mail.domain.ru:143 GatewayPorts yes Открываем туннель: $ ssh mail Выполнение заданной команды после подключения Параметр ProxyCommand позволяет выполнить произвольную команду. Для примера подключимся через шлюз к файловому серверу, который находится за NAT: $ vi .ssh/config Host gateway HostName ns.domain.ru Host filesrv HostName 192.168.5.201 ProxyCommand ssh gateway nc -w 180 %h %p Подключаемся: $ ssh filesrv Мультиплексирование ssh-сессий Использование параметра ControlMaster позволяет ускорить доступ к удаленному серверу за счет того, что в специальном файле сохраняются все параметры предыдущего сеанса, которые и используются при повторном подключении. Для примера создадим две Host-секции: $ vi .ssh/config Host srv1 HostName 213.167.XX.YY ControlMaster yes # Здесь %r - имя, %h - хост и %p - порт ControlPath ~/.ssh/ctl-%r-%h-%p Host srv1fast HostName 213.167.XX.YY ControlMaster no ControlPath ~/.ssh/ctl-%r-%h-%p Теперь на сервере srv1 выполняем утилиту uptime(1), логинимся на нем (чтобы создать локальный сокет для второго подключения), переходим на другую консоль и снова запрашиваем статистические счетчики: ttyp0$ time ssh srv1 uptime 5:55PM up 37 days, 9:19, 1 user, load averages: 0.33, 0.32, 0.33 0m0.77s real 0m0.06s user 0m0.01s system ttyp0$ ssh srv1 ttyp1$ time ssh srv1fast uptime 5:57PM up 37 days, 9:20, 2 users, load averages: 0.37, 0.34, 0.33 0m0.03s real 0m0.00s user 0m0.01s system Из примера видно, что при использовании мультиплексирования соединений время выполнения команды uptime(1) на удаленном сервере уменьшилось в 25 раз. Создание SOCKS-сервера OpenSSH можно использовать как специальный SOCKS-сервер, который поддерживает более гибкое проксирование, чем простое перенаправление портов. Например, команда: $ ssh -D1080 user@domain.ru Создает локальный SOCKS5-сервер, который ждет подключения на localhost:1080. Альтернативный вариант - прописать директиву DynamicForward в .ssh/config: $ vi .ssh/config Host proxy HostName ns.domain.ru DynamicForward 1080 Подключаемся, введя ssh proxy. Протестировать работу SOCKS5-сервера можно такой командой: $ echo -n "GET / HTTP/1.0\r\n\r\n" | nc -X 5 -x 127.0.0.1:1080 \ www.domain.ru 80 | head -4 HTTP/1.1 200 OK Date: Sat, 23 Feb 2008 14:27:43 GMT Server: Apache X-Powered-By: PHP/4.4.1 Теперь SOCKS-сервер готов к использованию: $ tsocks thunderbird Сажаем пользователей в песочницу В OpenSSH 4.9 появилась долгожданная поддержка chroot(2) для sshd(8), контролируемая с помощью опции ChrootDirectory. К примеру, заставим подключающегося по sftp пользователя worker переходить в измененный корневой каталог data: # vi /etc/ssh/sshd_config #Subsystem sftp /usr/libexec/sftp-server Subsystem sftp internal-sftp Match User worker X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp ChrootDirectory /data Пример для хостинговых клиентов: # vi /etc/ssh/sshd_config #Subsystem sftp /usr/libexec/sftp-server Subsystem sftp internal-sftp Match Group wwwusers X11Forwarding no AllowTcpForwarding no ForceCommand internal-sftp ChrootDirectory /var/www/hosting/%u Теперь зарегистрированные пользователи будут допущены только к "своему" каталогу, при подключении модификатор %u будет заменен именем пользователя. При необходимости можно использовать %h, который соответствует домашнему каталогу юзера. Скрываем записи о серверах, к которым мы подключались Некоторые администраторы, возможно, захотят зашифровать все IP и доменные адреса из файла .ssh/known_hosts. Делается это следующим образом: $ echo 'HashKnownHosts' >> ~/.ssh/config $ ssh-keygen -H -f ~/.ssh/known_hosts $ head -1 ~/.ssh/known_hosts +|1|TJ2SaXGqO8uHYeiA92KuNRIKR7M=|GpQB8Qz0tQPqA+nF+ghe37mpcHA= ssh-rsa AAAA[...] Управляющие последовательности SSH Управляющие последовательности SSH станут доступны, если в SSH-сессии сначала нажать <Enter>, затем управляющий символ сеанса (по умолчанию тильда, задается директивой EscapeChar) и специальную клавишу, которая указывает, какую именно функцию следует выполнить. Допустим, мы с mail.domain.ru зашли на bastion.domain2.ru и решили, что не плохо было бы открыть обратный шифрованный туннель к почтовому серверу для безопасной загрузки сообщений. С помощью комбинации клавиш "<Enter>~C" можно интерактивно управлять локальным и удаленным форвардингами (ключи '-L' и '-R'): bastion$ <Enter>~C ssh> -R 8110:mail.domain.ru:110 Forwarding port. Проверяем работу созданного почтового туннеля: bastion$ telnet localhost 8110 +OK Dovecot ready. В ответ получен баннер от Dovecot, значит, все в порядке. Кстати, обратившись к подсказке, получим список всех доступных ключей и дополнительных параметров: bastion$ <Enter>~C ssh> help Commands: -L[bind_address:]port:host:hostport Request local forward -R[bind_address:]port:host:hostport Request remote forward -KR[bind_address:]port Cancel remote forward Если в ~/.ssh/config установить значение директивы PermitLocalCommand в yes, то мы сможем выполнять команды в локальном шелле, т.е. на хосте, с которого зашли: ns$ ssh mx mx$ <Enter>~C ssh> !uptime # команда выполняется на хосте ns 7:02PM up 100 days, 11 mins, 1 user, load averages: 0.13, 0.21, 0.23 <Enter> mx$ uptime # команда выполняется на хосте mx 7:02PM up 4 days, 7:34, 1 user, load averages: 0.21, 0.23, 0.19 Если на предыдущем узле требуется выполнить сразу несколько команд, то SSH-сессию лучше временно засуспендить (приостановить выполнение программы ssh): mx$ <Enter>~<Ctrl-Z> [1] + Suspended "ssh" "$@" Чтобы перевести SSH-сессию из остановленного режима в активный, следует воспользоваться командой fg. Список текущих SSH-соединений можно просмотреть комбинацией: mx$ <Enter>~# The following connections are open: #0 client-session (t4 r0 i0/0 o0/0 fd 5/6 cfd -1) А для быстрого завершения SSH-сессии ставим точку: mx$ <Enter>~. Connection to 213.167.XX.YY closed. Сокращенный набор Чтобы в консоли не вводить полное доменное имя, порт и учетную запись для подключения к удаленной системе, стоит заручиться поддержкой директивы Host: $ vi ~/.ssh/config Host mx Hostname mx.domain.ru Port 2022 User admin Таким образом, достаточно ввести ssh mx, чтобы соединиться с нужным хостом. Получение доступа к закрытому сервису Многие администраторы в целях безопасности скрывают свои сервера в демилитаризованной зоне, либо за NAT'ом, и разрешают входящие соединения только с доверенных IP-адресов и по определенными портам. Поэтому доступ ко многим полезным ресурсам получить напрямую нельзя. Это как раз тот случай, когда использование SSH-форвардинга может исправить ситуацию. $ vi ~/.ssh/config Host gate Hostname gate.domain.ru # Для ускорения соединений включаем мультиплексирование SSH-сессий ControlMaster auto ControlPath ~/.ssh/ctl-%r-%h-%p # Перенаправляем локальный порт на файловый сервер (Win2k3 с поднятым VShell) LocalForward 8022 192.168.1.101:22 # Подключаясь к localhost:8022, мы будем попадать на файловый сервер Host fileserver Hostname localhost Port 8022 ControlMaster auto ControlPath ~/.ssh/ctl-%r-%h-%p HostKeyAlias fileserver Соединяемся с узлом gate и проверяем возможность подключения к локальному порту 8022: $ ssh -N -f gate $ telnet localhost 8022 SSH-2.0-VShell_3_0_4_656 VShell Теперь можно подключиться к файловому серверу, который находится за NAT'ом, в обход правил файерола, установленных на шлюзе: $ ssh fileserver Microsoft Windows [Version 5.2.3790] C:\Documents and Settings\Username\My Documents> Ограничение возможностей перебора паролей с помощью Pf Сервис SSH является любимой мишенью злоумышленников, поэтому следует принять некоторые меры безопасности. Одна из них - ограничение количества подключений, чтобы избежать DoS-атаки и перебора паролей. # vi /etc/pf.conf table <sshbf> persist block in log quick on $ext_if inet from <sshbf> pass in log on $ext_if inet proto tcp to $ext_if port ssh keep state \ (max-src-conn-rate 5/60, overload <sshbf> flush global) Данный набор правил инструктирует фильтр пакетов не допускать более 5 одновременных соединений к 22 порту за 60 секунд. Перенаправление X11-подключений Для перенаправления X11-подключений следует использовать ключ '-Y': $ ssh -Y user@domain.com Причем в конфигурационном файле /etc/ssh/sshd_config параметр X11Forwarding должен быть установлен в "yes". Если X-сервер запущен на локальной системе, то необходимо включить и X11UseLocalhost. Использование аутентификации на базе публичного ключа Генерируем пару ключей (секретный и публичный): % ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/andrushock/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/andrushock/.ssh/id_rsa. Your public key has been saved in /home/andrushock/.ssh/id_rsa.pub. The key fingerprint is: 25:95:5b:a6:d7:26:b6:f5:f9:a7:49:d4:a8:2a:0d:7d andrushock@midian Проверяем корректность прав доступа к директории .ssh и RSA-ключам: % ls -la .ssh | egrep -v 'total|\.\.' drwx------ 2 andrushock wsrc 512 Oct 19 20:42 ./ -rw------- 1 andrushock wsrc 1743 Jun 11 03:35 id_rsa -rw-r--r-- 1 andrushock wsrc 413 Jun 11 03:35 id_rsa.pub Добавляем публичный ключ в список авторизованных ключей на удаленной системе: % ssh user@host "cat >> .ssh/authorized_keys" < .ssh/id_rsa.pub В случае, если подкаталог .ssh и файл .ssh/authorized_keys на удаленной системе не существуют: % ssh user@host "mkdir -m 700 .ssh; umask 077; cat > .ssh/authorized_keys" < .ssh/id_rsa.pub Для сохранения парольных фраз к приватным ключам запускаем ssh-agent(1): % eval `/usr/bin/ssh-agent` Agent pid 3855 С помощью ssh-add(1) добавляем в память агента парольную фразу от нашего ключа: % ssh-add Enter passphrase for /home/andrushock/.ssh/id_rsa: Identity added: /home/andrushock/.ssh/id_rsa (/home/andrushock/.ssh/id_rsa) Для проверки просматриваем отпечаток секретного ключа: % ssh-add -l 2048 25:95:5b:a6:d7:26:b6:f5:f9:a7:49:d4:a8:2a:0d:7d /home/andrushock/.ssh/id_rsa (RSA) Выполняем вход на удаленный сервер без ввода пароля и парольной фразы: % ssh user@host OpenBSD 3.7-current (GENERIC) #1: Mon Aug 1 00:37:53 MSD 2005 Welcome to OpenBSD: The proactively secure Unix-like operating system. $ Пример использования функций оболочки для упрощения беспарольной аутентификации: % vi .profile ssh_agent_start() { id1=$HOME/.ssh/identity id2=$HOME/.ssh/id_dsa id3=$HOME/.ssh/id_rsa if [ ! "$SSH_AGENT_PID" ] && [ -f $id1 -o -f $id2 -o -f $id3 ]; then eval `/usr/bin/ssh-agent -s` /usr/bin/ssh-add < /dev/null export SSH_AGENT_SHELL=$$ fi } ssh_agent_stop() { if [ "$SSH_AGENT_PID" -a "$SSH_AGENT_SHELL"x = "$$"x ]; then /usr/bin/ssh-add -D < /dev/null eval `/usr/bin/ssh-agent -sk` fi } ssh_agent_start trap ssh_agent_stop 0 1 VPN на базе SSH Для примера возьмем два сервера: srv1 с IP-адресами 212.34.XX.YY и 192.168.2.1 подключен к сегменту внутренней сети 192.168.2.0/24, а srv2 с 213.167.XX.YY и 192.168.1.1 шефствует над подопечными из 192.168.1.0/24. Настроим VPN-туннель средствами OpenSSH, в котором будут использоваться адреса 10.0.0.1 и 10.0.0.2. Для наглядности сценарий можно представить следующим образом: (10.0.0.1) 212.34.XX.YY 213.167.XX.YY (10.0.0.2) 192.168.2.0/24 --- srv1 --- [ internet ] --- srv2 --- 192.168.1.0/24 192.168.2.1 192.168.1.1 Ключевые элементы сетевой конфигурации рассмотрены, теперь приступаем к настройкам. Логинимся на srv1 и правим главный конфигурационный файл sshd(8): srv1# vi /etc/ssh/sshd_config # Разрешаем туннелирование layer-3 # PermitTunnel point-to-point # VPN на базе OpenSSH требует привилегий суперпользователя, # поэтому аутентификацию под учетной записью root разрешаем # только с доверенных хостов # PermitRootLogin no Match Host 213.167.XX.YY,192.168.2.*,127.0.0.1 PermitRootLogin yes По окончании настроек не забываем отправить демону сигнал SIGHUP, чтобы он смог перечитать свой конфиг: srv1# kill -HUP `sed q /var/run/sshd.pid` Далее разрешаем прохождение пакетов на используемых туннельных псевдоустройствах [2]tun(4) (на tun0 у меня висит OpenVPN, tun1 - для OpenSSH): srv1# vi /etc/pf.conf pass quick on { tun0, tun1 } inet all Загружаем правила из конфига: srv1# pfctl -f /etc/pf.conf Создаем интерфейс tun1 и назначаем ему IP-адрес: srv1# ifconfig tun1 create srv1# ifconfig tun1 10.0.0.1 10.0.0.2 netmask 255.255.255.252 При помощи команды [3]ifconfig(8) проверяем его состояние: srv1% ifconfig tun1 tun1: flags=51<UP,POINTOPOINT,RUNNING> mtu 1500 groups: tun inet 10.0.0.1 --> 10.0.0.2 netmask 255.255.255.252 Не забываем добавить в таблицу маршрутизации удаленную подсеть: srv1# route add 192.168.1.0/24 10.0.0.2 Второй сервер выступает в роли SSH-клиента, поэтому процедура конфигурирования здесь чуть проще: srv2# echo 'Tunnel point-to-point' >> /etc/ssh/ssh_config Остальные настройки и действия практически идентичны описанным выше: правим и активируем рулесеты файервола, поднимаем tun1, присваиваем ему сетевой адрес (обратите внимание, порядок следования IP-адресов изменен) и добавляем статический маршрут: srv2# vi /etc/pf.conf pass quick on { tun0, tun1 } inet all srv2# pfctl -f /etc/pf.conf srv2# ifconfig tun1 create srv2# ifconfig tun1 10.0.0.2 10.0.0.1 netmask 255.255.255.252 srv2# route add 192.168.2.0/24 10.0.0.1 И, наконец, самый ответственный момент: устанавливаем защищенное соединение между двумя сетями: srv2# ssh -f -w 1:1 212.34.XX.YY true Чтобы снизить накладные расходы, к списку аргументов имеет смысл добавить ключи "-o Compression=yes -x -a -n" (сжимать передаваемые данные, отключить пересылку пакетов X11, запретить аутентификацию с помощью агента и направить /dev/null на стандартный входной поток stdin(4)). Теперь проверим доступность удаленного узла, находящегося "за первым сервером": srv2% ping 192.168.2.101 PING 192.168.2.101 (192.168.2.101): 56 data bytes 64 bytes from 192.168.2.101: icmp_seq=0 ttl=127 time=2.508 ms Если все ОК, можно дальше развивать предложенную схему, упрощая или, наоборот, усложняя настройки. Например, применить беспарольную аутентификацию на базе ключей, создать конфигурационный файл для автоматического создания псевдоустройства tun1: srv2# echo '10.0.0.2 10.0.0.1 netmask 255.255.255.252' > /etc/hostname.tun1 Занести необходимые статические маршруты и запуск "ssh -f -w" в один из сценариев начальной загрузки (/etc/rc.local) или в отдельный скрипт, чтобы все выполнялось одной командой, без дополнительных телодвижений. Чтобы использовать OpenSSH на уровне OSI 2, в качестве значения директив PermitTunnel и Tunnel следует использовать ethernet, а затем объединить в мост внешний сетевой интерфейс и псевдоустройство tunX Стоит отметить, с помощью OpenSSH возможно построение не только Site-to-Site VPN (межсайтовое подключение, в котором два маршрутизатора создают туннель в интернете), но и Client-to-Site (VPN-подключение удаленного доступа для проводных и беспроводных клиентов).

<< Предыдущая ИНДЕКС Исправить src / Печать Следующая >>

Обсуждение [ RSS ]
  • 1, grinder (??), 14:15, 24/09/2009 [ответить]  
  • +/
    Оригиналы находятся по адресу

    http://www.synack.ru/articles/x_07_2008_xakep_pro_volshebnye_kriptotunneli

    http://www.synack.ru/articles/x_06_2008_xakep_pro_kaleidoskop_tainyh_znanii

     

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Спонсоры:
    MIRhosting
    Inferno Solutions
    Hosting by Ihor
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2019 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру