Как настроить ipfw+nat для отдельных ip адресов в FreeBSD 12.2?

Добрый день!
Настраиваю ipfw + nat и возникла проблема, когда прописываю правило для всего трафика, то nat работает:
$cmd add 5 nat 1 ip from any to any via hn0

Но под nat попадает весь трафик, а мне только определенные ip адреса нужно выпускать.
Теперь пишу вот такое правило для одного ip адреса и доступ в интернет с адреса который указан в правиле пропадает:
$cmd add 5 nat 1 log ip from 10.35.0.254 to any via hn0


Файл rc.conf:
# Имя компьютера
hostname="test"

# Параметры сети
gateway_enable="YES"
network_interfaces="hn0 hn1 lo0"
ifconfig_hn0="inet 172.16.14.6 netmask 255.255.255.248"
ifconfig_hn1="inet 172.16.14.67 netmask 255.255.255.192 broadcast 172.16.14.127"
defaultrouter="172.16.14.5"

# Параметры ssh
sshd_enable="YES"

# Параметр сохранения дампа в случае фатального сбоя
dumpdev="AUTO"

# Параметры firewall
firewall_enable="YES"
firewall_nat_enable="YES"
firewall_nat_interface="hn0"
firewall_script="/etc/rc.firewall"

keymap="ru.win"
font8x16="vgarom-8x16


Файл rc.firewall:
#!/bin/sh

# Переменные
cmd="/sbin/ipfw"

# Основные параметры
$cmd -f flush # Сброс всех правил
$cmd -q queue flush # Сброс всех очередей
$cmd -q table all flush # Сброс всех таблиц

# Проверка пакета на соответствие набору динамических правил
$cmd add 3 check-state

### ПРАВИЛА ##
# Разрешение на весь трафика по внутреннему интерфейсу
#$cmd add 10 allow all from any to any via lo0

# Разрешение на подключение по SSH
$cmd add 50 allow tcp from any to 172.16.14.67 32822 in via hn1
$cmd add 51 allow tcp from 172.16.14.67 32822 to any out via hn1 established

# Разрешение ICMP трафика - эхо-запрос, эхо-ответ, время жизни пакета
$cmd add 55 allow icmp from any to any icmptypes 0,8,11

# Routing network
$cmd add 60 allow all from 10.35.0.0/24 to 172.16.14.0/29
$cmd add 61 allow all from 172.16.14.0/29 to 10.35.0.0/24

# Разрешение DNS
$cmd add 65 allow tcp from any to me dst-port 53 keep-state
$cmd add 65 allow udp from any to me dst-port 53 keep-state
$cmd add 66 allow udp from me to any keep-state

# Разрешение HTTP и HTTPS трафика
$cmd add 70 allow tcp from any to me dst-port 80 via hn1 keep-state
$cmd add 70 allow tcp from me to any keep-state
$cmd add 71 allow tcp from any to me dst-port 443 via hn1 keep-state
$cmd add 71 allow tcp from any to me dst-port 8080 via hn1 keep-state

# Разрешение на весь трафик на локальном интерфейсе
#$cmd add 75 allow all from any to any via hn1

# Конфигурация NAT
$cmd nat 1 config log if hn0 reset same_ports

# Правила NAT для всего трафика
$cmd add 5 nat 1 ip from any to any via hn0

# Правила NAT для отдельных IP адресов
#$cmd add 5 nat 1 log ip from 10.35.0.254/32 to any via hn0

# ТАБЛИЦА 1 (разрешен исходящий трафик)

# Правило ТАБЛИЦЫ 1
$cmd add 01000 allow ip from "table(1)" to any keep-state

# ТАБЛИЦА 2 (разрешен исходящий и входящий трафик)
$cmd table 2 add 172.16.14.5 #sphinx

# Правила ТАБЛИЦЫ 2
$cmd add 02000 allow ip from "table(2)" to any
$cmd add 02000 allow ip from any to "table(2)"

# Запретить весь остальной трафик
$cmd add 65534 deny log all from any to any


