Поиск по сайту:

Как использовать Port Knocking, чтобы скрыть демон SSH от злоумышленников в Ubuntu


Статус: устарело

В этой статье рассматривается версия Ubuntu, которая больше не поддерживается. Если вы в настоящее время используете сервер под управлением Ubuntu 12.04, мы настоятельно рекомендуем обновить или перейти на поддерживаемую версию Ubuntu:

  • Обновите Ubuntu до версии 14.04.
  • Обновление Ubuntu 14.04 до Ubuntu 16.04
  • Перенесите данные сервера в поддерживаемую версию.

Причина:

Смотрите вместо этого:

Введение

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

Брандмауэры существуют, и их следует использовать для блокировки доступа к портам, не используемым службой, но все еще остается вопрос, что делать со службами, к которым вы хотите получить доступ, но не хотите предоставлять доступ всем. Вы хотите получить доступ, когда вам это нужно, но хотите, чтобы он был заблокирован в противном случае.

Стук портов — это один из методов сокрытия служб, запущенных на вашем компьютере. Это позволяет вашему брандмауэру защищать ваши службы, пока вы не запросите открытие порта для определенной последовательности сетевого трафика.

В этом руководстве мы обсудим, как реализовать стук портов как метод скрытия вашего демона SSH на VPS Ubuntu 12.04 с помощью пакета knockd.

Примечание. В этом руководстве рассматривается безопасность IPv4. В Linux безопасность IPv6 поддерживается отдельно от IPv4. Например, \iptables поддерживает только правила брандмауэра для адресов IPv4, но у него есть аналог IPv6, называемый \ip6tables, который можно использовать для поддержки правил брандмауэра для сетевых адресов IPv6.

Если ваш VPS настроен для IPv6, не забудьте защитить сетевые интерфейсы IPv4 и IPv6 с помощью соответствующих инструментов. Дополнительные сведения об инструментах IPv6 см. в этом руководстве: Как настроить инструменты для использования IPv6 на Linux VPS.

Как работает детонация портов?

Стук портов работает путем настройки службы для просмотра журналов брандмауэра или интерфейсов захвата пакетов для попыток подключения. Если выполняется определенная последовательность предопределенных попыток соединения (или «стуков»), служба изменит правила брандмауэра, чтобы открыть соединения на определенном порту.

Это позволяет вам скрывать свои услуги до тех пор, пока вы не планируете их использовать. Это было бы нецелесообразно для чего-то вроде HTTP-сервера, потому что вы хотели бы, чтобы соединения были доступны в любое время. Но это было бы полезно для служб, предназначенных для использования только известными законными пользователями, такими как SSH.

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

Еще более полезным является то, что нет обратной связи при попытках постучать. Сканирование злоумышленника увидит, что все обычные порты закрыты, и если он попытается выполнить последовательность детонации, ему придется проверять между каждой попыткой, был ли открыт порт. Часто этого достаточно, чтобы отговорить или запретить злоумышленников.

Для наших целей мы будем использовать брандмауэр iptables, поставляемый с Ubuntu 12.04, и установим демон с именем knockd, чтобы обеспечить функциональность перехвата портов.

Настройте IPTables для блокировки большей части трафика

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

По умолчанию Ubuntu поставляется с установленным iptables. Однако правил по умолчанию не существует, поэтому разрешен весь трафик. Чтобы создать свой собственный набор правил, вы можете узнать, как настроить брандмауэр с помощью iptables, здесь.

Для наших целей мы будем использовать большинство правил из этого руководства.

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

sudo iptables -A INPUT -i lo -j ACCEPT

Это добавляет правило к цепочке \INPUT. Эта цепочка обрабатывает все подключения, поступающие на сервер. Это правило указывает iptables принимать весь трафик через сетевой интерфейс \lo, который является локальным интерфейсом обратной связи, используемым для внутренней связи.

Затем мы хотим убедиться, что разрешаем все установленные соединения и трафик, связанный с установленными соединениями, набрав:

sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

Это правило указывает iptables принимать трафик, связанный с уже установленным соединением. Это важно, потому что, как только мы начнем блокировать соединения, мы не хотим, чтобы наш текущий сеанс SSH был прерван.

Затем вы захотите разрешить постоянные, доступные для всего мира сервисы. Под этим я подразумеваю добавление правил для служб, которые должны быть всегда запущены и видимы. Например, если у вас есть веб-сайт, который обслуживается через стандартный порт 80, вы хотите постоянно разрешать этот трафик.

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

Используйте этот синтаксис, чтобы установить свои собственные правила:

<пред>

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

Теперь мы отбросим все, что мы специально не разрешили. Добавьте это правило:

