Третья, заключительная часть моей серии статей про portknocking (PK). Начало этой серии читайте здесь.
Сегодня мы завершим рассмотрение этого метода скрытия своих подключений и любого взаимодействия (например, авторизации) с целевым сервером, рассмотрев самый навороченный и современный вид PK — гибридный. Также мы подведём итог всему этому делу, укажем слабые и сильные места всех рассмотренных подходов.
Гибридными называют технологии PK, в рамках которых сочетаются сразу несколько разнородных концепций. Обобщая, можно выделить типичные составляющие гибридного PK (HPK): традиционный port-knocking, стеганография, криптография, реализация обоюдной авторизации (часто двухсторонняя SPA).
Не нужно думать, что подобные «слоеные бутерброды» изобретают лишь для увеличения формальной сложности защиты — скорее это попытка ювелирно подогнать друг под друга разные техники, чтобы каждая органично нивелировала своими преимуществами недостатки другой — и наоборот.
Существует несколько работ подробно описывающих HPK, из-за недостатка места я сосредоточусь лишь на двух, — типичных преимуществах этого подхода:
fwknop
), то это создает весьма ощутимую нагрузку на сервер. Это открывает возможность злоумышленнику для намеренной эксплуатации «родовой особенности» этой техники, что потенциально приведёт к возникновению сильнейшего DDoS-эффекта.HPK в этой дилемме занял выигрышную компромиссную позицию: он маркирует каждый свой «магический пакет», но при этом для сокрытия идентифицирующего признака применяются продвинутые методы стеганографии. Как пример последнего, номер запрашиваемого для открытия сервиса/порта + пакет авторизации здесь может быть передан даже не на транспортно-сетевом уровне TCP/IP, а на прикладном уровне (или их смешении), — будучи внедрены в обычное со всех точек зрения png-изображение.
fwknop
и так далее). У такого подхода есть ещё несколько преимуществ, но для баланса отметим и главный недостаток — общий алгоритм взаимодействия при этом резко усложняется.У разных реализаций HPK имеются множество нюансов, поэтому предлагаю очень кратко коснуться технических особенностей лишь одной, но весьма достойной — Tariq:
scapy
для пассивного сниффинга всего входящего трафика, равно как и для конструирования обратного пакета-ответа. Несмотря на своё бесспорное техническое совершенство, HPK обычно алгоритмически очень сложен, что особенно ощущается при подборе клиента и иногда лишает мобильности и простоты его использования.
Известный американский специалист по безопасности Брайн Хатч (автор популярной серии книг «Linux Exposed») описал и реализовал в 2009 году систему для прослушки DNS-запросов на предмет скрытых knock-knock запросов. В его оригинальной реализации простая Perl-программа под названием watch_dns
просматривала весь UDP-трафик поступающий на локальный DNS-сервер, формируя список всех запрашиваемых хостов, а также IP-адреса источников запросов.
Второй Perl-скрипт в режиме реального времени сканировал это список и по специальному правилу выделял доменные имена, интерпретируя их как команды-запросы (для чего был разработан довольно простой, но в тоже время гибкий язык HidenHand).
Даже с точки зрения внешнего наблюдателя, который имел бы полный доступ к трафику обмена сообщениями между сервером и клиентом, не происходило бы ничего необычного — DNS-сервер, также как и все остальные сервисы работают штатным образом. Здесь, в отличие от обычного port knocking’a, нет вообще никаких бессмысленных, подозрительных или странных пакетов (например, ACK-запросов без ответа и т.п.). Но на самом деле HiddenHand позволяет не только открывать порты по запросу клиента, но также удаленно конструировать новые правила для работы системы безопасности, абсолютно незаметно, через имена подходящих по названию доменов-команд, динамически корректируя её логику работы и настройки.
Пока мы сосредоточились лишь на серверной стороне этой реализации, но стоит отметить также и удивительную простоту управления подобным механизмом со стороны клиента. В самом деле, здесь не нужно использовать какой-то сторонний «сакральный код» — для этого подходит множество подручных и обыденных программ, таких как nslookup
или host
, также можно воспользоваться веб-интерфейсами аналогичных сервисов. Но на самом деле все обстоит даже ещё проще. Брайан рекомендует создание на авторитетном DNS-сервере домена (находящимся полностью под вашим контролем) настройку для произвольного субдомена, который будет использоваться именно для этой цели.
Например, для созданного домена третьего уровня my.megashop.net
можно настроить тригеры прослушки и интерпретации ваших DNS-команд, при каждом обращении к нему. После этого можно использовать обычный браузер, для запроса к подобному домену, например запрос к ресурсу static.my.megashop.net
может открывать порт с SSH, а обращение к изображениям хранимым на img.my.megashop.net
будет снова закрывать его. На самом деле, подобные запросы могут исходить откуда угодно, не обязательно от вашего браузера, а, например, от стороннего сайта, который хостит страницу, элемент которой (.css-файл или картинка-аватор, как в примере Брайана) загружается с данного ресурса.
Брайан приводит рабочую демонстрацию этого, когда вход на его любимый технический форум (после авторизации на форуме происходит подгрузка аватора с «магического субдомена»), вызывает вышеописанный эффект «веерно падающего домино», когда в конечном результате SSH «вдруг» оживает и начинает принимать запросы. Фактически, на базе идей PK здесь реализована классическая двухфазовая авторизация (в данном случае SSH), за тем лишь отличием, что в отличии, например, от подобной двухступенчатой схемы у Google, здесь факт прохождения идентификации носит крайне неявный характер (успешный вход на публичный форум = первая фаза аутентификации при доступе к приватному SSH).
Хочу отдельно подчеркнуть, что этот дополнительный уровень сокрытия и безопасности очень прост в реализации. Брайн использовал три простых Perl-скрипта, на написание и отладку которых у него ушел один викэнд.
В заключение ещё раз подчеркну: port knocking не претендует заменить традиционную аутентификацию, это лишь дополнительный слой безопасности, который эффективно нейтрализует огромное количество специализированных инструментов и методов, разработанных для автоматизации подбора паролей, изучения уязвимостей публичных сервисов и поиска ошибок настройки, а также последующего их взлома или незаконного использования.
Во многом PK основывается на известном принципе «security through obscurity» и позволяет вывести наиболее чувствительные сервисы из зоны прямой видимости (и досягаемости) злоумышленника.
Но, как и любая технология, PK не лишен недостатков. Традиционная схема (TPK) подвержена опасности нарушения последовательности доставки (или потери) пакетов из-за естественных сетевых коллизий, сложностям в некоторых случаях при подключении через NAT/PAT (в этом случае можно попробовать более всеядный вариант — uPortKnock), использовании в многопользовательской среде или на нагруженных системах.
Кроме того на неё легко осуществить своего рода DDoS-атаку: когда злоумышленник бомбардируя потоком случайных «стуков» защищенный сервер (и для создания этого «шума» хватит даже низкоскоростного подключения), блокирует всякую возможность авторизоваться у легального пользователя. Большинство этих и других проблем успешно решаются в более современных реализациях PK, в первую очередь в вышерассмотренных методиках на основе SPA и HPK.
~
Общее оглавление и начало этой серии статей — доступно здесь.
4 комментария
Вся эта магия не имеет никакого смысла.
По одной очевидной сисадмину, но неочевидной программёру причине.
Настраиваешь SSH с доступом _исключительно_ по 4096-битному ключу. Отключаешь вход по паролю. Отключаешь все другие виды аутентификации, кроме ключа.
Все. Сбрутить 4096 битный ключ - я хочу видеть это. :) И пусть ломают ноги. Даже без ограничения доступа по IP извне. :)
PS. Ах, да - и своевременно обновляем OpenSSH. Как любой критичный сервис. Не из репов или портов, где мэнтайнер не обязан чесаться. А из исходников. Ручками. Не кажется ли вам, коллега, что это проще и легче, нежели городить неочевидные городки? Ах, да. В качестве наворота в угоду линукс-фанбоям, можно наложить патчи obfuscated SSH. И закрыть необфусцированный порт. Правда, клиент есть только один для таких серверов. Но это уже проблемы фанбоев, не правда ли? :)
SSH с входом _только_ по 4096 битному ключу решает все проблемы без чорной магии. Отключаем все остальные виды входов. Точка.
В этом случае на любую попытку брута SSHD тупо отвечает - "Key required". Ставим лимит по числу запусков от попыток зафоркать систему запусками SSHD, ставим задержки на неудачные логины с прирастанием времени таймаута - и вперед, до скончания веков брутить будут.
Вот такой конфиг:
# $OpenBSD: sshd_config,v 1.93 2014/01/10 05:59:19 djm Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
Port 22222
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
# The default requires explicit activation of protocol 1
#Protocol 2
# HostKey for protocol version 1
#HostKey /usr/local/etc/ssh_host_key
# HostKeys for protocol version 2
HostKey /usr/local/etc/ssh_host_ed25519_key
HostKey /usr/local/etc/ssh_host_rsa_key
#HostKey /usr/local/etc/ssh_host_dsa_key
#HostKey /usr/local/etc/ssh_host_ecdsa_key
# Lifetime and size of ephemeral version 1 server key
#KeyRegenerationInterval 1h
#ServerKeyBits 1024
# Ciphers and keying
#RekeyLimit default none
# Logging
# obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH
#LogLevel INFO
# Authentication:
#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10
#RSAAuthentication yes
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /usr/local/etc/ssh_known_hosts
#RhostsRSAAuthentication no
# similar for protocol version 2
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
IgnoreUserKnownHosts yes
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication no
#PermitEmptyPasswords no
# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes
AllowAgentForwarding no
AllowTcpForwarding no
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
X11UseLocalhost no
#PermitTTY yes
PrintMotd no
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
UsePrivilegeSeparation yes
#PermitUserEnvironment no
Compression yes
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
Banner /etc/issue
# override default of no subsystems
Subsystem sftp /usr/local/libexec/sftp-server
KexAlgorithms diffie-hellman-group-exchange-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group14-sha1
Ciphers chacha20-poly1305@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512,hmac-sha2-256
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
####
Ах, да - и криптоустановки харденим. Не дефолты. Телемаркет.