Port-Forward для всех IP на интерфейсе
Я использую веб-сервер на основе Java как непривилегированный пользователь. Поэтому он прослушивает порты 8080 и 8443 вместо 80 и 443.
Прямо сейчас я использую следующее pf
правила для внутренней переадресации портов:
rdr pass on $ext_if proto tcp from any to $ext_ip port 80 -> $ext_ip port 8080
rdr pass on $ext_if proto tcp from any to $ext_ip port 443 -> $ext_ip port 8443
(с макросами, определенными для $ext_if
а также $ext_ip
очевидно)
Теперь я хочу добавить больше IP-адресов в интерфейс (для SSL vHosts) - как лучше всего это сделать? Нужно ли повторять эти правила для каждого добавленного IP? Или я могу как-то сделать правило для "каждого IP на этом интерфейсе"?
РЕДАКТИРОВАТЬ: К сожалению, IP-адреса не из одной подсети. Я попытался перечислить их в $ext_ip
макрос, но я все еще предпочел бы решение, где мне не нужно явно добавлять каждый IP.
Спасибо!
3 ответа
Мои исследования показывают, что нет pf.conf
пункт, который даст вам этот уровень однозначного расширения правил.
Я надеялся, что вы могли бы сделать это с макросами, которые в вашем случае были бы что-то вроде:
vhost_ips = "{ 198.51.100.4, 198.51.100.5 }"
rdr pass on $ext_if proto tcp from any to $vhost_ips port 80 -> $ext_ip port 8080
rdr pass on $ext_if proto tcp from any to $vhost_ips port 443 -> $ext_ip port 8443
... но если макрос используется более одного раза в одной и той же строке, он фактически расширяет последние до всего макроса и вызывает циклический перебор:
rdr pass on int0 proto tcp from any to 198.51.100.4 port 80 -> { 198.51.100.4, 198.51.100.5 } port 8080 round-robin
rdr pass on int0 proto tcp from any to 198.51.100.5 port 443 -> { 198.51.100.4, 198.51.100.5 } port 8443 round-robin
... что я уверен, что это не то, что вы хотели.:-) Таблицы также, кажется, отсутствуют. Страница руководства прямо говорит:
"Таблицы могут также использоваться для адреса перенаправления правил nat и rdr и в параметрах маршрутизации правил фильтрации, но только для циклических пулов".
Так что, к сожалению, похоже, что ваш единственный вариант - вручную поддерживать список или создать его в виде отдельного файла и включить его.
Также, к сожалению, include
пункт не упоминается в pf.conf
man-страницы в моих системах 7.4, 8.2 или 9.0-RC2, поэтому, если вы работаете со стандартной PF, поставляемой с FreeBSD, я считаю, что они работают с PF, импортированным из OpenBSD 4.5, которая, похоже, не поддерживает include
... но на всякий случай вот способ сгенерировать include:
$ cat vhost.list
198.51.100.4
198.51.100.5
$ cat gen-vhosts-pf.sh
#!/bin/sh
for ip in `egrep -v ^# /etc/vhost.list`; do
echo "rdr pass on \$ext_if proto tcp from any to $ip port 80 -> $ip port 8080"
echo "rdr pass on \$ext_if proto tcp from any to $ip port 443 -> $ip port 8443"
done
$ ./gen-vhosts-pf.sh | sudo tee /etc/pf.conf.vhosts
rdr pass on $ext_if proto tcp from any to 198.51.100.4 port 80 -> 198.51.100.4 port 8080
rdr pass on $ext_if proto tcp from any to 198.51.100.4 port 443 -> 198.51.100.4 port 8443
rdr pass on $ext_if proto tcp from any to 198.51.100.5 port 80 -> 198.51.100.5 port 8080
rdr pass on $ext_if proto tcp from any to 198.51.100.5 port 443 -> 198.51.100.5 port 8443
... который будет импортирован в pf.conf с:
include "/etc/pf.conf.vhosts"
Если вы не используете PF с поддержкой включений, это будет немного сложнее, но вы поняли идею.
Извините за немного разбросанные исследования; Я также не смог найти канонический способ запросить у PF информацию о его версии, поэтому мне пришлось немного повозиться.
РЕДАКТИРОВАТЬ: Вы можете сделать в том числе с load anchor
пункт, хотя, похоже, вам придется повторить $ext_if
макрос внутри якоря.
Я не думаю, что вам нужно делать что-то особенное, поскольку псевдонимы не настроены как отдельные сетевые устройства. Это в отличие от Linux, где у вас есть eth0
, eth0:1
, eth0:2
которые рассматриваются как дискретные интерфейсы. Следовательно, правила pf должны быть расширены для применения ко всем IP-адресам, присутствующим на этом интерфейсе:
# ifconfig sis2 192.168.4.1 netmask 255.255.255.0 alias
# ifconfig sis2
sis2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:00:24:c6:4d:ee
priority: 0
media: Ethernet autoselect (100baseTX full-duplex)
status: active
inet 192.168.1.1 netmask 0xffffff00 broadcast 192.168.1.255
inet6 fe80::200:24ff:fec6:4dee%sis2 prefixlen 64 scopeid 0x3
inet 192.168.4.1 netmask 0xffffff00 broadcast 192.168.4.255
Используя следующие правила pf...
# allow untrusted -> trusted ssh & http traffic
untrust="sis2"
pass in log on $untrust inet proto tcp from $untrust:network to $trust:network port 22
pass in log on $untrust inet proto tcp from $untrust:network to $trust:network port 80
И это распространяется на следующее...
@32 pass in log on sis2 inet proto tcp from 192.168.1.0/24 to 192.168.0.0/24 port = ssh flags S/SA
@33 pass in log on sis2 inet proto tcp from 192.168.1.0/24 to 192.168.0.0/24 port = www flags S/SA
@34 pass in log on sis2 inet proto tcp from 192.168.4.0/24 to 192.168.0.0/24 port = ssh flags S/SA
@35 pass in log on sis2 inet proto tcp from 192.168.4.0/24 to 192.168.0.0/24 port = www flags S/SA
@36 pass in log on sis1 inet proto tcp from 192.168.0.0/24 to 192.168.0.1 port = ssh flags S/SA
Вам нужно будет повторно применить ваши правила pf, используя pfctl
но это все, что вам нужно сделать, чтобы учесть псевдонимы IP-адресов, если ваши макросы и правила верны.
Кроме того, вы можете игнорировать все псевдонимы интерфейса в pf, перечислив его interface:0
,
Предполагая, что все IP-адреса находятся в одной подсети, вы можете использовать агрегацию
$ext_net = "192.168.1.0/24"