Суперсервер и IPv6
Денис Колисниченко
1. Настройка сервера inetd
2. Настройка tcpd
3. Протокол IPv6
4. Установка xinetd
5. Настройка xinetd
6. Параметры запуска xinetd
7. Пример файла конфигурации /etc/xinetd
В статье пойдет речь об общей настройке суперсервера Internet inetd/xinetd, а также о его настройке для работы с протоколом IPv6.
Для начала определимся почему inetd/xinetd называется все же суперсервером? Потому что он отвечает за установление TCP соединения, то есть он прослушивает пакеты и запускает необходимые программы для обработки информации. Например, если в запросе клиента будет требование установить соединение с двадцать первым портом, то суперсервер вызовет сервер ftp, конечно, при условии, что соединение с 21-м портом разрешено - противном случае клиент получит сообщение Connection refused. По правде говоря, все не так просто как я описал - на практике все намного сложнее: за установление TCP соединений отвечает демон tcpd (в более ранних версиях Linux его не было), программы-сервисы (httpd, ftpd) могут постоянно находится в памяти (режим standalone), в этом случае они сами обрабатывают пакеты, и, соответственно, суперсервер их уже не вызывает...
Для начала разберемся с настройкой inetd. Этот сервер использовался в дистрибутиве RedHat до 7-ой версии, в более новых версиях он заменен на xinetd.
Для конфигурирования inetd нам нужно будет отредактировать два файла - /etc/ined.conf и /etc/services. Первый, собственно, и есть файлом конфигурации суперсервера, а во втором перечислены все сетевые службы, которые доступны в вашей системе.
Формат файла services: имя_службы порт/протокол псевдоним_службы.
Пример 1.1. Фрагмент файла /etc/services
pop-2 109/tcp postoffice # POP version 2 pop-2 109/udp pop-3 110/tcp # POP version 3 pop-3 110/udppostoffice в данном случае является псевдонимом. Для некоторых служб могут потребоваться использование нескольких протоколов (как в примере 1.1 для POP3 используется два протокола - TCP и UDP) и/или нескольких портов:
Пример 1.2. Несколько портов для сервиса ftp (RedHat 6.0)
ftp-data 20/tcp ftp 21/tcp
В других версиях ftp может потребоваться только одна запись - ftp 21/tcp.
Из соображений безопасности лучше закомментировать символом # сервисы, которые вы не планируете использовать, например если у вас роутер, то зачем вам sendmail (port 25)?
Теперь переходим к файлу /etc/inetd. Он имеет следующий формат:
service sock_type proto flags user path_to_server args
Пример 1.3 Фрагмент файла /etc/inetd.conf
ftp stream tcp nowait root /usr/sbin/tcpd in.ftpd
stream означает stream-сокет, nowait - суперсервер продолжает слушать порт после выполнения одного сервера для определенного порта. wait устанавливается только на stream сокетах.
/usr/sbin/tcpd - сервер, который будет вызван для обработки соединения, а in.ftpd - аргумент, то есть какую программу должен выполнить tcpd после проверки некоторой информации (о ней немного позже). Вы можете написать и так
Пример 1.4. Прямой вызов службы ftp (ProFTP)
ftp stream tcp nowait root /usr/sbin/in.proftpd in.proftpd
В данном случае сразу будет вызван демон ProFTP. in.proftpd является ссылкой на proftpd. Если будете использовать такой вызов ProFTP, позаботтесь о том чтобы proftpd имел тип inetd, а не standalone.
А теперь разберемся, что же представляет из себя демон tcpd - он является еще одним барьером в системе безопасности.
tcpd аутентифицирует удаленных пользователей и проверяет корректность из запросов. С помощью этого демона можно ограничить запросы с удаленных компьютеров. Файл hosts.allow содержит список хостов, которым разрешено подключаться к вашей системе, а hosts.deny - запрещено. Записи имею формат служба:хост.домен. Если вы хотите разрешить или запретить доступ всем, используйте ALL. Запись ALL:ALL открывает или закрывает доступ к вашей машине всем компьютерам для всех видов сервисов.
Пример 2.1. Файл /etc/hosts.allow
http:ALL ftp:ALL ALL:server.dhsilabs.com
В примере 2.1 доступ к http и ftp разрешен всем, к доступ ко ВСЕМ сервисам разрешен только компьютеру server.dhsilabs.com.
Думаю, что основной момент настройки понятен, и теперь переходим к протоколу IPv6.
Схема 32-разрядной адресации протокола IPv4 привела к дефициту IP-адресов. В новой версии протокола IP (IPv6, ранее именовавшегося IPng - IP next generation) адрес состоит из 16-ти октетов. Адрес изображается в виде восьми пар октетов, разделенных двоеточиями. В версии 6 используется 128-разрадные адреса получателей и отправителей (это в 4 раза больше, чем в 4-ой версии). Адрес в формате IPv6 может выглядеть так: 3A3F:BC21:F133:56C4:A103:DB11:1000:400F
Заголовок IPv6-пакета разработан таким образом, чтобы минимизировать содержащуюся в нем информацию. Поля параметров и поля, которые не являются необходимыми, вынесены за пределы заголовка.
Протокол IPv6 подробно описан в RFC 1883, а IPv4 - 791.
Суперсервер xinetd является достойной заменой inetd. К тому же он, в отличии от inetd, поддерживает IPv6. Даже если вы пока не планируете переходить на IPv6, установка xinetd будет очень полезной из-за расширенных функций суперсервера. xinetd появился в RedHat начиная с 7-ой версии и обычно устанавливается во время установки системы. Если у вас он еще не установлен, сейчас самое время это сделать.
Можно пойти по пути наименьшего сопротивления и установить xinetd из RPM-пакета, а можно и выкачать из Internet последнюю версию xinetd и установить его из исходников.
Вводим ./configure (до этого нужно перейти в каталог, куда вы распаковали исходники и желательно иметь права root)
Таблица 4.1. Параметры configure
Параметр | Описание |
--with-libwrap | Демон будет использовать tcp wrappers. При этом у вас уже должны быть установлены libwrap. С этой опцией xinetd будет сперва проверять ваши /etc/hosts.allow и /etc/hosts.deny файлы, и только после этого запускает свой механизм контроля доступа. |
--with-loadavg | Компилирует xinetd с опцией max_load. Этот параметр остановит сервис, когда нагрузка достигнет определенного уровня. |
--with-inet6 | Включает поддержку IPv6 |
Внимание!При включении IPv6 все IPv4-сокеты становятся IPv6-сокетами и соответственно ядро (это прежде всего) и все программы должны поддерживать IPv6. Поэтому вам нужно перекомпилировать ваше ядро с поддержкой IPv6. Если ваше ядро не поддерживает IPv6, выкачайте последнюю версию из Internet. После включения IPv6 запросы IPv4 также будут обрабатываться.
Теперь введите make, а зетем - make install.
Файл конфигурации xinetd - /etc/xinetd.conf отличается по синтаксису от файла конфигурации inetd. Если inetd у вас уж енастроен и вам лень настравивать все заново воспользуйтесь программой itox:
itox < /etc/inetd.conf > /etc/xinetd.conf
При условии, что файл конфигурации inetd - /etc/inetd.conf, а xinetd - /etc/xinetd.conf. В любом случае, вам не помешает разобраться с форматом xinetd.conf
Синтаксис xinetd.conf:
service < service_name> { <атрибут> <оператор_присваивания> <значение> <значение> ... <атрибут> <оператор_присваивания> <значение> <значение> ... ... <атрибут> <оператор_присваивания> <значение> <значение> ... }
Оператор может быть одним из следующих: '=', '+=', '-='. Большинство атрибутов может работать только с оператором '='. Назначение операторов следующее:
'=' - присвоить значение атрибуту '+=' - добавить еще одно значение '-=' - удалить значение
Атрибут может иметь несколько значений, указанных через пробел.
Некоторые параметры очень похожи не параметры inetd.
service_name - это имя сервиса (login, shell, telnet, ftp, pop3 и т.д.)
attribute:
id - используется, если сервисы используют разные протоколы. Обычно совпадает с именем сервиса.
type - может быть использована любая комбинация из следующих значений:
Если RPC-сервисы у вас работаю неккоректно после установки xinetd, вы можете использовать для них старый inetd - inetd и его новая версия xinetd прекрасно уживаются вместе. В файле /etc/inetd.conf оставьте только RPC-сервисы, а остальное закомментируйте, а в /etc/xinetd.conf - наоборот.
flags - в качестве значения может быть использована любая комбинация из следующих значений:
disabled - может принимать 2 значения, "yes" и "no". Если указать yes, сервис запускаться не будет
socket_type - может принимать следующие значения:
protocol - протокол, по которому будет работать сервер (tcp, udp, ...)
wait - имеет 2 значения: 'yes' и 'no'. Значение 'yes' устанавливается только на stream сокетах. При
значении no суперсервер продолжает слушать порт после выполнения сервера.
user - определяет GID серверного процесса. Имена групп можно найти в файле /etc/group
server - путь к серверу
server_args - аргументы, которые будут переданы серверу.
only_from - удаленные хосты, которым будет доступен сервис. В качестве значения принимает список хостов, IP адресов или сетей. Это своеобразный "аналог" hosts.allow
no_access - этим хостам данный сервис не будет доступен. А это - "аналог" hosts.deny. Если не один из атрибутов (only_from и no_access) не указан, то сервис будет доступен всем.
access_times - интервалы времени в форме hour:min-hour:min, в которых сервис будет доступен. Например: 9:00-18:00
log_type - определяет куда сервис будет посылать логи. Значения:
log_on_failure - определяет куда сервис будет посылать логи если сервис по каким либо причинам не запустился:
log_on_success - определяет какая информация будет писаться в лог. Можно комбинировать любые из следующих значений:
rpc_number - определяет номер rpc сервиса
rpc_version - определяет версию rpc сервиса.
env - значение атрибуте - это список строк типа: 'name=value'. Эти будт добавлены в окружение перед тем как сервер будет запущен.
passenv - значение атрибута - это список переменных окружения из окружения xinetd, которые могут быть переданы серверу.
port - определяет порт сервиса. Если он указан в файле /etc/services, то он должен совпадать с ним
redirect - позволяет tcp сервису делать редирект на другой хост. Значение - host:port
interface - устанавливает интерфейс на котором будет работать сервис. Синтаксис: interface=(ip address of interface)
bind - синоним для interface
banner - имя файла, который будет показываться при соединении с сервисом
banner_success - имя файла, который будет показываться при удачном соединении
banner_fail - имя файла, который будет показываться при неудачном соединении
cps - атрибут имеет 2 аргумента. Первый устанавливает количество коннектов в секунду. Если это число будет превышено, сервис будет временно недоступен. Второй - число секунд, после которых сервис снова будет доступен
max_load - загрузка. При достижении максимума, сервер перестает принимать запросы на соединение. Значение - число типа float
instances - определяет число серверов, которые может быть активны одновременно для сервиса. (по умолчанию лимита нет). Значением этого атрибута может быть число, либо - UNLIMITED
nice - устанавливает приоритет сервиса.
Вам не обязательно указывать все эти атрибуты для каждого сервиса. Можно указать только необходимые:
protocol (только для RPC сервисов и для всех, которые не описаны в /etc/services)
rpc_version (только для RPC сервисов)
rpc_number (только для RPC сервисов, которых нет в /etc/rpc)
port (тлько для не-RPC сервисов, которые не описаны в /etc/services)
Следующие атрибуты поддерживают все операторы присваивания:
Эти арибуты также могут принимать разные значения в разных service секциях.
Файл конфигурации может содержать секцию default, в которой описаны атрибуты по умолчанию.
Они будут одинаковы для всех сервисов. Возможные атрибуты по умолчанию:
Я надеюсь, что с настройкой все понятно. Если же мои надежды не оправдались, в конце статьи вы найдете пример файла /etc/xinetd.conf. Сейчас же займемся запуском только что откомпилированного и настроенного суперсервера. А запускать-то его можно с такими опциями:
Таблица 6.1. Параметры запуска xinetd
Параметр | Описание |
-f filename | Устанавливает альтернативный файл конфигурации. Файл по умолчанию - /etc/xinetd.conf |
-pidfile pid_file | Файл с ID процесса |
-stayalive | Даже если ни один сервис не прописан, демон должен выполняться ("остаться в живых") |
-loop rate | Задает количество коннектов в секунду |
-d | режим отладки (debug mode) |
-reuse | Перед тем как связать сокет сервиса с IP-адресом, суперсервер установит опцию сокета SO_REUSEADDR |
-limit limit | Ограничение на количество одновременно запущенных процессов |
В таблице я указал не все параметры запуска, выбрав лишь самые нужные. Более подробную информацию вы сможете получить в документации по xinetd.
Также как и inetd, xinetd можно контролировать с помощью сигналов.
Таблица 6.2. Сигналы суперсервера
Сигнал | Описание |
SIGUSR1 | Суперсервер перечитает файл конфигурации |
SIGQUIT | Остановит xinetd | SIGTERM | Перед остановкой xinetd все процессы будут остановлены |
Теперь, как и обещал, привожу пример файла конфигурации:
Пример 7.1. Фрагмент файла конфигурации /etc/xinetd:
defaults { instances = 25 log_type = FILE /var/log/servicelog log_on_success = HOST PID log_on_failure = HOST RECORD only_from = 111.11.111.0 111.111.112.0 only_from = localhost 192.168.1.0/32 disabled = tftp } service login { flags = REUSE socket_type = stream protocol = tcp wait = no user = root server = /usr/etc/in.rlogind log_type = SYSLOG local4 info } service telnet { flags = REUSE socket_type = stream wait = no user = root server = /usr/etc/in.telnetd bind = 127.0.0.1 log_on_failure += USERID } service telnet { flags = REUSE disabled = yes socket_type = stream wait = no user = root # server = /usr/etc/in.telnetd bind = 192.231.139.175 redirect = 128.138.202.20 23 log_on_failure += USERID } service ftp { socket_type = stream wait = no user = root server = /usr/etc/in.ftpd server_args = -l instances = 4 log_on_success += DURATION USERID log_on_failure += USERID access_times = 2:00-8:59 12:00-23:59 nice = 10 } service name { socket_type = dgram wait = yes user = root server = /usr/etc/in.tnamed } service tftp { socket_type = dgram wait = yes user = root server = /usr/etc/in.tftpd server_args = -s /tftpboot } service smtp { socket_type = stream protocol = tcp wait = no user = qmaild id = smtp server = /var/qmail/bin/tcp-env server_args = /var/qmail/bin/qmail-smtpd log_on_success -= DURATION USERID PID HOST EXIT log_on_failure -= USERID HOST ATTEMPT RECORD } service finger { socket_type = stream disabled = yes wait = no user = nobody server = /usr/etc/in.fingerd } service echo { type = INTERNAL id = echo-stream socket_type = stream protocol = tcp user = root wait = no } service echo { type = INTERNAL id = echo-dgram socket_type = dgram protocol = udp user = root wait = yes } service rstatd { type = RPC disabled = no flags = INTERCEPT rpc_version = 2-4 socket_type = dgram protocol = udp server = /usr/etc/rpc.rstatd wait = yes user = root }
Как видно из примера, я описал лишь те сервисы, которые больше всего необходимы, доступ к сервисам могут получать только из сетей 111.111.111.0, 111.111.112.0 и 192.168.1.0. Можно также указывать адрес и маску подсети, например 192.168.1.0/32. Вместо sendmail я использую qmail. Можно было бы запускать qmail в режиме standalone, но так как я не очень часто пользуюсь услугами 25-го порта, мне удобнее запускать сервис smtp через xinetd. Из соображений безопасности я отключил некоторые сервисы: finger, telnet.