Назад | Перейти на главную страницу

Переадресация портов для всех 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-адрес.

Спасибо!

Мои исследования показывают, что нет 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 страницы руководства в моих системах 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, который поддерживает include, это будет немного сложнее, но вы поняли идею.

Извините за немного разрозненное исследование; Я также не смог найти канонического способа запросить у 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"