Firewall из RedOS

от автора

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

Что же из себя представляет NGFW (Next Generation Firewall)? За основу я взял модель FW Check Point. А значит, как минимум:

  • Firewall Blade — Собственно сам брандмауэр

  • IPS — Intruder Prevention System — система обнаружения и блокировки атак на основе поведенческого анализа по базе сигнатур

  • IPSec — построение VPN-туннелей (site-2-site, client-2-site)

  • Application Control / URL Filtering — контроль приложений и фильтрация по URL

  • Antivirus / AntiBot — проверка на вирусы/боты на лету, анализ пакетов

  • SandBlast — песочница с очисткой активного содержимого в файлах

На текущий момент из всего списка компонентов реализовано только FW, IPS, IPSec VPN. Напомню, что все компоненты OpenSource, а сама RedOS бесплатна для домашнего использования.

Версии ПО:
RedOS Murom 7.3.3 (server-minimal)
Suricata 7.0.1
WireGuard 1.0
OpenVPN 2.6.0
ShadowSocks 2.9.1
StrongSwan 5.9.9

В качестве FW будем использовать nftables (в RedOS он хоть и встроен в ядро, самой утилиты управления нет, предполагается, что админ сам выберет утилиту firewalld, nft, iptables)

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

Сразу оговорю, все настройки лучше делать под root. Сейчас в меня посыпятся хейты, однако сразу сообщу, NGFW — это не пользовательская задача. И да, SSH-доступ следует открывать только для внутренних администраторов, с внешней стороны его лучше не открывать. Также PermitRootLogin ставить no, использовать sudoers и т.п. и желательно использовать ssh-ключи с паролем. И да, параметр Listen в /etc/ssh/sshd_config лучше указывать конкретный IP из внутренней сети.

Итак, приступим. Этап 1. Настройка FW

Разумеется первым, а вернее нулевым действием после установки чистой ОС ее надо обновить.

dnf update -y reboot

Во-первых необходимо установить и преднастроить FW, для этого ставим и настраиваем nftables. Предварительно проверяем, что же установлено.

iptables -V iptables v1.8.9 (nf_tables)

В выводе nf_tables означает, что в ядре используется nftables. В моем случае я использовал mininal server инсталляцию, поэтому никаких «обвесов» у меня нет. Но для общего случая следует проверить и по необходимости деинсталировать лишнее

Удаляем обвесы nftables
systemctl status firewalld systemctl stop firewalld systemctl disable firewalld dnf remove firewalld

Проверим все ли необходимые модули ядра загружены. xt_conntrack / nf_conntrack (контроль состояния сессий) и 802.1q (для поддержки VLAN)

lsmod | grep xt_conntrack lsmod | grep 8021q

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

modprobe xt_conntrack modprobe 8021q

Если ошибок нет, то добавляем модули для загрузки в boot time. Создаем файл /etc/modules-load.d/mymod.conf

xt_conntrack 8021q

Теперь установим необходимую утилиту nft и настроим запуск службы

dnf install nftables systemctl enable nftables --now

Далее в файле /etc/sysconfig/nftables.conf указываем откуда подгружать конфиг FW

include "/etc/nftables/mynetworkfw.nft"

Далее есть 2 варианта управления файрволом, через конфиг и службу, либо прямыми командами nft и сохранением конфига nft list ruleset >/etc/nftables/mynetworkfw.nft.Принципиально разницы нет, однако при перезагрузке службы Handle правил будет обнуляться (то же самое при перезагрузке системы в целом). При редактировании правил через команды nft, Handle будет уникальным.

Теперь собственно необходим дефолтовый конфиг nftables. В частности, input/output и сама цепочка forward. Ниже приведу примерный файл /etc/nftables/mynetworkfw.nft

