TCP Wrappers


В главе 6 говорилось, что сетевые соединения устанавливаются различными программами, ожидающими запросов на соединение. Когда программа собрана с поддержкой TCP Wrappers, она проверяет полученный запрос в соответствии с правилами TCP Wrappers. Если правила требуют отвергнуть запрос, программа немедленно его отвергает. Вопреки своему названию, TCP Wrappers работает как с сетевыми соединениями TCP, так и с соединениями UDP. TCP Wrappers — это установившийся стандарт UNIX, который был внедрен в FreeBSD. Тем не менее отдельные программы могут и не работать с TCP Wrappers. Почти все программы, составляющие основную часть FreeBSD, работают с TCP Wrappers, однако некоторые программы сторонних разработчиков — нет.

Программное обеспечение TCP Wrappers реализовано в виде разделяемой библиотеки с именем libwrap. Как будет показано в главе 12, разделяемая библиотека — это библиотека программного кода, который может совместно использоваться несколькими программами. Любые программы, скомпилированные с поддержкой libwrap, могут использовать функции TCP Wrappers.

Наиболее часто Wrappers применяются для защиты inetd — программы, которая запускает меньшие демоны. Программа inetd(8) обсуждается в главе 15. Хотя в примерах этой главы TCP Wrappers будут применяться для защиты программ inetd(8), этим же способом можно защитить любую другую программу. Несмотря на наличие защиты для inetd(8), вам нужно убедиться, что inetd(8) не предлагает ненужных служб, как вы делаете то же самое для всей системы в целом.

Конфигурирование Wrappers

TCP Wrappers проверяют каждый входящий запрос на соединение, последовательно сверяясь с правилами в /etc/hosts.allow. Как только найдено первое совпавшее правило, процесс немедленно прекращается. Значит, порядок правил очень важен. Каждое правило занимает отдельную строку. Она состоит из трех частей, разделенных двоеточиями: имени демона, списка клиентов и списка параметров. Вот простой пример такой строки:

ftpd : all : deny

В этом примере имя демона — ftpd, а список клиентов — all, что означает все хосты. Наконец, параметр deny означает «отвергать все соединения». Никто не сможет подключиться к серверу FTP на этом хосте, если более раннее правило не предоставило такой доступ.

В предыдущих примерах мы ссылались только на два параметра: accept и deny. Соответственно, они разрешают или запрещают соединения. Есть много других параметров, которые будут рассмотрены позже.

Имя демона

Имя демона — это название программы, набираемое в командной строке. Например, inetd(8) запускает программу ftpd(8), когда получает входящий FTP-запрос. Веб-сервер Apache запускает программу, называемую httpd. Значит, если ваша версия Apache поддерживает wrappers, используйте имя демона httpd. (Обратите внимание: inetd(8) не используется для запуска сервера Apache, тем не менее он может обладать поддержкой TCP Wrappers.) Специальное имя демона ALL соответствует всем демонам, которые поддерживают wrappers.

Если за системой закреплено несколько IP-адресов, можно указать разные правила для каждого IP-адреса, за которые отвечает демон. В этом случае IP-адрес представляет собой часть имени демона:

ftpd@192.168.1.1 : ALL : deny
ftpd@192.168.1.2 : ALL : accept

В этом примере есть два имени демона: ftpd@192.168.1.1 и ftpd@192.168.1.2. Для каждого из них есть отдельное правило TCP Wrappers.

Список клиентов

Список клиентов — это список разделенных пробелами конкретных IP-адресов, блоков сетевых адресов, имен хостов, имен доменов и ключевых слов. Имена хостов и IP-адреса просты, и их надо лишь перечислить.

ALL: netmanager.absolutefreebsd.com 192.168.1.5 : allow

При наличии такого правила в самом начале файла /etc/hosts.allow TCP Wrappers позволит подключаться к любым службам системы моему компьютеру с именем netmanager и любому другому хосту с IP-адресом 192.168.1.5. (При этом я мог бы заблокировать доступ другими средствами.)

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

ALL: 216.136.204.0/255.255.255.0 : deny

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

ALL : .mycompany.com : allow

Если список клиентов достаточно длинный, то его можно хранить в файле и прописывать к нему путь в поле клиента в /etc/hosts.allow. Исходя из моего опыта, в сети ISP возможно большое количество хостов с произвольно разбросанными адресами, а в корпоративной сетевой среде рабочие станции, управляющие сетью, могут быть разбросаны по всему миру. Каждая рабочая станция, как и любая другая рабочая станция, использовала одно и то же правило TCP Wrappers и занимала полдюжины строк в /etc/hosts.allow. Поддерживая список всех рабочих станций в одном файле, я смог централизовать все изменения.

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

