Friday 20 November 2009

Creating user based firewalls on inbound pptp connections

There are certain security situations where you want to be able to allow a remote user to connect to your network using pptp, but you want to lock down what devices on the network they have access to.

Usually with the linux pptp system, once the user is connected, assuming ip forwarding is running on the host that is the pptp end point, they have access to anything on the local subnet.

What I've done to allow some control over this situation is create some custom scripts to go in /etc/ppp/ip-up.d and /etc/ppp/ip-down.d

For the "up" version I have:

#!/bin/sh

PPP_USER=`/usr/bin/w | /bin/grep "$PPP_IFACE" | sed "s/ .*//"`

if [ -x "/etc/ppp/userfw/$PPP_USER" ]; then
"/etc/ppp/userfw/$PPP_USER"
fi

exit 0


and for the down version I have

#!/bin/sh

PPP_RULE=`/sbin/iptables -L FORWARD -n -v --line-numbers | /bin/grep "$PPP_IFACE" | /usr/bin/head -1 | /bin/sed "s/ .*//"`
while [ "$PPP_RULE" != "" ]
do
/sbin/iptables -D FORWARD "$PPP_RULE"
PPP_RULE=`/sbin/iptables -L FORWARD -n -v --line-numbers | /bin/grep "$PPP_IFACE" | /usr/bin/head -1 | /bin/sed "s/ .*//"`
done

PPP_RULE=`/sbin/iptables -L INPUT -n -v --line-numbers | /bin/grep "$PPP_IFACE" | /usr/bin/head -1 | /bin/sed "s/ .*//"`
while [ "$PPP_RULE" != "" ]
do
/sbin/iptables -D INPUT "$PPP_RULE"
PPP_RULE=`/sbin/iptables -L INPUT -n -v --line-numbers | /bin/grep "$PPP_IFACE" | /usr/bin/head -1 | /bin/sed "s/ .*//"`
done

exit 0


Then create a directory /etc/ppp/userfw and put in there per user scripts

e.g.
#!/bin/sh
/sbin/iptables -A FORWARD -i "$PPP_IFACE" -j ACCEPT
/sbin/iptables -A INPUT -i "$PPP_IFACE" -j ACCEPT


(yes - that's a silly example as it just gives complete access - which they had anyway)

With this lot, you have a simple method to lock certain users down to only be able to access certain things on your network - within the flexibility of the iptables system. The important thing to do is to make sure that your user based rules all reference the interface with $PPP_IFACE so that they are attached to the right connection and they're deleted again with the down script when the interface is removed.

No comments: