03.08.2003

Содержимое /proc, связанное с настройкой Firewall в Linux

В подавляющем большинстве случаев настройка firewall в Linux сводится к манипуляциям сетевыми фильтрами ядра, то есть правилами, создаваемыми при помощи таких инструментов, как iptables (ядра 2.4), ipchains (ядра 2.2) или даже ipfwadm (ядра 2.0). Тем не менее, ядро содержит параметры независящие от установленных правил фильтрации, влияющие на обработку ядром сетевых пакетов. В этой статье будут рассмотрены эти параметры и влияние, которое они оказывают на сетевую безопасность Linux хоста или firewall на базе Linux.

В подавляющем большинстве случаев настройка firewall в Linux сводится к манипуляциям сетевыми фильтрами ядра, то есть правилами, создаваемыми при помощи таких инструментов, как iptables (ядра 2.4), ipchains (ядра 2.2) или даже ipfwadm (ядра 2.0).

Тем не менее, ядро содержит параметры независящие от установленных правил фильтрации, влияющие на обработку ядром сетевых пакетов. В этой статье будут рассмотрены эти параметры и влияние, которое они оказывают на сетевую безопасность Linux хоста или firewall на базе Linux.

Что такое директория /proc в Linux?

Существует множество настроек ядра Linux, которые могут изменяться от машины к машине. Традиционно есть набор настроек, устанавливаемых при компиляции, а также изменяемых при помощи системных вызовов. Например, каждая машина имеет имя хоста, устанавливаемое при загрузке при помощи системного вызова sethostname(2), так же как iptables читает и устанавливает правила сетевых фильтров используя getsockopt(2) и setsockopt(2) соответственно.

Современные ядра Linux имеют множество настроек, которые могут быть изменены. Предоставление возможности изменения всего множества настроек становится неуклюжим и вынуждает администраторов писать код C для их изменения в реальном времени. Для этого и была создана файловая система /proc [1].  /proc является виртуальной файловой системой. Она не размещается на каком-либо физическом или удаленном диске и дает возможность просмотра конфигурации системы во время её работы.

Файловая система /proc может просматриваться как любая другая файловая система. Содержимое представлено в виде обычных файлов, директорий и символьных ссылок, но при их помощи можно просматривать информацию самого ядра.  Некоторые из них могут быть изменены root, но большинство существуют только для чтения. Для просмотра этих файлов можно использовать cat и more:

# <b>cd /proc</b>
# <b>ls -l version</b>
-r--r--r--  1 root root   0 Jun 20 18:30 /proc/version
# <b>cat version</b>
Linux version 2.4.21 (guru@example.com) (gcc version 2.95.4 20011002) ...

Заметьте, что по команде ls ядро показывает не совсем правильную информацию. Файлы, если их просматривать, имеют содержимое, но всегда имеют длину в 0 байт. Вместо того, чтобы тратить время на выяснение того, сколько будет занимать вывод при просмотре файла, ядро просто полагает размер файла равным 0, а время файла считает текущим.

/proc/sys

Всё содержимое /proc, которое может быть изменено при работе системы, находится в директории /proc/sys. Существует два способа модификации: при помощи стандартных команд unix, и с помощью sysctl. Ниже приведен пример, показывающий как можно установить имя хоста двумя способами:

Изменение псевдофайлов /proc вручную

# <b>ls -l /proc/sys/kernel/hostname</b>
 -r--r--r--  1 root root   0 Jun 20 18:30 /proc/sys/kernel/hostname
 
 # <b>hostname</b>
 catinthehat
 
 # <b>cat /proc/sys/kernel/hostname</b>
 catinthehat
 
 # <b>echo 'redfishbluefish' > /proc/sys/kernel/hostname</b>
 
 # <b>hostname</b>
 redfishbluefish

Изменение псевдофайлов /proc используя sysctl

