# OpenVPN - IPTables DNAT to-port <port-range> load bala

## saffy

I have an interesting scenario on which I need some help...

I have built an OpenVPN server which is to be placed in the DMZ of our corporate firewall, the person in charge of the firewall will only allow udp traffic on a single port number to reach my VPN server, unfortunately OpenVPN will only allow one connection per port and I need four people to use this VPN server.

I can run four OpenVPN deamons on four different udp ports, however I need a method of accepting connections on the port number allowed through the firewall and then somehow load-balancing this connection over the four OpenVPN daemons. As each daemon will only accept one connection, I need to make sure new connections are sent to a daemon which does not have an already established connection.

I read some info on the IPTables DNAT to-port option but from what I read this will not load balance properly in this situation. Does anyone out there have any experience with a similar situation??

----------

## meyerm

Are you're clients coming from different IPs (from the view of the server)?

----------

## saffy

Yes, the clients will be connecting from their homes, therefore should all have different source IP addresses. These addresses are not always static.

----------

## meyerm

Your clients are 100.100.100.1 to 100.100.100.4, your server 200.200.200.1. Then do something like this on the server side:

```

iptables -t nat -A PREROUTING -s 100.100.100.1 -p udp --dport 5000 -j DNAT --to 200.200.200.1:5001

iptables -t nat -A PREROUTING -s 100.100.100.2 -p udp --dport 5000 -j DNAT --to 200.200.200.1:5002

iptables -t nat -A PREROUTING -s 100.100.100.3 -p udp --dport 5000 -j DNAT --to 200.200.200.1:5003

iptables -t nat -A PREROUTING -s 100.100.100.4 -p udp --dport 5000 -j DNAT --to 200.200.200.1:5004

```

I don't know if this will work. But if it does, you can have 4 OpenVPNs listen on the port 5001 to 5004 and all clients can connect to port 5000. Each client gets its own dedicated openvpn server.

Hopefully this works. Please report if it does  :Smile: 

	Marcel

----------

## Derringer

 *meyerm wrote:*   

> Your clients are 100.100.100.1 to 100.100.100.4, your server 200.200.200.1. Then do something like this on the server side:
> 
> ```
> 
> iptables -t nat -A PREROUTING -s 100.100.100.1 -p udp --dport 5000 -j DNAT --to 200.200.200.1:5001
> ...

 

This would work if he knew the incoming source IPs of the connections.  Unfortunately, the way I understand it, is that he does not =/

Besides the warning that it is not a great idea to allow any and all IPs to setup a VPN connection without knowing at least a range of possible IPs they could be connecting from, I'll assume that you have no other choice and are aware of the dangers, however small.  (I realize this is to a DMZ, but I'm also assuming that there is a reason for you to use VPN to begin with, and that at some point, these connections will have somewhat trusted privileging in some regard).

I am anxious to hear what you find by trying DNAT to-port using a single entry port.  I *hope* iptables would bypass the first port if it was in use, but I cannot say for sure if this will really happen.  Technically, you don't need load balancing as much as you need each of the DNATs to only handle one request at a time, and allow the next rule to be processed if that port is in use.  I am very curious if this works, but I am equally leery from what I know about DNAT (i.e. it was designed for services that can handle multiple requests to the same port, and that is what might be a problem =/)

Let us know what you find.  If you could even narrow an IP block for each of the home users, you would kill both birds with one stone, imo.  If each user had at least a Class-C unique block they were pulling their dynamic IPs from, you could use the approach outlined  by Meyerm.  It does require, however, that you can discern and keep unique these port ranges.  It would also further tighten the security of the connections, but might be an initial adminstrative burden on you or allow for issues if one of the home users' ISPs changes blocks on you.

(Of course the best thing would be if you could have 4 ports!! =p )

----------

## saffy

Thanks for your help guys...

I really don't want to use a rule based on source address if I can help it, as this takes flexibility away from home users and also means I need to be mindful of changes on the user side. Two of the users also use the same ISP which makes things a bit more difficult.

The users will be using PKI authentication for their VPN connections therefore I am less concerned on limiting who can establish connection to the port (as I understand it, openvpn will not reply to a connection attempt unless a valid certificate is presented)

I was hoping that the DNAT to-port <port-range> option would load-balance new connections in a round-robin fashion which would give me what I need, but I've read two posts on the internet where people found that using this option resulted in the first listening port being used which was always the first-port regardless of whether it already had a connection.

Looks like I might have to beat-up the firewall admin......

Thanks

----------

## meyerm

Hmm, just a question (I don't have the time to test any further - my train is parting - will have another look later):

Are you sure openvpn only accept one connection?

```

mirror root # openvpn --dev tap0 --secret /root/static.key

Mon Feb  2 11:09:49 2004 0: OpenVPN 1.5.0 i686-pc-linux-gnu [SSL] [LZO] built on Jan 12 2004

Mon Feb  2 11:09:49 2004 1: TUN/TAP device tap0 opened

Mon Feb  2 11:09:49 2004 2: UDPv4 link local (bound): [undef]:5000

Mon Feb  2 11:09:49 2004 3: UDPv4 link remote: [undef]

Mon Feb  2 11:11:02 2004 4: Peer Connection Initiated with 10.10.10.68:5000

Mon Feb  2 11:12:14 2004 5: Peer Connection Initiated with 10.10.10.250:5000

```

until later...

----------

## saffy

Interesting.... the OpenVPN website mentions in several places that you need to run multiple daemons to support multiple connections.... but I will be testing this sometime in the next few days.

I'll post info on my test results....

----------

## saffy

I have now tested the VPN server and it works very well with a single connection at a time. When a second connection comes in it successfully authenticates but the first connection is rendered inactive.

I have done some more reading on the internet and there are two things I would like to try:-

1) run 5 OpenVPN instances listening on different udp port numbers and use the nth match IPTables module to load balance incoming udp connections over the 5 instances. i.e.

1st initial udp match -> instance1

              2nd initial udp match -> instance2

              3rd initial udp match -> instance 3

              ...... etc

The only problem is how do you match the initial udp packet? would !related,established work?? also if I can match and DNAT the initial udp packet would the remaining packets automatically pick up the appropriate DNAT setting

OR

2) create 5 alias IP addresses on the external interface and use DNAT to <ip-range> which as I understand performs round-robin load balancing.

Any ideas and comments on these would be much appreciated.

----------

## fleed

I think using the 5 alias IP addresses with a DNS round robin is the best solution, at least it's the cleanest so it's less likely to give you trouble. I wonder how big companies handle this sort of stuff when they have loads of roadwarriors connecting to a central vpn server...

----------

## meyerm

I don't think they use OpenVPN...  :Smile: 

For these fields that Cisco crap or the FreeSwan patches are suitable. But OpenVPN has other advantages (tunneling through a proxy is simply awesome!  :Smile:  ).

----------

## saffy

I've got it working!

Using the following IPTables command, I was able to run 10 openvpn daemons on ports 5001 to 5011, run the command ten times each time increasing the --packet and --to-ports number by one.

I now have an OpenVPN server able to accept 10 simultaneous connections.

```
iptables -t nat -A PREROUTING -i eth1 -p udp -d 172.23.51.211 -m udp --destination-port 5000 -m state --state NEW -m nth --every 10 --packet 0 -m limit --limit 1/second --limit-burst 1 -j REDIRECT --to-ports 5001
```

Wow! it works flawlessly   :Very Happy: 

----------

## tdb

Yeah, that's from the openvpn users list. I was just gonna post that.

----------

## Derringer

That is a cool IPTABLES line.  Bookmarking this for later use.  Grats on getting it working =)

----------

