NAT позволяет администраторам воспользоваться зарезервированными адресными блоками, описанными в RFC 1918. Как правило, внутренняя сеть будет настроена на использование одного или нескольких из этих сетевых блоков.
10.0.0.0/8 (10.0.0.0 - 10.255.255.255) 172.16.0.0/12 (172.16.0.0 - 172.31.255.255) 192.168.0.0/16 (192.168.0.0 - 192.168.255.255)OpenBSD, используемая для преобразования сетевых адресов (NAT), должна иметь как минимум два сетевых интерфейса: один для интернета, другой для внутренней сети. NAT будет транслировать запросы из внутренней сети, поэтому они будут поступать от OpenBSD системы с NAT.
Когда пакеты проходят через шлюз NAT (NAT gateway), они изменяются таким образом, как будто их отправляет сам шлюз. Он записывает изменения, которые вносит в свою таблицу состояний, чтобы в последствии мог отменить изменения в возвращаемых пакетах и обеспечить, чтобы эти пакеты проходили через firewall и не блокировались. Например, могут быть сделаны следующие изменения:
Когда интернет-хост отвечает на пакеты клиентской внутренней машины, они будут адресованы внешнему IP-адресу NAT-шлюза на выбранный для NAT-соединения порт. Затем NAT шлюз выполнит поиск таблицы состояний, чтобы определить, соответствуют ли полученные пакеты уже установленному соединению. Уникальное совпадение будет найдено на основе комбинации IP/порта, которая сообщает PF, что пакеты принадлежат соединению, инициированному внутренней (клиентской) машиной. Затем PF внесет противоположные изменения в исходящие пакеты и перенаправит ответные пакеты клиентской машине во внутренней сети.
Трансляция ICMP-пакетов происходит аналогичным образом, но естественно без изменения порта клиента.
# sysctl net.inet.ip.forwarding=1 # echo 'net.inet.ip.forwarding=1' >> /etc/sysctl.confИли, если используется IPv6:
# sysctl net.inet6.ip6.forwarding=1 # echo 'net.inet6.ip6.forwarding=1' >> /etc/sysctl.conf
nat-to
параметр для
исходящего pass
правила.
Часто вместо установки pass
правила используется правило
match
.
Когда пакет попадает под критерий правила match
, параметры
(например, nat-to
) в этом правиле запоминаются и применяются
к пакету, когда достигается pass
правило, соответствующее пакету.
Это позволяет обрабатывать целый класс пакетов с помощью одного правила
match
, а затем конкретные решения о разрешении трафика можно
принимать с помощью правил block
и pass
.
На практике формат конфига pf.conf
выглядит слелующим образом:
match out on interface [af] \ from src_addr to dst_addr \ nat-to ext_addr [pool_type] [static-port] [...] pass out [log] on interface [af] [proto protocol] \ from ext_addr [port src_port] \ to dst_addr [port dst_port]
match
match
, любые дополнительные параметры,
указанные в этом правиле, запоминаются для будущего использования
(становятся "sticky" («прикрепленными»)).
pass
match
правилу, в котором были указаны параметры, они будут
применены к этому пакету. Правила pass
могут иметь свои
собственные параметры; они имеют приоритет над параметрами, указанными
в правиле match
.
out
nat-to
можно указывать только для исходящих пакетов.
log
log (all)
.
interface
af
inet
для IPv4 или inet6
для IPv6.
PF обычно может определить этот параметр на основе адреса(ов) источника/назначения.
protocol
src_addr
/netmask
(e.g. /24
).
Each IP address on the interface is combined with the netmask to
form a CIDR network block which is substituted into the rule.
:network
- substitutes the CIDR network block (e.g.,
192.168.0.0/24)
:broadcast
- substitutes the network broadcast
address (e.g., 192.168.0.255)
:peer
- substitutes the peer's IP address on a
point-to-point link
In addition, the :0
modifier can be appended to either
an interface name/group or to any of the above modifiers to
indicate that PF should not include aliased IP addresses in the
substitution.
These modifiers can also be used when the interface is contained in
parentheses.
Example: fxp0:network:0
!
("not")
modifier.
any
meaning all addresses
src_port
!=
(not equal)
<
(less than)
>
(greater than)
<=
(less than or equal)
>=
(greater than or equal)
><
(range)
<>
(inverse range)
The last two are binary operators (they take two arguments) and do not include the arguments in the range.
:
(inclusive range)
The inclusive range operator is also a binary operator and does include the arguments in the range.
port
option is not usually used in nat
rules
because the goal is usually to NAT all traffic regardless of the port(s) being
used.
dst_addr
dst_port
ext_addr
( )
.
This tells PF to update the rule if the IP address(es) on the named
interface changes.
This is highly useful when the external interface gets its IP address
via DHCP or dial-up, as the ruleset doesn't have to be reloaded each
time the address changes.
:network
- substitutes the CIDR network block (e.g.,
192.168.0.0/24)
:peer
- substitutes the peer's IP address on a
point-to-point link
In addition, the :0
modifier can be appended to either
an interface name/group or to any of the above modifiers to indicate
that PF should not include aliased IP addresses in the substitution.
These modifiers can also be used when the interface is contained in
parentheses.
Example: fxp0:network:0
pool_type
static-port
This would lead to a most basic form of these lines similar to this:
match out on tl0 from 192.168.1.0/24 to any nat-to 198.51.100.1 pass on tl0 from 192.168.1.0/24 to anyOr the following may be used:
pass out on tl0 from 192.168.1.0/24 to any nat-to 198.51.100.1This rule says to perform NAT on the
tl0
interface for any
packets coming from 192.168.1.0/24 and to replace the source IP address
with 198.51.100.1.
While the above rule is correct, it is not recommended form.
Maintenance could be difficult as any change of the external or internal
network numbers would require the line be changed.
Compare instead with this easier to maintain line (tl0
is
external, dc0
internal):
pass out on tl0 inet from dc0:network to any nat-to tl0The advantage should be fairly clear: the IP addresses of either interface can be changed without changing this rule. Note that
inet
should be specified in this case to ensure that
only IPv4 addresses are used, avoiding unexpected surprises.
When specifying an interface name for the translation address as above, the IP address is determined at pf.conf load time, not on the fly. If DHCP is being used to configure the external interface, this can be a problem. If the assigned IP address changes, NAT will continue translating outgoing packets using the old IP address. This will cause outgoing connections to stop functioning. To get around this, PF can automatically update the translation address by putting parentheses around the interface name:
pass out on tl0 inet from dc0:network to any nat-to (tl0)This method works for translation to both IPv4 and IPv6 addresses.
binat-to
parameter.
A binat-to
rule establishes a one-to-one mapping between an
internal IP address and an external address.
This can be useful, for example, to provide a web server on the internal
network with its own external IP address.
Connections from the internet to the external address will be translated to
the internal address and connections from the web server (such as DNS requests)
will be translated to the external address.
TCP and UDP ports are never modified with binat-to
rules as they
are with nat
rules.
Example:
web_serv_int = "192.168.1.100" web_serv_ext = "198.51.100.6" pass on tl0 from $web_serv_int to any binat-to $web_serv_ext
nat-to
.
Например, если приведенный выше пример NAT был изменен так:
pass out on tl0 from 192.168.1.0/24 to any nat-to 198.51.100.79 pass out on tl0 from 192.168.1.208 to anyТогда вся сеть 192.168.1.0/24 будет транслировать пакеты на внешний адрес 198.51.100.79, за исключением 192.168.1.208.
-s state
.
Эта опция выведет список всех текущих сеансов NAT:
# pfctl -s state fxp0 tcp 192.168.1.35:2132 (198.51.100.1:53136) -> 198.51.100.10:22 TIME_WAIT:TIME_WAIT fxp0 udp 192.168.1.35:2491 (198.51.100.1:60527) -> 198.51.100.33:53 MULTIPLE:SINGLEОбъясним первую строку:
self
появится, если состояние
floating
.