# <b>hostname</b>
 redfishbluefish
 
 # <b>sysctl kernel.hostname</b>
 kernel.hostname = redfishbluefish
 
 # <b>sysctl -w kernel.hostname=hop-on-pop</b>
 kernel.hostname = hop-on-pop
 
 # <b>hostname</b>
 hop-on-pop

Заметьте, основное отличие между этими двумя методами состоит в том, что sysctl использует точку [2] вместо слэша как разделитель. В качестве начального пути подразумевается proc.sys. sysctl может принимать имя файла как аргумент, и в этом случае происходит изменение параметров в этом файле:

# <b>hostname</b>
 hop-on-pop
 
 # <b>cat reset_hostname</b>
 kernel.hostname=butterbattlebook
 
 # <b>sysctl -p reset_hostname</b>
 ; Set our hostname
 kernel.hostname=butterbattlebook
 ;
 ; Turn on syncookies
 net.ipv4.tcp_syncookies = 1
 
 # <b>hostname</b>
 butterbattlebook

При запуске с ключом –p и без указания имени файла, будет использован /etc/sysctl.conf.

Изменения, производимые с переменными /proc влияют только на запущенное в данный момент ядро. Значения переменных вернутся в значения по умолчанию, установленные во время компиляции, при следующей загрузке ядра. Если вы хотите, чтобы изменения сохранились, то вы можете или написать скрипт, выполняемый при загрузке, или создать файл /etc/sysctl.conf. Большинство дистрибутивов Linux запускают sysctl –p во время нормального процесса загрузки.

Содержимое /proc, связанное с firewall

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

Если вы заинтересованы в изучении других переменных ядра, почитайте man proc(5).  Существует несколько файлов в исходниках ядра, в директории Documentation, содержащих более полную информацию. Для начала можно почитать /usr/src/linux/Documentation/filesystems/proc.txt и /usr/src/linux/Documentation/networking/ip-sysctl.txt.

Некоторые параметры ядра являются целыми числами, например, kernel.random.entropy_avail содержит байты энтропии, доступные для генератора случайных чисел. Другие являются произвольными строками, например, fs.inode-state содержит число выделенных и свободных inode, разделенные пробелами. Большинство же параметров, связанных с firewall, содержат простые бинарные значения, где «1» означает «включен», а «0» - «выключен».

Машина с Linux может иметь более одного интерфейса, и вы можете устанавливать некоторые параметры независимо для каждого интерфейса. Эти параметры находятся в директории /proc/sys/net/ipv4/conf, которая содержит все доступные интерфейсы, такие как lo, eth0, eth1 или wav0, а также директории: all и default.

Если вы изменяете параметры в директории /proc/sys/net/ipv4/conf/all, то измененные параметры будут установлены для всех интерфейсов, а также в default. При изменении параметров в /proc/sys/net/ipv4/conf/default, все вновь создаваемые интерфейсы будут иметь указанные значения. Это имеет смысл только для машин, у которых интерфейсы могут добавляться во время работы, таких как ноутбуки с картами PCMCIA или машины, которые создают новые интерфейсы при помощи VPN или PPP.

Фалы Proc

Ниже приведены файлы proc, которые вы можете изменять для обеспечения сетевой безопасности. При описании перед каждым файлом я буду указывать enable(1) или disable(0) для того, чтобы показать рекомендуемые настройки там, где это имеет смысл. Вы можете использовать следующие функции шелл  для установки значений из скрипта при загрузке системы:

enable () { for file in $@; do echo 1 > $file; done }
disable () { for file in $@; do echo 0 > $file; done }

enable /proc/sys/net/ipv4/icmp_echo_ignore_all

Когда включено, игнорируются все ICMP ECHO REQUEST пакеты (ping). На самом деле не повышает уровень безопасности, но помогает спрятать хост от поиска пингованием, что в свою очередь может предотвратить сканирование портов. Например, nmap не будет сканировать хост, не отвечающий на ping, если не задан параметр –P0. Тем не менее, установка этого параметра мешает тестировать нормальную работу сети.

enable /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

