Брандмауэр уровня приложений - tcpwrappers

TCP Wrappers – изначально набор вспомогательных программ 'запускалок' (tcpd, miscd и вспомогательные программы), для контроля за IP адресами клиентов, стартующих сетевые сервисы через inetd. Основная функция, управляющая проверкой правил, hosts_access(request) была в последующем выделена в отдельную библиотеку libwrap. В настоящее время эту библиотеку используют самые разнообразные сервисы, такие как xinetd, sshd, rsyncs и т.п. Полный список программ, использующих TCP Wrappers, можно получить, выполнив следующую команду:

strings -f  /usr/sbin/* /usr/local/sbin/* |  grep hosts_access

Функция hosts_access использует два конфигурационных файла /etc/hosts.allow и /etc/hosts.deny (в FreeBSD только /etc/hosts.allow), которые могут иметь классический или расширенный синтаксис.

Классический вариант

В классическом варианте вначале проверяются все правила из hosts.allow. Если хоть одно правило применимо к паре сервис-клиент, то соединение устанавливается. Затем проверяются все правила из hosts.deny. При нахождении соответствия соединение отклоняется. Если правила нет, то соединение устанавливается. Чтобы явно разрешить доступ только по правилам из hosts.allow, необходимо добавить в hosts.deny правило ALL:ALL.

Классический синтаксис описан в man странице HOSTS_ACCESS(5). Файлы состоят из строк вида

daemon_list : client_list [ : shell_command ]

где

  • daemon_list – список имён сервисов (в xinetd имена прописываются явно в конфигурации службы, для остальных программ они совпадают с именем исполняемого файла) или ключевое слово ALL;
  • client_list – список имён/адресов клиентов;
  • shell_command – вспомогательная команда, например, для логирования событий. В современном варианте это поле имеет другой формат.

Современный вариант

Файлы /etc/hosts.allow и /etc/hosts.deny эквивалентны по своему назначению. Каждое правило может содержать результат – allow или deny. Если в правиле результат не прописан явно, то он вычисляется по правилу классического варианта. Можно считать, что все правила находятся hosts.allow, а hosts.deny остается пустым. Выполняется первое найденное правило.

Синтаксис правил описан в man странице HOSTS_OPTIONS(5). Файлы состоят из строк вида

daemon_list : client_list : option [: option ...]

daemon_list, client_list полностью совместимы с классическим синтаксисом, а опции позволяют понизить привилегии, запустить дополнительную программу параллельно с сервисом или вместо него, и, наконец, принять решение allow или deny. Опции выполняются слева направо. Опция allow/deny должна стоять последней, поскольку после неё произойдёт запуск сервиса или прекращение работы.

Для запуска дополнительных программ используются две опции: spawn shell_command – запуск программы в параллельном процессе одновременно с сетевым сервисом, и twist shell_command – запуск программы в текущем процессе вместо сервиса. Командам в качестве параметров можно передать некоторую информацию о соединении. spawn не влияет на запуск основного сервиса, поэтому за ней должна следовать опция allow или deny. twist затирает текущий процесс и, соответственно, дальнейшие проверки опций. Однако, через параметры в twist можно передать имя исполняемого файла сервиса, чтобы выполнить его после дополнительных проверок.

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

В конце списка правил можно добавить правило по умолчанию ALL:ALL:deny, иначе подразумевается наличие ALL:ALL:allow.

Формат списка client_list

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

Ключевые слова (часть опущена):

  • ALL – все хосты
  • PARANOID – хосты, у которых цепочка преобразований IP->Имя->IP даёт адрес, отличный от исходного.

Шаблоны (часть опущена):

  • .example.org – все имена из домена
  • 192.168.1. – все IP адреса подсети
  • 192.168.132.0/255.255.254.0 – IP адреса по маске
  • /etc/deny.list – текстовый файл, состоящий из строк, содержащих списки хостов в любой описанной выше форме
  • www.*.ru - подстановка вместо звёздочки любого количества символов. Не может быть частью предыдущих шаблонов.

Подстановки при запуске внешних команд

  • %a (%A) Адрес клиента (сервера)
  • %h (%H) Имя клиента (сервера)
  • %d Имя сервиса
  • %p Идентификатор процесса (PID)

Примеры

#классический стиль
sshd : .example.com
vsftpd : 192.168. 
ALL : 192.168.1.0/255.255.255


# Разрешаем подключение из домена .example.com
# кроме station15.example.com
sshd : station15.example.com : deny
sshd : .example.com : allow
#Дополнительно запрещаем всем кроме домена *.hacker.org
sshd : ALL EXCEPT *.hacker.org:twist /bin/echo "Reject - bad host name %h"
# Фактически разрешаем *.hacker.org (остальные уже заблокированы)
# с логированием соединений в файл /tmp/sshd.connections
sshd : ALL:spawn /bin/echo "%d at %I connected from %i" > /tmp/sshd.connections: allow
# Запрещаем остальные соединения
ALL:ALL:deny