21 способ обеспечения безопасности OpenSSH

Не на каждом сервере есть ftp, samba или какая-либо другая программа, предоставляющая удаленные возможности, однако, на большинстве UNIX хостов мы встретим OpenSSH. OpenSSH предоставляет нам широкие возможности, однако, любые излишние возможности могут дать несколько дверей взломщику. Я же хочу показать как прикрыть некоторые из них, чтобы ваши UNIX хосты были защищены по протоколу SSH. Эта переведенная статья 2009-го года, однако даже сегодня она актуальна в полной мере.

OpenSSH это реализация протокола SSH. OpenSSH используется для удаленного входа, создания бекапов, удаленного файлового трансфера через scp или sftp и многое другое. SSH идеально подходит для того, чтобы сохранить конфиденциальность и целостность данных, передаваемых между двумя сетями или системами. Однако, основным преимуществом является сервер аутентификации, который может работать с помощью публичных ключей. Время от времени появляются новости о 0-day exploit для OpenSSH. Здесь же изложены несколько методов, которые позволят вам повысить безопасность OpenSSH сервера, не смотря на такие новости.

Стандартные файлы настроек и порт SSH:

  • /etc/ssh/sshd_config - конфигурационный файл сервера OpenSSH
  • /etc/ssh/ssh_config - конфигурационный файл клиента OpenSSH
  • ~/.ssh/ - пользовательские конфигурационные директории
  • ~/.ssh/authorized_keys и ~/.ssh/authorized_keys2 - списки публичных ключей (RSA или DSA), которые могут быть использованы для авторизации в пользовательский аккаунт
  • /etc/nologin - если этот файл существует, то система будет отказываться пускать кого-либо кроме root-пользователя. Лучше удалить и не использовать.
  • /etc/hosts.allow и /etc/hosts.deny - списки контроля доступа (ACL)
  • SSH стандартный порт : TCP 22

Содержание

1: Отключите OpenSSH сервер

Рабочие станции и ноутбуки могут работать без OpenSSH сервера. Если вам не нужна удаленная авторизация или возможности файлового трансфера, отключите или удалите SSH сервер. Закройте лишнюю дверь, если вы её не используете. CentOS / RHEL / Fedora Linux - пользователи могут отключить или удалить openssh-server с помощью этих команд:

chkconfig sshd off
yum erase openssh-server

Debian / Ubuntu Linux пользователи могут отключить и удалить с помощью утилиты apt-get:

apt-get remove openssh-server

Так же вам вероятно потребуется обновить настройки вашего firewall'а (iptables), чтобы удалить правила для ssh. Для CentOS / RHEL / Fedora редактируйте файлы /etc/sysconfig/iptables и /etc/sysconfig/ip6tables. После окончания перезапустите iptables:

service iptables restart
service ip6tables restart

Для пользователей Debian / Ubuntu это, как правило, один файл — /etc/init.d/iptables. После редактирования которого смело перезапускаем firewall.

/etc/init.d/iptables restart

2: Используйте только второй протокол SSH

SSH протокол первой версии (SSH-1) подвержен проблемам и уязвимостям безопасности с помощью атак вида man-in-the-middle. SSH-1 полностью устарел и его не стоит использовать. Откройте файл sshd_config и проверьте, что подобная строка имеет место:

1
Protocol 2

3: Ограничьте пользователям SSH доступ

Изначально все пользователи системы могут входить через SSH используя свои пароли или публичные ключи. Порой вы создаете UNIX / Linux пользователей для ftp или email. Однако, такие пользователи тоже могут зайти в систему через ssh. Они будут иметь полный доступ к системным инструментам, включая компиляторы и скриптовые языки, такие как Perl, Python, которые могут открыть сетевые порты и удовлетворить множество других капризов. Один из моих клиентов имел устаревший php-скрипт и атакующий воспользовался возможностью и создал новый аккаунт в системе через этот php-скрипт. И тем не менее, атакующий не смог проникнуть через ssh, потому что его пользователь не был указан в директиве AllowUsers. Доступ к системе через SSH имели только пользователи root, vivek и jerry и это было указано в файле sshd_config:

1
AllowUsers root vivek jerry

В качестве альтернативы, вы можете разрешить доступ всем пользователям через SSH, но ограничить лишь нескольким с помощью следующей строки:

1
DenyUsers saroj anjali foo

Вы также можете настроить Linux PAM, разрешающий или запрещающий авторизацию через sshd-сервер. Вы можете создать список имен групп для авторизации или же запрета авторизации через данный протокол.

4: Настройте время ожидания при простое для выхода

Пользователь может зайти на сервер через ssh и если вы настроите таймаут простоя, то сможете избежать необслуживаемой ssh сессии. Откройте sshd_config и проверьте следующие значения определены:

1
2
ClientAliveInterval 300
ClientAliveCountMax 0

Здесь выставлено время ожидания(простоя) в секундах (300 с = 5 мин.). Когда это время пройдет, простаивающая сессия пользователя будет закрыта, и пользователь автоматически выйдет из системы.

5: Отключите .rhosts файлы

OpenSSH сервер может использовать протокол Rlogin для авторизации, и подобное стоит пресекать. Отключите чтение пользовательских файлов ~/.rhosts и ~/.shosts. Обновите sshd_config со следующими настройками:

1
IgnoreRhosts yes

SSH может имитировать поведение устаревшей комманды rsh, просто отключите небезопасный доступ через RSH.

6: Отключите аутентификацию на основе хоста

Для отключения подобной аутентификации, обновите sshd_config со следующей опцией:

1
HostbasedAuthentication no

7: Отключите доступ root через SSH

Это означает что доступ пользователя root через ssh поверх сети не нужен. Обычные пользователи могут использовать утилиты su или sudo(предпочтительней) чтобы повысить права до уровня root. Это позволяет быть уверенным в получении информации о том, кто запускал привилегированные команды на системе через sudo. Для отключения входа root пользователя через SSH обновите sshd_config со след. строкой:

1
PermitRootLogin no

8: Включите предупреждающий баннер

Установка предупреждающего баннера сводится к редактированию следующей строки и создания соотв. файла:

1
Banner /etc/issue

Пример файла /etc/issue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
----------------------------------------------------------------------------------------------
You are accessing a XYZ Government (XYZG) Information System (IS) that is provided for authorized use only.
By using this IS (which includes any device attached to this IS), you consent to the following conditions:
+ The XYZG routinely intercepts and monitors communications on this IS for purposes including, but not limited to,
penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM),
law enforcement (LE), and counterintelligence (CI) investigations.
+ At any time, the XYZG may inspect and seize data stored on this IS.
+ Communications using, or data stored on, this IS are not private, are subject to routine monitoring,
interception, and search, and may be disclosed or used for any XYZG authorized purpose.
+ This IS includes security measures (e.g., authentication and access controls) to protect XYZG interests--not
for your personal benefit or privacy.
+ Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching
or monitoring of the content of privileged communications, or work product, related to personal representation
or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work
product are private and confidential. See User Agreement for details.
----------------------------------------------------------------------------------------------

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

9: Настройте firewall на порту ssh (22)

Вы должны настроить firewall для ssh порта (22) обновив конфигурации iptables или же pf firewall. Обычно, сервер OpenSSH должен принимать только входящие соединения вашей сети или другой удаленной сети.

Настройка iptables

Измените ваш /etc/sysconfig/iptables (для пользователей Redhat) для подтверждения соединений только с сетями 192.168.1.0/24 и 202.54.1.5/29:

1
2
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -s 202.54.1.5/29 -m state --state NEW -p tcp --dport 22 -j ACCEPT

Если вы используете IPv6, не забудьте отредактировать /etc/sysconfig/ip6tables (для пользователей Redhat):

1
-A RH-Firewall-1-INPUT -s ipv6network::/ipv6mask -m tcp -p tcp --dport 22 -j ACCEPT

Заменив ipv6network::/ipv6mask вашим IPv6 диапазоном.

В случае других дистрибутивов, таких как Debian, ничего принципиально не меняется. Нужно также добавить подобные правила в INPUT цепочку.

Настройка *BSD PF Firewall

Если вы используете PF firewall настройте /etc/pf.conf следующим образом:

1
pass in on $ext_if inet proto tcp from {192.168.1.0/24, 202.54.1.5/29} to $ssh_server_ip port ssh flags S/SA synproxy state

10: Измените порт SSH и ограничьте используемый IP