Таблица 9.1. Ключевые слова TCP Wrappers

Ключевое слово Назначение
ALL Под это ключевое слово подпадает любой возможный хост.
LOCAL Под это ключевое слово подпадает любой хост, чье имя не содержит точку. Обычно это машины в локальном домене. Даже компьютеры, находящиеся на противоположном конце земного шара, но использующие то же имя домена, согласно этому правилу считаются «локальными».
UNKNOWN Под это слово подпадают машины с неопределимыми именами хостов или пользователей. Как правило, если машина устанавливает соединение IP, ее IP-адрес известен. Однако для определения имен хостов необходим DNS, а для отслеживания имен пользователей — identd(8). Этот параметр следует использовать очень внимательно, так как временные неполадки в DNS могут сделать неразрешимыми даже имена локальных хостов, а в большинстве хостов identd(8) не работает по умолчанию. Никто не хочет, чтобы машина стала недоступной только потому, что сервер имен неверно настроен, особенно если эта машина и есть сервер имен!
KNOWN Под это ключевое слово подпадает любой хост с определимым именем и IP-адресом.
PARANOID Под это ключевое слово подпадает любой хост, имя которого не соответствует его IP-адресу. Представим запрос на соединение с хоста с адресом 192.168.84.3, который выдает себя за mail.absolutefreebsd.com. Получив запрос, TCP Wrappers проверит, какой IP-адрес у mail.absolutefreebsd.com. Если TCP Wrappers получит IP-адрес, отличающийся от исходного IP-адреса, то хост подпадает под это правило. Системные администраторы, не имеющие времени на сопровождение своего сервера DNS, скорее всего не имеют времени на обновление своей системы и наложение «заплат».

Большинству ключевых слов, перечисленных в табл. 9.1, необходим работающий сервер DNS. Применяя эти ключевые слова, вы должны обеспечить высокую надежность службы DNS и должны помнить о существенной связи между DNS и другими программами. Если DNS не работает, то демоны, использующие wrappers и ключевые слова, не смогут распознать ни один хост. Это значит, что все хосты подпадут под правила UNKNOWN, которое обычно создается таким, что отвергает все запросы на соединение. Кроме того, недействующий DNS на стороне удаленных пользователей может сорвать их доступ к вашим серверам, поскольку ваши серверы DNS не смогут получить необходимую информацию с клиентских серверов DNS. Наконец, при активном использовании правил, построенных на базе DNS, злоумышленнику достаточно вызвать перегрузку сервера DNS, чтобы провести распространенную атаку под названием «отказ в обслуживании» (Denial of Service).

Другие ключевые слова доступны, но не так полезны или безопасны. Например, разрешать соединения можно на основе имени пользователя на удаленной машине, от которой исходит запрос. Однако не следует полагаться на имя пользователя или сетевое имя удаленной системы. Если настройки TCP Wrappers на моей домашней системе разрешают подключение лишь пользователю с именем «mwlucas», то при желании кто-нибудь легко добавит учетную запись с этим именем на своей машине FreeBSD. Кроме того, доступ по имени пользователя опирается на ранее упомянутый протокол identd, поддерживаемый небольшим количеством хостов. На странице руководства hosts_access(5) можно найти другие малоизвестные и такие же бесполезные параметры.

Ключевые слова ALL и ALL EXCEPT

Ключевые слова ALL и ALL EXCEPT можно использовать как для имени демона, так и для списка клиентов. Под ключевое слово ALL подпадает абсолютно все. Например, по умолчанию файл /etc/hosts.allow начинается с правила, разрешающего все подключения, с любых адресов и к любому демону:

ALL : ALL: accept

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

ALL : 192.168.1.87 : deny

В этом примере отвергаются все подключения с хоста 192.168.1.87.

Категорически заблокировать доступ от всех хостов — не самая лучшая идея. Однако следует помнить, что программа TCP Wrappers читает правила последовательно и останавливается на первом подходящем правиле. Ключевое слово ALL позволяет легко установить запрет или разрешение по умолчанию. Рассмотрим следующий набор правил:

ALL : 192.168.8.3 192.168.8.4 : accept
ftpd : ALL : accept
ALL : ALL : deny

В этом примере рабочим станциям 192.168.8.3 и 192.168.8.4 (возможно, это рабочие станции системных администраторов) разрешен доступ ко всем демонам. Далее, любой желающий может подключиться к сервису FTP на этой машине. Наконец, все остальные соединения запрещены. Это удобно при выборе стратегии запрета по умолчанию.

