Собрание статей и заметок преимущественно по администрированию операционных систем Linux и Windows (но не только). Цель - собрать в одном месте полезное и интересное, что то вроде записной книжки. Большая часть скопирована целиком или скомпилирована из найденного в интернете, и я никоим образом не предендую на авторство, которое мне не принадлежит, чукча не писатель, чукча читатель. Некоторые же статейки - написаны мной, в качестве шпаргалок по мотивам прохождения некоторых квестов.
Настройка PPPoE с шейпингом трафика для небольшой сети
Однажды возникла задача настроить раздачу интернета на пару десятков компьютеров (офисные и домашние). Коробочные решения оказались либо платными, либо достаточно сложно настраиваемыми, поэтому было принято решение использовать собственное на базе Debian Linux. Опытом его поднятия я хочу поделиться с вами в этом посте, но приведенные здесь версии могли немного устареть с момента написания мануала «для себя», так что нужно проявить некоторую внимательность. Также, нужно учитывать, что приведенное решение далеко от идеального и профессионального. Оно поможет скорее тем, кому нужно быстро поднять у себя сервер, раздающий интернет. В конце у нас будет раздача интернета через PPPoE с назначением внутренних IP клиентам, шейпинг трафика, DNS сервер и простой мониторинг текущих сессий из консоли.
Выполняем nano /etc/bind/named.conf.options Добавляем в конец файла: allow-transfer { none; };
allow-query { 10.128.0.0/16; localhost; }; //подсеть наших пользователей
allow-recursion { 10.128.0.0/16; localhost; }; //рекурсия только локальным
version "My ISP DNS"; //скрыли информацию о версии сервера Начнем настраивать chroot-окружение для нашего сервера DNS. Создадим каталоги корневой файловой системы сервера DNS — root-dns: mkdir -p /root-dns/etc
mkdir /root-dns/dev
mkdir -p /root-dns/var/cache/bind
mkdir -p /root-dns/var/run/bind/run
/etc/init.d/bind9 stop
nano /etc/default/bind9 Нашли строчку «OPTIONS=» и заменили: OPTIONS="-u bind -t /root-dns" mv /etc/bind /root-dns/etc
ln -s /root-dns/etc/bind /etc/bind
nano /etc/init.d/bind9 Нашли строчку «OPTIONS=» и заменили: OPTIONS="-u bind -t /root-dns" Запускаем: nano /etc/init.d/rsyslogd Нашли «RSYSLOGD_OPTIONS» и заменили: RSYSLOGD_OPTIONS="-c3 -a /root-dns/dev/log" Защитим от редактирования и удаления файл конфигурации named.conf: chattr +i /root-dns/etc/bind/named.conf Примечание. Не забудьте снять атрибут «i» перед редактированием файла конфигурации (chattr -i …) mknod /root-dns/dev/null c 1 3
mknod /root-dns/dev/random c 1 8
chmod 666 /root-dns/dev/null /root-dns/dev/random
chown -R bind:bind /root-dns/var/*
chown -R bind:bind /root-dns/etc/bind
/etc/init.d/bind9 start
Сервер PPPoE
cd /tmp
apt-get build-dep pppoe
apt-get source pppoe
cd rp-pppoe-3.8/src
./configure Запускаем: nano config.h Теперь в только что созданном файле config.h нужно заменить строчку: /* #undef HAVE_LINUX_KERNEL_PPPOE */ на строчку: #define HAVE_LINUX_KERNEL_PPPOE 1 Выполняем: cd ..
./debian/rules PLUGIN_PATH=/usr/lib/pppd/2.4.4/rp-pppoe.so
./debian/rules binary
cd ..
dpkg -i pppoe_3.8-3_i386.deb Заморозим пакет в системе, чтобы предотвратить его автоматическое обновление: echo pppoe hold | dpkg —set-selections С этого момента нужно как минимум при каждом обновлении системы просматривать список обновлений. Если для pppoe будет выпущено обновление, закрывающее уязвимость, необходимо будет собрать пакет из свежих исходников заново, снять фиксацию пакета в системе с помощью команды: echo pppoe install | dpkg --set-selections Теперь в системе установлен пакет с PPPoE-сервером, позволяющим поддерживать PPPoE-соединения на уровне ядра. Для запуска сервера в этом режиме, к команде описанной в предыдущем разделе нужно добавить опцию -k: pppoe-server -I eth1 -L 192.168.0.1 -k Запускаем: nano /etc/ppp/pppoe-server-options Вставляем: logfile /var/log/pppoe.log
debug
mtu 1472
mru 1472
auth
require-pap
#require-chap
default-asyncmap
ktune
lcp-echo-interval 20
lcp-echo-failure 2
ms-dns 10.128.0.1
plugin radius.so
plugin radattr.so
10.128.0.1:
nobsdcomp
noccp
noendpoint
noipdefault
noipx
novj
receive-all Запускаем: nano /etc/ppp/options В конфиге /etc/ppp/options: убираем всё, ставим: lock Запускаем: nano /etc/init.d/pppoe-server Скрипт: #!/bin/bash
# init file for rp-pppoe server
#
# description: PPPOE kernel mode server
#
# processname: pppoe-server
# chkconfig: - 45 45
# source function library
#. /etc/rc.status
case "$1" in
start)
echo -n "Starting PPPOE server: "
/usr/sbin/pppoe-server -I eth0 -L 10.128.0.1 -R 10.128.1.1 -k
#Здесь eth0 — интерфейс, который смотрит в локальную сеть
#10.128.0.1 - IP PPPoE сервера
#10.128.1.1 - Первый IP адрес клиента
#touch /var/lock/subsys/pppoed
#rc_status -v
;;
stop)
echo -n "Shutting down PPPOE server: "
pkill pppoe-server
#rm -f /var/lock/subsys/pppoed
#rc_status -v
;;
restart)
$0 stop
$0 start
;;
status)
status pppoe-server
;;
*)
echo "Usage: pppoed {start|stop|restart|status}"
exit 1
esac
exit 0 Запускаем: rcconf Отключаем bind. Потом туда опять заходим и видим что он вообще исчез из списка. Внизу он таки есть, а рядом наш pppoe-server. Включили и то и то. Вышли. cd /root-dns/etc/bind
rndc-confgen -r /dev/urandom -a
chgrp bind rndc.key
chmod +r rndc.key
nano named.conf.options В конце файла добавляем: controls {
inet 127.0.0.1 allow { localhost; } keys { rndc-key; };
};
include "/etc/bind/rndc.key"; Теперь ещё нужно включить форвардинг в ядре и сделать подхват правил iptables. Конфигурация пока будет тестовой.
Запускаем: nano /etc/sysctl.conf Раскомментировали, добавили чего небыло: net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.tcp_syncookies=1
net.ipv4.ip_forward=1
kernel.panic = 1
kernel.panic_on_oops = 1
kernel.panic_on_io_nmi = 1
kernel.panic_on_unrecovered_nmi = 1 Последние 4 строчки — это перезагрузка при различных падениях системы, чтобы не ездить ради перезагрузки куда-то в другой город. Сохранили, далее делаем тестовый конфиг для iptables: iptables -t nat -F
iptables-save > /etc/firewall.conf
nano rc.local Теперь в rc.local у нас будет: ifconfig eth0 up
iptables-restore </etc/firewall.conf Далее, конфигурируем /etc/network/interfaces — тут eth0 получился локальным, для него ничего вообще не пишем, разве что auto eth0. А по поводу eth1 — если это интернет — я бы задумался о статическом внешнем айпи, в противном случае нельзя использовать SNAT, а только MASQUERADE, а он сильнее грузит систему. Запускаем: nano /etc/network/interfaces Конфиг: auto lo
iface lo inet loopback
auto eth0
auto eth1
allow-hotplug eth0 eth1
iface eth1 inet dhcp В данном листинге eth1 — интернет через NAT и DHCP конфиг.
Пробный запуск сервера PPPoE
Далее надо протестировать PPPoE без радиуса. Для этого комментируем 2 строчки плагинов в /etc/ppp/pppoe-server-options. Запускаем: nano /etc/ppp/pppoe-server-options Конфиг: #plugin radius.so
#plugin radattr.so Запускаем: nano /etc/ppp/pap-secrets Дописываем в конец либо заменяем полностью содержимое: test * test 10.128.2.10 Запускаем pppoe-server: /etc/init.d/pppoe-server start Перезагрузили сервер, проверили PPPoE и инет. На любом клиенте создаем PPPoE соединение и подключаемся, используя логин и пароль test. Для того чтобы инет работал у клиента, нужно включить маскарадинг: iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE Работает? Хорошо, вернули как было: iptables -t nat -F
FreeRadius
Запускаем: nano /etc/radiusclient/servers Заменяем содержимое файла: 127.0.0.1 my-isp-radius Запускаем: nano /etc/radiusclient/radiusclient.conf Заменяем содержимое файла: auth_order radius,local
login_tries 4
login_timeout 60
nologin /etc/nologin
issue /etc/radiusclient/issue
# RADIUS settings
authserver localhost:1812
acctserver localhost:1812
servers /etc/radiusclient/servers
dictionary /etc/radiusclient/dictionary
login_radius /usr/sbin/login.radius
# RADIUS server
seqfile /var/run/radius.seq
mapfile /etc/radiusclient/port-id-map
default_realm
radius_timeout 10
radius_retries 3
login_local /bin/login Запускаем: nano /etc/freeradius/radiusd.conf Заменяем содержимое файла: prefix = /usr
exec_prefix = /usr
sysconfdir = /etc
localstatedir = /var
sbindir = ${exec_prefix}/sbin
logdir = /var/log/freeradius
raddbdir = /etc/freeradius
radacctdir = ${logdir}/radacct
# Месторасположение конфигурационных и лог файлов.
confdir = ${raddbdir}
run_dir = ${localstatedir}/run/freeradius
# Каталог с подгружаемыми модулями.
libdir = ${exec_prefix}/lib
# Месторасположение pid-файла. Содержащего идентификатор процесса.
pidfile = ${run_dir}/freeradius.pid
# Имя пользователя и группа от которых запускается FreeRADIUS
user = freerad
group = freerad
# Максимальное время (в секундах) используемое для обработки запроса.
max_request_time = 30
# Удалить запросы которые обрабатываются более чем max_request_time
delete_blocked_requests = no
# Время ожидания (в секундах) перед очисткой reply запроса отправленного NAS.
cleanup_delay = 5
# Максимальное количество запросов хранимых сервером. Это число должно быть равно
# количеству клиентов помноженному на 256.
# К примеру для четырех клиентов оно будет 1024.
max_requests = 5120
# Закрепить за ip адресом. По умолчанию RADIUS сервер при старте принимает
# запросы со всех ip адресов.
bind_address = 127.0.0.1
# Закрепить за FreeRADIUS конкретный port. Если указан ноль,
# то значение берется из /etc/services
port = 0
# Запретить/разрешить ip адреса в dns имена.
# Включение этой опции может сильно снизить производительность.
hostname_lookups = no
# Создавать/несоздавать отладочные файлы при падении сервера.
allow_core_dumps = no
# Разрешить использование регулярных выражений.
regular_expressions = yes
extended_expressions = yes
# Записывать полный User-Name аттрибут если найден в запросе.
log_stripped_names = no
# Записывать в лог попытки авторизации.
log_auth = yes
# Записывать в логи пароли при авторизации.
# log_auth_badpass - не корректные пароли
# log_auth_goodpass - корректные пароли
log_auth_badpass = yes
log_auth_goodpass = no
# Включить/выключить коллизию пользователей.
usercollide = no
# конвертировать логин и/или пароль до или после авторизации.
lower_user = no
lower_pass = no
# удалить пробелы в логине и/или пароле.
nospace_user = no
nospace_pass = no
# настройки безопасности от возможных DoS аттак.
security {
# Максимальное допустимое количество аттрибутов в RADIUS пакете.
max_attributes = 200
# Задержка (в секундах) перед отправкой Access-Reject пакета.
reject_delay = 1
# Не отвечать на запросы Status-Server
status_server = no
}
# Конфигрурация клиентов RADIUS сервера.
# Описывается в отдельном файле.
$INCLUDE ${confdir}/clients.conf
# Отключить snmp поддержку.
snmp=no
# Настрока пула процессов.
thread pool {
# количество первоначально запущенных процессов.
start_servers = 5
# Максимально возможное количество процессов.
max_servers = 32
# Динамическая регулировка количества процессов.
min_spare_servers = 3
max_spare_servers = 10
# Количество принимаемых запросов процессом. МОжет помочь при утечках памяти в
# RADIUS сервере. Если выставить 300, процессы будут периодически перегружаться
# для уборки мусора.
max_requests_per_server = 0
}
# Секция конфигурации динамических модулей.
modules {
# Модуль PAP авторизации.
# Необходим для обработки запросов с PAP авторизацией.
# encryption_scheme указывает в каком виде хранятся пароли.
# clear - подразумевает в открытом виде.
pap {
encryption_scheme = clear
}
# Модуль CHAP авторизации.
# Необходим для обработки запросов с CHAP авторизацией.
# authtype подразумевает обработку запросов только с аттрибутом Auth-Type=CHAP
chap {
authtype = CHAP
}
# Модуль преобработки запросов.
# Т.е. перед авторизацией пакета.
preprocess {
# huntgroups - хинт группы см. файл huntgoups.
# hints - хинты.
huntgroups = ${confdir}/huntgroups
hints = ${confdir}/hints
# Обработка Cisco VSA.
with_cisco_vsa_hack = no
}
# Модуль Microsoft CHAP авторизации.
# Поддерживает так же еще и Microsoft CHAP v2
# authtype подразумевает обработку запросов только с аттрибутом Auth-Type=MS-CHAP
# use_mppe = no указывает на отсутствие компресии VPN туннеля.
mschap {
authtype = MS-CHAP
use_mppe = no
}
# Модуль записей Livingston RADIUS типа.
# usersfile содержит авторизационные записи пользователей.
# Рекомендуется использовать только для тестов и выставления значений по умолчанию.
# acctusersfile содержит пользователей подлежащих учету (аккаунтингу).
# compat - совместимость. При использовании файлов только FreeRADIUS можно отключить.
files {
usersfile = ${confdir}/users
compat = no
}
# Создать уникальный ключ для аккаунтинг сессии.
# Многие NAS повторно используют Acct-Session-ID.
# key перечисление аттрибутов для генерации Acct-Session-ID
acct_unique {
key = "User-Name, Acct-Session-Id, NAS-IP-Address, Client-IP-Address, NAS-Port-Id"
}
# Конфигурация авторизации и аккаунтинга посредством СУБД
# содержится в отдельном файле cakesql.conf
#$INCLUDE ${confdir}/sql.conf
#$INCLUDE ${confdir}/sql/mysql/counter.conf
}
# Авторизация
# сначала идет пакет передается в preprocess
# где может быть модифицирован.
# Далее chap mschap обрабатывают chap и mschap авторизацию.
authorize {
preprocess
chap
mschap
# Не ведем логи пакетов авторизации.
# auth_log
files
#sql
}
# Аунтификация
# Секция содержит модули доступные, для аунтификации.
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
}
# Преобразование аккаунтинговых пакетов.
preacct {
preprocess
}
# Секция ведения аккаунтинга.
accounting {
# Создание Acct-Session-Id если ваш NAS генрит их вполне корректно можете убрать.
acct_unique
# Не создаем detail лог.
detail
# Помещать аккаунтинговые пакеты в СУБД
#sql
}
# Секция ведения логов reply-пакетов.
post-auth {
# Не ведем детальный лог репли пакетов.
reply_log
}
log {
destination = files
file = ${logdir}/radius.log
syslog_facility = daemon
stripped_names = no
auth = no
auth_badpass = no
auth_goodpass = no
} Запускаем: nano /etc/freeradius/clients.conf Заменяем содержимое файла: client localhost {
ipaddr = 127.0.0.1
secret = my-isp-radius
require_message_authenticator = no
nastype = other
} Запускаем: nano /etc/freeradius/users Конфиг: steve Cleartext-Password := "testing"
Service-Type = Framed-User,
Framed-Protocol = PPP,
Framed-IP-Address = 10.128.13.3,
Framed-IP-Netmask = 255.255.0.0,
Framed-Routing = Broadcast-Listen,
Framed-Filter-Id = "std.ppp",
Framed-MTU = 1500,
Framed-Compression = Van-Jacobsen-TCP-IP
DEFAULT Hint == "CSLIP"
Framed-Protocol = SLIP,
Framed-Compression = Van-Jacobson-TCP-IP
DEFAULT Hint == "SLIP"
Framed-Protocol = SLIP Вообще в будущем вам нужно будет настроить связку с MySQL, но на данном этапе это не критично. При добавлении пользователя нужно перезапустить Freeradius: /etc/init.d/freeradius restart Теперь нужно разобраться с шейпингом трафика. Идея такова, что скорость должна регулироваться индивидуально для каждого пользователя и передаваться в виде атрибута от Radius-сервера серверу NAT. Зачем? Для того чтобы в последствии было возможно расширить структуру и распределить нагрузку между несколькими NAS.
Шейпинг трафика
Итак, подготовка. Установим Wondershaper: aptitude install wondershaper Этот пакет представляет собой один скрипт, работающий с CBQ/HTB приоритезацией и имеющий вменяемый формат вызова. При желании можно протестировать его работу до внедрения: wondershaper ppp0 512 512 Естественно, ppp0 должен существовать и быть результатом соединения клиента с нашим сервером. После того как команда выполнена, можно веб-браузером клиента зайти на любой сайт, измеряющий скорость, типаspeedtest.net— и убедиться что она таки режется шейпером. Для сброса настроек без рассоединения с клиентом (кика то есть), делаем wondershaper clear ppp0 и убеждаемся в том, что скорость опять нормальная (то есть равна скорости, которую мы берем от «старшего брата» на WAN интерфейсе. Добавление ограничений скорости нужно автоматизировать, используя простой парсер файлов /var/run/radattr.ppp*, которые появляются при успешном ppp соединении и содержат все атрибуты, передаваемые Radius-сервером серверу PPPoE. Займемся атрибутами. Дополняем содержимое файла дополнительных атрибутов /etc/freeradius/dictionary вот этим: Запускаем: nano /etc/freeradius/dictionary Конфиг: # Limit session traffic
ATTRIBUTE Session-Octets-Limit 227 integer
# What to assume as limit - 0 in+out, 1 in, 2 out, 3 max(in,out)
ATTRIBUTE Octets-Direction 228 integer
# Connection Speed Limit
ATTRIBUTE PPPD-Upstream-Speed-Limit 230 integer
ATTRIBUTE PPPD-Downstream-Speed-Limit 231 integer
ATTRIBUTE PPPD-Upstream-Speed-Limit-1 232 integer
ATTRIBUTE PPPD-Downstream-Speed-Limit-1 233 integer
ATTRIBUTE PPPD-Upstream-Speed-Limit-2 234 integer
ATTRIBUTE PPPD-Downstream-Speed-Limit-2 235 integer
ATTRIBUTE PPPD-Upstream-Speed-Limit-3 236 integer
ATTRIBUTE PPPD-Downstream-Speed-Limit-3 237 integer
ATTRIBUTE Acct-Interim-Interval 85 integer Далее, эти же атрибуты нужно добавить в словарь Raduisclient-а. Редактируем /etc/radiusclient/dictionary, в конце добавляем то же самое: Запускаем: nano /etc/radiusclient/dictionary Конфиг: # Limit session traffic
ATTRIBUTE Session-Octets-Limit 227 integer
# What to assume as limit - 0 in+out, 1 in, 2 out, 3 max(in,out)
ATTRIBUTE Octets-Direction 228 integer
# Connection Speed Limit
ATTRIBUTE PPPD-Upstream-Speed-Limit 230 integer
ATTRIBUTE PPPD-Downstream-Speed-Limit 231 integer
ATTRIBUTE PPPD-Upstream-Speed-Limit-1 232 integer
ATTRIBUTE PPPD-Downstream-Speed-Limit-1 233 integer
ATTRIBUTE PPPD-Upstream-Speed-Limit-2 234 integer
ATTRIBUTE PPPD-Downstream-Speed-Limit-2 235 integer
ATTRIBUTE PPPD-Upstream-Speed-Limit-3 236 integer
ATTRIBUTE PPPD-Downstream-Speed-Limit-3 237 integer
ATTRIBUTE Acct-Interim-Interval 85 integer Всё отлично, теперь они (FreeRadius и RadiusClient) друг друга поймут. Соответственно, в настройках пользователей freeradius-а появятся дополнительные строчки с указанием лимита входящей и исходящей скорости (но не обязательные). Пример /etc/freeradius/users с учетом изменений: Запускаем: nano /etc/freeradius/users Конфиг: steve Cleartext-Password := "testing"
Service-Type = Framed-User,
Framed-Protocol = PPP,
Framed-IP-Address = 10.128.13.3,
Framed-IP-Netmask = 255.255.0.0,
Framed-Routing = Broadcast-Listen,
Framed-Filter-Id = "std.ppp",
Framed-MTU = 1500,
Framed-Compression = Van-Jacobsen-TCP-IP PPPD-Downstream-Speed-Limit = 1024,
PPPD-Upstream-Speed-Limit = 1024
DEFAULT Hint == "CSLIP"
Framed-Protocol = SLIP,
Framed-Compression = Van-Jacobson-TCP-IP
DEFAULT Hint == "SLIP"
Framed-Protocol = SLIP Теперь NAS получает сведения о скорости, но не умеет их обрабатывать. Делаем два скрипта, выполняющих парсинг переданных атрибутов при установлении соединения: Запускаем: nano /etc/ppp/ip-up.d/0001shaper Скрипт: #!/bin/sh
/root-scripts/shape-on $1 $5
exit 0 Запускаем: nano /etc/ppp/ip-down.d/0001shaper Скрипт: #!/bin/sh
/root-scripts/shape-off $1 $5
exit 0 Как видно из этих листингов, вызывается некий скрипт, применяющий и отменяющий шейпинг. С этого момента — поподробнее. $1 — это переданное имя интерфейса, то есть ppp0 к примеру, $5 — это Framed-IP, то есть IP клиента PPP. Создадим заветный каталог и положим в него два файла: mkdir /root-scripts
nano /root-scripts/shape-on Скрипт: #!/bin/sh
if [ -f /var/run/radattr.$1 ]
then
DOWNSPEED=`awk '/PPPD-Downstream-Speed-Limit/ {print $2}' /var/run/radattr.$1`
UPSPEED=`awk '/PPPD-Upstream-Speed-Limit/ {print $2}' /var/run/radattr.$1`
wondershaper $1 $DOWNSPEED $UPSPEED
fi
iptables -A FORWARD -s $2 -j ACCEPT
iptables -A INPUT -s $2 -j ACCEPT
iptables -t nat -A POSTROUTING -s $2 -o eth1 -j MASQUERADE Запускаем: nano /root-scripts/shape-off Скрипт: #!/bin/sh
iptables -D FORWARD -s $2 -j ACCEPT
iptables -D INPUT -s $2 -j ACCEPT
iptables -t nat -D POSTROUTING -s $2 -o eth1 -j MASQUERADE Запускаем: chmod +x /root-scripts/* В листингах eth1 — это всё ещё WAN интерфейс. Итак, что мы получаем в результате: Клиент соединяется с сервером PPP, получает IP адрес. Автоматически вызывается скрипт, настраивающий шейпинг на клиентском PPP интерфейсе и включающий для него маскарадинг. При рассоединении правило маскарадинга удаляется также автоматически. Вроде как wondershaper не нужно принудительно отцеплять от pppx, во всяком случае мануалы об этом молчат и всё нормально работает на практике.
Простая защита на основе iptables
Теперь уделим немножко внимания iptables и безопасности сервера. Заменим /etc/firewall.conf: Запускаем: nano /etc/firewall.conf Скрипт: #!/bin/bash
###bad_tcp_packets chain
iptables -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK -m state --state NEW -j REJECT --reject-with tcp-reset
#iptables -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG --log-prefix "New not syn:"
iptables -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP
###allowed chain
iptables -A allowed -p TCP --syn -j ACCEPT
iptables -A allowed -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A allowed -p TCP -j DROP
###input chain
iptables -A INPUT -p TCP -j bad_tcp_packets
iptables -A INPUT -p ALL -i $LO_IFACE -j ACCEPT
iptables -A INPUT -p ALL -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p TCP -i $INET_IFACE -j tcp_packets
iptables -A INPUT -p UDP -i $INET_IFACE -j udp_packets
iptables -A INPUT -p ICMP -i $INET_IFACE -j icmp_packets
#iptables -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT INPUT packet died: "
###forward chain
iptables -A FORWARD -p tcp -j bad_tcp_packets
#custom rules
#iptables -A FORWARD -s 10.128.0.10/32 -d 192.168.1.1/32 -p tcp -j ACCEPT iptables -A FORWARD -s 10.128.0.0/16 -d 192.168.1.1/32 -p tcp -j DROP
#/custom rules
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
#iptables -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT FORWARD packet died: "
###OUTPUT chain
iptables -A OUTPUT -p tcp -j bad_tcp_packets
iptables -A OUTPUT -p ALL -j ACCEPT
#iptables -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG --log-level DEBUG --log-prefix "IPT OUTPUT packet died: "
###mangle
iptables -t mangle -A POSTROUTING -o $INET_IFACE -j TTL --ttl-set 64 Что мы тут видим? Во-первых, выделенное правило. Оно будет отличаться в реальной конфигурации или просто отсутствовать за ненадобностью, но смысл таков: если шлюзом для сервера является ADSL модем или подобный девайс с веб-админкой, нам не нужно выдумывать хитрые пароли для входа туда. Вместо этого, мы запрещаем к ним обращаться из клиентских туннелей, но одному таки разрешаем — это будет сервисная учетная запись, которой можно на него ломиться. Само собой, она не для клиентов. Далее. Добавлены команды, включающие защиту от брутфорсинга SSH сервера. Для их работы нужно настроить blocksshd.
BlockSSHd
Для начала его нужно скачать сblocksshd.sourceforge.net/и разархивировать файлы куда-нибудь. Я использовал для закачки wget, но путь — понятное дело — вырезал со странички SourceForge, то есть он будет скорее всего другим: cd /tmp
wget downloads.sourceforge.net/project/blocksshd/blocksshd/BlockSSHD%201.3/blocksshd-1.3.tar.gz?use_mirror=kent Этот скрипт написан на Perl и требует некоторых дополнительных модулей для работы. Итак, займемся модулями: cpan
upgrade
install Sys::Syslog
install Sys::Hostname
install File::Tail
install Tie::File
install Net::DNS
install Net::Subnets
install Getopt::Long
exit Обращаю внимание на то, что всё это одним махом не нужно копировать и вставлять в терминал. Это потому что каждая операция требует большого количества времени для выполнения и в процессе всей установки Cpan будет задавать вопросы. На все вопросы можно просто нажимать Enter, там по умолчанию всё правильно, как ни странно. Теперь нужно распаковать blocksshd и установить его: cd /tmp
tar -xvzf ./blocksshd-1.3.tar.gz
cd blocksshd-1.3
make install Ну и естественно, версия на момент написания мануала была именно эта, а может быть любая, так что нужно внимательно всё сделать а не копипастить в консоль. Осталось отредактировать конфигурацию blocksshd: Запускаем: nano /etc/blocksshd.conf Конфиг: $cfg = {
os => 'linux', # Target OS - either linux or bsd
chain => 'blocksshd', # Name of iptables or pf chain
logfile => '/var/log/secure', # Log file to monitor
logcheck => '10', # How often to check the log file max_attempts => '4', # Max number of failures
timeout => '360', # Reset IP count if no activity after time out in seconds unblock => '1', # Enable unblocking
unblock_timeout => '43200', # Time in seconds after which to unblock a blocked IP address restore_blocked => '0', # Turn on checking for previously blocked IPs
log_ips => '/etc/blocksshd.list', # Log file for blocked IPs
pid_file => '/var/run/blocksshd.pid', # Location of PID file send_email => '0', # Enable the sending of email notifications
email => 'root', # Email address to send notifications
mail => '/bin/mail', # Location of mail binary
email_whois_lookup => '1', # enable whois lookup of the blocked ip addres in the sent email
whois => '/usr/bin/whois', # location of the whois binary
sed => '/bin/sed', # location of the sed binary
iptables => '/sbin/iptables', # Location of iptables binary - only for Linux
pfctl => '/sbin/pfctl', # Location of pfctl binary - only for BSD
whitelist => [qw{
127.0.0.1/32
}], # whitelist - list of IPs that will never be blocked - IPs must be specified in the form ad$
};
#leave 1; here!
1; В этом листинге нужно обратить внимание на выделенные строчки. Первая — максимальное число попыток входа с одного адреса, вторая — нужно ли разблокировать забаненный айпи по истечении времени в секундах, указанного в третьей строчке. Четвертая — оповещать ли по email о попытках взлома. Теперь можно перезагрузить сервер и тестировать то что получилось.
Простейший мониторинг
Для удобства мониторинга активных сессий можно использовать скрипт, написанный «на коленке». Создадим его и настроим симлинк для простого запуска, ну и проверим конечно: Запускаем: nano /root-scripts/clients Скрипт: #!/usr/bin/php
<?
function time_since($original) {
$chunks = array(
array(60 * 60 * 24 , 'D '),
array(60 * 60 , 'h:'),
array(60 , 'min'),
);
$today = time();
$since = $today - $original;
for ($i = 0, $j = count($chunks); $i < $j; $i++) {
$seconds = $chunks[$i][0];
$name = $chunks[$i][1];
if (($count = floor($since / $seconds)) != 0) {
break;
}
}
$print = "$count{$name}";
if ($i + 1 < $j) {
$seconds2 = $chunks[$i + 1][0];
$name2 = $chunks[$i + 1][1];
if (($count2 = floor(($since - ($seconds * $count)) / $seconds2)) != 0) {
$print .= "$count2{$name2}";
}
}
return $print;
}
$t = getPPPTunnels();
addRadParams($t);
clientTable($t); Запускаем: chmod +x /root-scripts/clients
ln -s /root-scripts/clients /usr/bin/clients
clients Получим что-то типа: IP Address | MAC Address | NAT | User name | TX (up) | RX (down) | Uptime
-----------------------------------------------------------------------------------------------------
10.128.1.7 | 1:00:19:66:df:39:26 | on | room56 | 507.4 MiB | 445.5 MiB | 16h:31min
10.128.1.3 | 23:00:13:8f:70:30:03 | on | room47 | 8.2 MiB | 137.8 MiB | 1h:14min
10.128.1.5 | 3:00:a1:b0:11:74:cf | on | room50 | 19.2 MiB | 500.2 MiB | 16h:30min Вот и всё, наш сервер готов к использованию. По своим наблюдениям могу сказать, что простого системника с 1 гб DDR1 и 2 ГГц процессором хватает для раздачи 16-мегабитного канала для 30 пользователей (больше просто не нужно было) и ощутимой нагрузки система не испытывает.