Первоначально SSH слушает все доступные интерфейсы и IP адреса доступных на системе и ограничение прослушивания порта и смена самого порта может повысить безопасность (Обычно bruteforce скрипты пытаются соединиться только на порту #22). Для того чтобы привязать OpenSSH слушать только ip 192.168.1.5 и 202.54.1.5 на порту #300, просто подправьте вашу конфигурацию:

1
2
3
Port 300
ListenAddress 192.168.1.5
ListenAddress 202.54.1.5

11: Используйте сильные пароли и ключи

Невозможно оценить насколько важно использовать сильные пароли и ключи. Brute-Force атака работает если вы используете пароли, которые основываются на данных из словарей. Есть также специальные расширенные "словари", которые могут содержать наиболее популярные пароли. Они называются rainbow tables. Вы можете заставить пользователей избегать пароли подверженные подобным атакам и выявлять слабые пароли с помощью утилиты John the Ripper. Вот пример генератора случайных паролей, написанных на баше (положите его в ваш ~/.bashrc):

1
2
3
4
5
genpasswd() {
local l=$1
[ "$l" == "" ] && l=20
tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs
}

Если вы совсем параноик, то вместо /dev/urandom используйте /dev/random

Запустите в консоли:

genpasswd 16
uw8CnDVMwC6vOKgW

12: Используйте публичные ключи для аутентификации

Используйте пару ключей публичный/приватный с парольной защитой для приватного ключа. Посмотрите как использовать аутентификацию основанную на RSA и DSA и никогда не используйте пустой ключ (без passphrase) для логина.

13: Используйте Keychain для аутентификации

Keychain это специальный bash-скрипт созданный для удобства и гибкости использования аутентификации на ключах. Он может дать некоторые фишки безопасности даже на ключи без passphrase. Узнайте как установить и использовать keychain утилиты.

14: Ограничьте SSHD с помощью chroot (Заприте пользователей в их домашних директориях)

По умолчанию пользователям разрешено гулять по директориям сервера, даже таким как /etc, /bin/ и другим. Вы можете защитить ssh используя chroot или специальные утилиты вроде rssh. Но с выходом OpenSSH версий 4.8p1 или 4.9p1 вам больше не нужно надеяться на такие сторонние решения. Посмотрите в этот пост чтобы узнать о новой директиве ChrootDirectory блокирующей пользователей в их собственных домашних директориях.

15: Используйте TCP Wrapper'ы

TCP Wrapper это сетевая ACL система (использующая списки контроля доступа), основанная на хостах, используемая для фильтрации доступа в сеть и OpenSSH поддерживает TCP wrapper'ы. Просто обновите ваш /etc/hosts.allow для разрешения SSH только с адресов 192.168.1.2 172.16.23.12:

1
sshd : 192.168.1.2 172.16.23.12

Просмотрите этот FAQ о настройке и использованию TCP wrapper'ов под Linux / Mac OS X и другими UNIX-подобными операционными системами.

16: Запретите пустые пароли

Вы должны явно запретить удаленный логин для аккаунтов с пустыми паролями, обновив sshd_config следующей строкой:

1
PermitEmptyPasswords no

17: Препятствуйте SSH взломщикам (Brute Force Attack)

Brute force это способ положить крипто-систему на лопатки используя большое количество возможностей одиночных систем или распределенных компьютерных сетей. Для препятствия таким атакам на SSH просто используйте следующие программные решения:

  • DenyHosts утилита для безопасности SSH серверов, написанная на Python. Она предназначена для предотвращения BF-аттак анализируя неудачные попытки аутентификации из лога и последующей блокировки ip адресов, с которых и производилась попытка входа.
  • Fail2ban программа работающая аналогичным образом, и также написанная на Python. Имеет большую популярность, так как защищает от BF-аттак не только SSH-сервер, но и другое ПО.
  • security/sshguard-pf защищает от BF атак как ssh так и другие сервисы, используя pf firewall
  • security/sshguard-ipfw защищает от BF атак как ssh так и другие сервисы, используя ipfw firewall
  • security/sshguard-ipfilter защищает от BF атак как ssh так и другие сервисы, используя ipfilter firewall
  • security/sshblock блокирует abusive попытки ssh входа/
  • Brute Force Detection Модульный shell-скрипт для парсинга логов приложения и проверки на неудачные попытки аутентификации. Стоит использоваться на системах, где логи приложений имеют свой уникальный формат, и под каждый лог нужены свои уникальные регулярные выражения.
  • IPQ BDB filter Может рассматриваться как легкая версия fail2ban.

18: Входящие ограничения соединений порта #22

Оба firewall'а, и netfilter и pf, позволяют устанавливать простые регулирующие опции на входящие соединения #22 порта.

Пример с использованием iptables

Следующий пример режет все входящие соединения, у которых было более 5 попыток на #22 порт за 60 секунд:

1
2
3
4
5
#!/bin/bash
inet_if=eth1
ssh_port=22
$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --set
$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --update --seconds 60 --hitcount 5 -j DROP

Другой пример с iptables:

1
2
3
4
5
$IPT -A INPUT -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT
$IPT -A INPUT -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o ${inet_if} -p tcp --sport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT
# another one line example
# $IPT -A INPUT -i ${inet_if} -m state --state NEW,ESTABLISHED,RELATED -p tcp --dport 22 -m limit --limit 5/minute --limit-burst 5-j ACCEPT

Для больших деталей используйте команду:

man iptables

Пример с использованием *BSD PF

Следующие ограничения представляют из себя всего 20 максимальных соединений от источника за все время или 15 попыток за 5 секундный интервал. Если кто-то нарушает наши правила, то он попадает в нашу таблицу abusive_ips и блокируется на дальнейшие соединения. И в окончание стоит упомянуть о flush. Он просто обнуляет заполненные таблицы, если нам это потребуется.

1
2
3
4
sshd_server_ip="202.54.1.5"
table persist
block in quick from
pass in on $ext_if proto tcp to $sshd_server_ip port ssh flags S/SA keep state (max-src-conn 20, max-src-conn-rate 15/5, overload flush)

19: Используйте Port Knocking

Одним из первых способов защиты была показана смена порта на нестандартный. Однако, простым nmap можно его найти, и начать BF-атаку. Но что, если закрывать сначала все порты, и лишь при определенных обстоятельствах открывать порт ssh. И какие же можно использовать обстоятельства? Можно использовать попытки соединений по какому-то определенному набору, или последовательности портов. И лишь после таких действий открывать порт для ssh, и разрешать соединение с клиентом, потому что он знает в какие двери нужно было постучать (knocking). Для такой техники нам ничего не потребуется кроме вашего firewall'а:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$IPT -N stage1
$IPT -A stage1 -m recent --remove --name knock
$IPT -A stage1 -p tcp --dport 3456 -m recent --set --name knock2
 
$IPT -N stage2
$IPT -A stage2 -m recent --remove --name knock2
$IPT -A stage2 -p tcp --dport 2345 -m recent --set --name heaven
 
$IPT -N door
$IPT -A door -m recent --rcheck --seconds 5 --name knock2 -j stage2
$IPT -A door -m recent --rcheck --seconds 5 --name knock -j stage1
$IPT -A door -p tcp --dport 1234 -m recent --set --name knock
 
$IPT -A INPUT -m --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name heaven -j ACCEPT
$IPT -A INPUT -p tcp --syn -j doo

Сначала мы стучимся в порт #1234, потом в #3456, затем в #2345 и входим по #22 порту, который открылся.

20: Используйте анализаторы логов

Читайте ваши логи используя logwatch или logcheck. Эти утилиты могут упростить вам жизнь. Они будут проходить по логом по данным интервалам времени и сообщать об участках и деталях, которые вы хотите видеть. И удостоверьтесь что директива LogLevel имеет значение INFO или DEBUG в sshd_config:

1
LogLevel INFO

21: Обновляйте OpenSSH и операционные системы

Это лучше всего делать через такие инструменты как yum, apt-get, freebsd-update или другие для использования последних security-патчей.

Иные способы

Чтобы скрыть версию openssh, вы должны обновить исходный код и заново скомпилировать openssh. Проверьте что такие опции включены:

1
2
3
4
5
6
7
8
9
10
11
# Включить разделение привилегий
UsePrivilegeSeparation yes
# Предотвращение использования незащищенных домашних директорий и ключевых прав доступа к файлам.
StrictModes yeshttp://rus-linux.net/nlib.php?name=/MyLDP/sec/openssh.html
# Turn on reverse name checking
VerifyReverseMapping yes
# Отключение форвардинга портов, если он не нужен.
AllowTcpForwarding no
X11Forwarding no
# Если вы аутентифицируетесь только по ключам, то можно выключить логин по паролям.
PasswordAuthentication no

Проверяйте файл настроек перед перезапуском sshd:

1
# /usr/sbin/sshd -t

Есть и другие техники, но о них стоит поговорить в отдельности. 🙂

Источник: welinux.ru.

Ejina
2012-02-10 18:39:00
Спасибо!
AlexN
2015-03-07 18:38:00
Тоже взял что-то полезное, спасибо. Но не понятно пару нюансов, если нету в файле sshd_config таких строк AllowUsers root, как их туда правильно прописать?