sudo iptables -A INPUT -j DROP

Любой трафик, который не был обработан вышеуказанными правилами, будет отброшен. Вы можете просмотреть свои правила, набрав:

sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -j DROP

Как видите, у нас до сих пор нет правил для принятия новых SSH-соединений.

Если на этом этапе ваше соединение прервано, вам нужно будет получить доступ к серверу через панель управления, нажав кнопку «Доступ к консоли» в правом верхнем углу:

Это действует как прямой вход в систему и не использует SSH, поэтому ваши правила не повлияют на него.

После того, как вы установили свои правила iptables, сделайте их постоянными с помощью iptables-persistent. Установите его, набрав:

sudo apt-get install iptables-persistent

После этого запустите службу, набрав:

sudo service iptables-persistent start

Установите службу Knockd

Служба, которая знает о перехвате портов, которую мы будем использовать, называется knockd. Мы можем установить его, просто набрав:

sudo apt-get install knockd

Это установит утилиту, но не запустит службу по умолчанию.

Это мера предосторожности для предотвращения немедленной блокировки демоном важного трафика. Вы должны настроить и явно включить эту службу.

Настройте Knockd для использования стука портов

Чтобы настроить сервис, нам придется отредактировать файл конфигурации. Откройте этот файл с привилегиями root:

sudo nano /etc/knockd.conf

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

[options]
        UseSyslog

[openSSH]
        sequence    = 7000,8000,9000
        seq_timeout = 5
        command     = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn

[closeSSH]
        sequence    = 9000,8000,7000
        seq_timeout = 5
        command     = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
        tcpflags    = syn

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

В разделе \options мы видим директиву UseSyslog. Это говорит постукиванию, что он должен регистрировать свою информацию, используя обычные методы системного журнала. Это будет вставлять журналы в /var/log/ сообщения.

Если вы хотите указать другой файл журнала, вы можете сделать это с помощью этой опции:

<пред>

Внизу у нас есть две секции. Названия этих разделов могут быть любыми. Они используются для группировки набора правил, каждое из которых будет соответствовать одному событию.

Например, в нашем файле есть раздел, который откроет наш порт SSH, и раздел, который снова закроет его.

Параметр, задающий характер стука, находится здесь:

<пред>

Это означает, что этот набор правил будет совпадать, если один и тот же IP-адрес запрашивает соединение через порт 7000, за которым следует непосредственно порт 8000 и, наконец, порт 9000.

Два других параметра в этом наборе также определяют, соответствует ли активность:

seq_timeout = 5
tcpflags = syn

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

Второй указывает флаг, который должен присутствовать в tcp-пакетах, чтобы они считались действительными. Значение syn, которое мы здесь видим, обычно используется для того, чтобы отличать пакеты, которые нам нужны, от пакетов, созданных в фоновом режиме такими программами, как SSH.

Наконец, мы видим команду:

command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport 22 -j ACCEPT

Вы должны распознать это как правило iptables. Как указывает метка раздела «openSSH», этот раздел откроет порт для SSH-соединений при выполнении правильной последовательности.

Однако, если вы были внимательны во время настройки iptables, вы увидите, что это новое правило использует параметр -A для добавления этого правила в конец цепочки INPUT. . Это поместит это правило после правила сбрасывания всех оставшихся подключений.

Чтобы исправить эту ситуацию, нам нужно изменить эту команду. Замените команду правилом, чтобы вставить новое правило вверху списка. Мы делаем это, используя параметр -I и ссылаясь на местоположение как на правило 1:

command = /sbin/iptables -I INPUT 1 -s %IP% -p tcp --dport 22 -j ACCEPT

С этим изменением в начало цепочки INPUT будет добавлено новое правило для приема SSH-соединений от пользователя, который постучал. Часть правила %IP% будет заменена IP-адресом, который сделал приемлемый стук.

Второй раздел SSH делает почти то же самое, но использует другую последовательность и удаляет правило из iptables, которое открывало соединения с SSH. Мы можем нажать эту последовательность, чтобы закрыть пробел, который мы открыли.

На практике вы всегда должны менять последовательность этих двух разделов на что-то по существу случайное. Сохранение последовательности по умолчанию эффективно устраняет любую защиту, которую устанавливает детонация портов.

Прежде чем мы настроим что-либо дальше, давайте проверим нашу текущую настройку. Сохраните и закройте файл.

Внедрить службу Knockd

Теперь, когда мы настроили Knockd для корректного набора правил, мы можем протестировать его, внедрив наш демон. Имейте в виду, что, хотя конфигурация действительна, на данный момент она небезопасна, если вы не изменили последовательность портов для каждой секции детонации.

