Universal Plug and Play (uPnP) in Debian

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

11 Responses to “Universal Plug and Play (uPnP) in Debian”

  1. Nick Leverton says:

    Hi,

    I’m currently in the process of updating linux-igd for the forthcoming release of Lenny. Thanks for the plug for this software ! I would like to pass on the SECURITY note which will be in the next version of the package:

    Be aware that, even if this software and the upnp libraries all prove
    to be bug free and completely secure, the Microsoft Internet Gateway
    Device is designed to allow any computer that has access to the daemon
    to open up any ports on your firewall and give incoming port forwarding
    to any other port on any internal computer (possibly also external,
    I haven’t tested that).

    This means that a PC or game console which you want to allow to
    forward ports to itself can also open and redirect any ports to any
    other machine.

    You can restrict the ranges of access by limiting access to your
    configured IGD uPnP chains through further iptables rules or chains,
    but you cannot make linux-igd secure because IGD is insecure by design.
    It may in future be possible to restrict use of linux-igd but this
    has not yet been done. I am sure contributions will be welcome.

    Also, some uPnP features may allow computers to execute programs
    on the uPnP gateway, so you should think about running upnpd in a
    chroot containing no other binaries. I do not know whether this was
    uPnP’s intention but it seems to be a risk with some implementations.
    Using a chroot is doubly important since linux-igd by default runs as
    root in order to manipulate netfilter iptables.

  2. Bwuutje says:

    I would take that ‘seriously consider’ out.

    Serious.

    One that is wise enough to run Linux and Netfilter should and will not seriously consider running uPnP. Since it is a dangerous way of dynamically opening the firewall. One infection of one machine in the LAN is enough to undo the whole fireall function.

    Serious.

    Bwuutje.

  3. Bwuutje says:

    Keep in mind I object the term ‘seriously consider’ not the article itself !

    Bwuutje.

  4. termina says:

    While I understand there are security issues with uPnP, can’t most of these issues be solved using iptables? I don’t have any uPnP exploits (if you know of one, could you direct me to it? Seems like a great way to test a firewall using uPnP).

    I’ve edited the post, and am using my firewall rules script as an example. Could you let me know what I could change to make uPnP less of a security risk? 🙂

  5. Bwuutje says:

    No, IGD is (also) about opening the firewall. So changing the iptables rules.

    Nick Levertons posting is correct and explains it very nicely.

    Nice article, surely helpful. But I still object to the one term 🙂

    Bwuutje.

  6. termina says:

    Your objection has been noted, and over-ruled.

    Well, actually I removed it. 🙂 Thanks for your comments.

    I’ve also added a bit of a disclaimer at the beginning.

  7. Vineeth says:

    Hi guys,

    Is there any way that i can make my ubuntu laptop act as a UPnP device?

    I want to be able to view my media on the laptop on a different device/PC.

  8. termina says:

    I don’t think you understand what uPnP is.

    If you want to view your media from a different machine, you might want to look into NFS, to be able to mount your media files to other machines over the network.

  9. Vineeth says:

    You sir are actually right. I really don’t understand what Upnp is, never heard the word. I read up on it for half an hour and started looking for solutions. My friend suggested me Upnp and thats what i went with. This is what i am trying to achieve. I have a ton of media on my Ubuntu laptop. Lets say i bring in a brand new PC and connect it to my local network, i want my PC to notify me that there is a Laptop that can share its media or (the way i understand) say a Upnp service is available. I just want to accept and start getting my media right away. The philosophy is how you use a USB drive, you insert a usb drive and the computer tells u about its presence and u open it and start using it. I tried “Fuppes” yesterday and i got it to work on my Ps3 and Xbox 360. They showed up as media servers. But i just cant get it to show up on my Windows laptop. I will definitely look into NFS as you suggested. If you have suggestions please let me know.

  10. termina says:

    Windows and NFS is a bit complicated; look into setting up a SAMBA file server for this. Ubuntu has graphical ways to share folders using samba; just right-click and go to ‘Sharing Options’

  11. termina says:

    Updated article so copying/pasting will no longer garble the quote character.

Leave a Reply to Bwuutje Cancel reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.