Как сделать систему FreeBSD более безопасной

FreeBSD - достаточно безопасная операционная система.

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

Кто должен читать этот документ?

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

Организация сети

inetd (Inet Демон)

Организация сети играет очень важную роль в общей системной безопасности. FreeBSD базируется на 4.4BSD, в которой встроена поддержка сети и действительно имеет один из наиболее мощных и быстрых TCP/IP стеков. Стек обеспечивает поддержку многих протоколов таких как telnet, ftp, talk, rsh, и т.п.

Основной файл конфигурации находится в /etc и называется inetd.conf.

Я буду использовать редактор vi в этих примерах.

Когда Вы откроете файл в редакторе, Вы увидите простой текст ASCII, который сообщает inetd как запускать тот или иной сервис, от имени какого пользователя запускается данный сервис и т.п. (смотрите man 5 inetd.conf).

Поскольку этот файл - основной файл, который запускает все сетевые сервисы, очень важно правильно его сконфигурировать. Чтобы выключить сервис, Вы должны установить "#" в начале строки. Вообще, размещение "#" в начале строки в любом из конфигурационных файлов UNIX-систем, исключает эту строку.

Основной практический метод: выключить сервисы, с которыми Вы незнакомы. В идеале, в inetd.conf может и не быть ни одной записи.

Небольшой пример:

Вы делаете web-сервер, т.е. Вам достаточно выполнять на этой машине 2 сервиса: ssh и httpd, и НИЧЕГО БОЛЕЕ.

Информация о ssh следует ниже.

Если Вы решите не использовать демонов в файле inetd.conf, то, Вы можете просто выключить inetd. Для того, чтобы cделать это, отредактируйте /etc/rc.conf файл и измените:

inetd_enable="YES"

на

inetd_enable="NO"

В этом случае никто не сможет использовать telnet, rlogin или ftp для доступа к вашему компьютеру.

Если Вы хотите использовать inetd, рассмотрите возможность использования tcp wrappers. Более подробную информацию Вы можете найти на ftp://ftp.win.tue.nl/pub/security/index.html#software

Если Вы решили оставить inetd, регистрируйте и по мере надобности увеличивайте количество соединений в одну минуту (по умолчанию - 256, я рекомендую 1024 - установите это значение как посчитаете нужным).

Небольшое дополнение: если у Вас "медленное" соединение (например, модем), это неважно, но если у вас быстрое соединение (64k), этим параметром могут воспользоваться для создания атаки DoS (Denied of Service). Злоумышленник может создать простой shell-сценарий, чтобы спровоцировать более 256 соединений с вашим компьютером, которые заставят inetd отключить этот сервис. С другой стороны, если Вы хотите поддержать одновременно 1024 соединений - Вы должны правильно сконфигурировать inetd, в противном случае кто-нибудь может также вызвать DoS (Denied of Service) и повредить ваш компьютер. Следовательно, конфигурационный файл /etc/rc.conf должен содержать следующее:

inetd_enable="YES"

inetd_flags="-l -R 1024"

это включит регистрацию (ключ -l) и максимальное количество будет увеличено до 1024.

Вам также следует изменить ваш файл /etc/syslog.conf в директории /etc, но об этом мы поговорим позже, при рассмотрении syslogd.

SSH (Secure SHell)

Я упомянул выше, что в некоторых случаях Вы, возможно, не будете выполнять inetd.

Например, если Вы поддерживаете Web, News или NFS, нет необходимости включать другие сервисы на машине. "Как же мне управлять моей машиной?" - спросите Вы. Ответ: SSH. Вы можете войти в систему, используя SSH (Secure Shell).

Secure Shell был разработан как альтернатива rsh, rlogin и других Berkeley r* команд, но SSH можно использовать и вместо таких приложений как telnet и ftp. У SSH много характеристик, но его по большей части используют для шифрования соединения, чтобы предохранить явные текстовые пароли и остальную часть данных, путешествующие в "чистом виде". Если Вы используете telnet, ваше соединение может было подсмотрено. (Если Вы думаете, что S/Key является решением, то должен Вас огорчить: в этой реализации все еще существуют проблемы вставки данных и захвата соединения.)