Ключевое слово ALL EXCEPT применяется для еще большего сокращения предыдущего набора правил. ALL EXCEPT позволяет перечислять хосты как исключения; под правило подпадает то, что не перечислено в списке. Рассмотрим тот же набор правил, переписанный с применением ALL EXCEPT:

ALL : 192.168.8.3 192.168.8.4 : accept
ALL EXCEPT ftpd : ALL : deny

Разумеется, это правило основано на стратегии запрета по умолчанию, которая допускает возможность соединения с сервером FTP.

Одни администраторы считают более понятными правила с ALL, другие — с ALL EXCEPT. Важно помнить, что первое подходящее правило останавливает сличение, поэтому применение правила ALL требует осторожности.

Если вы лишь приступаете к изучению TCP Wrappers, лучше всего будет разрешить любые соединения с локального хоста — вы наверняка обнаружите массу программ, которые не в состоянии работать в отсутствие возможности подключаться к локальному компьютеру. Добавьте в начало файла hosts.allow следующее правило:

ALL : localhost : allow

Параметры

Мы уже видели в действии два параметра: allow и deny. Параметр allow предписывает разрешить соединение, deny — блокировать. По умолчанию файл hosts.allow начинается с правила, которое соответствует всем демонам и всем клиентам и разрешает все возможные соединения. Если необходимо защитить сервисы, то это правило не должно быть первым в списке. В то же время оно хорошо подойдет в качестве последнего правила при использовании стратегии разрешения соединений по умолчанию. Точно так же правило ALL:ALL:deny прекрасно подойдет в качестве последнего правила при использовании стратегии запрета соединений по умолчанию. Помимо простых allow и deny, TCP Wrappers поддерживают и другие параметры, увеличивая гибкость наборов правил.

Длинные правила

При использовании большого числа параметров правила TCP Wrappers становятся чересчур длинными. Для повышения удобочитаемости в файле hosts.allow можно использовать символ обратного слэша (\) как знак переноса правила на следующую строку.

Протоколирование

Как только сделан выбор между принятием и отклонением запроса на подключение, информацию о запросе можно зарегистрировать в протоколе. Предположим, вы хотите разрешить все запросы, исходящие от конкурента, но занести их в протокол. Точно так же может потребоваться знать о том, сколько запросов на соединение было отклонено от машин из-за неполадок в DNS, особенно если указано ключевое слово PARANOID. Протоколирование — это удобно. Чем больше объем протокола, тем лучше. Дисковое пространство стоит много дешевле, чем ваше время.

Параметр severity (строгость) посылает сообщение программе системного протоколирования (system log), syslogd(8). Программу syslogd можно настроить на переадресацию сообщений в произвольный файл, в зависимости от источника (facility) syslogd и выбранного уровня важности сообщения (глава 20):

telnetd: ALL: severity auth.info : allow

Это правило подразумевает протоколирование всех соединений telnet.

Возврат сообщений

Параметр twist позволяет выполнять произвольные команды интерпретатора (shell) и сценарии, когда кто-либо пытается установить соединение с защищаемым демоном TCP, и возвращает вывод команд удаленному пользователю. twist работает только с соединениями TCP. (Не забывайте, что UDP — это протокол без установления соединения; не существует соединения, по которому можно вернуть ответ. Значит, необходимо предпринять изощренные и трудоемкие усилия, чтобы twist мог работать с UDP. Кроме того, те программы, которые используют UDP, обычно не ожидают подобного ответа и не готовы его принять и интерпретировать. Применение twist для UDP не стоит возникающих трудностей.) twist принимает команду интерпретатора как аргумент и действует по правилу «отклонить и что-нибудь сделать». Для использования twist необходимо знать основы создания сценариев командного интерпретатора; возможны очень сложные варианты применения twist, но здесь будут представлены более простые.

Если используется запрет по умолчанию, то twist полезен для последнего правила. Параметр twist можно использовать для возврата ответа лицу, пытающемуся установить соединение. Например, так:

ALL : ALL : twist /bin/echo "Вы не можете использовать этот сервис."

Чтобы не предоставлять конкретный сервис тому или иному хосту, можно явно указать имя демона и список клиентов:

sendmail : .spammer.com : twist /bin/echo \
"Как спамер, вы не можете использовать этот сервис."

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

Если вы настроены дружелюбно, можете оповещать людей о причине отклонения их запросов на соединения. Следующее правило с twist отклоняет все запросы на установление соединения, исходящие от хостов, чьи имена не соответствуют их IP-адресам, и объясняет причину отказа:

ALL : PARANOID : twist /bin/echo \
"Ваш DNS неработоспособен. Возвращайтесь, когда устраните неполадки."

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

Комментарии запрещены.