Пять простых шагов для защиты ssh в Ubuntu.
Размещено: 8-05-2015, 11:59 | Просмотров: 5242 | Комментариев: 0
Одна из самых важных вещей, которые нужно сделать сразу же после подключения сервера с Ubuntu к сети интернет — это, конечно же, защита от несанкционированного доступа к управлению сервером через ssh. Если этого не сделать, то очень быстро специально написанные программы, сканирующие глобальную сеть, обнаружат, что на вашем сервере открыт порт 22 и что для полного контроля над системой достаточно только подобрать пароль для пользователя root. Конечно, абсолютной защиты не существует, но максимально усложнить задачу злоумышленнику нам вполне по силам. Рассказ о методах защиты ssh я буду вести, учитывая возможные особенности как для полноценных выделенных серверов с Ubuntu, так и для VPS/VDS серверов.
Защищать доступ по ssh безусловно нужно. Если вы этого еще не делали, то просто загляните в файл /var/log/auth.log. Наверняка там есть записи о попытках несанкционированного доступа к системе.

Шаг первый
Изменяем номер порта ssh. Самое простое и очевидное, что можно сделать. Для этого открываем в текстовом редакторе (например, в nano) файл /etc/ssh/sshd_config:
sudo nano /etc/ssh/sshd_config

В одной из его первых строк находим директиву Port. Заменяем номер порта 22 на один из нестандартных портов, например, на 4117.
# What ports, IPs and protocols we listen for
Port 4117

После этого перезапускаем ssh-сервер:
sudo service ssh restart

…и вполне предсказуемо теряем связь с сервером. Поэтому заново подключаемся по ssh, но теперь указываем в параметрах подключения новый порт, например, так:
ssh -p 4117 root@example.org

Смена номера порта ssh позволяет избавиться от большинства попыток перебора паролей автоматическими программами. Однако от более профессиональных попыток несанкционированного доступа к вашей системе этот шаг не спасет. Вместе с ним следует применять и другие методы защиты.

Шаг второй
Отключаем учетную запись суперадминистратора (root). Сразу оговорюсь, что в Ubuntu учетная запись root по умолчанию отключена. Однако многие хостинг-провайдеры, у которых арендуются выделенные сервера, включают учетную запись root в операционных системах Ubuntu. Если вы используете выделенный сервер, то учетную запись root можно и нужно отключить. С точки зрения защиты ssh это усложнит перебор паролей — ведь кроме пароля теперь нужно будет знать еще и имя пользователя. Отключение учетной записи root в Ubuntu происходит при выполнении команды удаления пароля суперадминистратора:
sudo passwd -l root

Внимание! Перед отключением учетной записи администратора убедитесь, что у вас есть другая учетная запись с правами на выполнение команды sudo.
Поэтому на примере создания новой учетной записи test покажу как создать нового пользователя и наделить его правом выполнения команды sudo. Собственно, сначала создадим нового пользователя. Будем считать, что новый пользователь создается из-под учетной записи root, поэтому намеренно опускаю ключевое слово sudo перед командой adduser:
adduser test

Далее нужно узнать, кому в системе разрешено выполнять команды от имени суперпользователя, используя ключевое слово sudo. Для этого нам нужно заглянуть в файл visudo:
visudo