Я надеюсь, что теперь Вы созрели, для того, чтобы выключить inetd полностью и установить SSH. Если Вы думаете, что не сможете жить без услуг предусмотренных inetd, тогда, по крайней мере, включите регистрацию (логирование) и увеличьте до максимума количество соединений в минуту.

Загрузить SSH можно с ftp://ftp.funet.fi/pub/unix/security/login/ssh или (что проще):

# cd /usr/порты/security/ssh

# make install

Если у Вас есть не-Unix клиенты, то для Windows SSH можно получить здесь:

http://fox.doc.ic.ac.uk/~ci2/ssh/

http://www.zip.com.au/~roca/ttssh.html

SecureCRT от http://www.vandyke.com

Inetd (часть II)

telnetd

Итак, Вы все еще хотите использовать inetd.

Давайте посмотрим на опции в inetd.conf, которые помогут сделать услуги более безопасными.

Нападающий сначала соберет информацию о сети или системе, которую он собирается атаковать. Первое, что Вы можете сделать, чтобы предохранить себя от взлома, добавить ключ "-h" для telnet демона:

telnet stream tcp nowait root /usr/libexec/telnetd telnetd -h

Что написано в манах ???

#man telnetd

......

-h Не выводить специфической информации о машине прежде, чем вход в систему будет завершен.

......

Пока есть много других путей для того, чтобы собрать системную информацию. Если Вы не хотите запускать telnet демон совсем, просто добавьте "#" в начале строки:

#telnet stream tcp nowait root /usr/libexec/telnetd telnetd

Дополнительно можно добавить ключ "-U" для telnet демон, который устанавливает соединение, только в случае если об этом хосте есть запись в DNS:

telnet stream tcp nowait root /usr/libexec/telnetd telnetd -h -U

Это немного поможет увеличить общую безопасность вашей системы.

ftpd

Теперь давайте посмотрим на ftpd.

У FreeBSD есть демон ftp сконфигурированный таким образом, чтобы делать некоторую регистрацию (логирование). Вы увидите, что ftpd запускается с ключом "-l" из inetd.conf. Вам также следует сконфигурировать ваш syslogd (syslog демон), чтобы обеспечить поддержку для протокола сгенерированного демоном ftp.

Что написано в манах?

# man ftpd

.....

-l Каждый сеанс ftp(1) зарегистрирован используя syslog со средством LOG_FTP.

Если эта опция определена дважды, то: retrieve (get), send (put),

append, delete, make directory, remove directory, а также операции переименовывания

и их аргументы будут зарегистрированы !!!.

Примечание: по умолчанию, сообщения LOG_FTP не отображаются syslogd(8)...

.....

Разрешим ftpd протоколировать свои действия. В файл /etc/syslog.conf (также `man 5 syslog.conf`) добавьте следующую строку:

ftp.* /var/log/ftpd

Запустите команду

# touch /var/log/ftpd

т.к. syslogd не может создавать файлы.

Не забывайте добавлять имя нового log-файла в другой конфигурационный файл /etc/newsyslog.conf, чтобы заставить демон периодически менять файлы.

Если Вы хотите увидеть более подробную информацию о вашем демоне ftp, просто добавьте еще один символ "-l" в строку ftp в /etc/inetd.conf:

ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l -l

Вместо стандартного UNIX-протокола ftp следует использовать команду scp (Secure Copy, которая является частью пакета SSH), но если Вы все еще хотите оставить анонимный доступ ftp, запустите ваш демон ftp с ключем "-A":

ftp stream tcp nowait root /usr/libexec/ftpd ftpd -l -A

Вы можете также отредактировать /etc/ftpwelcome, чтобы предупредить о том, что ftpd допускает только анонимные соединения и, что зарегистрированные пользователи должны использовать scp вместо ftp. Если Вы разрешите анонимный доступ по ftp, то, следует использовать ключ -S, для того, чтобы регистрировать анонимные соединения по ftp:

ftp stream tcp nowait root /usr/libexec/ftpd ftpd -A -S

fingerd

