Роутер на FreeBSD: настраиваем NAT и PF с понятной проверкой каждого шага
В этой инструкции мы превратим обычный сервер FreeBSD с двумя сетевыми интерфейсами в полноценный шлюз для небольшой сети. В результате клиенты из LAN будут получать адреса, выходить в интернет через один внешний IP, а незапрошенные подключения со стороны WAN будут блокироваться.
Пример рассчитан на следующую схему: внешний интерфейс em0 получает адрес от провайдера, внутренний em1 обслуживает сеть 192.168.10.0/24, а сам шлюз имеет LAN-адрес 192.168.10.1. Имена интерфейсов обязательно замените на свои.
1. Проверяем интерфейсы и маршруты
Сначала важно убедиться, что FreeBSD сама видит интернет и оба сетевых адаптера определились корректно. NAT не починит отсутствующий маршрут или неправильно назначенный адрес.
freebsd-version
ifconfig -a
netstat -rn
ping -c 3 1.1.1.1
fetch -qo- https://example.com | headВ таблице маршрутов должен быть маршрут default через WAN. Успешный ping по IP показывает, что связь есть; успешный fetch дополнительно подтверждает работу DNS и HTTPS.
2. Делаем резервную копию
Перед изменением сети сохраняем конфигурацию. Это особенно важно при удалённой работе: одна ошибка в PF может отрезать SSH.
mkdir -p /root/router-backup
cp /etc/rc.conf /root/router-backup/rc.conf.before
cp /etc/pf.conf /root/router-backup/pf.conf.before 2>/dev/null || true
sysrc -a > /root/router-backup/sysrc-before.txt
ifconfig -a > /root/router-backup/ifconfig-before.txt
netstat -rn > /root/router-backup/routes-before.txt3. Назначаем адрес LAN-интерфейсу
Адрес 192.168.10.1 станет основным шлюзом для компьютеров внутри сети. Он должен быть статическим: если адрес шлюза изменится, клиенты потеряют доступ наружу.
sysrc ifconfig_em1="inet 192.168.10.1 netmask 255.255.255.0"
service netif restart em1
ifconfig em1После применения интерфейс должен показывать адрес 192.168.10.1/24. Если вы подключены через этот интерфейс по SSH, перезапуск сети выполняйте только при наличии консоли или второго канала доступа.
4. Включаем маршрутизацию
По умолчанию FreeBSD принимает пакеты только для себя. Параметр gateway_enable разрешает пересылать их между LAN и WAN — именно это превращает сервер в роутер.
sysrc gateway_enable="YES"
sysctl net.inet.ip.forwarding=1
sysctl net.inet.ip.forwardingОжидаемый результат — net.inet.ip.forwarding: 1. Команда sysrc сохранит настройку после перезагрузки, а sysctl включает её сразу.
5. Создаём правила PF и NAT
PF выполняет две задачи. Первая — фильтрация: разрешить клиентам выходить наружу и запретить случайные входящие соединения. Вторая — NAT: подменить внутренние адреса одним адресом WAN-интерфейса.
cat > /etc/pf.conf <<'EOF'
wan = "em0"
lan = "em1"
lan_net = "192.168.10.0/24"
set skip on lo0
scrub in all
nat on $wan from $lan_net to any -> ($wan)
block all
pass out on $wan inet from ($wan) to any keep state
pass in on $lan from $lan_net to any keep state
pass in on $wan proto tcp from any to ($wan) port 22 keep state
EOF
pfctl -nf /etc/pf.confКоманда pfctl -nf только проверяет синтаксис и ничего не применяет. Отсутствие вывода означает, что файл разобран успешно. SSH на WAN оставлен открытым в примере; лучше ограничить его своим административным IP.
6. Включаем PF
После успешной проверки включаем автозапуск и загружаем правила. Делайте это из консоли или держите открытой вторую SSH-сессию.
sysrc pf_enable="YES"
sysrc pf_rules="/etc/pf.conf"
service pf start
pfctl -f /etc/pf.conf
pfctl -sr
pfctl -sn
pfctl -sipfctl -sr показывает правила фильтрации, -sn — NAT, а -si — общее состояние PF. Так мы проверяем не просто запуск службы, а фактическую загрузку нужной политики.
7. Раздаём клиентам адреса через DHCP
DHCP не обязателен для работы маршрутизации, но избавляет от ручной настройки каждого компьютера. Клиенты получат адрес, шлюз и DNS автоматически.
pkg install -y isc-dhcp44-server
sysrc dhcpd_enable="YES"
sysrc dhcpd_ifaces="em1"
cat > /usr/local/etc/dhcpd.conf <<'EOF'
authoritative;
subnet 192.168.10.0 netmask 255.255.255.0 {
range 192.168.10.100 192.168.10.200;
option routers 192.168.10.1;
option domain-name-servers 1.1.1.1, 8.8.8.8;
default-lease-time 3600;
max-lease-time 86400;
}
EOF
service isc-dhcpd start
service isc-dhcpd status8. Проверяем с клиентского компьютера
Проверку выполняем по уровням. Так сразу понятно, где именно проблема: адрес, шлюз, NAT или DNS.
ip addr
ip route
ping -c 3 192.168.10.1
ping -c 3 1.1.1.1
getent hosts example.com
curl -I https://example.comЕсли шлюз пингуется, а 1.1.1.1 нет — проверяйте forwarding и PF. Если IP работает, но имя сайта не открывается — проблема почти наверняка в DNS, а не в NAT.
9. Смотрим трафик и счётчики
Когда «вроде всё настроено», но интернет не работает, пакеты лучше увидеть своими глазами. Сниффер покажет, доходят ли запросы до шлюза и выходят ли через WAN.
tcpdump -ni em1 host 192.168.10.100
tcpdump -ni em0 icmp
pfctl -vvs rules
pfctl -ss
service isc-dhcpd status
tail -f /var/log/messages10. Безопасный rollback
Откат возвращает предыдущие файлы и отключает новые службы. Выполняйте его с локальной консоли, если доступ по сети уже потерян.
service isc-dhcpd stop 2>/dev/null || true
service pf stop
cp /root/router-backup/rc.conf.before /etc/rc.conf
cp /root/router-backup/pf.conf.before /etc/pf.conf 2>/dev/null || true
service netif restart
service routing restartКритерий успеха: клиент получает адрес из диапазона 192.168.10.100–200, видит шлюз 192.168.10.1, пингует внешний IP, разрешает DNS-имена и открывает сайты. PF при этом показывает активные states и счётчики проходящего трафика.