Ну «Secure», так «Secure»…

«Сервер» мой домашний — это просто системный блок, лежащий на холодильнике. Ни монитора, ни клавиатуры с мышью к нему не подключено. Все управление своим «сервером» я осуществляю дистанционно по сети. Для этого я установил и настроил службу удаленного доступа — «сервер-NX». Процедура установки и настройки уже описана мной тут. NX-сервер в своей работе использует механизмы службы SSH (secure shell), и поэтому, у сервера запущен демон SSH, который постоянно ожидает соединений на 22 порту. Естественно, с этой же целью в моем ADSL-маршрутизаторе настроен «port forvarding» 22-го порта на мой «сервер» (я им не только из дома, но и с работы «порулить» могу). А с другой стороны «бог даровал» народу всевозможные программы «сканеров портов». И как следствие, периодически кто-то пытается подобрать к моему серверу имя пользователя и пароль, о чем «сервер» мой все четко пишет в файл протокола аутентификации /var/log/auth.log :

Failed password for invalid user bin from XXX.XXX.XXX.XXX port 52100 ssh2
Failed password for invalid user daemon from XXX.XXX.XXX.XXX4.32.126 port 52567 ssh2
Failed password for invalid user sync from XXX.XXX.XXX.XXX port 52610 ssh2
Failed password for invalid user shutdown from XXX.XXX.XXX.XXX port 52676 ssh2
Failed password for invalid user halt from XXX.XXX.XXX.XXX port 52728 ssh2
Failed password for invalid user uucp from XXX.XXX.XXX.XXX port 52777 ssh2
Failed password for invalid user smmsp from XXX.XXX.XXX.XXX port 53021 ssh2

Причем, число подобных строк в протоколе может достигать нескольких тысяч за час (неймется им!). «Хорошая» штука — сканер портов. Без нее у «гражданина-хакера» уже все пальцы «в дым стерлись бы»!.. А так — сиди, чай попивай!..

Получится ли у «хакера» войти в мой «сервер» или нет — это еще вопрос. Но, как говорится, «береженого бог бережет». Чтож, будем защищаться! В принципе, у SSH существует сравнительно простой способ напрочь забыть о таких «взломщиках». Для этого нужно просто настроить доступ к серверу по SSH-ключу, и полностью отключить возможность входа по паролю. Ключ может быть длинный, например, 2048 байт, и подобрать его будет, мягко говоря, затруднительно. Как настроить службу SSH, подробно описано на вот этой странице, и дублировать тут ее целиком я не вижу смысла. Если вкратце, то лично я, руководствуясь информацией с этой страницы, находясь в консоли той клиентской машины и с правами того пользователя, для которых настраиваем доступ к серверу по ключу, выполнил всего две команды. Сначала я выполнил следующее:

ssh-keygen -t rsa -b 2048

Данная команда сначала спрашивает имя файла ключа (используем значения, предложенные по умолчанию), потом предлагает ввести дополнительный пароль (passphrase) для ключа (это повышает безопасность, но потом пароль нужно будет вводить все время), и затем создает пару ключей (приватный и публичный) в папке $HOME/.ssh/ на клиентской машине. Именно эти ключи и будут в дальнейшем использоваться вместо пароля при идентификации пользователя на сервере. После этого, перейдя в папку $HOME/.ssh/ я выполнил вторую команду:

ssh-copy-id -i id_rsa.pub dmitry@myserver

Эта команда сперва спрашивает пароль пользователя на сервере, а затем копирует публичный ключ (файл id_rsa.pub) в папку указанного пользователя на указанный сервер (естественно, вместо «dmitry» Вы подставляете свое имя пользователя, а вместо «myserver» имя своего сервера). После этого проверяем возможность беспарольного входа — в консоли клиентской машины вводим команду:

ssh dmitry@myserver

Результат успешного выполнения данной команды — вы входите в консоль сервера, не вводя никаких паролей. После этого можно в SSH отключить возможность доступа по паролю — в файле /etc/ssh/sshd_config сервера строку «PasswordAuthentication yes» заменить на «PasswordAuthentication no«. Учтите, что после внесения изменений в конфигурацию сервера, его нужно перезапустить. После этого сканеры портов не смогут подбирать пароль к Вашему компьютеру по той простой причине, что доступ по паролю будет отключен!

И все было бы хорошо, если бы не одно «но». После таких манипуляций становится невозможным вход в сервер при помощи NX! Об этом, кстати, четко сказано в документации к NX-серверу — «работа службы в случае запрета SSH-доступа по паролю невозможна». Читаем мы, правда, обычно уже «потом»… Честно говоря, поначалу я был удивлен. Еще при настройке сервера NX я видел, что им при аутентификации используется не пароль, а публичный ключ. Понимание того, «почему нельзя», пришло после прочтения все того же файла протокола аутентификации в начале NX-сессии. В нем мы видим следующие три строки:

Accepted publickey for nx from 192.168.1.15 port 3640 ssh2
Accepted password for dmitry from 127.0.0.1 port 45410 ssh2
Accepted publickey for dmitry from 127.0.0.1 port 45411 ssh2

Как мы видим в приведенном фрагменте лога, ИЗВНЕ в сервер входит не пользователь «dmitry«, а пользователь «nx«. Причем, входит не по паролю, а по ключу (тому самому, который и «длинный», и «трудно подбираемый»). А вот имя пользователя (в моем случае — «dmitry«) и пароль (как следует из второй приведенной строки), используется уже для запуска сессии только ВНУТРИ сервера.

Что нам это дает? Во-первых, понимание того, что доступ по паролю все-таки нужно включить обратно. А то «кина не будет»!… Поэтому, в файле /etc/ssh/sshd_config сервера снова возвращаем на место строку «PasswordAuthentication yes» (аутентификация по паролю разрешена). Не забываем при этом перезапустить сервер. Выходит, что мы вернулись к тому, с чего начинали! Но, у SSH есть еще одна возможность — управление доступом пользователей. Причем, с учетом адреса(ов) машин(ы), с которой(ых) данный пользователь пытается получить доступ к серверу. Каким образом мы можем это использовать? Возьмем всё тот же файл конфигурации демона SSH (/etc/ssh/sshd_config), и впишем в него следующие строки:

AllowUsers nx
AllowUsers dmitry@127.0.0.1

А теперь о том, что это строки обозначают. И начнем со второй строки. В ней указано, что пользователю «dmitry» разрешен вход в сервер ТОЛЬКО ЛИШЬ С ВНУТРЕННЕГО АДРЕСА «127.0.0.1» (того, что указан после «собаки»). И ни с каких других! Кстати, вместо конкретного адреса может быть указан шаблон, например, «192.168.0.*» (вся локальная сеть). А теперь вернемся к первой строке — она разрешает доступ к серверу пользователю «nx«. Причем, так как в ней нет никаких указаний адресов после «собаки», то данному пользователю доступ разрешен с ЛЮБОГО адреса. И еще один нюанс — сам факт наличия в конфигурации SSH-сервера пользователей, разрешенных директивой «AllowUsers«, обозначает, что всем другим доступ к серверу ЗАПРЕЩЕН!

Если быть более точным, то директив, управляющих доступом по SSH четыре: DenyUsers (запрещенные пользователи), AllowUsers (разрешенные пользователи), DenyGroups (запрещенные группы), и AllowGroups (разрешенные группы). До тех пор, пока в конфигурации демона SSH нет ни одной из этих директив, доступ разрешен ВСЕМ. Наличие ЛЮБОЙ из указанных директив будет ограничивать доступ соответствующим образом. В случае использования НЕСКОЛЬКИХ (или всех) указанных директив порядок проверки будет следующим: DenyUsers, AllowUsers, DenyGroups, и наконец AllowGroups.

В итоге, указавши двух пользователей как приведено выше, мы получили следующее — ИЗВНЕ в наш сервер может войти только лишь один пользователь «nx«. Войдя в сервер, пользователь «nx» запускает уже ЛОКАЛЬНУЮ (с адреса 127.0.0.1) сессию пользователя «dmitry«, который хоть и аутентифицируется по паролю, но уже ВНУТРИ сервера …

Таким образом, сейчас тому, кто захочет войти в мой «сервер» понадобится всего лишь подобрать публичный ключ. Тот, который длинной 2048 бит… Кому не лень, пусть подбирает!

ЗЫ. Если же для «себя любимого» (или другого пользователя) нужно оставить и возможность входа в Secure Shell (SSH), то во все тот же файл конфигурации демона SSH (/etc/ssh/sshd_config) нужно вписать соответствующие «разрешающие» строки с указанием адреса(ов) компьютера(ов), с которых необходимо разрешить доступ. Например вот так:

AllowUsers dmitry@91.121.15.100

(разрешает доступ пользователю «dmitry» с компьютера с адресом «91.121.15.100«). Или, например, вот так для всей подсети (внутренней):

AllowUsers dmitry@192.168.0.*