Когда включен, хост игнорирует широковещательные ping. Лучше игнорировать широковещательные ping, потому что иначе вы сможете стать невольным участником распределенной DoS атаки, такой как Smurf.

disable /proc/sys/net/ipv4/conf/*/accept_source_route

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

enable /proc/sys/net/ipv4/conf/*/rp_filter

Если включен, то когда пакет приходит на один интерфейс, а ответ исходит из другого, пакет сбрасывается. Необязательно для хоста с одним интерфейсом, но помните, что соединения PPP и VPN обычно имеют свои собственные интерфейсы, поэтому лучше этот параметр все-таки включить. Включенный параметр может создать проблемы для маршрутизаторов в сети с динамически изменяемыми маршрутами. Тем не менее, на firewall/маршрутизаторах, являющихся единственной точкой соединения между сетями, это автоматически обеспечивает защиту от спуфинга без использования сетевых ACL.

disable /proc/sys/net/ipv4/conf/*/accept_redirects

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

disable /proc/sys/net/ipv4/conf/*/secure_redirects

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

disable /proc/sys/net/ipv4/conf/*/send_redirects

Если ваша машина является маршрутизатором, и существуют альтернативные пути, о которых вам надо сообщать клиентам (имеется несколько маршрутизаторов в сети), то этот параметр должен быть включен. Если ваша сеть стабильна, и хосты уже знают правильные маршруты, то этот параметр не обязательно держать включенным. Для хостов, не являющихся марщрутизаторами, включение этого параметра не понадобится никогда.

disable /proc/sys/net/ipv4/ip_forward

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

(integer) /proc/sys/net/ipv4/ipfrag_high_thresh

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

(integer) /proc/sys/net/ipv4/ipfrag_low_thresh

Аналогично ip_frag_high_thresh, но задает минимальное количество памяти, выделяемое под сборку фрагментированных пакетов.

(integer) /proc/sys/net/ipv4/ipfrag_time

Число секунд, которое ядро должно хранить IP фрагменты перед тем, как сбросить их. Обычно 30 секунд является хорошим выбором. Уменьшите это значение, если атакующие формируют множество фрагментов, и вы сможете лучше обслуживать полезные соединения.

enable /proc/sys/net/ip_always_defrag

Всегда дефрагментировать фрагментированные пакеты перед тем, как передавать их firewall. Linux 2.4 и более поздние ядра не имеют этой записи в /proc – дефрагментация включена по умолчанию.

(integer) /proc/sys/net/ipv4/tcp_max_orphans

Число поддерживаемых локальных сокетов, которые более не прикреплены к какому-либо из процессов. Эти сокеты обычно являются результатом оборванных сетевых соединений, например, состояние FIN-WAIT, когда удаленный хост не подтверждает разрыв TCP соединения. После того, как указанный предел достигнут, зависшие соединения  немедленно убираются из ядра. Если ваш firewall выступает в роли обычного фильтра пакетов, этот параметр не играет большой роли, но он, безусловно, будет полезен для хостов, содержащих, например, веб-сервер. Этот параметр устанавливается при загрузке системы учитывая количество памяти в системе.

Другие параметры, которые могут быть полезны включают в себя tcp_retries1 (определяет максимально количество попыток TCP на посылку), tcp_retries2 (максимальное количество попыток на посылку по существующему TCP соединению), tcp_orphan_retries (максимальное количество попыток на посылку для закрытого нами соединения), tcp_fin_timeout (как долго удерживать сокеты с частично закрытым состоянием, перед тем как сбросить их). Все эти параметры могут быть установлены с учетом нужд настраиваемой машины и не являются непосредственно связанными с безопасностью.

(integer) /proc/sys/net/ipv4/icmp_ratelimit
(integer) /proc/sys/net/ipv4/icmp_ratemask

Эти два параметра позволяют ограничить частоту генерации ICMP пакетов. icmp_ratelimit определяет сколько пакетов, удовлетворяющих icmp_ratemask, в единицу времени (на большинстве систем это 1/100 секунды) может быть послано. ratemask представляет собой логическое ИЛИ кодов ICMP, чьи частоты вы хотите ограничить. (Значения кодов можно посмотреть в /usr/include/linux/icmp.h). Маска по умолчанию включает в себя коды destination unreachable, source quench, time exceeded и parameter problem. Если вы увеличите ограничение, то сможете замедлить или даже обмануть сканеры портов, но это может препятствовать работе настоящих индикаторов ошибок сети.

enable /proc/sys/net/ipv4/conf/*/log_martians

