How to set multiple client IPs mapped to multiple public IPs on a single OpenVPN server?
I have a properly working setup of an OpenVPN server in which:
- Each client has its own VPN IP address
- Each client IP is tied to a public IP
- Client configs are separated by CCDs
So far, a client is set a single VPN IP address which is tied to a single public IP address. And everything works pretty fine. Here's a diagram:
LAN SIDE OpenVPN Server
------------------. .---------------
Client1: 10.9.0.5 \ / 69.94.150.5
Client2: 10.9.0.6 } --- cloud --- { 69.94.150.6
Client3: 10.9.0.7 / \ 69.94.150.7
------------------' '---------------
In short: 1 client = 1 key = 1 private IP = 1 public IP.
Every CCD is set to give an IP, so if I want to swap IPs between Client1 and Client2 I just swap client config files without needing anything else on the server.
Now, I'm in need of giving a single client more than one IP... like:
LAN SIDE OpenVPN Server
------------------. .---------------
Client1: 10.9.0.5 \ / 69.94.150.5
Client2: 10.9.0.6 \ / 69.94.150.6
Client3: 10.9.0.7 } --- cloud --- { 69.94.150.7
10.9.0.8 / \ 69.94.150.8
10.9.0.9 / \ 69.94.150.9
------------------' '---------------
The problem is that when I copy more than one config file to a client, only the latest IP responds from the internet and all local traffic is routed through a single gateway... In that example, only 69.94.150.9 responds and everything goes out from it.
What am I missing to properly have all Client3 public IPs properly routed to the machine that has those configs assigned?
server.conf:
local 69.94.142.236
port 1294
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
topology subnet
server 10.9.0.0 255.255.255.0
ifconfig-pool-persist ipp-server2.txt
client-config-dir ccd-server2
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"
client-to-client
keepalive 5 30
cipher AES-128-CBC
comp-lzo
user nobody
group nogroup
persist-key
persist-tun
status openvpn-status-server2.log
log-append /var/log/openvpn-server2.log
verb 3
CCDs (named as "node-X", where X = last octet of public IP):
ifconfig-push 10.9.0.X 255.255.255.0
Server /etc/iptables.up.rules:
*nat
:PREROUTING ACCEPT [913:79716]
:INPUT ACCEPT [30:1969]
:OUTPUT ACCEPT [4:284]
:POSTROUTING ACCEPT [15:852]
-A PREROUTING -d 69.94.150.5/32 -j DNAT --to-destination 10.9.0.5
-A PREROUTING -d 69.94.150.6/32 -j DNAT --to-destination 10.9.0.6
-A PREROUTING -d 69.94.150.7/32 -j DNAT --to-destination 10.9.0.7
-A PREROUTING -d 69.94.150.8/32 -j DNAT --to-destination 10.9.0.8
-A PREROUTING -d 69.94.150.9/32 -j DNAT --to-destination 10.9.0.9
-A POSTROUTING -s 10.9.0.5/24 -j SNAT --to-source 69.94.150.5
-A POSTROUTING -s 10.9.0.6/24 -j SNAT --to-source 69.94.150.6
-A POSTROUTING -s 10.9.0.7/24 -j SNAT --to-source 69.94.150.7
-A POSTROUTING -s 10.9.0.8/24 -j SNAT --to-source 69.94.150.8
-A POSTROUTING -s 10.9.0.9/24 -j SNAT --to-source 69.94.150.9
COMMIT
*mangle
:PREROUTING ACCEPT [2501:318690]
:INPUT ACCEPT [864:148083]
:FORWARD ACCEPT [286:49874]
:OUTPUT ACCEPT [739:181739]
:POSTROUTING ACCEPT [1025:231613]
COMMIT
*filter
:INPUT ACCEPT [864:148083]
:FORWARD ACCEPT [144:20189]
:OUTPUT ACCEPT [739:181739]
-A FORWARD -s 10.9.0.0/16 -j ACCEPT
COMMIT
Client config files (all the same except for the embedded ca, cert and key, in which the "common name" is node-X):
client
dev tun
proto udp
remote 69.94.142.236 1294
resolv-retry infinite
nobind
user nobody
group nogroup
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
ns-cert-type server
cipher AES-128-CBC # AES
comp-lzo
verb 3
<ca>
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
</key>
The "simple" approach I'm using:
- Copy the next files to /etc/openvpn on the client:
- node-5.conf to get 10.9.0.7 <--> 69.94.150.7
- node-8.conf to get 10.9.0.8 <--> 69.94.150.8
- node-9.conf to get 10.9.0.9 <--> 69.94.150.9
ifconfig results:
eth0 Link encap:Ethernet HWaddr 00:0c:29:9d:3d:c5
inet addr:192.168.0.125 Bcast:192.168.0.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe9d:3dc5/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:17580 errors:0 dropped:0 overruns:0 frame:0
TX packets:11953 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:7027620 (7.0 MB) TX bytes:1447134 (1.4 MB)
tun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.9.0.9 P-t-P:10.9.0.9 Mask:255.255.255.0
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:496 (496.0 B) TX bytes:508 (508.0 B)
tun1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.9.0.8 P-t-P:10.9.0.8 Mask:255.255.255.0
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:60 (60.0 B) TX bytes:0 (0.0 B)
tun2 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.9.0.7 P-t-P:10.9.0.7 Mask:255.255.255.0
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
RX bytes:100 (100.0 B) TX bytes:0 (0.0 B)
route table:
Destination Gateway Genmask Flags Metric Ref Use Iface
default 10.9.0.1 128.0.0.0 UG 0 0 0 tun0
default 192.168.0.1 0.0.0.0 UG 0 0 0 eth0
10.9.0.0 * 255.255.255.0 U 0 0 0 tun0
10.9.0.0 * 255.255.255.0 U 0 0 0 tun1
10.9.0.0 * 255.255.255.0 U 0 0 0 tun2
69.94.142.236 192.168.0.1 255.255.255.255 UGH 0 0 0 eth0
128.0.0.0 10.9.0.1 128.0.0.0 UG 0 0 0 tun0
192.168.0.0 * 255.255.255.0 U 0 0 0 eth0
As I can see, the default gateway is being set as 10.9.0.1 and it is going through tun0.
Perhaps I am missing route entries? Is there a way to push them from the CCDs?
Note: I also tried a p2p approach creating /30 subnets, but it didn't work: I got the same results (everything going through a single IP/device and no proper routing for the rest).