Сервис finger поставляется сконфигурированным по умолчанию: он не допускает запросы без имени пользователя. И это правильно. Если вы хотите отказаться от выполнения услуги finger, установите комментарий (символ "#" в начале строки). Если Вы хотите выполнять сервис finger, разрешите регистрацию добавив ключ "-l":

finger stream tcp nowait nobody /usr/libexec/fingerd fingerd -s -l

Протоколы от fingerd по умолчанию поступают в /var/log/messages. Если Вы хотите иметь протокол демона finger в другом файле, добавьте следующую строку к вашему /etc/syslog.conf файлу:

daemon.notice /var/log/fingerd

Что в манах???

$ man 5 syslog.conf

Я обычно запрещаю выполнение talk и comsat, а также другие сервисы, которые мне лично не нужны. Как я говорил ранее, если вы не знаете что делает тот или иной сервис, или он Вам не нужен - отключайте его выполнение.

Некоторые маны, в которых Вы могли найти полезную и имеющую отношение к сетевой конфигурации:

inetd, ftpd, telnetd, fingerd, syslogd, comsat, talkd, rshd, rlogind, и inetd.conf.

Смотрите также на ссылки ("SEE ALSO") указанные на этих страницах.

ipfw (IP FireWall)

IP Firewall фильтрует пакеты: ни больше, ни меньше.

Тем не менее, Вы должны рассмотреть поддержку ipfw в ядре. Я обычно компилирую поддержку для ipfw в большинстве своих машинах, и в большинстве моих ядер config выглядит приблизительно так:

options IPFIREWALL #finger

options IPFIREWALL_VERBOSE #log

options IPFIREWALL_DEFAULT_TO_ACCEPT

Первая строка включает в ядро основную IP Firewall поддержку.

Вторая строка конфигурирует ipfw, чтобы зарегистрировать принятые или отвергнутые пакеты.

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

Примечание.

ИСКЛЮЧИТЕ ОПЦИЮ ЕСЛИ ВЫ НЕ ЗНАЕТЕ ЧТО ИЛИ НЕ ПОНИМАЕТЕ ЧТО ДЕЛАЕТЕ!!! Это неправильный метод конфигурирования firewall'а. Все пакеты должны быть отвергнуты по умолчанию. НЕ добавляйте опцию IPFIREWALL_DEFAULT_TO_ACCEPT, если Вы строите безопасную систему или firewall. Убедитесь, что сначала все пакеты отвергнуты по умолчанию, а только после используйте правила дополнения, чтобы допустить соединения/пакеты. Смотрите /etc/rc.firewall для более подробной информации.

Небольшое обозрение по /etc/rc.firewall и примерные файлы конфигурации, а также схему установки firewall'а - смотрите URL внизу страницы.

log_in_vain

Вы можете также изменить некоторые полезные переменные ядра через команду sysctl:

# sysctl -w net.inet.tcp.log_in_vain=1

# sysctl -w net.inet.udp.log_in_vain=1

Это обеспечит Ваc регистрацией предпринимаемых соединений, которые сервер не умеет выполнять.

Например, если у Вас нет DNS-сервера на вашем компьютере, а кто-то пытается использовать ваш компьютер как DNS, Вы увидите нижеследующее сообщение:

Connection attempt UDP yourIP:53 from otherIP:X (где X - некоторый порт >1023)

Это сообщение можно увидеть с помощью команды

# dmesg

dmesg показывает системный буфер сообщений ядра. Но в буфере содержится небольшое количество сообщений. Эти же сообщения регистрируются в /var/log/messages

# tail -1 /var/log/messages

Jun 12 19:36:03 machi /kernel: Connection attempt UDP yourIP:53 from otherIP:X

Заключение

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

$ netstat -na | grep LISTEN

эта команда сообщит Вам какие порты имеют сервисы, ждущие соединение. Чем меньше - тем лучше :) Тот, кто будет выполнять сканирование портов, чтобы обнаружить какие порты у вас открыты - увидит то же самое. Также убедитесь, что syslog действительно регистрирует сообщения:

# cd /var/протокол

# tail -10 fingerd ftpd messages

