Суть задачи сводиться к пробросу порта для torrent клиента на машину в локальной сети (172.16.2.1:57941)
Имеем:gateway# uname -a
FreeBSD gateway.myhome.network 8.2-RELEASE FreeBSD 8.2-RELEASE #1: Wed Oct 26 15:40:52 EEST 2011 xxxxx@gateway.myhome.network:/usr/obj/usr/src/sys/NEWKERNEL i386
gateway# ifconfig
stge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
ether 00:1d:60:5c:72:b2
inet 172.16.2.38 netmask 0xffffff00 broadcast 172.16.2.255
media: Ethernet autoselect (100baseTX <full-duplex,flowcontrol,rxpause,txpause>)
status: active
stge1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=8209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC,LINKSTATE>
ether 00:00:21:22:14:e3
inet ХХХ.ХХХ.45.116 netmask 0xfffffe00 broadcast ХХХ.ХХХ.45.255
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
gateway# diff /usr/src/sys/i386/conf/GENERIC /usr/src/sys/i386/conf/NEWKERNEL
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT=50
options IPFIREWALL_NAT
options LIBALIAS
options ROUTETABLES=2
options DUMMYNET
options DEVICE_POLLING
options HZ="1000"
options NETGRAPH
options NETGRAPH_ETHER
options NETGRAPH_SOCKET
options NETGRAPH_TEE
options NETGRAPH_MPPC_ENCRYPTION
#options NETGRAPH_MPPC_COMPRESSION
options NETGRAPH_BPF
options NETGRAPH_IFACE
options NETGRAPH_KSOCKET
options NETGRAPH_L2TP
options NETGRAPH_PPP
options NETGRAPH_PPPOE
options NETGRAPH_PPTPGRE
options NETGRAPH_TCPMSS
options NETGRAPH_VJC
options NETGRAPH_ONE2MANY
options NETGRAPH_RFC1490
options NETGRAPH_TTY
options NETGRAPH_UI
gateway# cat /etc/rc.conf
ifconfig_stge0="inet 172.16.2.38 netmask 255.255.255.0"
ifconfig_stge1="dhcp"
ifconfig_stge1_alias0="lladdr 00:00:21:22:14:e3"
gateway_enable="YES"
firewall_enable="YES"
firewall_script="/usr/local/etc/ipfw_rules.sh"
gateway# sysctl -a | grep net.inet.ip.fw
net.inet.ip.fw.default_to_accept: 0
net.inet.ip.fw.autoinc_step: 10
net.inet.ip.fw.one_pass: 0
net.inet.ip.fw.enable: 1
gateway# ipfw nat show config
ipfw nat 1 config if stge1 log same_ports unreg_only reset redirect_port udp 172.16.2.1:57941 57941 redirect_port tcp 172.16.2.1:57941 57941
ipfw nat 2 config if ng0 log same_ports unreg_only reset redirect_port udp 172.16.2.1:57941 57941 redirect_port tcp 172.16.2.1:57941 57941
gateway# cat /usr/local/etc/ipfw_rules.sh
#!/bin/sh
flg="-q"
cmd="/sbin/ipfw $flg"
if [ $flg != "-n" ] ; then
$cmd flush
$cmd pipe flush
$cmd queue flush
fi
iflan="stge0"
ifdmz="stge1"
ifppp="ng0"
ifvpn="ng1"
nat_out="skipto 4000"
else_deny="skipto 5000"
ks="keep-state"
sks="setup $ks"
verbose="log logamount 100"
clientd="dst-port 1024-65535"
clients="src-port 1024-65535"
pppon="set 2" # включаем правила с ng0 интерфейсом после поднятия pppoe интерфейса
vpnon="set 3" # включаем правила с ng1 интерфейсом после поднятия vpn интерфейса
# создаем таблицу адресов специального назначения для интерфейса DMZ
$cmd table 1 add 0/8 # loopback
$cmd table 1 add 127.0/8 # loopback
$cmd table 1 add 172.16.0/12 # RFC 1918 private IP
$cmd table 1 add 192.0.2.0/24 # reserved for docs
$cmd table 1 add 169.254.0/16 # DHCP auto config
$cmd table 1 add 204.152.64.0/23 # Sun cluster interconnect
$cmd table 1 add 224.0/3 # class D multicast
$cmd table 1 add 240.0/4 # class E multicast
# создаем таблицу адресов специального назначения для интерфейса PPP
$cmd table 2 add 0/8 # loopback
$cmd table 2 add 127.0/8 # loopback
$cmd table 2 add 192.168.0/16 # RFC 1918 private IP
$cmd table 2 add 172.16.0/12 # RFC 1918 private IP
$cmd table 2 add 10.0/8 # RFC 1918 private IP
$cmd table 2 add 192.0.2.0/24 # reserved for docs
$cmd table 2 add 169.254.0/16 # DHCP auto config
$cmd table 2 add 204.152.64.0/23 # Sun cluster interconnect
$cmd table 2 add 224.0/3 # class D multicast
$cmd table 2 add 240.0/4 # class E multicast
$cmd set disable 2
$cmd set disable 3
#################################################
# Описываем правила
#################################################
# разрешаем все для внутреннего интерфейса
$cmd add allow via $iflan
# разрешаем кольцо
$cmd add allow via lo0
# разрешаем все для vpn интерфейса
$cmd add set 3 allow via $ifvpn
# чтобы не гонять анализатор по всем правилам, делим правила по направлениям движения пакетов
$cmd add skipto 1000 proto all in recv $ifdmz # входящий трафик обработаем потом.
$cmd add $pppon skipto 1000 proto all in recv $ifppp # входящий трафик обработаем потом.
# разрешаем установленные соединения
$cmd add check-state
# запрещаем ACK пакеты отсутствующие в таблице динамических правил
$cmd add deny $verbose proto tcp established
#################################################
# Секция исходящих пакетов (заворачиваем что нужно на NAT, остальное баним)
# С этого места и далее пакеты только принятые с внутреннего интерфейса
# и предназначенные для отправки на внешние, поэтому где нет необходимости
# опции указывающие через какие интерфейсы будут идти пакеты можно опустить.
#################################################
# разрешаем HTTP и HTTPS, POP3, SMTP и SMTPS(465 и 587), IMAP(143) и IMAPS(993), ICQ(5190)
$cmd add 200 $nat_out proto tcp $clients dst-port 25,80,110,443 out xmit $ifdmz $sks
$cmd add $pppon $nat_out proto tcp $clients dst-port 25,80,110,143,443,465,587,993,5190 out xmit $ifppp $sks
# разрешаем исходящие torrent
$cmd add $nat_out proto tcp src-port 57941 $clientd $sks
$cmd add $nat_out proto udp src-port 57941 $clientd $ks
[поскипано]
# запрещаем что не разрешили
$cmd add $else_deny proto all
# КОНЕЦ СЕКЦИИ ИСХОДЯЩИХ ПАКЕТОВ
#################################################
#################################################
# секция входящих пакетов
#################################################
# запрещаем то, чего не должно быть
$cmd add 1000 deny { src-ip "table(1)" or dst-ip "table(1)" } in recv $ifdmz
$cmd add $pppon deny { src-ip "table(2)" or dst-ip "table(2)" } in recv $ifppp
[еще много чего запрещаем]
# проверяем входящие пакеты на наличие записей в таблице NAT + перенаправляем порт 57941
$cmd add nat 1 $verbose proto all in recv $ifdmz
$cmd add $pppon nat 2 $verbose proto all in recv $ifppp
# разрешаем установленные соединения
$cmd add check-state
##### $TORRENT ########
$cmd add allow $verbose proto tcp $clients dst-port 57941 in recv $ifdmz $sks
$cmd add allow $verbose proto udp $clients dst-port 57941 in recv $ifdmz $ks
$cmd add $pppon allow $verbose proto tcp $clients dst-port 57941 in recv $ifppp $sks
$cmd add $pppon allow $verbose proto udp $clients dst-port 57941 in recv $ifppp $ks
# запрещаем ACK пакеты отсутствующие в таблице динамических правил
$cmd add deny $verbose proto tcp established
# запрещаем что не разрешили
$cmd add $else_deny proto all
#################################################
#################################################
##### $NAT_OUT ########
# секция исходящих пакетов
[стандартная процедура, ничего интересного]
$cmd add 4000 allow proto all in recv $ifdmz # ответный stateful пакет соответствующго исходящего
$cmd add $pppon allow proto all in recv $ifppp
$cmd add nat 1 $verbose out xmit $ifdmz
$cmd add $pppon nat 2 $verbose out xmit $ifppp
$cmd add allow $verbose proto all out
# КОНЕЦ NAT_OUT СЕКЦИИ
#################################################
#################################################
# запрещаем что не разрешили
$cmd add 5000 deny log logamount 0 via $iflan
$cmd add 5010 deny log logamount 0 via $ifdmz
$cmd add 5020 $pppon deny log logamount 0 via $ifppp
$cmd add 5030 deny log logamount 0 proto all
и результат работы напоследок (только значащие правила):
gateway# ipfw -cd show
00230 0 0 skipto 4000 proto tcp src-port 57941 dst-port 1024-65535 setup keep-state
00240 194365 88915868 skipto 4000 proto udp src-port 57941 dst-port 1024-65535 keep-state
01120 47 2416 allow log logamount 100 proto tcp src-port 1024-65535 dst-port 57941 in recv stge1 setup keep-state
01130 17 1023 allow log logamount 100 proto udp src-port 1024-65535 dst-port 57941 in recv stge1 keep-state
01140 525 25496 allow log logamount 100 proto tcp src-port 1024-65535 dst-port 57941 in recv ng0 setup keep-state
01150 731 46063 allow log logamount 100 proto udp src-port 1024-65535 dst-port 57941 in recv ng0 keep-state
01160 14 736 allow log logamount 100 proto tcp src-port 1024-65535 dst-port 32049 in recv ng0 setup keep-state
01170 6 273 allow log logamount 100 proto udp src-port 1024-65535 dst-port 32049 in recv ng0 keep-state
01180 9 528 allow log logamount 100 proto tcp src-port 1024-65535 dst-port 8794 in recv ng0 setup keep-state
01190 13 632 allow log logamount 100 proto udp src-port 1024-65535 dst-port 8794 in recv ng0 keep-state
и динамические правила (только входящие):
## Dynamic rules (263):
01150 3 174 (8s) STATE udp 87.103.211.202 41721 <-> 172.16.2.1 57941
01150 3 174 (7s) STATE udp 109.54.53.119 53674 <-> 172.16.2.1 57941
01150 0 0 (7s) STATE udp 89.179.43.25 13533 <-> 172.16.2.1 57941
01150 3 174 (6s) STATE udp 188.134.33.167 61293 <-> 172.16.2.1 57941
01150 3 174 (7s) STATE udp 195.209.233.252 35178 <-> 172.16.2.1 57941
01140 5 240 (298s) STATE tcp 85.114.21.255 63838 <-> 172.16.2.1 57941
01150 0 0 (4s) STATE udp 84.203.72.155 38202 <-> 172.16.2.1 57941
то есть вроде работает, но сервисы не соглашаются.
В частности http://www.whatsmyip.org/port-scanner/ радостно сообщает что "Port 57941 Timed-out"
gateway# netstat -Aa не показывает интересующий меня порт на прослушке и вообще никак.
Где я чего как обычно не доглядел???