I
I
Ivan Semenov2021-08-13 19:38:52
FreeBSD
Ivan Semenov, 2021-08-13 19:38:52

How to configure ipfw+nat for individual ip addresses in FreeBSD 12.2?

Good afternoon!
I set up ipfw + nat and a problem arose when I write a rule for all traffic, then nat works:
$cmd add 5 nat 1 ip from any to any via hn0

But all traffic falls under nat, and I only need to release certain ip addresses.
Now I am writing this rule for one ip address and Internet access from the address specified in the rule disappears:

$cmd add 5 nat 1 log ip from 10.35.0.254 to any via hn0


rc.conf file :
# Имя компьютера
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 file :
#!/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 output (if $cmd add 5 nat 1 ip from any to any via hn0 is enabled ):
[email protected]:~ # 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
[email protected]:~ # 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
[email protected]:~ # 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
[email protected]:~ # 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

But if I include a rule for a specific ip address, then ICMP echo reply is no longer on the hn1 interface.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
K
Karpion, 2021-08-14
@Karpion

You clearly did not understand the principles of operation of ipfw and kernel nat.
You have a masquerading rule nat 1; I didn't watch it, I hope it's correct.
Next, you need to drive into this masquerading the packets that the client sends to the server: from 10.35.0.254; very good, although I would add the "outgoing" condition.
But besides this, in the same masquerading it is necessary to taxi the packets coming from the server in response to client requests. It is advisable to taxi into masquerading only the necessary packages; the corresponding rule will be something like "from anyone; incoming to hn0; you can add the IP address of the hn0 interface, it is taken from you automatically".
Well, or you can use the rules based on keep-state; I have no experience in this area.
I also highly recommend writing ipfw rules strictly in ascending order of numbers: it's much easier to read that way.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question