Если Вы не видите что-либо в ваших протоколах, убедитесь, что, Вы перезапустили inetd и syslogd процессы:

# kill -HUP `cat /var/run/syslog.pig` `cat /var/run/inetd.pid`

Файловые системы

Поскольку в UNIX все считается файлом, очень важно правильно защищать ваши файловые системы. Этот процесс начинается прежде, чем установка самой OS: Вам нужно вычислить и разбить жесткий диск на разделы.

О чем стоит задуматься и что Вы должны знать?

Первое. Вы можете монтировать разные файловые системы разными параметрами. (некоторые примеры ниже).

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

Если Вы пришли из Linux-мира, обратите внимание, что пока Linux устанавливает всю ОС на один корневой раздел "/", FreeBSD по умолчанию делает установку в три файловых системы "/", "/usr" и "/var". Это облегчает использование некоторых программ (например, команда dump).

Есть некоторые преимущества и в безопасности.

Одна из таких вещей, которые я обычно делаю - разделение разделов на области, где пользователи имеют право писать и области, где пользователи не имеют право писать. Области, где пользователи имеют право писать, следует смонтировать с опцией "nosuid". Итак, Вы должны иметь один раздел для директорий пользователей: /home или /usr/home. Также Вы можете создать отдельный раздел для /var/tmp, а после указать ваш /tmp на этот раздел:

# rm -rf /tmp

# ln -s /var/tmp /tmp

Например, Вы можете сделать следующее:

# cat /etc/fstab

# Device Mountpoint FStype Options Dump Pass

#

/dev/sd0s1b none swap sw 0 0

/dev/sd0s1a / ufs rw 1 1

/dev/sd0s1g /usr ufs rw 2 2

/dev/sd0s1h /usr/home ufs rw,nosuid 2 2

/dev/sd0s1f /var ufs rw 2 2

/dev/sd0s1e /var/tmp ufs rw,nosuid 2 2

proc /proc procfs rw 0 0

Вам следует убедиться, что все директории, где пользователи могут писать, или установлены в "nosuid", или с помощью chmod в такое положение, что пользователи ничего не смогут написать. По умолчанию во FreeBSD это можно сделать с /var/spool/uucppublic или Вы можете установить вашу файловую систему "/var" в положение "-nosuid".

# chmod o-w /var/spool/uucppublic

Если Вы хотите найти все ваши директории исполнительного листа, выпустите:

# find / -perm -0777 -type d -ls

Как обнаружить какие файлы устанавливаются в вашей системе как suid или guid? Поищем с помощью find(1):

# find / -perm -2000 -ls

# find / -perm -4000 -ls

Вы можете не использовать ключ "-ls" для более компактного вывода. Один из самых простых способов - сделать "chmod 000" на тех бинарных файлах, которые никогда не будете использовать. Обычно это касается uustat, uucico (если Вы никогда не будете пользоваться uucp). Это касается и ppp, и pppd в том случае, если Вы не собираетесь использовать на этой машине PPP. Если Вы не собираетесь печатать с этой машины или на эту машину, Вы можете установить "chmod 000" на lpr, lprq, lprm. Здесь Вы можете спросить: что может остановить хакера от простого демонтирования и последующего монтирования без флага "-nosuid"? Да, ничто, пока Вы не измените securelevel.

Securelevel

Ядро BSD имеет такое понятие, как securelevel. Пока некоторые спорят о том, правильно это или нет, следует применять это или нет, попробуем разобраться в чем тут дело. Securelevel - это уровень защиты, с которым выполняется ядро. Разные уровни подразумевают под собой разные методы проверки защиты системы. Очень туманно...

# man 8 init

Ядро работает с четырьмя другими уровнями безопасности.

Любой процесс суперпользователя может поднять уровень безопасности,

но только init может уменьшить его. Уровни безопасности:

-1 Всегда небезопасный режим. Запускайте систему на уровне 0.

0 Небезопасный режим. Флаги неизменения и добавления могут быть выключены.

Со всеми устройствами можно производить операции записи и чтения, основываясь

на разрешениях.

1 Безопасный режим. Система неизменна и флаги системного добавления не