Вывод tcpdump (если включено правило $cmd add 5 nat 1 ip from any to any via hn0 ):
root@test:~ # tcpdump -i hn1 ip dst 87.250.250.242
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on hn1, link-type EN10MB (Ethernet), capture size 262144 bytes
17:51:44.933010 IP 10.35.0.254 > ya.ru: ICMP echo request, id 1, seq 10881, length 40
17:51:45.946430 IP 10.35.0.254 > ya.ru: ICMP echo request, id 1, seq 10882, length 40
17:51:46.959209 IP 10.35.0.254 > ya.ru: ICMP echo request, id 1, seq 10883, length 40
17:51:47.972262 IP 10.35.0.254 > ya.ru: ICMP echo request, id 1, seq 10884, length 40
^C
4 packets captured
32 packets received by filter
0 packets dropped by kernel
root@test:~ # tcpdump -i hn0 ip dst 87.250.250.242 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on hn0, link-type EN10MB (Ethernet), capture size 262144 bytes
17:52:04.161056 IP 172.16.14.6 > ya.ru: ICMP echo request, id 1, seq 10900, length 40
17:52:05.166632 IP 172.16.14.6 > ya.ru: ICMP echo request, id 1, seq 10901, length 40
17:52:06.179511 IP 172.16.14.6 > ya.ru: ICMP echo request, id 1, seq 10902, length 40
17:52:07.192413 IP 172.16.14.6 > ya.ru: ICMP echo request, id 1, seq 10903, length 40
17:52:08.205604 IP 172.16.14.6 > ya.ru: ICMP echo request, id 1, seq 10904, length 40
^C
5 packets captured
17 packets received by filter
0 packets dropped by kernel
root@test:~ # tcpdump -i hn0 ip src 87.250.250.242   
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on hn0, link-type EN10MB (Ethernet), capture size 262144 bytes
17:52:19.382741 IP ya.ru > 172.16.14.6: ICMP echo reply, id 1, seq 10915, length 40
17:52:20.395769 IP ya.ru > 172.16.14.6: ICMP echo reply, id 1, seq 10916, length 40
17:52:21.409117 IP ya.ru > 172.16.14.6: ICMP echo reply, id 1, seq 10917, length 40
17:52:22.422061 IP ya.ru > 172.16.14.6: ICMP echo reply, id 1, seq 10918, length 40
^C
4 packets captured
15 packets received by filter
0 packets dropped by kernel
root@test:~ # tcpdump -i hn1 ip src 87.250.250.242
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on hn1, link-type EN10MB (Ethernet), capture size 262144 bytes
17:52:32.538532 IP ya.ru > 10.35.0.254: ICMP echo reply, id 1, seq 10928, length 40
17:52:33.551822 IP ya.ru > 10.35.0.254: ICMP echo reply, id 1, seq 10929, length 40
17:52:34.564786 IP ya.ru > 10.35.0.254: ICMP echo reply, id 1, seq 10930, length 40
17:52:35.578049 IP ya.ru > 10.35.0.254: ICMP echo reply, id 1, seq 10931, length 40
^C
4 packets captured
40 packets received by filter
0 packets dropped by kernel

А вот если включаю правило для конкретного ip адреса то ICMP echo reply на интерфейсе hn1 уже нет.
  • Вопрос задан
  • 454 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Karpion
Вы явно не поняли принципов работы ipfw и kernel nat.

У Вас есть правило маскарадинга nat 1; я его не смотрел, надеюсь, что там всё верно.
Далее надо зарулить в этот маскарадинг пакеты, которые клиент посылает серверу: from 10.35.0.254; очень хорошо, хотя я бы добавил условие "исходящие".
Но кроме этого, в тот же маскарадинг надо зарулить и пакеты, идущие от сервера в ответ на запросы клиента. Желательно заруливать в маскарадинг только нужные пакеты; соответствующее правило будет что-то типа "от кого угодно; входящие на hn0; можно добавить IP-адрес интерфейса hn0, он у Вас берётся автоматически".

Ну или можно воспользоваться правилами на базе keep-state; у меня нет опыта в этой области.

Ещё я очень советую писать правила ipfw строго в порядке возрастания номеров: так намного легче читать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы