Port-Forward para todos os IPs em uma interface

2

Estou executando um servidor da Web baseado em java como um usuário não privilegiado. Portanto, ele escuta nas portas 8080 e 8443 em vez de 80 e 443.

Neste momento, estou usando as seguintes regras pf para encaminhar as portas internamente:

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

(com macros definidas para $ext_if e $ext_ip , obviamente)

Agora quero adicionar mais IPs à interface (para SSL vHosts) - qual é a melhor maneira de fazer isso? Tenho que repetir essas regras para cada IP adicionado? Ou posso de alguma forma fazer uma regra para "todos os IPs nessa interface"?

EDIT: Infelizmente, os IPs não são da mesma sub-rede. Eu tentei listá-los na macro $ext_ip , mas ainda preferiria uma solução em que não precise adicionar todos os IP explicitamente.

Obrigado!

    
por Henning 05.12.2011 / 12:30

3 respostas

1

Minha pesquisa mostra que não há nenhuma cláusula pf.conf que permita obter esse nível de expansão de regras um para um.

Eu esperava que você pudesse fazer isso com macros, o que no seu caso seria algo como:

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

... mas se a macro for usada mais de uma vez na mesma linha, ela expandirá as últimas para a macro inteira e invocará o round-robin:

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

... o que eu tenho certeza que não foi o que você pretendia. :-) As tabelas também parecem estar fora. A página man explicitamente diz:

"As tabelas também podem ser usadas para o endereço de redirecionamento das regras nat e rdr e nas opções de roteamento das regras de filtragem, mas apenas para os pools de round-robin."

Então, infelizmente, parece que sua única opção é manter manualmente a lista ou gerá-la como um arquivo separado e incluí-la.

Além disso, infelizmente, a cláusula include não é mencionada nas páginas pf.conf man nos meus sistemas 7.4, 8.2 ou 9.0-RC2, então se você estiver executando o PF padrão que acompanha o FreeBSD, acredito que eles estejam rodando o PF importado do OpenBSD 4.5, que não parece suportar include ... mas só por precaução, aqui está uma maneira de gerar o 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

... que seria importado para o pf.conf com:

include "/etc/pf.conf.vhosts"

Se você não estiver executando um PF que ofereça suporte a includes, será um pouco mais complicado, mas você terá a ideia.

Desculpe pela pesquisa ligeiramente dispersa; Eu também não consegui encontrar uma maneira canônica de perguntar à PF por suas informações de versão, então tive que me debater um pouco.

EDITAR: Você pode fazer inclusões com a cláusula load anchor , embora pareça que você terá que repetir sua macro $ext_if dentro da âncora.

    
por 06.12.2011 / 05:15
0

Supondo que todos os IPs estejam na mesma sub-rede, você pode usar Agregação

$ext_net = "192.168.1.0/24"
    
por 05.12.2011 / 17:10
0

Não acho que você precise fazer algo especial, pois os aliases não são configurados como dispositivos de rede separados. Isso é diferente do Linux, no qual você tem eth0 , eth0:1 , eth0:2 que são tratados como interfaces discretas. Conseqüentemente, as regras pf devem se expandir para aplicar a todo o endereço IP presente nessa interface:

# 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

Usando as seguintes regras 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

E isso se expande para o seguinte ...

@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

Você precisará reaplicar suas regras pf usando pfctl , mas isso é tudo o que você precisa fazer para considerar os endereços IP com alias, supondo que suas macros e regras estejam corretas.

Além disso, você pode ignorar todos os aliases em uma interface no pf, listando-o em interface:0 .

    
por 06.12.2011 / 06:19