Нам нужно включить службу, отредактировав другой файл. Откройте этот файл с привилегиями root:

sudo nano /etc/default/knockd

Нам нужно изменить параметр START_KNOCKD на \1, чтобы запустить службу:

<пред>

Сохраните и закройте файл.

Теперь мы можем запустить службу, набрав:

sudo service knockd start

Это запустит демон и позволит вам изменить наборы правил iptables, постукивая по последовательностям портов.

Тест на детонацию портов

Теперь мы должны проверить нашу способность изменять правила iptables, используя настроенную нами последовательность пробивания портов.

В новом окне терминала мы можем использовать инструменты для запроса этих портов. Лучше оставить другой сеанс открытым на случай возникновения проблем. Опять же, если вы случайно заблокируете себя, используйте кнопку «доступ к консоли» в правом верхнем углу страницы дроплета в панели управления.

Мы можем использовать множество различных инструментов, чтобы стучать. Некоторыми популярными вариантами являются netcat, nmap и специально разработанный клиент, называемый соответственно knock.

В этом примере мы будем использовать nmap, поскольку он установлен по умолчанию в большинстве дистрибутивов Linux и OS X.

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

<пред>

Вы не должны получить ответ от сервера, а время ожидания клиента SSH должно истечь. Это связано с тем, что наш демон SSH в настоящее время заблокирован iptables. Введите ctrl-C, чтобы завершить попытку SSH, если время ожидания не истекло автоматически.

Из-за установленного параметра тайм-аута последовательности у нас есть очень ограниченное количество времени, чтобы попасть в правильную последовательность. Мы будем использовать небольшой встроенный bash-скрипт, чтобы быстро использовать эти порты.

На своем локальном компьютере введите следующую команду:

<пред>

В команде измените три числа на числа, которые вы выбрали для своей последовательности, чтобы открыть порт SSH. Измените server_ip_address, чтобы он отражал адрес вашего сервера.

Это вызовет nmap последовательно на всех перечисленных вами портах.

После этого вы сможете регулярно входить в SSH:

<пред>

Мы можем повторно закрыть порт, нажав другую последовательность, которую мы настроили:

<пред>

Стук портов с помощью утилиты Knock

Более простой способ постучать — использовать утилиту knock, предоставленную создателями knockd. Это включено в пакет Knockd, поэтому вы можете установить его на нашу клиентскую машину так же, как мы сделали с сервером:

sudo apt-get install knockd

Вы также можете получить Knock-клиенты с веб-сайта проекта в разделе «скачать». Доступны собственные клиенты для OS X и Windows (и даже клиенты для iOS и Android).

После того, как у вас установлен клиент Knock, вы можете легко выполнить последовательность, просто используя этот синтаксис:

<пред>

Итак, для нашего примера вы можете открыть свой SSH-порт, набрав:

<пред>

Это намного быстрее, чем другой упомянутый метод.

Мы можем закрыть порт, набрав:

<пред>

Настройка Knockd для автоматического закрытия соединений

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

Снова откройте файл конфигурации:

sudo nano /etc/knockd.conf

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

Мы можем закомментировать или удалить разделы «openSSH» и «closeSSH». Мы заменим их одним разделом, который назовем просто «SSH»:

[options]
    UseSyslog

[SSH]

В этом новом разделе мы установим последовательность, tcpflags и тайм-аут последовательности, как и в других разделах. Мы также включим команду, которую мы использовали для открытия порта SSH:

<пред>

[SSH]

Выберите уникальную последовательность портов. Как видите, в этом примере мы используем четыре порта. Мы можем увеличить количество портов, если все они могут быть задействованы в течение времени, указанного в параметре seq_timeout.

Параметр start_command аналогичен параметру command, используемому в другом примере. Мы решили использовать этот вариант просто для того, чтобы более подробно рассказать о том, что мы делаем.

После этого мы добавим несколько новых параметров, которые помогут нам закрыть порт:

<пред>

[SSH]

cmd_timeout — это количество секунд, в течение которых постукивание будет ждать перед выполнением команды, содержащейся в переменной stop_command.

В результате при использовании правильной последовательности демон откроет порт SSH. Затем он подождет 10 секунд, а затем снова закроет порт.

Сохраните и закройте файл.

Внедрите новое правило, перезапустив демон:

sudo service knockd restart

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

<пред>

Дыра, которую мы создаем в нашем брандмауэре, закроется за нами через 10 секунд.

Заключение

Хотя о детонации портов иногда говорят в пренебрежительном тоне как о безопасности через неясность (сокрытие службы вместо ее фактической защиты), это отличный способ добавить дополнительный уровень защиты от случайных атак.

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

Джастин Эллингвуд