Введение в систему безопасности Gentoo Linux

Kim Nielsen  Author
John P. Davis  Editor
Eric R. Stockbridge  Editor
Carl Anderson  Editor
Jorge Paulo  Editor
Sven Vermeulen  Editor
Benny Chuang  Editor
Sune Jeppesen  Editor
Tiemo Kieft  Editor
Zack Gilburd  Editor
Alexandr Logechnik  Translator

Updated 10 Ноябрь, 2003

1. Введение

Этот документ предназначен для людей использующих Gentoo Linux как сервер или если они чувствуют, что их настольная система нуждается в усилении безопасности.

Note: Если после прочтения этого документа вы заинтересованы в более обширном материале о безопасности Gentoo, посмотрите здесь - Проект безопасности Gentoo

2. Планирование до инсталляции

Безопасность физического доступа

Не имеет значение сколько мер безопасности вы ввели, их все легко можно обмануть, если атакующий имеет физический доступ к серверу. Вы должны быть уверенны, что к вашему серверу, никто случайный не может получить доступ. Например, установите сервер в закрытом помещении. Хорошей идеей будет закрытый шкаф. Для более высокого уровня защиты можете установить пароль на BIOS, и разрешить загрузку только с жесткого диска. Для пользователей лэптопов, пароль на БИОС отличная идея.

Планирование демонов/сервисов

Напишите на бумаге, какие сервисы должны быть на сервере, и какие предполагаются в будущем. Это поможет лучше составить схему разделов системы. Это также облегчит стратегию обнаружение атак. Конечно нет смысла документировать это если вы сами используете один или несколько компьютеров. Пример: если вы используете один компьютер для брандмауэра, на нем не должно быть никаких сервисов, исключая, возможно, sshd.

Задокументируйте это и используемую версию sshd - это поможет вам отслеживать, что в системе нуждается в обновлении если, например, кто-то найдет дыру в безопасности sshd. Также документ поможет в определении кто должен иметь доступ к системе.

Схема разделов

Золотые правила:

Суперпользователь

Пользователь 'root' - наиболее жизненоважный пользователь системы, и должен использоваться, только если это необходимо. Если атакующий получил root доступ, вы не можете быть уверенны в системе - переустановите ее.

Золотые правила для 'root'

Gentoo имеет общую защиту для обычных пользователей, например докучливый su. По умолчанию настройки PAM позволяют пользователям, которые входят в группу wheel, использовать su.

Политики безопасности

Здесь приведены несколько причин, почему политики безопасности необходимы.

Должно быть очевидно, почему очень важно создание политик для систем, с больше чем один пользователем и почему важно обучать пользователей принципам сетевой безопасности.

Политика - это документ (или несколько документов) с ответами на вопросы, типа кто, где, что и почему. Каждый пользователь в вашей системе/сети должен прочесть, понять и подписаться под ним. Очень важно, если вы возьмете на себя задачу обьяснить и помочь понять политику, и объяснить почему политика безопасности так важна, и что произойдет если они будут нарушать политику (в документе это также должно быть описано). Раз в год, они должны перечитывать документ, ведь он может измениться, и конечно для напоминания пользователю.

Note: Политика должна быть легкой для чтения и понимания, быть ясной в каждом из ее разделов.

Большинство пунктов политики может быть реализовано прямо в операционной системе или в брандмауэре.

Политика безопасности должна по крайней мере содержать следующие темы:

Политика для ИТ-структуры может быть несколько иной чем для обычных пользователей.

Политика безопасности может стать огромной и жизненноважная информация может быть легко забыта. Политика для ИТ-структуры может содержать информация которая секретна для обычных пользователей, и поэтому политика должна быть разбита на несколько политик, таких как "Политика использования ПО", "Политика паролей", "политика электронной почты" и "Политика доступа в интернет".

Вы можете найти пример политики на The SANS Security Policy Project. Если вы имеете маленькую сеть, и думаете что эта политика большая, вы можете заглянуть сюда Site Security Handbook.

3. Укрепление безопасности после/во время инсталляции

Флаг USE

Файл make.conf содержит определенные пользователем флаги USE, /etc/make.profile/make.defaults содержит флаг USE установленный по умолчанию для Gentoo Linux. Для использования этого документа важны следующие флаги: pam (Подключаемый Авторизационный Модуль), tcpd (TCP оболочка) и ssl (Secure Socket Layer). Они все присутствуют в установленном флаге по умолчанию.

Пароль на GRUB

Grub поддерживает 2 разных пути задания пароля в его конфигурационные файлы (/boot/grub/grub.conf). Один с паролем в виде обычного текста, и другой с md5+salt шифрованием.

Code Listing 3.1: /boot/grub/grub.conf

timeout 5
password changeme

Это добавит пароль changeme и если не будет введен пароль, будет просто использовать загрузку по умолчанию.

Когда добавляете пароль md5, вам необходимо конвертировать пароль в зашифрованный формат (man crypt), который используется в /etc/shadow. Больше информации вы можете прочесть в man crypt. Зашифрованный пароль changeme должен выглядеть где-то так $1$T7/dgdIJ$dJM.n2wZ8RG.oEiIOwJUs.

Или его можно конвертировать прямо в шеле grub'а:

Code Listing 3.2: md5crypt в шеле grub'a

#/sbin/grub

    GRUB  version 0.92  (640K lower / 3072K upper memory)

   [ Minimal BASH-like line editing is supported.  For the first word, TAB
     lists possible command completions.  Anywhere else TAB lists the possible
     completions of a device/filename. ]

grub> md5crypt

Password: ********
(Набираем changeme)
Encrypted: $1$T7/dgdIJ$dJM.n2wZ8RG.oEiIOwJUs.

grub> quit

Тогда скопируйте и вставьте ваш пароль в /boot/grub/grub.conf.

Code Listing 3.3: /boot/grub/grub.conf

timeout 5
password --md5 $1$T7/dgdIJ$dJM.n2wZ8RG.oEiIOwJUs.

Таймаут в 5 секунд нужен, если система удаленная и может быть перезагружена без использования клавиатуры. Прочтите больше о пароле в grub'e просто запустив info grub.

Пароль на LILO

LILO также поддерживает два пути обращения с паролем: глобальный и на образ, оба в виде обычного текста.

Глобальный пароль устанавливается в начале файла конфигурации:

Code Listing 3.4: /etc/lilo.conf

password=changeme
restricted
delay=3

Второй способ - задать пароль на раздел:

Code Listing 3.5: /etc/lilo.conf

image=/boot/bzImage
      read-only
      password=changeme
      restricted

Если опция restricted не установлена, он будет требовать каждый раз.

Чтобы новый пароль установленный lilo.conf вам нужно запустить /sbin/lilo.

Ограничение использования консоли

Файл /etc/securetty допускает указание, какие устройства tty (терминалы) могут аутентифицировать root'a.

Мы советуем закомментировать все строки, кроме vc/1. Это позволит root'у аутентифицироваться только раз на одном терминале.

Note: Пользователи входящие в группу wheel могут использовать su - чтобы root на других терминалах.

Code Listing 3.6: /etc/securetty

vc/1

4. Более детальное логирование

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

Также очень важно, чтобы log файлы были легко читаемы и удобны в управлении. При инсталляции Gentoo Linux вы можете выбрать 3 различных метода ведения логов.

Логирование: Syslogd

Syslogd самый распространенная программа ведения логов для Linux и в общем для Unix. Но она не имеет возможности ротации логов. Эта возможность предоставляется запуском /usr/sbin/logrotate с помощью cron и настраивается в /etc/logrotate.conf. Как часто логи должны подвергается ротации, сжатию и удалению, зависит от загрузки системы.

Ниже - стандартный файл syslog.conf с некоторыми добавленными опциями. Мы раскоментировали линии cron и tty и добавили удаленный сервер логирования, для усиления безопасности вы можете записывать логи в два места.

Code Listing 4.1: /etc/syslog.conf

#  /etc/syslog.conf     Configuration file for syslogd.
#
#                       For more information see syslog.conf(5)
#                       manpage.
#                       This is from Debian, we are using it for now
#                       Daniel Robbins, 5/15/99

#
# First some standard logfiles.  Log by facility.
#

auth,authpriv.*                 /var/log/auth.log
*.*;auth,authpriv.none          -/var/log/syslog
cron.*                         /var/log/cron.log
daemon.*                        -/var/log/daemon.log
kern.*                          -/var/log/kern.log
lpr.*                           -/var/log/lpr.log
mail.*                          /var/log/mail.log
user.*                          -/var/log/user.log
uucp.*                          -/var/log/uucp.log
local6.debug                    /var/log/imapd.log

#
# Logging for the mail system. Split it up so that
# it is easy to write scripts to parse these files.
#
mail.info                       -/var/log/mail.info
mail.warn                       -/var/log/mail.warn
mail.err                        /var/log/mail.err

# Logging for INN news system
#
news.crit                       /var/log/news/news.crit
news.err                        /var/log/news/news.err
news.notice                     -/var/log/news/news.notice

#
# Some `catch-all' logfiles.
#
*.=debug;\
        auth,authpriv.none;\
        news.none;mail.none     -/var/log/debug
*.=info;*.=notice;*.=warn;\
        auth,authpriv.none;\
        cron,daemon.none;\
        mail,news.none          -/var/log/messages

#
# Emergencies and alerts are sent to everybody logged in.
#
*.emerg                         *
*.=alert                        *

#
# I like to have messages displayed on the console, but only on a virtual
# console I usually leave idle.
#
daemon,mail.*;\
       news.=crit;news.=err;news.=notice;\
       *.=debug;*.=info;\
       *.=notice;*.=warn       /dev/tty8

#Setup a remote logging server
*.*                        @logserver

# The named pipe /dev/xconsole is for the `xconsole' utility.  To use it,
# you must invoke `xconsole' with the `-file' option:
# 
#    $ xconsole -file /dev/xconsole [...]
#
# NOTE: adjust the list below, or you'll go crazy if you have a reasonably
#      busy site..
#
#daemon.*,mail.*;\
#       news.crit;news.err;news.notice;\
#       *.=debug;*.=info;\
#       *.=notice;*.=warn       |/dev/xconsole

local2.*                -/var/log/ppp.log

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

Metalog

Metalog написанный Frank Dennis не позволяет вести логи на удаленной машине, но он имеет преимущество когда требуется производительность и гибкость в ведении логов. Он может вести логи по названию программы, нагрузке, средствам (как syslogd) и позволяет задавать статические выражения для запуска внешней программы в случае совпадения. Это очень хорошая возможность, для запуска любого действия когда необходимо.

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

Для postfix:

Code Listing 4.2: /usr/local/sbin/mail_pwd_failures.sh для postfix

#! /bin/sh
echo "$3" | mail -s "Warning (program : $2)" root

Для qmail:

Code Listing 4.3: /usr/local/sbin/mail_pwd_failures.sh для qmail

#!/bin/sh
echo "To: root
Subject:Failure (Warning: $2) 
$3
" | /var/qmail/bin/qmail-inject -f root

Запомните, чтобы сделать скрипт запускаемым запустите команду /bin/chmod +x /usr/local/sbin/mail_pwd_failures.sh

Затем раскомментируйте строку command в /etc/metalog/metalog.conf:

Code Listing 4.4: /etc/metalog/metalog.conf

command  = "/usr/local/sbin/mail_pwd_failures.sh"

Syslog-ng

Syslog-ng обеспечивает некоторые возможности syslog и metalog с маленьким отличием. Он может фильтровать сообщения основанные на уровне и содержимом (как metalog), обеспечивает удаленное ведение логов, может обрабатывать логи от syslogd (равномерные потоки в Solaris, писать на TTY, исполнять программы и он может работать как сервер ведения логов. По сути это лучшая программа, совмещает в себе преимущества обоих вышеуказанных программ в расширенной конфигурации.

Классическая конфигурация, слегка измененная.

Code Listing 4.5: /etc/syslog-ng/syslog-ng.conf

options { long_hostnames(off); sync(0); };

#source where to read log
source src { unix-stream("/dev/log"); internal(); };
source kernsrc { file("/proc/kmsg"); };

#define destinations
destination authlog { file("/var/log/auth.log"); };
destination syslog { file("/var/log/syslog"); };
destination cron { file("/var/log/cron.log"); };
destination daemon { file("/var/log/daemon.log"); };
destination kern { file("/var/log/kern.log"); };
destination lpr { file("/var/log/lpr.log"); };
destination user { file("/var/log/user.log"); };
destination mail { file("/var/log/mail.log"); };

destination mailinfo { file("/var/log/mail.info"); };
destination mailwarn { file("/var/log/mail.warn"); };
destination mailerr { file("/var/log/mail.err"); };

destination newscrit { file("/var/log/news/news.crit"); };
destination newserr { file("/var/log/news/news.err"); };
destination newsnotice { file("/var/log/news/news.notice"); };

destination debug { file("/var/log/debug"); };
destination messages { file("/var/log/messages"); };
destination console { usertty("root"); };
destination console_all { file("/dev/tty12"); };
destination xconsole { pipe("/dev/xconsole"); };

#create filters
filter f_auth { facility(auth); };
filter f_authpriv { facility(auth, authpriv); };
filter f_syslog { not facility(authpriv, mail); };
filter f_cron { facility(cron); };
filter f_daemon { facility(daemon); };
filter f_kern { facility(kern); };
filter f_lpr { facility(lpr); };
filter f_mail { facility(mail); };
filter f_user { facility(user); };
filter f_debug { not facility(auth, authpriv, news, mail); };
filter f_messages { level(info..warn) 
	and not facility(auth, authpriv, mail, news); };
filter f_emergency { level(emerg); };

filter f_info { level(info); };
filter f_notice { level(notice); };
filter f_warn { level(warn); };
filter f_crit { level(crit); };
filter f_err { level(err); };
filter f_failed { match("failed"); };
filter f_denied { match("denied"); };

#connect filter and destination
log { source(src); filter(f_authpriv); destination(authlog); };
log { source(src); filter(f_syslog); destination(syslog); };
log { source(src); filter(f_cron); destination(cron); };
log { source(src); filter(f_daemon); destination(daemon); };
log { source(kernsrc); filter(f_kern); destination(kern); };
log { source(src); filter(f_lpr); destination(lpr); };
log { source(src); filter(f_mail); destination(mail); };
log { source(src); filter(f_user); destination(user); };
log { source(src); filter(f_mail); filter(f_info); destination(mailinfo); };
log { source(src); filter(f_mail); filter(f_warn); destination(mailwarn); };
log { source(src); filter(f_mail); filter(f_err); destination(mailerr); };

log { source(src); filter(f_debug); destination(debug); };
log { source(src); filter(f_messages); destination(messages); };
log { source(src); filter(f_emergency); destination(console); };

#default log
log { source(src); destination(console_all); };

Очень легко для настройки, но и очень легко пропустить что-то в конфигурации, потому что файл огромный. Автор обещает некоторые расширенные функции, вроде шифрования, авторизации, сжатия и MAC контроль (Обязательный контроль за доступом). С этими опциями он станет идеальным сетевым логером, так исключается возможность слежения атакующим за логами.

Также syslog-ng имеет другие преимущества. Он не требует запуска как root!.

5. Монтирование разделов

Когда монтируете ext2, ext3 или reiserfs разделы, вы имеете несколько опций которые вы можете установить в /etc/fstab. Это:

К сожалению эти установки могут быть легко обойдены через не прямые пути. Кстати, установив путь /tmp как неисполняемый, остановит 99% всех детсадовских скриптов, в основном эксплойты сделаны так, чтобы запускать прямо /tmp.

Code Listing 5.1: /etc/fstab

/dev/sda1 /boot ext2 noauto,noatime 1 1
/dev/sda2 none swap sw 0 0
/dev/sda3 / reiserfs notail,noatime 0 0
/dev/sda4 /tmp reiserfs notail,noatime,nodev,nosuid,noexec 0 0
/dev/sda5 /var reiserfs notail,noatime,nodev 0 0
/dev/sda6 /home reiserfs notail,noatime,nodev,nosuid 0 0
/dev/sda7 /usr reiserfs notail,noatime,nodev,ro 0 0
/dev/cdroms /cdrom0 /mnt/cdrom iso9660 noauto,ro 0 0
proc /proc proc defaults 0 0

Warning: Установка /tmp как noexec может привести к неработоспособности некоторых скриптов.

Note: Информацию о дисковых квотах смотрите Раздел о дисковых квотах.

Note: Я не устанавливаю /var как noexec или nosuid даже если файлы никогда не будут исполняться из этой точки монтирования. Причина для этого, qmail инсталлируется в /var/qmail и ему должно быть разрешено запускать и иметь доступ к одному SUID файлу. Я устанавливаю /usr как read-only, так как никогда ничего туда не записываю, конечно если не хочу обновить Gentoo. Тогда я монтирую раздел как read-write, обновляю и монтирую снова.

Note: Даже если вы не используете qmail, Gentoo требует возможности исполнения в пути /var/tmp, так как компилирование ebuild происходит здесь, но может быть задан альтернативный путь, если сильно нужно иметь /var в noexec режиме.

6. Ограничение пользователей/групп

/etc/security/limits.conf

Контролирование ресурсов может быть очень эффективным, когда требуется предотвратить локальную DoS-атаку или использовать максимально возможное количество логинов для групп или пользователей.

Code Listing 6.1: /etc/security/limits.conf

*    soft core      0
*    hard core      0
*    hard nproc     15
*    hard rss       10000
*    -    maxlogins 2
@dev hard core      100000
@dev soft nproc     20
@dev hard nproc     35
@dev -    maxlogins 10

Если вы пытаетесь установить nproc или maxlogins в 0, наверное вы должны удалить пользователя вместо этого. Пример выше устанавливает группу dev, настройки для процессов, настроек core и maxlogins. Остальные настройки устанавливаются по умолчанию.

Note: Путь /etc/security/limits.conf часть PAM и используется только пакетами использующими PAM.

/etc/limits

Путь /etc/limits очень похож на файл лимитов /etc/security/limits.conf. Разница только в формате и в том что он работает только с пользователями или неопределенными пользователями(не группами). Давайте посмотрим на подходящую конфигурацию:

Code Listing 6.2: /etc/limits

*   L2 C0 U15 R10000
kn L10 C100000 U35

Здесь мы устанавливаем начальные значения и устанавливаем настройки для пользователя kn. Limits часть пакета sys-apps/shadow. Нет необходимости устанавливать какие-либо ограничения в этом файле если вы отключили pam в make.conf или не настроили PAM.

Квоты

Warning: Убедитесь что ваша файловая система работает с квотами. ReiserFS не работает с ними!

Установка квот на файловую систему предотвращает заполнение пользователями диска или записи до заполнения. Квоты разрешаются в ядре и добавляются на точку монтирования. В ядре опции которые разрешают квоты находятся в File systems->Quota support. Установите эти настройки, перекомпилируйте ядро и перезагрузитесь с новым ядром.

Начните установку квот emerge quota. Дальше измените ваш /etc/fstab и добавьте usrquota и grpquota на раздел, который вы хотите ограничивать в использовании места на диске, как указано ниже.

Code Listing 6.3: /etc/fstab

/dev/sda1 /boot ext2 noauto,noatime 1 1
/dev/sda2 none swap sw 0 0
/dev/sda3 / reiserfs notail,noatime 0 0
/dev/sda4 /tmp ext3 notail,noatime,nodev,nosuid,noexec,usrquota,grpquota 0 0
/dev/sda5 /var ext3 notail,noatime,nodev,usrquota,grpquota 0 0
/dev/sda6 /home ext3 notail,noatime,nodev,nosuid,usrquota,grpquota 0 0
/dev/sda7 /usr reiserfs notail,noatime,nodev,ro	0 0
/dev/cdroms/cdrom0 /mnt/cdrom iso9660 noauto,ro 0 0
proc /proc proc defaults 0 0

На каждый раздел, на котором вы разрешили квоты, создайте файлы квот (quota.user и quota.group) и положите их в корень раздела.

Code Listing 6.4: Создание файлов квот

# touch /tmp/quota.user
# touch /tmp/quota.group
# chmod 600 /tmp/quota.user
# chmod 600 /tmp/quota.group

Этот шаг должен быть сделан, для каждого раздела на котором разрешены квоты. После добавления и настройки файлов, вам необходимо добавить скрипт quota в runlevel default.

Code Listing 6.5: Добавление quota в runlevel default

# rc-update add quota default

Дальше мы настроим систему на проверку квот раз в неделю, добавлением следующей строки в /etc/crontab:

Code Listing 6.6: Добавление проверки quota в crontab

0 3 * * 0 /sbin/quotacheck -avug.

После перезагрузки машины, время настроить квоты для пользователей и групп. edquota -u kn запустит редактор определенный в $EDITOR (по умолчанию установлен nano) и вы сможете редактировать квоту для пользователя kn. edquota -g сделает тоже самое только для групп.

Code Listing 6.7: Настройка квот для пользователя kn

Quotas for user kn: 
/dev/sda4: blocks in use: 2594, limits (soft = 5000, hard = 6500) 
         inodes in use: 356, limits (soft = 1000, hard = 1500)

Для дополнительной информации прочтите man edquota или Quota mini howto.

/etc/login.defs

Если политика безопасности требует чтобы пользователи изменяли свои пароли каждую неделю, измените значение PASS_MAX_DAYS на 14 и PASS_WARN_AGE на 7. Это рекомендуется, в связи с тем что методы вроде brute force, подберут любой пароль, это только вопрос времени. Также установите LOG_OK_LOGINS в yes.

/etc/login.access

Файл login.access также часть пакета sys-apps/shadow, который дает таблицу управлением доступа логинов. Таблица используется для того чтобы контролировать, кто может, а кто не может логинится, основываясь на имени пользователя, имени группы, или имени хоста. По умолчанию все пользователи системы могут логинится, а файл содержит комментарии и примеры. Обеспечиваете ли вы безопасность сервера или рабочей станции, мы рекомендуем настраивать этот файл так, чтобы никто кроме вас не имел доступа к консоли.

Note: Эти настройки не применяются к root.

Code Listing 6.8: /etc/login.access

-:ALL EXCEPT wheel sync:console
-:wheel:ALL EXCEPT LOCAL .gentoo.org

Important: Будьте осторожны с настройкой этих опций, ошибка может лишить вас доступа к машине, если в не имеете доступа root.

Note: Эти настройки не применяются к SSH, так как SSH не исполняет /bin/login по умолчанию. Это может быть разрешено с помощью UseLogin yes в /etc/ssh/sshd_config. Так SSH будет использовать login и эти настройки будут распространятся и на него.

Эти настройки, для того, чтобы только члены группы wheel могли логинится локально, или например из домена gentoo.org. Может быть это слишком параноидально, но это лучше чем потом жалеть.

7. File permissions (разрешения для файлов)

World readable

Обычный пользователь не имеет доступа к файлам конфигурации или файлам паролей. Атакующий может украсть пароли из базы данных, или веб-сайта и использовать их для дефейса или что еще хуже, для удаления информации. Поэтому очень важно чтобы разрешения были правильными. Если вы уверены что файлы используются только root'ом установите их разрешения в 0600 и измените владельца файлов с помощью chown.

World/Group writable

Code Listing 7.1: Поиск файлов и директорий с разрешениями world-writable

# /usr/bin/find / -type f \( -perm -2 -o -perm -20 \) \ 
   -exec ls -lg {} \; 2>/dev/null >writable.txt
# /usr/bin/find / -type d \( -perm -2 -o -perm -20 \) \ 
   -exec ls -ldg {} \; 2>/dev/null >>writable.txt

Этим вы создадите огромный файл, с списком всех файлов с разрешениями на запись для group или everybody. проверьте разрешения и устраните файлы с world-writable для everyone, с помощью /bin/chmod o-w для файлов.

Файлы SUID/SGID

Файлам с битом SUID или SGID разрешается запускать их с привилегиями владельца - пользователя или группы владельца, но не запускающего файл пользователя. Обычно эти биты используются, если файлы должны запускаться как root, для их работы. Эти файлы могут послужить для компроментации root'a (если они содержать дыры в безопасности). Это очень опасно и файлов с битами SUID или SGID нужно избегать любой ценой. Если вы не используете файл, сделайте chmod 0 для него или unmerge для его пакета (проверить из какого пакета файл можно использовать qpkg -f, если у вас нет этих утилит просто установите их - emerge gentoolkit). В противном случае просто отключите бит SUID - chmod -s.

Code Listing 7.2: Поиск файлов setuid

# /usr/bin/find / -type f \( -perm -004000 -o -perm -002000 \) \ 
  -exec ls -lg {} \; 2>/dev/null >suidfiles.txt

Это создаст файл со списком всех файлов SUID/SGID.

Code Listing 7.3: Список приложений с setuid

/bin/su
/bin/ping
/bin/mount
/bin/umount
/var/qmail/bin/qmail-queue
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/crontab
/usr/bin/chage
/usr/bin/expiry
/usr/bin/sperl5.6.1
/usr/bin/newgrp
/usr/bin/passwd
/usr/bin/gpasswd
/usr/bin/procmail
/usr/bin/suidperl
/usr/lib/misc/pt_chown
/usr/sbin/unix_chkpwd
/usr/sbin/traceroute
/usr/sbin/pwdb_chkpwd

По умолчанию Gentoo Linux имеет немного файлов с SUID (это зависит от того, что установлено в системе), но вы можете получить список всех таких файлов, как указано выше. Большая часть команд не используется обычными пользователями, только root'ом. Отключите бит SUID на ping, mount, umount, chfn, chsh, newgrp, suidperl, pt_chown и traceroute с помощью chmod -s для каждого файла. Не убирайте на su, qmail-queue или unix_chkpwd. При отключение его на них, вы не сможете пользоваться su и получать почту. Отключением этого бита, вы исключаете возможность использования обычным пользователем (или атакующим) этих файлов для получения root'a через любой из этих файлов.

Только следующие файлы имеют на моей системе бит SUID - su, passwd, gpasswd, qmail-queue, unix_chkpwd и pwdb_chkpwd. Но если вы запускаете Х, вы будете иметь намного больше. так как Х-ы требуют доступ.

8. PAM (Pluggable Authentication Modules)

PAM - это набор разделяемых библиотек, которые обеспечивают альтернативные пути для авторизации в программах. pam в USE включен по умолчанию. Таким образом установка PAM на Gentoo Linux вполне разумна, но всегда имеется место для виража. Сперва установим cracklib.

Code Listing 8.1: Установка cracklib

# emerge cracklib

Code Listing 8.2: /etc/pam.d/passwd

auth	 required pam_pwdb.so shadow nullok
account	 required pam_pwdb.so
password required pam_cracklib.so difok=3 retry=3 minlen=8 dcredit=2 ocredit=2 
password required pam_pwdb.so md5 use_authtok
session	 required pam_pwdb.so

Этим мы установим cracklib который позволяет убедится, что пользователи используют пароли длиной минимум 8 символов, содержит минимум 2 цифры, 2 других символа (например точку, или пробел) и отличие от предыдущего пароля более чем 3 символа. Это заставит пользователей выбирать хорошие пароли (подходящие по политике паролей). Посмотрите документацию здесь -PAM для большего количества настроек .

Code Listing 8.3: /etc/pam.d/sshd

auth	 required pam_pwdb.so nullok 
auth     required pam_shells.so
auth	 required pam_nologin.so
auth	 required pam_env.so
account	 required pam_pwdb.so
password required pam_cracklib.so difok=3 retry=3 minlen=8 dcredit=2 ocredit=2 use_authtok
password required pam_pwdb.so shadow md5
session	 required pam_pwdb.so
session	 required pam_limits.so

Каждый сервис, который не настроен в файле PAM - /etc/pam.d будет использовать правила из /etc/pam.d/other. Установки по умолчанию - deny, как и должно быть. Но я люблю иметь много логов и поэтому я добавляю pam_warn.so. Последней настройкой будет pam_limits , который котролируется через /etc/security/limits.conf. Посмотрите - /etc/security/limits.conf section, если хотите использовать больше настроек.

Code Listing 8.4: /etc/pam.d/other

auth     required pam_deny.so 
auth     required pam_warn.so 
account  required pam_deny.so 
account  required pam_warn.so 
password required pam_deny.so 
password required pam_warn.so 
session  required pam_deny.so 
session  required pam_warn.so

9. TCP Wrappers

иля контролирования доступа к сервисам, обычно используют inetd (которого Gentoo не имеет), но он может использоваться xinetd и другими сервисами.

Note: Сервисы должны использовать tcpd в серверном аргументе вызова (в xinetd). Смотрите главу xinetd, для большей информации.

Code Listing 9.1: /etc/hosts.deny

ALL:PARANOID

Code Listing 9.2: /etc/hosts.allow

ALL: LOCAL @wheel
time: LOCAL, .gentoo.org

Как вы видите формат файла очень похож на /etc/login.access. Tcpd поддерживает специфические сервисы и они не работают в таких же зонах безопасности. Эти настройки применяются только к сервисам, которые используют tcp wrappers.

Также возможно исполнение команд, когда происходит использование сервиса (например может быть использован, когда необходимо активировать релей для dial-in пользователей), но мы не рекомендуем использовать эту возможность, так как она создает проблемы, которые трудно устранить. Примером может служить следующее, вы настроили скрипт, для посылки предупреждения каждый раз когда срабатывает deny-правило, но атакующий может запустить DoS-атаку, которая будет заставлять правило срабатывать, и вам будут посылаться сообщения, это может создать много почтовых I/O-подключения, что может вызвать проблемы с почтой. Прочтите man 5 hosts_access для большей информации.

10. Безопасность ядра

Удаление ненужных функций

Основное правило при конфигурации ядра - удалите все, что вам не нужно. Это поможет создать маленькое ядро, но также и исключит, возможные уязвимости, которые могут быть в драйверах или некоторых функциях.

Также подумайте о возможности исключить из ядра поддержку модулей. Конечно root kit можно установить и без этой функции, но сделать это намного сложнее.

/proc (флаги ядра)

Много параметров ядра могут быть изменены, через файловую систему /proc или с помощью sysctl.

Для динамического изменения параметров ядра и переменных "на лету" вам нужно указать переменную CONFIG_SYSCTL в ядре. Она указана по умолчанию в стандартном ядре вер. 2.4. kernel.

Code Listing 10.1: Фильтрация пакетов ping

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all

Это действие укажет ядру просто игнорировать все ping-пакеты или сообщения протокола ICMP тип 0. Причиной для этого служит, то что ICMP-пакеты могут содержать больше информации чем вы думаете. Администратры используют ping как средство диагностики и, но это не причина, чтобы внешнее подключение к интернету отвечало на ping. Но в тоже время необходимо разрешить ping из внутренней сети. В таком слчае можно возпользоваться настойками firewall.

Code Listing 10.2: Игнорирование широковещательных pings

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

Так вы отключите ответ на ICMP-broadcast'ы, что предотвратит атаки типа Smurf. Атака типа Smurf, работает так - посылается ping на адрес широковещательной рассылки в сети. Обычно атакующий использует поддельный адрес источника. Все компьютеры в сети ответят на этот адрес, и таким образом может быть поисходить flood пакетами на этот адреса.

Code Listing 10.3: Отключение source routed пакетов (роутинг пакета происходит по адресу источника, а не по адресу назначения)

# /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route

Source routing порождается источником пакета и заставляет все маршрутизаторы по пути следования к получателю маршрутизировать пакет так, как этого захотел источник. Не принимайте source routed пакетов. Атакующий может использовать роутинг для генерации сетевого трафика инициатором которого как-будто служит хост внутри вашей сети, и происходит ответ на его запрос, так атакующий может скомпроментировать вашу сеть. Source routing редко использовался для законных вещей, так что отключите его.

Code Listing 10.4: Отключение приема redirect

# /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects

Отключите прием ICMP-redirect. ICMP-redirects может быть использован для изменения вашей таблицы маршрутизации, что очень плохо.

Code Listing 10.5: Защита против неправильных сообщений о ошибках

# /bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

Разрешите защиту против поддельных сообщения о ошибках.

Code Listing 10.6: Разрешите фильтрацию обратного пути

# for i in /proc/sys/net/ipv4/conf/*; do
        /bin/echo "1" > $i/rp_filter
done

Note: Если вы включили IP-forwarding, вы также получите этот результат.

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

Warning: Однако, включение фильтрации reverse path, может создать проблемы, если вы используете asymmetric routing (пакет в к вам от хоста имеет путь отличный, при пакете от вас к хосту) или если вы используете non-routing хост, который имеет несколько IP адресов на нескольких интерфейсах.

Code Listing 10.7: Логирование всех spoofed, source routed и redirect пакетов

# /bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians

Логирование всех spoofed, source routed и redirect пакетов

Code Listing 10.8: Отключение IP-forwarding

# /bin/echo "0" > /proc/sys/net/ipv4/ip_forward

Убедитесь, что IP-forwarding выключен. Это нужно только для multi-homed хостов.

Все эти настройки пропадут, после перезагрузки машины. Поэтому я предлагаю добавить следующий скрипт в runlevel rc-update add procparam default и сделать его исполняемым chmod +x /etc/init.d/procparam.

Code Listing 10.9: /etc/init.d/procparam

#!/sbin/runscript

depend() {
 use checkroot
}

start() {
 ebegin "Setting /proc options."
 /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all
 /bin/echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
 /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_source_route
 /bin/echo "0" > /proc/sys/net/ipv4/conf/all/accept_redirects
 /bin/echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
 for i in /proc/sys/net/ipv4/conf/*; do
   /bin/echo "1" > $i/rp_filter
 done
 /bin/echo "1" > /proc/sys/net/ipv4/conf/all/log_martians
 /bin/echo "0" > /proc/sys/net/ipv4/ip_forward
 eend 0
}

Grsecurity

Патч с Grsecurity стандартный в ядре Gentoo, но отключен по умолчанию. Здесь мы его включим:

Настройте ваше ядро как обычно, а потом настройте опцию Grsecurity : (выбирите customized) и разрешите следующие опции:

Теперь скомпилируйте и установите security enhanced ядро.

Kerneli

Kerneli - это патч, который добавит шифрование в ядро. После его установки, вы получите новые опции в ядре, например: Cryptographic ciphers, digest algorithms и cryptographic loop filters.

Warning: Версия патча kerneli, non-stable для последней версии ядра, будьте осторожны с его использованием.

Другие патчи ядра

И вероятно, еще много чего....

11. Безопасность сервисов

Использование xinetd

xinetd -это замена для inetd (которого в Gentoo нет :), - internet services daemon. Он поддерживает контроль доступа по адресу удаленного хоста и по времени доступа. Также обеспечивает расширенное логирование событий, включая время запуска сервера, адресов удаленных хостов, имя пользователя авторизованного удаленно, uptime (продолжительность работы сервера) и действие по требованию.

Как и со всеми другими сервисами, очень важно иметь хорошую начальную настройку. Но так как xinetd требует запуска как root и поддерживает протоколы, возможности которых вы не знаете, мы не рекомендуем использовать его. Но если вы все равно хотите пользоваться им, вы можете усилить его безопасность:

Code Listing 11.1: Установка xinetd

# emerge xinetd tcp-wrappers

Отредактируйте файлы конфигурации:

Code Listing 11.2: /etc/xinetd.conf

defaults
{
 only_from      = localhost
 instances      = 10
 log_type       = SYSLOG authpriv info
 log_on_success = HOST PID
 log_on_failure = HOST
 cps            = 25 30
}

# This will setup pserver (cvs) via xinetd with the following settings:
# max 10 instances (10 connections at a time)
# limit the pserver to tcp only
# use the user cvs to run this service
# bind the interfaces to only 1 ip
# allow access from 10.0.0.*
# limit the time developers can use cvs from 8am to 5pm
# use tpcd wrappers (access control controlled in 
# /etc/hosts.allow and /etc/hosts.deny)
# max_load on the machine set to 1.0
# The disable flag is per default set to no but I like having 
# it in case of it should be disabled
service cvspserver
{
 socket_type    = stream
 protocol       = tcp
 instances      = 10
 protocol       = tcp
 wait           = no
 user           = cvs
 bind           = 10.0.0.2
 only_from      = 10.0.0.0
 access_times   = 8:00-17:00
 server         = /usr/sbin/tcpd
 server_args    = /usr/bin/cvs --allow-root=/mnt/cvsdisk/cvsroot pserver
 max_load       = 1.0
 log_on_failure += RECORD
 disable        = no
}

Для большей информации прочтите man 5 xinetd.conf.

ssh

Только организация защиты OpenSSH требует включения мощной системы авторизации основанной на шифровании открытым ключем. Много сайтов (вроде http://www.sourceforge.net, http://www.php.net и http://www.apache.org) были взломаны, благодаря утечкам паролей или благодаря плохим паролям.

Code Listing 11.3: /etc/ssh/sshd_config

#Only enable version 2
Protocol 2

#No direct root access
PermitRootLogin no

#Turn on RSA key authentication
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys

#Disable .rhost files and normal password auth.
RhostsAuthentication no
PasswordAuthentication no
PermitEmptyPasswords no

AllowHosts *.gentoo.org

#Only people in the wheel or admin group can be given access
AllowGroups wheel admin

#Of all the people in those groups, only kn and bs really have access
AllowUsers kn bs

#add logging level
SyslogFacility AUTH
LogLevel INFO

#bind
ListenAddress 127.0.0.1

Теперь все что требуется от пользователей, создать ключ (на машинах, откуда они хотят логиниться) с помощью следующей команды:

Code Listing 11.4: Создание пары ключей RSA

# /usr/bin/ssh-keygen -t rsa

И ввести пароль

Code Listing 11.5: Вывод на екран ssh-keygen

Generating public/private rsa key pair.
Enter file in which to save the key (/home/kn/.ssh/id_rsa):[Press enter]
Created directory '/home/kn/.ssh'.
Enter passphrase (empty for no passphrase): [Enter passphrase]
Enter same passphrase again: [Enter passphrase again]
Your identification has been saved in /home/kn/.ssh/id_rsa.
Your public key has been saved in /home/kn/.ssh/id_rsa.pub.
The key fingerprint is:
07:24:a9:12:7f:83:7e:af:b8:1f:89:a3:48:29:e2:a4 kn@knielsen

Это добавит два файла в каталог ~/.ssh/ - id_rsa и id_rsa.pub. Файл id_rsa - это приватный ключ и он должен быть сохранен от доступа других людей, кроме вас. Другой файл - id_rsa.pub передается любому серверу, к которому вы хотите иметь доступ. Добавьте ключи в дериктория пользователя, в ~/.ssh/authorized_keys, после этого пользователь будет иметь возможность логиниться.

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

Для большей информации посмотрите сайт - OpenSSH.

X

По умолчанию XFree настроен как Xserver. Это может быть опасным, так как пользователи Х используют нешифрованное ТСР-соединение и открыт для подключения xclient.

Important: Если вам не нужен этот сервис - отключите его!

Но если вы хотите использовать вашу рабочую станцию как Xserver используйте команду /usr/X11R6/bin/xhost с осторожностью. Это команда позволяет иметь доступ пользователей с других хостов, для подключения к Х. Это может быть использовано, если вам необходимо, какое-то Х-приложение с другой машины, только через сеть. Синтаксис - /usr/X11R6/bin/xhost +имя_хоста

Warning: Никогда не используйте xhost +! Это сделает возможным подключение любого клиента и контролирование Х. Если атакующий имеет доступ к Х, он может отследить ваши нажатия клавиш и контролировать desktop. Если вы пользуетесь им, всегда указывайте хост.

Лучшее решения для безопасности, полное отключение этой возможности при старте Х - startx -- -nolisten tcp или отключить ее совсем в конфигурации.

Code Listing 11.6: /usr/X11R6/bin/startx

defaultserverargs="-nolisten tcp"

Убедитесь что startx не перезаписывается, когда устанавливается новая версия XFree, тогда вы должны защитить его. Добавьте следующую строку в /etc/make.conf:

Code Listing 11.7: /etc/make.conf

CONFIG_PROTECT_MASK="/usr/X11R6/bin/startx"

Если вы используете графический login manager, вам нужно другое решение.

For gdm (Gnome Display Manager)

Code Listing 11.8: /etc/X11/gdm/gdm.conf

[server-Standard]
command=/usr/X11R6/bin/X -nolisten tcp

Для xdm (X Display Manager) и kdm (Kde Display Manager)

Code Listing 11.9: /etc/X11/xdm/Xservers

:0 local /usr/bin/X11/X -nolisten tcp 

FTP

Обычно использование FTP (File Transfer Protocol) плохая идея. Он использует нешифрованные данные, прослушивает два порта (обычно 20 и 21 порты), и можно логиниться как anonymous, поэтому многие атакующие ищут открытый FTP. Так как FTP-протокол имеет проблемы с безопасностью, вы должны использовать sftp или HTTP вместо него. Если нет, усильте безопасность вашего сервиса, так хорошо как вы можете и готовьтесь к чему угодно.

Pure-ftpd

Pure-ftpd - это ответвление от trollftpd. Он был изменен для по причинам безопасности и функциональности Frank'ом Dennis'ом.

Используйте виртуальных пользователей (никогда системные акаунты) путем задания опций AUTH. Установите ее в - -lpuredb:/etc/pureftpd.pdb и создайте пользователей используя /usr/bin/pure-pw.

Code Listing 11.10: /etc/conf.d/pure-ftpd

AUTH="-lpuredb:/etc/pureftpd.pdb"

## Misc. Others ##
MISC_OTHER="-A -E -X -U 177:077 -d -4 -L100:5 -I 15"

И настройте MISC_OTHER для запрещения авторизации anonymous (-E), использовать chroot для каждого пользователя (-A), пользователь не может читать/записывать файлы имя которых начинается с точки (-X), максимальное время неактивности пользователя (-I), лимит рекурсии (-L) и корректность umask.

Warning: НЕ используйте опции -w или -W! Если вы хотите иметь у себя сайт вареза, перестаньте читать этот документ!

Документацию вы можете найти здесь - http://www.pureftpd.org.

Proftpd

Proftpd имел несколько проблем с безопасностью, но большинство уже решены. Давайте немного расширим безопасность:

Code Listing 11.11: /etc/proftpd/proftpd.conf

ServerName "My ftp daemon"
#Don't show the ident of the server
ServerIdent on "Go away"

#Makes it easier to create virtual users
RequireValidShell off

#Use alternative password and group file (passwd uses crypt format)
AuthUserFile "/etc/proftpd/passwd"
AuthGroupFile "/etc/proftpd/group"

# Permissions
Umask 077

# Timeouts and limitations
MaxInstances 30
MaxClients 10 "Only 10 connections allowed"
MaxClientsPerHost 1 "You have already logged on once"
MaxClientsPerUser 1 "You have already logged on once"
TimeoutStalled 10
TimeoutNoTransfer 20
TimeoutLogin 20

#Chroot everyone
DefaultRoot ~

#don't run as root
User  nobody
Group nogroup

#Log every transfer
TransferLog /var/log/transferlog

#Problems with globbing
DenyFilter \*.*/

Вы можете найти документацию - http://www.proftpd.org.

Vsftpd

Vsftpd (сокращение от - very secure ftp) маленький ftp-daemon, работает корректно с начальными установками. Он прост и не имеет не много функций (вроде виртуальных пользователей) как pureftp и proftp.

Code Listing 11.12: /etc/vsftpd

anonymous_enable=NO
local_enable=YES

#read only
write_enable=NO

#enable logging of transfers
xferlog_std_format=YES

idle_session_timeout=20
data_connection_timeout=20
nopriv_user=nobody

chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chrootlist

ls_recurse_enable=NO

Как вы видите, нет возможности для индивидуальных разрешений и по умолчанию отключен chroot. Но подход к настройкам anonymous, очень хорош. Иногда когда требуется иметь доступ anonymous на ftp-сервер - vsftpd действительно хорошо решает подобные задачи.

Apache

Apache (1.3.26) идет с весьма неплохой конфигурацией. Мы улучшим некоторые вещи, вроде привязки на один адрес и исключения возможности утечки информации. Следующие опции вы должны изменить в конфигурационном файле:

Если вы не отключили ssl в /etc/make.conf перед инсталляцией apache, вы должны иметь доступ к запущенному ssl-серверу. Просто добавьте следующую строку:

Code Listing 11.13: /etc/conf.d/apache

HTTPD_OPTS="-D SSL"

Code Listing 11.14: /etc/apache/conf/apache.conf

#Make it listen on your ip
Listen 127.0.0.1
BindAddress 127.0.0.1
#It is not a good idea to use nobody or nogroup - 
#for every service not running as root 
#(just add the user apache with group apache)
User apache
Group apache
#Will keep apache from telling about the version
ServerSignature Off
ServerTokens min

Apache компилируется с опциями --enable-shared=max и --enable-module=all. Это по умолчанию разрешает все модули, так что вы должны закомментировать все модули которые вы не используете в разделе LoadModule (LoadModule и AddModule). Перезапустите сервис после завершения, /etc/init.d/apache restart.

Вы можете найти документацию - http://www.apache.org.

Qmail

Qmail самый защищенный почтовый сервер. Он написан с самого начала с идеей безопасности. Он не допускает релея по умолчанию и не имеет дыр в безопасности с 1996 года. Просто сделайте emerge qmail.

Bind

Вы можете найти документацию - Internet Software Consortium, также вы можете найти "BIND 9 Administrator Reference Manual" в doc/arm.

Djbdns

Здесь действительно нечего сказать о djbdns, за исключением того, что автор предлагает деньги за найденную дыру в безопасности. Так что можете попробовать его использовать http://www.djbdns.org/ он очень отличается от Bind v.9, но вы можете попробовать его использовать.

Samba

Samba это протокол для передачи файлов в сетях Microsoft/Novell и он не должен использоваться через Internet. Но никогда не помешает укрепить безопасность.

Code Listing 11.15: /etc/samba/smb.conf

[global]
  #Bind to an interface
  interfaces = eth0 10.0.0.1/32

  #Make sure to use encrypted password
  encrypt passwords = yes
  directory security mask = 0700

  #allow traffic from 10.0.0.*
  hosts allow = 10.0.0.

  #Enables user authentication 
  #(don't use the share mode)
  security = user
  
  #Disallow privileged accounts
  invalid users = root @wheel

  #Maximum size smb shows for a share (not a limit)
  max disk size = 102400

  #Uphold the password policy
  min password length = 8
  null passwords = no

  #Use PAM (if added support)
  obey pam restrictions = yes
  pam password change = yes

Убедитесь что разрешения - корректны для каждой общей папки и прочтите документацию - documentation.

Теперь перезапустите сервер, и добавьте пользователей, которые должны иметь доступ к этому сервису. Это делается с помощь /usr/bin/smbpasswd с параметром -a.

Chroot или виртуальные сервера

Chrooting для сервиса - путь для ограничения окружения сервиса (или пользователя), для доступа его только к тому что нужно и закрытия путей (или информации) для приобретения прав root. Если сервис запущен как любой другой пользователь (nobody, apache, named) атакующий может иметь доступ к файлам с правами этого пользователя. Это означает что атакующий не может получить прав root, даже если сервис имеет дыру в безопасности.

Некоторые сервисы вроде pure-ftpd и bind имеют возможности для chroot'инга, а другие нет. Если сервис поддерживает его - используйте, иначе ищите как его сделать. Давайте посмотрим как можно сделать chroot, для начального понимания работы chroot, мы протестируем его на примере bash.

Создайте директорию /chroot (mkdir chroot). И найдите динамические библиотеки которые необходимы bash (если скомпилирован с опцией -static этот шаг можно пропустить):

Эта команда создаст список библиотек используемых bash.

Code Listing 11.16: Создание списка используемых библиотек

# ldd /bin/bash
  libncurses.so.5 => /lib/libncurses.so.5 (0x4001b000)
  libdl.so.2 => /lib/libdl.so.2 (0x40060000)
  libc.so.6 => /lib/libc.so.6 (0x40063000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Теперь давайте создадим окружение для bash.

Code Listing 11.17: Создание chroot-окружения для bash

# mkdir /chroot/bash
# mkdir /chroot/bash/bin
# mkdir /chroot/bash/lib

Дальше скопируем файлы используемые bash (/lib) в chroot директорию lib и скопируем команды bash в директорию chroot bin. Это создаст точную копию окружения, только меньшей функциональности. После копирования попробуйте выполнить: chroot /chroot/bash. Если вы перейдете в корень вашего каталога /, вы увидите что это работает. Иначе вы увидите сообщение о том что файлы отсутствуют. Нехватает некоторых библиотек для библиотек bash'a. Некоторые библиотеки могут зависить от других библиотек.

Внутри chroot-окружения ничего не будет работать кроме echo. Это потому что в окружении нет других команд, а echo это встроенная возможность bash.

Это все что можно для начала сказать о сервисах в chroot. Одно но: сервис иногда зависит от устройств и конфигурационных файлов /etc. Просто скопируйте их (устройства могут быть скопированы с помощью cp -a) в chroot-окружение, поправьте init-скрипт для использования chroot перед исполнением. Это может трудно найти какие устройства и конфигурационные файлы используются сервисом. Поэтому можно использовать strace для этого. Запустите сервис с /usr/bin/strace и просмотрите на открытые для чтения, записи файлы, также на соединения открытые сервисом. Так вы можете понять, какие устройства и файлы необходимо скопировать. Но в большинстве случаев достаточно просто скопировать файл passwd (отредактируйте копию и удалите пользователей которые ничего не требуются для сервиса), /dev/zero, /dev/log и /dev/random.

Другой способ создания безопасного окружения - использование виртуального окружения сервера. Это создаст копию существующего Linux'а и boot-файлов в виртуальном режиме. Это значит что если сервер будет взломан, это будет только виртуальный сервер, но не настоящая инсталляция.

Пример виртуального сервера

12. Брандмауэры

Брандмауэр

Люди часто думают что брандмауэр обеспечивает совершенную защиту, но это неправильно. В большинстве случаев лучше вообще не иметь брандмауэра, чем иметь его с неправильной конфигурацией. Брандмауэр - это ПО, и оно требует такой же настройки как и все остальные программы, потому что он тоже может содержать ошибки.

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

Брандмауэры используются для двух случаев:

Обычно есть 3 типа брандмауэров:

Брандмауэр должен быть на для отдельной машине, на которой не запущено сервисов (или только sshd), это рекомендуется для безопасности.

Фильтрация пакетов

Весь сетевой трафик идет в форме пакетов. Большая сумма трафика также разбивается на маленькие пакеты для легкости обработки и потом собираются при достижении пункта назначения. В заголовке каждого пакета содержится информация о том как и куда он должен доставляться. Именно эта информация и используется когда пакет фильтруется брандмауэром. Фильтрация основана на:

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

Недостатки:

Преимущества:

Пример свободно распространяемых брандмауэров для Linux:

Релеинг соединений

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

Весь трафик проверяется, подвергается мониторингу и весь нелегальный трафик может быть отклонен.

Недостатки:

Программный gateway

Программный gateway служит прокси сервером для приложений и осуществляет от их имени обмен данными. Он находится в дали от посторонних глаз за DMZ (демилитаризованная зона - часть внутренний сети, которая видна сквозь firewall) или за firewall'ом который не разрешает внешних подключений. Фильтрация основана на:

Преимущества:

Недостатки:

Программные прокси считаются наиболее безопасными, так как не требуют запуска от имени root и к сети за хостом нет доступа из интернета.

Пример свободно распространяемых программных прокси:

Iptables

Для того чтобы iptables работал, он должен быть разрешен в ядре. Вы можете добавить его как модуль (команда iptables загрузит необходимый модуль, когда он необходим) и скомпилируйте свое ядро. Для большей информации, как его настроить прочтите Iptables Tutorial Chapter 2: Preparations. После того как у вас будет скомпилировано новое ядро (или пока оно компилируется) вы можете установить iptables. Просто сделайте emerge iptables и он должен заработать.

Теперь давайте попробуем запустить его - iptables -L. Его что-то не так, проверьте свою конфигурацию.

Iptables - новый,усовершенствованный, брандмауэр в ядре Linux 2.4.x. Он является продолжение брандмауэра ipchains, который присутствует в ядре Linux 2.2.x. Одно из главных улучшений - iptables имеет возможность фильтрации пакетов по статус соединения (stateful filter). С такой фильтрацией возможно отслеживать каждое TCP-соединение.

TCP-соединение состоит из серий пакетов содержащих информацию о IP-адресе источника, IP-адресе пункта назначения, последовательный номер пакета (чтобы пакеты могли быть пересобранны в случае ошибки, чтобы не потерять данные). ТСР это connection-ориентированный протокол, в отличии от UDP, который не устанавливает соединение.

При проверке заголовка TCP-пакета, статусный фильтр может определить: принятый пакет часть уже установленного соединения или нет и решить - принимать его или отвергнуть.

С stateless-фильтром (фильтр не изменяет своего состояния во время выполнения) возможно обмануть фильтр, и пакет будет принят, хотя должен был быть отвергнут при проверке ТСР-заголовка. Это может быть сделано путем манипуляции с SYN-флагом или другими флагами TCP-заголовка. С stateful-фильтрацией возможно отвергнуть пакет, который не является частью уже установленного соединения. Это также исключит возможность так называемого "stealth-сканирования" так как пакеты не части уже установленных соединений.

Iptables обеспечивают несколько других функций вроде NAT (Network Address Translation) и шейпинга трафика (ограничение пропускной способности соединения). Шейпинг трафика в высшей степени полезно при пресечении DoS-атак (Denial of Service) вроде атак SYN-flood.

TCP-соединение устанавливается после тройного рукопожатием. Когда устанавливается ТСР-соединение клиент посылает пакет с установленным SYN-флагом в заголовке к серверу, сервер отвечает SYN+ACK-пакетом к клиенту. Когда SYN+ACK-пакет принят клиентом, он отвечает третьим АСК-пакетом, в подтверждение установленного соединения.

SYN-flood атака проводится путем посылки SYN-пакета, но не отвечая на SYN+ACK-пакет packet. Клиент может подделать IP-адрес, ведь ему не требуется получение ответа. Серверная сторона добавит соединения в очередь полуоткрытых, когда примет SYN-пакеты и будет ожидать ACK-пакета перед удалением соединения из очереди. Эта очередь ограничена количеством соединений, и если все ячейки ее, будут заполнены, хост не сможет открыть нового соединения. Если АСК-пакет не принят за время таймаута - соединения удаляется из очереди. Величина таймаута различна, но обычно составляет в пределах 30-60 секунд или больше. Клиентская сторона инициирующая атаку, посылает множество SYN-пакетов, с разными IP-адресами источника к атакуемому серверу, так быстро как позволяет канал, заполняя таким образом очередь соединений, и лишая возможности подключения обычных пользователей.

В этом случае возможность ограничения скорости соединения весьма кстати. По возможности ограничьте скорость приема SYN-пакетов используя -m limit --limit 1/s. Это будет ограничивать количество принятых SYN-пакетов до одного в секунду.

Теперь практический материал.

Когда iptables загружены в ядро, вы имеете 5 мест (hooks), куда можете записывать свои правила. Они называются INPUT, OUTPUT, FORWARD, PREROUTING и POSTROUTING и содержат список правил для фильтрации. Каждое правило описывает как должен выглядеть заголовок пакета, и что делать с этим пакетом. если правило не соответствует пакету - оно передается дальше по цепочке.

Вы можете записать правило в 5 главных цепочек или создать новую цепочку и добавить в нее правило из существующей цепочки. Iptables поддерживает следующие опции:

Опция: Описание:
-A Добавление
-D Удаление
-I Вставка
-R Перезапись
-L Список
-F Удалить все правила в цепочке или все цепочки
-Z Обнулить счетчики в цепочке или всех цепочек
-C Тест этого пакета в цепочке
-N Создать новую цепочку управляемую пользователем
-X Удалить цепочку управляемую пользователем
-P Изменить политику для действия в цепочке
-E Изменить имя цепочки
-p Протокол
-s Адрес/маска источника
-d Адрес/маска пункта назначения
-i Входное имя (ethernet-имя)
-o Выходное имя (ethernet-имя)
-j Jump (действие для правила)
-m Расширенное сравнение (можно использовать расширения)
-n Цифровой вывод адресов и портов
-t Таблица для манипуляций
-v Режим verbose (для отладки, выдается более подробная информация)
-x Расширенные номера (показывает точные значения)
-f Применять только ко второму или последующим пакетам
-V Версия пакета
--line-numbers Выводит количество строк при листинге

Для начала мы попробуем блокировать все ICMP-пакеты для нашей машины, только для того чтобы показать пример в iptables.

Code Listing 12.1: Блокирование всех ICMP-пакетов

# iptables -A INPUT -p icmp -j DROP

Сначала мы указали цепочку куда должно добавиться правило, дальше протокол и действие для правила. Действие может быть определено пользователем или одно из специальных действий ACCEPT, DROP, REJECT, LOG, QUEUE, MASQUERADE. В этом случае мы используем DROP - действие которое отклоняет пакеты, не отвечая клиенту.

Теперь попробуйте ping localhost. Вы не получите никакого ответа, так как iptables отклонит все входящие пакеты ICMP сообщений. Также вы не сможете пинговать другие машины, так как будут отклонены ответные пакеты. Теперь сбросим цепочку, чтобы вернуть ICMP потоки.

Code Listing 12.2: Сброс всех правил

# iptables -F

Теперь рассмотрим stateful-фильтр в iptables. Если вы хотите использовать stateful-фильтрацию входящих пакетов, вы должны разрешить его так:

Code Listing 12.3: Принятие пакетов которые создаются уже установленным соединением

# iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

Это разрешит принятие пакетов из уже установленных соединений или связанной с ними цепочки INPUT. И вы можете отклонять любой пакет который не находится таблице соединений спомощью - iptables -A INPUT -i eth0 -m state --state INVALID -j DROP. Это разрешит stateful-фильтрацию в iptables и загрузит необходимое расширение. Если вы хотите разрешить другие соединения к вашей машине, вы можете использовать --state NEW. Iptables содержит некоторые модули для различных нужд. Некоторые из них:

Модуль/Совпадение Описание Расширенные опции
mac Проверяющее расширение для входящих пакетов по mac-адресу. --mac-source
state Позволяет stateful-фильтрацию --state (states are ESTABLISHED,RELATED, INVALID, NEW)
limit Ограничение скорости --limit, --limit-burst
owner Позволяет совпадения различных характеристик хоста создающего пакет --uid-owner userid --gid-owner groupid --pid-owner processid --sid-owner sessionid
unclean Различные проверки пакетов на "правильность"

Давайте попробуем создать цепочку управляемую пользователем и применить ее к одной из уже существующих:

Code Listing 12.4: Creating a user defined chain

(Создаем новую цепочку с одним правилом)
# iptables -X mychain
# iptables -N mychain
# iptables -A mychain -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
(Политика по умолчанию весь исходящий трафик разрешен. Входящий запрещен.)
# iptables -P OUTPUT ACCEPT
# iptables -P INPUT DROP
(И добавим ее в цепочку INPUT)
# iptables -A INPUT -j mychain

После применения правила с цепочке INPUT мы имеем политику: все исходящие пакеты разрешены, все входящие пакеты выкидываются.

Вы можете найти документацию здесь - Netfilter/iptables documentation.

Давайте посмотрим теперь полный пример. Здесь приведена моя политика безопасности брандмауэра/шлюза:

Code Listing 12.5: /etc/init.d/firewall

#!/sbin/runscript
IPTABLES=/sbin/iptables
IPTABLESSAVE=/sbin/iptables-save
IPTABLESRESTORE=/sbin/iptables-restore
FIREWALL=/etc/firewall.rules
DNS1=212.242.40.3
DNS2=212.242.40.51
#inside
IIP=10.0.0.2
IINTERFACE=eth0
LOCAL_NETWORK=10.0.0.0/24
#outside
OIP=217.157.156.144
OINTERFACE=eth1

opts="${opts} showstatus panic save restore showoptions rules"

depend() {
  need net procparam
}

rules() {
  stop
  ebegin "Setting internal rules"

  einfo "Setting default rule to drop"
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP

  #default rule
  einfo "Creating states chain"
  $IPTABLES -N allowed-connection
  $IPTABLES -F allowed-connection
  $IPTABLES -A allowed-connection -m state --state ESTABLISHED,RELATED -j ACCEPT
  $IPTABLES -A allowed-connection -i $IINTERFACE -m limit -j LOG --log-prefix \ 
      "Bad packet from ${IINTERFACE}:"
  $IPTABLES -A allowed-connection -j DROP

  #ICMP traffic
  einfo "Creating icmp chain"
  $IPTABLES -N icmp_allowed
  $IPTABLES -F icmp_allowed
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \ 
      time-exceeded -j ACCEPT
  $IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \ 
      destination-unreachable -j ACCEPT
  $IPTABLES -A icmp_allowed -p icmp -j LOG --log-prefix "Bad ICMP traffic:"
  $IPTABLES -A icmp_allowed -p icmp -j DROP

  #Incoming traffic
  einfo "Creating incoming ssh traffic chain"
  $IPTABLES -N allow-ssh-traffic-in
  $IPTABLES -F allow-ssh-traffic-in
  #Flood protection
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL RST --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL FIN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \ 
      ALL SYN --dport ssh -j ACCEPT
  $IPTABLES -A allow-ssh-traffic-in -m state --state RELATED,ESTABLISHED -p tcp --dport ssh -j ACCEPT

  #outgoing traffic
  einfo "Creating outgoing ssh traffic chain"
  $IPTABLES -N allow-ssh-traffic-out
  $IPTABLES -F allow-ssh-traffic-out
  $IPTABLES -A allow-ssh-traffic-out -p tcp --dport ssh -j ACCEPT

  einfo "Creating outgoing dns traffic chain"
  $IPTABLES -N allow-dns-traffic-out
  $IPTABLES -F allow-dns-traffic-out
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS1 --dport domain \ 
      -j ACCEPT
  $IPTABLES -A allow-dns-traffic-out -p udp -d $DNS2 --dport domain \ 
     -j ACCEPT

  einfo "Creating outgoing http/https traffic chain"
  $IPTABLES -N allow-www-traffic-out
  $IPTABLES -F allow-www-traffic-out
  $IPTABLES -A allow-www-traffic-out -p tcp --dport www -j ACCEPT
  $IPTABLES -A allow-www-traffic-out -p tcp --dport https -j ACCEPT

  #Catch portscanners
  einfo "Creating portscan detection chain"
  $IPTABLES -N check-flags
  $IPTABLES -F check-flags
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -m limit \ 
      --limit 5/minute -j LOG --log-level alert --log-prefix "NMAP-XMAS:" 
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -m limit --limit \ 
      5/minute -j LOG --log-level 1 --log-prefix "XMAS:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG \ 
      -m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS-PSH:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -m limit \ 
      --limit 5/minute -j LOG --log-level 1 --log-prefix "NULL_SCAN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -m limit \ 
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/RST:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit \ 
      --limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/FIN:"
  $IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

  # Apply and add invalid states to the chains
  einfo "Applying chains to INPUT"
  $IPTABLES -A INPUT -m state --state INVALID -j DROP
  $IPTABLES -A INPUT -j icmp_allowed 
  $IPTABLES -A INPUT -j check-flags
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A INPUT -j allow-ssh-traffic-in
  $IPTABLES -A INPUT -j allowed-connection

  einfo "Applying chains to FORWARD"
  $IPTABLES -A FORWARD -m state --state INVALID -j DROP
  $IPTABLES -A FORWARD -j icmp_allowed 
  $IPTABLES -A FORWARD -j check-flags
  $IPTABLES -A FORWARD -o lo -j ACCEPT
  $IPTABLES -A FORWARD -j allow-ssh-traffic-in
  $IPTABLES -A FORWARD -j allow-www-traffic-out
  $IPTABLES -A FORWARD -j allowed-connection

  einfo "Applying chains to OUTPUT"
  $IPTABLES -A OUTPUT -m state --state INVALID -j DROP
  $IPTABLES -A OUTPUT -j icmp_allowed
  $IPTABLES -A OUTPUT -j check-flags
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  $IPTABLES -A OUTPUT -j allow-ssh-traffic-out
  $IPTABLES -A OUTPUT -j allow-dns-traffic-out
  $IPTABLES -A OUTPUT -j allow-www-traffic-out
  $IPTABLES -A OUTPUT -j allowed-connection

  #Allow client to route through via NAT (Network Address Translation)
  $IPTABLES -t nat -A POSTROUTING -o $IINTERFACE -j MASQUERADE 
  eend $?
}

start() {
  ebegin "Starting firewall"
  if [ -e "${FIREWALL}" ]; then
    restore
  else
    einfo "${FIREWALL} does not exists. Using default rules."
    rules
  fi
  eend $?
}

stop() {
  ebegin "Stopping firewall"
  $IPTABLES -F
  $IPTABLES -t nat -F
  $IPTABLES -X
  $IPTABLES -P FORWARD ACCEPT
  $IPTABLES -P INPUT   ACCEPT
  $IPTABLES -P OUTPUT  ACCEPT
  eend $?
}

showstatus() {
  ebegin "Status"
  $IPTABLES -L -n -v --line-numbers
  einfo "NAT status"
  $IPTABLES -L -n -v --line-numbers -t nat
  eend $?
}

panic() {
  ebegin "Setting panic rules"
  $IPTABLES -F
  $IPTABLES -X
  $IPTABLES -t nat -F
  $IPTABLES -P FORWARD DROP
  $IPTABLES -P INPUT   DROP
  $IPTABLES -P OUTPUT  DROP
  $IPTABLES -A INPUT -i lo -j ACCEPT
  $IPTABLES -A OUTPUT -o lo -j ACCEPT
  eend $?
}

save() {
  ebegin "Saving Firewall rules"
  $IPTABLESSAVE > $FIREWALL
  eend $?
}

restore() {
  ebegin "Restoring Firewall rules"
  $IPTABLESRESTORE < $FIREWALL
  eend $?
}

restart() {
  svc_stop; svc_start
}

showoptions() {
  echo "Usage: $0 {start|save|restore|panic|stop|restart|showstatus}"
  echo "start)      will restore setting if exists else force rules"
  echo "stop)       delete all rules and set all to accept"
  echo "rules)      force settings of new rules"
  echo "save)       will store settings in ${FIREWALL}"
  echo "restore)    will restore settings from ${FIREWALL}"
  echo "showstatus) Shows the status" 
}

Бесплатные советы при создании брандмауэра:

  1. Продумайте политику брандмауэра перед ее воплощением
  2. Постарайтесь сохранить его простым
  3. Вы должны знать как работают протоколы (читайте RFC (Request For Comments))
  4. Помните что брандмауэр только часть ПО, которая запускается как root
  5. Тестируйте свой брандмауэр

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

Squid

Squid - очень мощный прокси сервер, который может фильтровать трафик по: времени, статическим выражениям в пути/URL, IP-адресу клиента/запрашиваемого сервера, домену, браузеру, имени пользователя, типу MIME и номеру порта (протокола). Вероятно я не указал всех возможностей, но это и не нужно.

В следующем примере я добавлю фильтр баннеров вместо фильтра порно-сайтов. Потому что Gentoo.org не должен быть в списках порно-сайтов. И я не хочу тратить время в поисках хороших сайтов для вас.

В этом случае моя политика такова:

Это реализуется в 4 простых шага.

Code Listing 12.6: /etc/squid/squid.conf

# Bind to a ip and port
http_port 10.0.2.1:3128

# Standard configuration
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
no_cache deny QUERY

# Add basic access control lists
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255

# Add who can access this proxy server
acl localnet src 10.0.0.0/255.255.0.0

# And ports
acl SSL_ports port 443
acl Safe_ports port 80
acl Safe_ports port 443
acl purge method PURGE

# Add access control list based on regular
# expressions within urls
acl archives urlpath_regex "/etc/squid/files.acl"
acl url_ads url_regex "/etc/squid/banner-ads.acl"

# Add access control list based on time and day
acl restricted_weekdays time MTWHF 8:00-17:00
acl restricted_weekends time A 8:00-13:00

acl CONNECT method CONNECT

#allow manager access from localhost
http_access allow manager localhost
http_access deny manager

# Only allow purge requests from localhost
http_access allow purge localhost
http_access deny purge

# Deny requests to unknown ports
http_access deny !Safe_ports

# Deny CONNECT to other than SSL ports
http_access deny CONNECT !SSL_ports

# My own rules

# Add a page do be displayed when
# a banner is removed
deny_info NOTE_ADS_FILTERED url_ads

# Then deny them
http_access deny url_ads

# Deny all archives
http_access deny archives

# Restrict access to work hours
http_access allow localnet restricted_weekdays
http_access allow localnet restricted_weekends

# Deny the rest
http_access deny all

Дальше заполним в files.acl какие файлы запрещены для скачивания. Я добавил zip, viv, exe, mp3, rar, ace, avi, mov, mpg, mpeg, au, ra, arj, tar, gz и z.

Code Listing 12.7: /etc/squid/files.acl

\.[Zz][Ii][pP]$
\.[Vv][Ii][Vv].*
\.[Ee][Xx][Ee]$
\.[Mm][Pp]3$
\.[Rr][Aa][Rr]$
\.[Aa][Cc][Ee]$
\.[Aa][Ss][Ff]$
\.[Aa][Vv][Ii]$
\.[Mm][Oo][Vv]$
\.[Mm][Pp][Gg]$
\.[Mm][Pp][Ee][Gg]$
\.[Aa][Uu]$
\.[Rr][Aa]$
\.[Aa][Rr][Jj]$
\.[Tt][Aa][Rr]$
\.[GgZz]$
\.[Zz]$

Note: Запомните - символы указанные в скобках [ ] заглавные и прописные, для того чтобы фильтр нельзя было обойти файлом с расширением например AvI вместо avi

Дальше мы зададим выражения для идентификации баннеров. Возможно воображение у вас будет лучше чем у меня:

Code Listing 12.8: /etc/squid/banner-ads.acl

/adv/.*\.gif$
/[Aa]ds/.*\.gif$
/[Aa]d[Pp]ix/
/[Aa]d[Ss]erver
/[Aa][Dd]/.*\.[GgJj][IiPp][FfGg]$
/[Bb]annerads/
/adbanner.*\.[GgJj][IiPp][FfGg]$
/images/ad/
/reklame/
/RealMedia/ads/.*
^http://www\.submit-it.*
^http://www\.eads.*
^http://ads\.
^http://ad\.
^http://ads02\.
^http://adaver.*\.
^http://adforce\.
adbot\.com
/ads/.*\.gif.*
_ad\..*cgi
/Banners/
/SmartBanner/
/Ads/Media/Images/
^http://static\.wired\.com/advertising/
^http://*\.dejanews\.com/ads/
^http://adfu\.blockstackers\.com/
^http://ads2\.zdnet\.com/adverts
^http://www2\.burstnet\.com/gifs/
^http://www.\.valueclick\.com/cgi-bin/cycle
^http://www\.altavista\.com/av/gifs/ie_horiz\.gif

В этой части мы хотим заменить баннер файлом. Обычно это html-файл с 4x4 прозрачным gif изображением.

Code Listing 12.9: /etc/squid/errors/NOTE_ADS_FILTERED

<HTML>
<HEAD>
<META HTTP-EQUIV="REFRESH" CONTENT="0; URL=http://www.insecurity.dk/images/4x4.gif">
<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
</HEAD>
<BODY>
<H1>Add filtered!</H1>

Note: Не закрывайте теги <HTML> <BODY> . Это сделает squid.

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

Но комбинирование пакетного фильтра (iptables) и прокси (squid) возможно лучшее решение, к тому же если squid находится в защищенном месте и к нему никто не имеет доступа снаружи. Нам все еще необходима защита от атак снаружи.

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

Note: В Мозилле это настраивается в Edit->Preferences->Advanced->Proxies.

Того же самого можно добиться если настроить iptables для прозрачного перенаправления всего исходящего трафика на squid. Это делается добавлением правила в iptables:

Code Listing 12.10: Разрещение portforwarding'a на наш прокси

# iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to proxyhost:3128
# iptables -t nat -A PREROUTING -p tcp --dport 443 -j DNAT --to proxyhost:3128

Что теперь мы знаем

Мы знаем следующее:

  1. Брандмауэр содержит потенциальную угрозу безопасности. Плохо настроенный брандмауэр может свести на нет все ваши меры безопасности.
  2. Как для начала настроить прокси
  3. Ключ к хорошему брандмауэру - знание работы протоколов которые вы хотите разрешить
  4. Что IP-трафик не всегда содержит легитимную информацию. ICMP-пакеты могут содержать полезную информацию о вашей сети.
  5. Как пресечь SYN-атаки
  6. Как фильтровать HTTP-трафик, удалять его содержимое.
  7. Комбинирование пакетного фильтра и прокси обеспечивает лучший контроль.

Теперь если вам действительно необходимо, вы сможете сделать такой брандмауэр какой вам нужен.

13. Детектирование атак

AIDE (Advanced Intrusion Detection Environment)

AIDE - это система обнаружения атак (бесплатная альтернатива Tripwire). Если вы уже знаете Tripwire у вас не должно возникнуть трудностей с изучением конфигурационных файлов AIDE.

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

Макрос Описание Синтаксис
ifdef если определен (If definded) @@ifdef "name"
ifndef Если не определен (If not defined) @@ifndef "name"
define Определение переменной (Define a variable) @@define "name" "value"
undef Присвоение переменной неопределенного значения (Undefine a variable) @@undef "name"
ifhost Если "имя хоста" (if "hostname") @@ifhost "hostname"
ifnhost Если не "имя хоста" (if not "hostname") @@ifnhost "hostname"
endif Endif нужно использовать после любых макросов исключая define и undef @@endif

Эти макросы очень часто используются, если вы имеете больше чем один хост с Gentoo и хотите использовать AIDE на всех. Но не на всех машинах работают одни и те же сервисы или даже пользователи.

Дальше мы настроим флаги и применим их к файлам и директориям. Это комбинация разрешений (permissions), свойств файлов и криптографические хеш/контрольных сумм.

Флаг описание
p разрешения (permissions)
i inode
n количество ссылок (number of links)
u пользователь (user)
g группа (group)
s размер (size)
b метка блока (block count)
m mtime
a atime
c ctime
S проверка растущего размер (check for growing size)
md5 контрольная сумма md5 (md5 checksum)
sha1 контрольная сумма sha1 (sha1 checksum)
rmd160 контрольная сумма rmd160 (rmd160 checksum)
tiger контрольная сумма tiger (tiger checksum)
R p+i+n+u+g+s+m+c+md5
L p+i+n+u+g
E Пустая группа (Empty group)
> Растущий лог файл p+u+g+i+n+S (Growing logfile p+u+g+i+n+S)

Если AIDE скомпилирован с поддержкой mhash он имеет несколько дополнительных возможностей:

Флаг Описание
haval Контрольная сумма haval (haval checksum)
gost Контрольная сумма gost (gost checksum)
crc32 Контрольная сумма crc32 (crc32 checksum)

Теперь мы можем создать наше правило из комбинации флагов указанных выше:

Code Listing 13.1: Создание набора правил для AIDE

All=R+a+sha1+rmd160
Norm=s+n+b+md5+sha1+rmd160

Последнее что нам надо сделать, чтобы создать наши конфигурационные файлы - это увидеть как добавить правило для файла или директории. Сначала вы набираете имя файла или директория и имя правила. AIDE добавит все файлы рекурсивно, если вы не укажите иного.

Флаг Описание
! Не добавлять этот файл или директорию.
= Добавить эту директорию, но не рекурсивно.

Давайте приведем полный пример:

Code Listing 13.2: /etc/aide/aide.conf

@@ifndef TOPDIR 
@@define TOPDIR /
@@endif

@@ifndef AIDEDIR 
@@define AIDEDIR /etc/aide
@@endif

@@ifhost smbserv
@@define smbactive
@@endif

# The location of the database to be read.
database=file:@@{AIDEDIR}/aide.db

# The location of the database to be written.
database_out=file:aide.db.new

verbose=20
report_url=stdout

# Rule definition
All=R+a+sha1+rmd160
Norm=s+n+b+md5+sha1+rmd160

@@{TOPDIR} Norm
!@@{TOPDIR}etc/aide
!@@{TOPDIR}dev
!@@{TOPDIR}proc
!@@{TOPDIR}root
!@@{TOPDIR}tmp
!@@{TOPDIR}var/log
!@@{TOPDIR}var/run
!@@{TOPDIR}usr/portage
@@ifdef smbactive
!@@{TOPDIR}etc/smb/private/secrets.tdb
@@endif
=@@{TOPDIR}home Norm

В выше приведенном примере вместе с некоторыми макросами мы указали где начинаются главные каталоги (topdir) и расположение директории AIDE. AIDE проверяет /etc/aide/aide.db при проверке файлов на целостность. Но при обновлении или создании новых файлов он сохраняет информацию в файле /etc/aide/aide.db.new. Это сделано для того, чтобы автоматически не перезаписать старый db файл. Опция report_URL пока не работает. Но авторы намерены реализовать возможность предупреждения по email или возможно исполнение скрипта.

После исправления конфигурационных файлов вы должны создать ваш db файл путем исполнения aide -i и потом скопировать файл /etc/aide/aide.db.new в /etc/aide/aide.db и добавить проверку по крону с помощью команды crontab -e выполненной как root.

Note: Также зависит от вашего процессора, дисков и флагов которых вы установили в файлах, сколько это займет времени.

Code Listing 13.3: Задания расписания aide как cronjob

0 3   * * * /usr/bin/aide -u

Note: Не забудьте настроить получение почты root. Иначе вы не сможете узнать, о сообщениях aide.

Так aide будет запускаться раз в день в 3 часа ночи. Это сделано для того, чтобы не мешать пользователям если они работают. Здесь я использовал опцию -u (обновление) вместо -C (проверка). Потому что -u также проверяет файлы, но не перезаписывает db файл, так как вы можете сделать это сами если он обнаружит какие-то изменения. Просто проверьте перед копированием изменения обнаруженные, на предмет - это сделали вы или атакующий.

Дальше, есть некoторые проблемы при хранении db файла локально, атакующий может (если знает что установлен aide) попробовать изменить db файл, обновить его или изменить /usr/bin/aide. Поэтому вы должны создать CD или другой носитель и скопировать на него .db файл, и бинарные файлы aide.

Информацию вы можете найти здесь - AIDE.

Snort

Snort - это сетевая система обнаружения атак (Network Intrusion Detection System, NIDS). Для установки и настройки настройки смотрите пример ниже.

Code Listing 13.4: Добавление пользователя snort в систему

# useradd snort -d /var/log/snort -s /dev/null
# chown -R snort /var/log/snort

Code Listing 13.5: /etc/conf.d/snort

PIDFILE=/var/run/snort_eth0.pid
MODE="full"
NETWORK="10.0.0.0/24"
LOGDIR="/var/log/snort"
CONF=/etc/snort/snort.conf
SNORT_OPTS="-D -s -u snort -dev -l $LOGDIR -h $NETWORK -c $CONF"

Code Listing 13.6: /etc/snort/snort.conf

(Шаг 1)
var HOME_NET 10.0.0.0/24
var EXTERNAL_NET any
var SMTP $HOME_NET
var HTTP_SERVERS $HOME_NET
var SQL_SERVERS $HOME_NET
var DNS_SERVERS [10.0.0.2/32,212.242.40.51/32]
var RULE_PATH ./

(Шаг 2)
preprocessor frag2
preprocessor stream4: detect_scans detect_state_problems detect_scans disable_evasion_alerts
preprocessor stream4_reassemble: ports all
preprocessor http_decode: 80 8080 unicode iis_alt_unicode double_encode iis_flip_slash full_whitespace
preprocessor rpc_decode: 111 32771
preprocessor bo: -nobrute
preprocessor telnet_decode

(Шаг 3)
include classification.config

(Шаг 4)
include $RULE_PATH/bad-traffic.rules
include $RULE_PATH/exploit.rules
include $RULE_PATH/scan.rules
include $RULE_PATH/finger.rules
include $RULE_PATH/ftp.rules
include $RULE_PATH/telnet.rules
include $RULE_PATH/smtp.rules
include $RULE_PATH/rpc.rules
include $RULE_PATH/rservices.rules
include $RULE_PATH/dos.rules
include $RULE_PATH/ddos.rules
include $RULE_PATH/dns.rules
include $RULE_PATH/tftp.rules
include $RULE_PATH/web-cgi.rules
include $RULE_PATH/web-coldfusion.rules
include $RULE_PATH/web-iis.rules
include $RULE_PATH/web-frontpage.rules
include $RULE_PATH/web-misc.rules
include $RULE_PATH/web-attacks.rules
include $RULE_PATH/sql.rules
include $RULE_PATH/x11.rules
include $RULE_PATH/icmp.rules
include $RULE_PATH/netbios.rules
include $RULE_PATH/misc.rules
include $RULE_PATH/attack-responses.rules
include $RULE_PATH/backdoor.rules
include $RULE_PATH/shellcode.rules
include $RULE_PATH/policy.rules
include $RULE_PATH/porn.rules
include $RULE_PATH/info.rules
include $RULE_PATH/icmp-info.rules
include $RULE_PATH/virus.rules
# include $RULE_PATH/experimental.rules
include $RULE_PATH/local.rules

Code Listing 13.7: /etc/snort/classification.config

config classification: not-suspicious,Not Suspicious Traffic,3
config classification: unknown,Unknown Traffic,3
config classification: bad-unknown,Potentially Bad Traffic, 2
config classification: attempted-recon,Attempted Information Leak,2
config classification: successful-recon-limited,Information Leak,2
config classification: successful-recon-largescale,Large Scale Information Leak,2
config classification: attempted-dos,Attempted Denial of Service,2
config classification: successful-dos,Denial of Service,2
config classification: attempted-user,Attempted User Privilege Gain,1
config classification: unsuccessful-user,Unsuccessful User Privilege Gain,1
config classification: successful-user,Successful User Privilege Gain,1
config classification: attempted-admin,Attempted Administrator Privilege Gain,1
config classification: successful-admin,Successful Administrator Privilege Gain,1

# NEW CLASSIFICATIONS
config classification: rpc-portmap-decode,Decode of an RPC Query,2
config classification: shellcode-detect,Executable code was detected,1
config classification: string-detect,A suspicious string was detected,3
config classification: suspicious-filename-detect,A suspicious filename was detected,2
config classification: suspicious-login,An attempted login using a suspicious username was detected,2
config classification: system-call-detect,A system call was detected,2
config classification: tcp-connection,A TCP connection was detected,4
config classification: trojan-activity,A Network Trojan was detected, 1
config classification: unusual-client-port-connection,A client was using an unusual port,2
config classification: network-scan,Detection of a Network Scan,3
config classification: denial-of-service,Detection of a Denial of Service Attack,2
config classification: non-standard-protocol,Detection of a non-standard protocol or event,2
config classification: protocol-command-decode,Generic Protocol Command Decode,3
config classification: web-application-activity,access to a potentially vulnerable web application,2
config classification: web-application-attack,Web Application Attack,1
config classification: misc-activity,Misc activity,3
config classification: misc-attack,Misc Attack,2
config classification: icmp-event,Generic ICMP event,3
config classification: kickass-porn,SCORE! Get the lotion!,1

Больше информации вы можете найти здесь - Snort.