Определяет должно ли ядро посылать в syslog сообщения о пакетах, полученных от недопустимых адресов.

(integer) /proc/sys/net/ipv4/neigh/*/locktime

Отклоняет изменения ARP адреса если запись существует меньше чем указанное количество времени (в 1/100 секунды). Если атакующий в вашей сети использует искажение ARP, для атаки типа man-in-the-middle, увеличение этого параметра может предотвратить засорение кэша ARP.

(integer) /proc/sys/net/ipv4/neigh/*/gc_stale_time

Определяет как часто (в секундах) требуется очищать старые записи ARP и производить новый ARP запрос. Более низкие значения позволят серверу быстрее среагировать на изменения IP (хорошо) или на атаку с искажением ARP (плохо).

disable /proc/sys/net/ipv4/conf/*/proxy_arp

Отвечать на ARP запрос, если известен путь к запрашиваемому хосту. Это может быть необходимо для некоторых firewall или VPN/маршрутизаторов, но на обычных хостах это лучше выключить.

enable /proc/sys/net/ipv4/tcp_syncookies

Очень популярная DoS атака заключается в посылке большого числа SYN пакетов на ваш сервер. При этом установка TCP связи не доводится до конца. Очередь полуоткрытых запросов соединений быстро заполняется, что мешает установке нормальных соединений. Так как соединение не должно быть обязательно завершено, такая атака не требует больших ресурсов от атакующей машины, поэтому её легко реализовать и контролировать.

Если параметр tcp_syncookies установлен (доступен только когда ядро собрано с CONFIG_SYNCOOKIES), тогда ядро обрабатывает SYN пакеты TCP в обычном режиме до тех пор, пока очередь не заполнится. После заполнения очереди включается механизм SYN cookies.

SYN cookies вообще не использует очередь SYN. Вместо этого ядро отвечает на каждый SYN пакет, как обычно SYN|ACK, но туда будет включено специально сгенерированное число на основе IP адресов и портов источника и получателя, а также времени посылки пакета. Атакующий никогда не получит эти пакеты, а поэтому и не ответит на них. При нормальном соединении, будет послан третий пакет, содержащий число, а сервер проверит был ли это ответ на SYN cookie и, если да, то разрешит соединение даже в том случае, если в очереди SYN нет соответствующей записи.

Включение механизма SYN cookies является очень простым способом борьбы против атаки SYN флудом. При этом немного больше загружается процессор из-за необходимости создавать и сверять cookie. Так как альтернативным решением является отклонять все запросы на соединение, SYN cookies являются хорошим выбором. Более подробная информация о внутренней работе SYN cookies, расположена на http://cr.yp.to/syncookies.html.

Заключение

При создании firewall в Linux, а также для обычного Linux хоста, администратору доступно большое количество параметров ядра для повышения безопасности сетевого стэка. В сочетании с дополнительными правилами, такими как сетевые фильтры (iptables) и ACL ядра, вы можете получить машину с высокой степенью защиты затратив при этом минимальные усилия.

Ссылки

[1] На самом деле параметры ядра можно изменять, используя вызов _sysctl(2), еще в старых версиях ядра Linux. К сожалению настоящие имена параметров ядра Linux изменяются от версии к версии, в то время как расположение их внутри файловой системы является более постоянным. Поэтому _sysctl(2) лучше не использовать.

[2] Sysctl может использовать слэши вместо точек, но использование точек является более традиционным.

или введите имя

CAPTCHA