В этом файле вы можете обнаружить следующие строки:
# User privilege specification
root ALL=(ALL) ALL
# Allow members of group sudo to execute any command after they have
# provided their password
# (Note that later entries override this, so you might need to move
# it further down)
%sudo ALL=(ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

Строки, приведенные выше означают, что выполнять команды от имени суперадминистратора может пользователь root, а также пользователи, входящие в группы sudo и admin. Поэтому достаточно поместить нового пользователя в одну из этих групп. Файл visudo, тем временем, следует закрыть, не внося в него изменений. После этого добавим пользователя test в группу sudo:
usermod -a -G sudo test

Чтобы убедиться, что пользователь test был добавлен в группу sudo, можно выполнить следующую команду:
id test

После этого закрываем сеанс ssh от имени пользователя root, входим в систему под пользователем test (помним, что поменяли номер порта в первом шаге) и отключаем учетную запись root:
logout
ssh -p 4117 test@example.org
sudo passwd -l root

Несмотря на то, что этот шаг, безусловно повышает безопасность доступа к серверу по ssh, оговорюсь, что некоторое дополнительное программное обеспечение (например, для управления и перезагрузки VPS/VDS сервера через веб-интерфейс) может требовать, чтобы учетная запись root была активной. При наличии такого программного обеспечения имеет смысл задать для пользователя root пароль понадежнее и не отключать эту учетную запись.

Шаг третий
Настраиваем вход в систему по ключу и отключаем вход по паролю. Намного безопаснее использовать не пароли, а ключи RSA. Сначала нужно на клиентском компьютере, с которого вы будете заходить по ssh на удаленный сервер, сгенерировать закрытый и публичный ключи.
ssh-keygen

Ключи по умолчанию сохраняются в домашний каталог пользователя, в файлы ~/.ssh/id_rsa (закрытый ключ) и ~/.ssh/id_rsa.pub (публичный ключ). Для того, что авторизоваться на удаленном сервере по этому ключу, нужно передать на сервер свой публичный ключ. Это можно сделать с помощью команды scp:
scp -P 4117 test@example.org:~ ~/.ssh/id_rsa.pub

Это командой мы загрузим файл id_rsa.pub на сервер example.org в домашний каталог пользователя test. Также в этой команде указан нестандартный номер порта ssh: 4117. Затем уже на удаленном сервере нужно добавить содержимое файла id_rsa.pub в файл ~/.ssh/authorized_keys в домашнем каталоге того пользователя, под которым мы хотим войти в систему, используя сгенерированный нами ключ. После добавления в authorized_keys исходный файл с публичным ключом можно удалить.
sudo sh -c 'cat ~/id_rsa.pub >> ~/.ssh/authorized_keys'
rm ~/id_rsa.pub

После этого разлогиниваемся на удаленном сервере командой logout и пытаемся зайти снова. Если сервер не спрашивает пароль, то все прошло успешно — и мы авторизовались с помощью секретного (закрытого) rsa-ключа ~/.ssh/id_rsa, находящего на нашем компьютере. Если авторизация по ключу не удается и сервер по прежнему спрашивает пароль, то с помощью ключа ‘-v’ включаем режим отладки ssh-соединения и разбираемся в причинах ошибки:
ssh -p 4117 -v test@example.org

После того как будет успешно настроена авторизация по ключам, следует отключить возможность авторизации по паролю. Для этого нужно найти в файле /etc/ssh/sshd_config директиву PasswordAuthentication и установить ее значение в ‘no':
# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no

После этого остается только перезапустить ssh:
sudo service ssh restart

В силу особенностей VPS/VDS хостинга, которые я описывал на втором шаге, иногда требуется, что учетная запись root была активной, и чтобы можно было войти под пользователем root, используя пароль. Поэтому иногда способ защиты ssh путем отключения паролей и настройки входа по rsa-ключам неприменим.

Шаг четвертый
Расставляем ловушки — настраиваем утилиту denyhosts. Утилита представляет собой python-скрипт, который анализирует файл /var/log/auth.log на наличие записей о несанкционированных попытках входа на сервер по ssh и добавляет ip-адреса, с которых осуществлялись эти попытки в файл /etc/hosts.deny (список ip-адресов, с которых запрещен вход по ssh). Утилита denyhosts — серьезный помощник в деле защиты ssh (да и других сервисов). При ее использовании задача подбора пароля усложняется до невозможности.
Сначала установим denyhosts из репозитория:
sudo aptitude install denyhosts

Сразу после установки утилита просканирует файл /var/log/auth.log и добавит ip-адреса, с которых осуществлялся подбор паролей, в /etc/hosts.deny. Наберитесь терпения, если в файле /var/log/auth.log уже много таких записей.
Сразу после установки denyhosts уже готово к работе, однако рекомендую обратить внимание на несколько настроек, которые находятся в файле /etc/denyhosts.conf. Во-первых, это директива PURGE_DENY, которая определяет время, в течение которого следует хранить заблокированные ip в списке hosts.deny. По умолчанию эта директива содержит пустое значение, что означает, что список hosts.deny не очищается никогда. Если ip-адрес туда попал, то больше нельзя будет зайти с него на этот сервер, используя ssh. Иногда это может привести к тому, что введя несколько раз неправильно свой пароль, мы можем заблокировать сами себе доступ к своему же серверу. Ситуация может усугубиться, если используется авторизация по ключам и выход в интернет осуществляется со статичного ip-адреса. Поэтому рекомендую установить эту директиву в значение, равное нескольким часам.
PURGE_DENY = 3h

Также рекомендую указать адрес электронной почты для рассылки уведомлений о неудачных попытках доступа к серверу:
ADMIN_EMAIL = test@example.org

Для того чтобы новые настройки вступили в силу, нужно перезапустить службу denyhosts:
sudo service denyhosts restart


По большому счету, описанных мной четырех шагов должно с лихвой хватить для повышения безопасности сервера при доступе по ssh. Последний пятый шаг, про который я хочу рассказать, может использоваться, когда требуется почти параноидальный подход к безопасности сервера. Метод, который будет описан в пятом шаге, использует технологию .

Ее суть заключается в том, что на сервере запускается специальная служба knockd, которая «слушает» подключения по всем портам, и при получении некоей ожидаемой последовательности подключений выполняет заранее заданную администратором команду. Такая технология дает дополнительную возможность по удаленному управлению сервером. Остается только закрыть порт ssh и задать службе knockd такую команду, которая заставит файерволл открыть порт ssh при получении определенной последовательности подключения к портам сервера. Далее я опишу как максимально просто и быстро сделать это в Ubuntu.

Шаг пятый
На удаленном сервере все ниже перечисленные действия следует производить с особой осторожностью, так как есть риск потерять связь с сервером в случае ошибки.
Сначала нужно установить пакет knockd. Вместе с ним также установится утилита knock, с помощью которой можно будет «простукивать» порты на удаленном сервере.
sudo aptitude install knockd

В составе Ubuntu есть упрощенный файерволл ufw, который значительно легче в понимании, чем iptables. Поэтому для открытия порта ssh службой knockd мы будем использовать именно ufw, который по своей сути является надстройкой для iptables. Пакет ufw установлен в Ubuntu по умолчанию. Если пакета ufw нет, то его можно установить. Однако должен предупредить, что если пакета ufw нет на виртуальном выделенном сервере (VPS/VDS), то его лучше не устанавливать. На таких серверах обычно используются специальные ядра linux, некоторые из которых несовместимы с файерволлом ufw.
И так, при включении файерволла ufw все порты закроются. Поэтому перед стартом ufw следует открыть порт, на котором у нас находится ssh. В большинстве случаев это порт 22, но в предыдущей статье мы использовали порт 4117 для этих целей.
sudo ufw allow 22
sudo ufw enable

Затем нужно настроить конфигурационные файлы службы knockd. Ниже я привожу пример конфигурационного файла для открытия порта 22 на удаленном сервере.
[options]
logfile = /var/log/knockd.log

[openSSH]
sequence = 4561:tcp,7127:udp,5934:tcp,3901:udp
seq_timeout = 30
tcpflags = syn
start_command = ufw allow from %IP% to any port 22
cmd_timeout = 30
stop_command = ufw delete allow from %IP% to any port 22

Таким образом, удаленный сервер, получив последовательность подключений по портам 4561:tcp,7127:udp,5934:tcp,3901:udp, выполнит команду по открытию порта 22 для ip-адреса, с которого производился запрос. По истечении 30 секунд, возможность подключения по порту 22 для текущего ip-адреса исчезнет, так как будет выполнена команда stop_command, которая удалит правило, разрешающее подключение по ssh для ip-адреса из списка.
Предупреждаю, что при тестировании службы knockd лучше указывать порт, отличный от 22, так как в случае ошибки в конфигурационном файле можно потерять связь с сервером.
После этого перезапускаем службу knockd. Сначала внесем изменения в файл /etc/default/knockd:
# control if we start knockd at init or not
# 1 = start
# anything else = don't start
#
# PLEASE EDIT /etc/knockd.conf BEFORE ENABLING
START_KNOCKD=1

Затем перезапустим саму службу:
sudo service knockd restart

На компьютере, с которого мы будем подключаться к удаленному серверу, также установим службу knockd и выполним команду, которая добавит в файерволл новое правило:
sudo aptitude install knockd
knock 4561:tcp 7127:udp 5934:tcp 3901:udp

Чтобы проверить, добавилось ли новое правило, нужно в течение 30 секунд выполнить на удаленном сервере команду:
sudo ufw status

Если в списке будет присутствовать правило, разрешающее доступ к порту с ip-адреса, с которого выполнялась команда knock, то значит служба knockd успешно настроена. После этого можно закрывать порт 22 и открывать его только при необходимости и только для определенного ip-адреса. Порт 22 можно закрыть на удаленном сервере следующей командой:
sudo ufw delete allow 22

Таким образом, технологию Port knocking можно использовать в качестве еще одного способа защитить свой выделенный сервер от недоброжелателей. Однако настраивать службу knockd нужно внимательно, так как возможна ситуация, при которой мы закроем себе доступ к управлению сервером.