Before I begin, uPnP does have some security implications. Users that can send uPnP requests can open any port to any other computer. Please read the comments below for more details.
If you are currently using a Linux router on a home network, you should consider uPnP. uPnP allows computers to request ports be opened for them, so applications that require open ports can work without work of the owner of the Linux router.
apt-get install libupnp0 linux-igd
Edit /etc/default/upnpd and specify your external and internal interfacecs; upnp does not support multiple interfaces but I suspect multiple instances of this program could accomplish this; just replace the /etc/init.d/upnpd file with a custom one like this
#!/bin/bash
case $1 in
start)
upnpd eth0 eth1
upnpd eth0 eth2
;;
stop)
killall upnpd
;;
esac
Restart the daemon, and you should see clients requesting ports in /var/log/syslog (grep for upnp).
If you do not, make sure that you see the following line in “route”
239.0.0.0 * 255.0.0.0 U 0 0 0 eth3
Where eth3 is your internal interface. If not, add it with
route add -net 239.0.0.0 netmask 255.0.0.0 eth3
Also, if you are blocking any ports with your firewall configuration, you may have to do the following to allow your clients request to reach the server.
iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 2869 -j ACCEPT
iptables -A INPUT -s 192.168.1.0/24 -p udp --dport 1900 -j ACCEPT
Where 192.168.1.0/24 is your internal network.
A good way to test to make sure this is working is using the Azureus bittorrent client’s NAT checking tool.
Below is a two network firewall script that I am currently using with uPnP; I can’t make any guarantees to how secure it is but it works quite well.
IP2="76.249.179.145"
IP3="76.249.179.147"
/sbin/ip addr add dev eth0 $IP2
/sbin/ip addr add dev eth0 $IP3
/sbin/depmod -a
/sbin/modprobe ip_tables
/sbin/modprobe ip_conntrack
/sbin/modprobe ip_conntrack_ftp
/sbin/modprobe ip_conntrack_irc
/sbin/modprobe iptable_nat
/sbin/modprobe ip_nat_ftp
/sbin/modprobe ip_nat_irc
IPT="/sbin/iptables"
INT0="eth0"
INT2="eth2"
INT3="eth3"
echo "1" > /proc/sys/net/ipv4/ip_forward
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo "65535" > /proc/sys/net/ipv4/ip_conntrack_max
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo "1" > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses
echo "1" > /proc/sys/net/ipv4/conf/all/accept_redirects
echo "0" > /proc/sys/net/ipv4/conf/all/log_martians
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 9000 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 1 > /proc/sys/net/ipv4/tcp_window_scaling
echo 0 > /proc/sys/net/ipv4/tcp_sack
echo 3000 > /proc/sys/net/ipv4/tcp_max_syn_backlog
$IPT -F
$IPT -X
$IPT -Z
$IPT -P INPUT DROP
$IPT -P FORWARD ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -N DROPLOG
$IPT -A DROPLOG -j ULOG -m limit --limit 2/hour --ulog-nlgroup 1 --ulog-qthreshold 20
$IPT -A DROPLOG -j REJECT
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -i $INT2 -j ACCEPT
$IPT -A INPUT -i $INT3 -j ACCEPT
$IPT -A FORWARD -i $INT3 -o $INT0 -j ACCEPT
$IPT -A FORWARD -i $INT0 -o $INT3 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -A FORWARD -i $INT2 -o $INT0 -j ACCEPT
$IPT -A FORWARD -i $INT0 -o $INT2 -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPT -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source $IP2
$IPT -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j SNAT --to-source $IP3
$IPT -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
$IPT -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE
$IPT -t nat -A POSTROUTING -s 192.168.2.48 -d 192.168.0.0/16 -j ACCEPT
$IPT -t nat -A POSTROUTING -s 192.168.0.0/16 -d 192.168.2.48 -j ACCEPT
$IPT -t nat -A POSTROUTING -s 192.168.1.1 -d 192.168.1.240 -j ACCEPT
$IPT -t nat -A POSTROUTING -s 192.168.1.240 -d 192.168.1.1 -j ACCEPT
$IPT -t nat -A POSTROUTING -s 192.168.2.48 -d 192.168.1.0/16 -j ACCEPT
$IPT -A INPUT -p tcp --dport 22 -j ACCEPT
$IPT -A INPUT -p tcp --dport 80 -j ACCEPT
#Allow uPnP from internal clients
$IPT -A INPUT -s 192.168.1.0/24 -p tcp --dport 2869 -j ACCEPT
$IPT -A INPUT -s 192.168.1.0/24 -p udp --dport 1900 -j ACCEPT
$IPT -A INPUT -s 192.168.2.0/24 -p tcp --dport 2869 -j ACCEPT
$IPT -A INPUT -s 192.168.2.0/24 -p udp --dport 1900 -j ACCEPT
$IPT -A INPUT -i eth2 -j ACCEPT
$IPT -A INPUT -i eth3 -j ACCEPT
$IPT -A INPUT -s 192.168.20.0/24 -j ACCEPT
$IPT -A INPUT -p tcp -s 192.168.1.0/24 --dport 3128 -j ACCEPT
$IPT -A INPUT -p tcp -s 192.168.2.0/24 --dport 3128 -j ACCEPT
$IPT -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 192.168.1.1:3128
$IPT -t nat -A PREROUTING -i eth2 -p tcp --dport 80 -j DNAT --to 192.168.1.1:3128
$IPT -t nat -A PREROUTING -i eth3 -p tcp --dport 80 -j DNAT --to 192.168.1.1:3128
$IPT -t nat -A PREROUTING -i eth4 -p tcp --dport 80 -j DNAT --to 192.168.1.1:3128
$IPT -t nat -A PREROUTING -i eth5 -p tcp --dport 80 -j DNAT --to 192.168.1.1:3128
$IPT -A INPUT -i eth0 -p tcp --syn --destination-port 3128 -j DROPLOG
$IPT -A INPUT -j DROPLOG