table inet fw {         chain incoming {                 type filter hook input priority filter; policy drop;                 ct state established,related accept                 ip saddr { 192.168.10.50, 192.168.20.25 } tcp dport 22 counter accept comment "SSH_admin"                 iifname "lo" accept comment "Localhost"                 # IPSec VPN Clients                 udp port 1194 counter accept comment "OpenVPN_clients"                 udp port 51820 counter accept comment "WireGuard_clients"                 udp port { 4500,500 } counter accept comment "IPSec_IKEv2_clients"                 tcp port 26789 counter accept comment "ShadowSocks_clients"         }          chain outgoing {                 type filter hook output priority filter; policy drop;                 ct state established,related accept                 ip daddr 192.168.1.1 udp dport 53 oifname "ens224.40" counter accept comment "DNS_UDP_requests"                 ip daddr 192.168.1.1 tcp dport 53 oifname "ens224.40" counter accept comment "DNS_TCP_requests"                 tcp dport { 80, 443, 21 } counter accept comment "FW_to_Inet"                 oifname "lo" accept comment "Localhost"         }          chain forwarding {                 type filter hook forward priority filter; policy drop;                 ct state established,related accept                 counter queue to 0         } }

Поясню по конфигу, 192.168.10.50, 192.168.20.25 это IP-адреса админов NGFW. 192.168.1.1 это наш роутер, подключенный в инет и осуществляющий NAT и играющий роль DNS-сервера локальной сети. Разумеется это лишь пример. Обратите внимание, что фильтрация трафика осуществляется не только на вход к серверу, но и на выход. Когда закончим настройку NGFW основная цепочка будет именно forwarding, тут будут правила NGFW. Забегаю наперед, counter queue to 0 — это уже IPS-правило, его надо будет указать уже после запуска Suricata. Кроме того, в FW уже преднастроены клиенты VPN с портами по умолчанию. Если порты в настройках VPN-сервисов указываете другие, то и в FW их надо учесть. Интерфейсы ens192 (external) и ens224 (internal), на последний из них приходит trunc (802.1q). Все настройки интерфейсов располагаются /etc/sysconfig/network-scripts/, где ifcfg-<interface> — настройки интерфейса, route-<interface> настройки маршрутов если на интерфейсе их не 1. Примеры таких настроек в спойлере

Настройки интерфейсов

ifcfg-ens192

TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="manual" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" IPV6INIT="yes" IPV6_AUTOCONF="yes" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="ens192" DEVICE="ens192" ONBOOT="yes" UUID="3cec767a-e4ba-3130-839e-5588d3602a81" IPADDR="192.168.1.254" NETMASK="255.255.255.0" GATEWAY="192.168.1.1" DNS1="192.168.1.1" DNS2="8.8.8.8"

узнать UUID интерфейса можно через nmcli con show

отсюда DNS попадут в /etc/resolv.conf, а GATEWAY в таблицу маршрутизации, DEFROUTE=yes означает, что маршрут 0.0.0.0/0.0.0.0 будет через GATEWAY

ifcfg-ens224

BOOTPROTO="none" DEVICE="ens224" ONBOOT="yes" TYPE="Ethernet"

Обратите внимание, что здесь нет особо никаких настроек. Это публикация интерфейса для использования в 802.1q. UUID здесь также не указан, чтобы NetworkManager не управлял этой заглушкой.

ifcfg-ens224.20

DEVICE=ens224.20 BOOTPROTO=none ONBOOT=yes IPADDR=192.168.20.1 PREFIX=24 NETWORK=192.168.20.0 VLAN=yes

после расписывания всех файлов конфигураций, рестартанем NetworkManager

systemctl restart NetworkManager

Итак, предварительно настроили FW. правила FW применяются «на лету», а значит при ручном написании правил через команду nft, создавая chain в таблице не спешите ставить drop, первоначально лучше ставить accept, чтобы не потерять подключение к серверу.

Этап 2. Установка Suricata.

По дефолту, в репозитории Fedora Extra (epel) есть пакет Suricata, однако он скомпилирован с ограничениями, да и версия Python нас не устроит, так что придется собирать из исходников. Установим репозиторий epel, скачиваем исходник Suricata и устанавливаем нужные компоненты для компиляции.

wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm yum localinstall epel-release-latest-7.noarch.rpm cd /usr/src wget https://www.openinfosecfoundation.org/download/suricata-7.0.1.tar.gz tar xzvf suricata-7.0.1.tar.gz rm -f suricata-7.0.1.tar.gz cd suricata-7.0.1/ dnf groupinstall "Development Tools" dnf install -y pcre2-devel libyaml-devel jansson-devel libpcap-devel pcapy python3-pcapy libcap-ng-devel file-devel lz4-devel rustc cargo dnf install -y libunwind libunwind-devel GeoIP-devel zlib zlib-devel libnetfilter_queue-devel libnetfilter_log-devel ./configure --enable-nfqueue --enable-nflog --prefix=/usr/ --sysconfdir=/etc/ --localstatedir=/var/ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python get-pip.py python -m pip install pyyaml make make install-full

Дальше нам необходимо поправить несколько моментов. Во-первых, надо настроить запуск службы suricata. Для этого создаем файл /usr/lib/systemd/system/suricata.service

[Unit] Description=Suricata IDS/IDP daemon After=network.target Requires=network.target Documentation=man:suricata(8) man:suricatasc(8) Documentation=https://redmine.openinfosecfoundation.org/projects/suricata/wiki  [Service] Type=forking Environment=LD_PREDLOAD=/usr/lib/libtcmalloc_minimal.so.4 Environment=CFG=/etc/suricata/suricata.yaml PID=/var/run/suricata/suricata.pid CapabilityBoundingSet=CAP_NET_ADMIN PIDFile=/var/run/suricata/suricata.pid ExecStart=/usr/bin/suricata -D -q 0 -q 1 -c $CFG --pidfile $PID -D ExecReload=/bin/kill -HUP $MAINPID ExecStop=/bin/kill $MAINPID PrivateTmp=yes InaccessibleDirectories=/home /root ReadOnlyDirectories=/boot /usr /etc  [Install] WantedBy=multi-user.target

Далее делаем chmod 755 /usr/lib/systemd/system/suricata.service и systemctl daemon-reload. Проверяем права доступа к созданным папкам, файлам, и т.д. /var/run/suricata, /etc/suricata/, /var/log/suricata. Если все права выставлены верно, значит проблем с запуском не возникнет. Запускам службу и ставим в автозапуск. systemctl enable suricata --now

Далее в cron добавляем обновление баз и перезагрузку этих правил. crontab -e

0 0 * * * /usr/lib/suricata-update >>/var/log/suricata/update.log 5 0 * * * /usr/lib/suricatasc -c reload-rules

Этап 3. Часть 1. Установка WireGuard

Установка WireGuard в RedOS задача не тривиальная.

Для начала необходимо установить необходимые репозитории. В частности, от Oracle Linux 7.

cd wget https://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/getPackage/oraclelinux-release-el7-1.0-17.el7.x86_64.rpm wget https://yum.oracle.com/repo/OracleLinux/OL7/latest/x86_64/getPackage/oraclelinux-developer-release-el7-1.0-6.el7.x86_64.rpm yum localinstall oraclelinux-release-el7-1.0-17.el7.x86_64.rpm yum localinstall oraclelinux-developer-release-el7-1.0-6.el7.x86_64.rpm

Потом выполнить преконфиг и установку в соответствии с Installation manual WireGuard

yum-config-manager --disable ol7_developer yum-config-manager --enable ol7_developer_UEKR6 yum-config-manager --save --setopt=ol7_developer_UEKR6.includepkgs='wireguard-tools*' dnf install wireguard-tools

После чего, эти репозитории можно отключить/удалить и т.п. Больше они не потребуются, но могут мешать. Лучше отключать после чего сделать очистку dnf clean packages

yum-config-manager --disable ol7_developer yum-config-manager --disable ol7_developer_UEKR6 # и д.р. пакеты от Oracle Linux. либо вручную в файлах /etc/yum.repos.d/.repo # установить параметр enable=0 # oraclelinux-developer-ol7.repo # oracle-linux-ol7.repo # uek-ol7.repo # virt-ol7.repo

После чего также проверяем наличие модуля ядра, его автозагрузку и т.п.

lsmod | grep wireguard modprobe wireguard echo wireguard >>/etc/modules-load.d/mymod.conf

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

cd /etc/wireguard wg genkey | tee priv.key | wg pubkey > pub.key chmod 600 *.key

Настраиваем подключение wireguard. Создаем файл /etc/wireguard/wgtun.conf

[Interface] PrivateKey = 8Kfqf4QdHL1pBKxT1NknbC7k9JCjyRj6hO1Mj+a4yU8= Address = 172.16.0.1/23 ListenPort = 51820  # Далее настройки каждого клиента # Клиент 1 [Peer] PublicKey = OIhY7IdxElaDH0amgCiZnLXx22sFn8QV8t40iihLaz8= AllowedIPs = 172.16.0.2/30  # Клиент 2 [Peer] PublicKey = QKqUuHDAtSw/xYs2AywdqiRHvcr1UzBwrKY7nphU8xg= AllowedIPs = 172.16.0.5/30

После чего проверяем его, если ошибок нет, то включаем службу

wg-quick up wgtun systemctl enable wg-quick@wgtun.service

Этап 3. Часть 2. Установка OpenVPN / ShadowSocks

Установка OpenVPN простая, у RedOS есть 2 версии OpenVPN и OpenVPN-Гост. Кому какой нравится. Мне ГОСТ не требуется, поэтому тут все просто. dnf install openvpn -y

Пример конфигурации OpenVPN. Создание CA опишу ниже. Этот CA мы будем использовать для OpenVPN / StrongSwan. Обратите внимание, что критично для конфигураций OpenVPN — это размещение конфигов клиента и сервера. В общих чертах, указание port обязательно для server и необязательно для client. Запускать службу OpenVPN будем так: systemctl start openvpn@config.service (для файла конфигурации /etc/openvpn/config.conf), systemctl start openvpn-client@config.service (для файла /etc/openvpn/client/config.conf) или systemctl start openvpn-server@config.service (для файла /etc/openvpn/server/config.conf). В нашем случае это файл /etc/openvpn/server/myvpnserver.conf

port 1194 proto udp dev tun0  ca /etc/openvpn/server/myvpnserver/ca.crt cert /etc/openvpn/server/myvpnserver/server.crt key /etc/openvpn/server/myvpnserver/server.key crl-verify /etc/openvpn/server/myvpnserver/crl.pem dh /etc/openvpn/server/myvpnserver/dh.pem  tls-server tls-timeout 120 tls-auth /etc/openvpn/server/myvpnserver/ta-srv.key 0  server 172.16.2.0 255.255.254.0 route 172.16.2.0 255.255.254.0  ;routes ;see DEFAULT in CCD  ;DHCP-Option ;see DEFAULT in CCD  ifconfig-pool-persist /etc/openvpn/server/00-universal/cips client-config-dir /etc/openvpn/server/00-universal/ccd  management localhost 7510 /etc/openvpn/server/myvpnserver/pwd keepalive 10 120 comp-lzo  persist-key persist-tun  status /var/log/openvpn/myvpnserver-status.log log /var/log/openvpn/myvpnserver-log.log

Теперь перед запуском сервиса необходимо создать все используемые файлы и настроить SELinux

dnf install libsemanage libsemanage-python semanage port -a -t openvpn_port_t -p tcp 7510 mkdir /etc/openvpn/server/myvpnserver mkdir /etc/openvpn/server/myvpnserver/ccd mkdir /var/log/openvpn echo "superhiddenpassword" >/etc/openvpn/server/myvpnserver/pwd chmod 700 /etc/openvpn/server/myvpnserver/pwd openvpn --genkey --secret /etc/openvpn/server/myvpnserver/ta-srv.key

Файл cips OpenVPN создаст сам, в нем будет хранить закрепленные за пользователями/серверами IP-адреса. Про сертификаты, ключи Diffie-Hellman, списки отзыва сертификатов ниже, в разделе про StrongSwan. А пока проверим запуск OpenVPN (будут ошибки из-за отсутствующих файлов)

systemctl start openvpn-server@myvpnserver.service # увидели ошибку, теперь добавим в загрузку, но без запуска systemctl enable openvpn-server@myvpnserver.service

Установка же ShadowSocks не тривиальна и снова потребует сборки и компиляции

dnf install git pcre-devel asciidoc xmlto mbedtls-devel libsodium-devel libcares-devel libev-devel cd /usr/src git clone https://github.com/shadowsocks/shadowsocks-libev.git cd shadowsocks-libev/ git submodule update --init --recursive ./autogen.sh ./configure make make install

Создаем пользователя, папку конфигов и сервис (для удобства openvpn-like сервис)

adduser --system --no-create-home -s /sbin/nologin shadowsocks mkdir -p /etc/shadowsocks

Содержание файла /usr/lib/systemd/system/shadowsocks@.service

[Unit] Description=Shadowsocks proxy server  [Service] User=root Group=root Type=simple ExecStart=/usr/local/bin/ss-server -c /etc/shadowsocks/%i.json -a shadowsocks -v start ExecStop=/usr/local/bin/ss-server -c /etc/shadowsocks/%i.json -a shadowsocks -v stop  [Install] WantedBy=multi-user.target

Примерное содержание конфига ss (/etc/shadowsocks/main.json)

{     "server":"178.128.122.54",     "server_port": 26789,     "password":"your_password",     "timeout": 300,     "method": "aes-256-gcm",     "fast_open": true }

Права и запуск службы

chmod 755 /etc/systemd/system/shadowsocks@.service systemctl daemon-reload systemctl enable shadowsocks@main.service --now

Этап 3. Часть 3. Установка и настройка StrongSwan (IPSec IKEv2)

Устанавливаем и запускаем

dnf install strongswan systemctl enable strongswan --now

Создаем CA (без него не построить туннели на базе сертификатов). Лучше такой CA не держать на сервере в публичной сети, по крайней мере его приватный ключ. Для этой задачи штатно можно использовать strongswan pki, openssl, либо готовый скрипт easy-rsa. Мы возьмем последний, поскольку будем делать универсальный CA для служб OpenVPN и StrongSwan.

dnf install easy-rsa # забираем установленный набор в папку mkdir /usr/ca chmod 700 /usr/ca cd /usr/ca cp -Rv /usr/share/easy-rsa/3.0.8/ ./ # Инициируем CA ./easyrsa init-pki ./easyrsa build-ca ./easyrsa gen-dh # Создаем сертификат для OpenVPN сервера ./easyrsa gen-req ovpn nopass ./easyrsa sign-req server ovpn ./easyrsa gen-crl # Копируем нужные ключи для OpenVPN cp ./pki/ca.crt /etc/openvpn/server/myvpnserver/ cp ./pki/issued/ovpn.crt /etc/openvpn/server/myvpnserver/server.crt cp ./pki/private/ovpn.key /etc/openvpn/server/myvpnserver/server.key cp ./pki/dh.pem /etc/openvpn/server/myvpnserver/ cp ./pki/crl.pem /etc/openvpn/server/myvpnserver/ # Можно запускать наш OpenVPN systemctl start openvpn-server@myvpnserver.service

Инициировали CA, выпустили сертификат, запустили OpenVPN. Что дальше? Настраиваем strongswan.

# Создаем новый тип сертификата IPSec cp ./x509-types/serverClient ./x509-types/ipsec # Заменяем строку extendedKeyUsage = serverAuth,clientAuth # на extendedKeyUsage = serverAuth, clientAuth, 1.3.6.1.5.5.7.3.17 # и добавляем Subject Alternative Names. Важно указать реальные IP и привязанные при наличии DNS subjectAltName=DNS:vpn.example.com,DNS:localhost,IP:127.0.0.1,IP:185.185.101.23,DNS:185.185.101.23 # В файл./vars добавляем переменные set_var EASYRSA_CERT_EXPIRE     3650 set_var EASYRSA_EXTRA_EXTS      "DNS:vpn.example.com,DNS:localhost,IP:127.0.0.1,IP:185.185.101.23,DNS:185.185.101.23" # Все готово, выпускаем сертификат ./easyrsa gen-req swan nopass ./easyrsa sign-req ipsec swan # Проверяем наши сертификаты openssl x509 -noout -text -in ./pki/issued/swan.crt # Должны быть указаны параметры: X509v3 Extended Key Usage:                 TLS Web Server Authentication, TLS Web Client Authentication, 1.3.6.1.5.5.7.3.17 X509v3 Subject Alternative Name:                 DNS:vpn.example.com, DNS:localhost, IP Address: 127.0.0.1, IP Address:185.185.101.23, DNS:185.185.101.23 # Теперь копируем все необходимое cp ./pki/ca.crt /etc/strongswan/ipsec.d/cacerts/ca.pem cp ./pki/issued/swan.crt /etc/strongswan/ipsec.d/certs/swan.pem cp ./pki/private/swan.key /etc/strongswan/ipsec.d/private/swan.pem # Подключаем сертификат, в файл /etc/strongswan/ipsec.secrets вписываем приватный ключ : RSA swan.pem

Теперь пишем конфиг /etc/strongswan/ipsec.conf

config setup     charondebug="ike 2, knl 2, cfg 2, net 2, esp 2, dmn 2,  mgr 2"  conn %default     keyexchange=ikev2     ike=aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024!     esp=aes128gcm16-ecp256,aes256gcm16-ecp384,aes128-sha256-ecp256,aes256-sha384-ecp384,aes128-sha256-modp2048,aes128-sha1-modp2048,aes256-sha384-modp4096,aes256-sha256-modp4096,aes256-sha1-modp4096,aes128-sha256-modp1536,aes128-sha1-modp1536,aes256-sha384-modp2048,aes256-sha256-modp2048,aes256-sha1-modp2048,aes128-sha256-modp1024,aes128-sha1-modp1024,aes256-sha384-modp1536,aes256-sha256-modp1536,aes256-sha1-modp1536,aes256-sha384-modp1024,aes256-sha256-modp1024,aes256-sha1-modp1024,aes128gcm16,aes256gcm16,aes128-sha256,aes128-sha1,aes256-sha384,aes256-sha256,aes256-sha1!     dpdaction=clear     dpddelay=300s     rekey=no     left=%any     leftsubnet=0.0.0.0/0     leftcert=swan.pem     right=%any     rightdns=8.8.8.8,8.8.4.4     rightsourceip=172.16.4.0/23  conn IPSec-IKEv2     keyexchange=ikev2     auto=add  conn IPSec-IKEv2-EAP     also="IPSec-IKEv2"     rightauth=eap-mschapv2     rightauthby2=pubkey     rightsendcert=never     eap_identity=%any  conn CiscoIPSec     keyexchange=ikev1     forceencaps=yes     authby=xauthrsasig     xauth=server     auto=add

Клиентам StrongSwan нужны будут свои сертификаты в P12. Для OpenVPN можно использовать pem, либо при использовании eToken,ruToken,JaCarta и пр. — pfx с паролем. Для этого можно использовать встроенные в easyrsa командлеты. export-p7, export-p12.

Этап 4. Включение маршрутизации

Для включения маршрутизации вносим изменения в sysctl. /etc/sysctl.d/10-forward.conf

net.ipv4.ip_forward=1 net.ipv6.conf.all.forwarding=1 # Включаем "на лету". После переагрузки ОС параметры подтянутся автоматически. sysctl -p /etc/sysctl.d/10-forward.conf

Послесловие

Ну и в конце, после настроек необходимых VPN-сервисов не забывайте открывать для них входящие и исходящие правила на FW. Также для маршрутизации и NAT необходимо прописывать соответствующие правила МЭ.

Полезные ссылки


ссылка на оригинал статьи https://habr.com/ru/articles/766862/