могут быть выключены; диски для монтирования файловых систем, устройства /dev/mem,

и /dev/kmem не могут быть открыты для записи.

2 Очень безопасный режим. То же, что и безопасный режим. Дополнение: диски не могут

открываться для записи (исключая команду mount(2)) вне зависимости от

от того смонтированы они или нет.

Этот уровень предотвращает подделку файловых систем демонтируя их,

но и предотвращает запуск newfs(8), пока система находится в многопользовательском режиме.

3 Режим сетевой безопасности. То же, что и очень безопасный режим, плюс правила

фильтрования IP-пакетов (смотрите ipfw(8) и ipfirewall(4)) не могут быть изменены

и конфигурация dummynet(4) не может быть перестроена.

Если уровень безопасности первоначально -1, то init оставит это неизменным.

В противном случае, init размещает, чтобы выполнять систему на уровне 0

в однопользовательском режиме и уровне 1 для многопользовательского

режима. Если Вам нужен уровень 2 - то его можно установить в

однопользовательском режиме, например, в сценарии запуска /etc/rc,

используя sysctl(8).

Например, если ваша система - Web-сервер, Вы можете благополучно установить ваш securelevel равный 2. Но, если Вы запускаете X-сервер, установка securelevel на 1 или выше могут вызвать проблемы, поскольку X-серверу требуется открывать /dev/mem и /dev/kmem для записи, а securelevel 1 запрещает выполнять эти операции. Правда можно сделать и так: установить ваш securelevel после того, как Вы запустили X-сервер, но если Вы запустили X-сервер, у вас уже есть другие серьезные вопросы по безопасности, нежели беспокойство о securelevel. Узнаем об установленном securelevel:

# sysctl kern.securelevel,

чтобы поднять ваш securelevel:

# sysctl -w kern.securelevel=X

где X - 0, 1 или 2.

У Вас могут возникать проблемы, если Вы модернизируете вашу систему с помощью "make world" или если Вы пересобираете ядро, при работе с securelevel 1 или выше. Дело в том, что по умолчанию "make install" установит ваше ядро с системным неизменным флагом:

# ls -lo /kernel

-r-xr-xr-x 1 root wheel schg 1061679 Июня 30 01:27 /kernel

Это "schg" предохраняет Ваше ядро:

# id

uid=0(root) gid=0(wheel) groups=0(wheel), 2(kmem)

# sysctl kern.securelevel

kern.securelevel: 2

# rm -rf /kernel rm: /kernel: Operation not permitted

# mv /kernel /tmp/

mv: rename /kernel в /tmp/kernel: Operation not permitted

Если Вы работаете в securelevel 1 или 2, этот флаг не может быть выключен:

# chflags noschg /kernel

chflags: /kernel: Operation not permitted

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

# touch /boot.config

# chflags schg /boot.config

По умолчанию, в вашей системе будут присутствовать некоторые двоичные файлы с включенным schg флагом:

# ls -lo /sbin | grep schg

-r-x------ 1 bin bin schg 204800 Июля 19 20:38 init

# ls -lo /bin | grep schg

-r-sr-xr-x 1 root bin schg 192512 Июля 19 20:36 rcp

Поскольку мы поговорили о системных неизменных флагах, можно рассмотреть случай выполнения chflags schg на поддеревьях /sbin и /bin. Это сделает более трудным доступ к "черным ходам" в вашей системе (особенно при использовании securelevel).

# chflags schg /bin/*

# chflags schg /sbin/*

Поскольку /sbin может быть перемещен и после этого создан новый /sbin, следует провести туже самую операцию над каталогами:

# chflags schg /bin; chflags schg /sbin

Помните! Если вы сделали достаточно много изменений на файловых флагах - это обязательно, в свою очередь, повлечет за собой проблемы при "make world". В этом случае можно предложить сделать "make world" в однопользовательском режиме. Дополнительную информацию о "make world" можно прочитать здесь:

http://www.nothing-going-on.demon.co.uk/FreeBSD/make-world/make-world.html

Маны, связанные с вышеуказанными темами: init(8), chflags(1), sysctl(8)

Обновлено: 12.03.2015