Allowing a VPN through the Linux firewall


 

 

 

 

 

Introduction to this web page

This web page is about configuring a Linux firewall to allow it to pass a VPN connection. It is based on the script used in earlier web pages on this site about setting up a Linux firewall.

Note that the changes shown below to the firewall configuration script are being made in order to allow a VPN conection to a remote VPN server. The VPN client is on the secure subnet behind the firewall.

These changes may not allow a VPN connection through the firewall where the VPN server is behind the firewall.

 

A brief introduction to VPN`s

As the name implies, a Virtual Private Network is a way of establishing a secure private connection between two computers separated by a public network system, such as the internet.

It is a virtual network, because it doesn`t set up a discrete physical connection between the two computers, the two computers agree a way of talking to each other across the public network in a way that is unknown to any other computers, so they appear to have a private connection

There are several ways of implementing a VPN, some of the methods used are

  • PPTP - designed by Microsoft, used as the default on Windows XP

  • IPsec - originally designed to go with IPv6, it has now been ported to IPv4. It is more secure than PPTP, however there are a few different incarnations of it, so there can be incompatibilty problems with it.

  • Other propriety systems, where the client and server are ( probably ) supplied by a single manufacturer

This web page is about getting PPTP through the Linux Firewall, with an XP client on the secure subnet talking to a remote PPTP compatible VPN server.

 

The PPTP protocol

The PPTP protocol has two parts to it

  • A TCP over IP based control part, that runs on port 1723

  • A GRE over IP based data part. GRE is the General Routing Encapsulation protocol, sometimes referred to as Generic Routing Encapsulation. According to IANA, this is specified as protocol number 47

Once there is an established connection, the VPN client is talking to the VPN server via an IP based series of packets.

This series of packets is encapsulated in a series of GRE packets, which are exchanged over normal IP based packets via the public network.

So this means the client actually has two ip addresses - the one used by the core connection, and the one used by layer 3 for the packets crossing the public network.

As far as the firewall is concerned, we only need to worry about the ip addresses used at layer 3 for connections via the public network.

 

Through the firewall

Quite a lot of documentation about VPN`s talks about tunnels - setting up a tunnel across a network, or creating a tunnel through a firewall for a VPN connection.

We don`t need to create a tunnel through our Linux firewall for VPN traffic - it is preferable to treat VPN packets just as any other packet, and to use the same type of filtering.

To do this, we treat the two parts of the VPN connection differently.

The first part, the TCP/IP packets on port 1723, can be treated exactly the same as any other TCP/IP packet, and we add some rules for port 1723.

For the incoming packets, we add the rule

    iptables -t filter -A incoming-1 -p tcp --sport 1723 -s 123.45.67.89 -j incoming-2 

and for the outgoing packet, we add

    iptables -t filter -A outgoing-2 -p tcp --dport 1723 -d 123.45.67.89 -j ACCEPT 

Both of these lines are placed along side the other rules that specify ports.

The second part, the GRE data packets, do require some special treatment, as all the rules on the firewall are currently designed around TCP/IP, UDP/IP, or ICMP/IP.

For the incoming packets, we add the rule

    iptables -t filter -A incoming-1 -p 47 -s 123.45.67.89 -j incoming-2 

and for the outgoing packets, we add

    iptables -t filter -A outgoing-2 -p 47 -d 123.45.67.89 -j ACCEPT 

And as above, these rules can be placed along with the rules with specify the various ports.

We now have to add a rule to allow stateful packet filtering for the data part of the VPN connection. The existing rules for this only specify that TCP, UDP, and ICMP packets are subject to stateful packet filtering. So we add the rule -

    iptables -t filter -A incoming-2 -p 47 -m state --state ESTABLISHED -j ACCEPT 

This rule can be placed alongside the other rules that specify that stateful packet filtering is required.

Note that the keyword "ESTABLISHED" in this rule doesn`t have the same meaning as it does in Cisco router access lists.

In Cisco access lists, the keyword ESTABLISHED means that the packet header is examined for the status of the ACK and RST flags. As it is only TCP packets that have ACK and RST flags, the ESTABLISHED keyword can only be used with TCP packets.

In the Linux iptables world, the ESTABLISHED keyword means that the incoming packet is compared to the database of outgoing packets within the ip_conntrack module, and a decision is made whether to accept or reject the incoming packet from that comparison. As the status of flags is not part of the decision making process, the technique can be used for many different types of packet - TCP, UDP, ICMP, GRE, etc. So we can do full stateful packet filtering on the GRE packets, as well as on the TCP/IP port 1723 control packets.

This stateful packet filtering in Linux iptables is similar in effect to Cisco reflexive access lists.

 

A sample script

If you want a full sample of the shell configuration script for a firewall that allows a PPTP based VPN to travel through it, then here it is.

As on previous web pages, this link is to an actual shell script, not a web page. You should be able to download it through your browser, though some browers will display it as if it is a normal html coded web page.

 

More on VPN tunnels

Having now established that we don`t need to create a tunnel through our firewall in order to get the VPN link through the firewall, at first sight, it appears that our secure subnet is still safe.

However it isn`t - because the existence of the VPN has created a diferent kind of tunnel through our firewall - our firewall doesn`t look inside the encapsulated traffic contained within the GRE packets.

So any kind of corrupt or malicious packets that get encapsulated at the far end of the VPN link will pass through our firewall without detection, and can then get access to the hosts on the secure subnet.

At present, my thinking on this is that we need 3 firewalls to provide effective protection. Is this paranoia ?

Here is the arrangement -

 

The theory is that

  • Firewall 1 allows through the wanted baseband packets for HTTP, POP 3, Telnet, DNS, etc, but blocks malicious packets. It also blocks the VPN traffic.

  • Firewall 2 blocks all traffic except the VPN traffic - TCP/IP port 1723 and GRE. This firewall therefore protects the VPN client from attacks via the internet.

  • Firewall 3 is configured to allow through the wanted services that are required by the hosts on the secure subnet, but blocks malicious packets that may have been encapsulated at the far end of the VPN link.

As said above, running three firewalls in this way is at the moment just a theory, I haven`t tried it in practice

 


© 2005 Ron Turner


Return to the Index page