Well it was bound to happen sooner or later, but working on projects at the office I have segmented networks for various things, and the stuff I host only has to talk to one specific thing out on the internet. Â But things change, and flexibility is demanded as now I suddenly have half a dozen VPS’s out on the internet, that not only need to talk back to my office, but also need to talk to eachother. Â And of course adding that n+1 becomes tedious, and worse when one host goes down, and you have people pointing the wrong way. Â If only there was a solution…
And there is, as this ‘problem’ was solved forever ago with this magical thing called routing protocol. Â Before I was doing OpenVPN with a network to network type setup, but now I want to dynamically route, and considering it’s a small network, I’m free to use any protocol, even RIP is fine, as I have about 15 networks to advertise. Â In the end I went with BGP for really no real reason. Â RIP/OSPF,ISIS would have worked just as well.
The first thing is that to configure OpenVPN is that I didn’t want the normal ‘shared network’ setup, nor the tun style where OpenVPN intercepts the invalid destination address. Â While it does bring up links, and work for dynamic setups, I’m just bringing up static links that are point to point, and single host only. Â Also BGP wants the source and destination originating address to match, so a tunnel interface that is 10.0.1.6 10.0.1.5, but expects the destination to be 10.0.1.1 isn’t going to work. Â So I went with the old p2p style config.
As a template I used this site right here:
First generate a static key:
openvpn --genkey --secret static.key
Next setup the config for the ‘server’ side. Â In this case, each of my VPS’es is a server since they all have registered addresses, and don’t move as often. Â My office is going to move soon, and in the off even that I need to travel with my office setup it’s nice to bring it online wherever, and have it connect. Â At the same time if my office is down, this is why I want the VPSes to be able to talk to eachother.
Server config:
mode p2p port 1194 # Â We listen to port 1194 dev tun # possibly tun0 Linux proto udp # protocol UDP, TCP: proto tcp-server ifconfig 10.5.0.1 10.5.0.2 # Â Local IP <-> Remote IP # Here adjust the path to point to the generated Key secret /etc/openvpn/static.key ping 10 # Sends every 10 seconds a ping to the remote site ping-restart # 180 after 3 minutes without pings reconnecting the remote ping-timer-rem # only after we've let another peer ping-restart verb 3 # increase to debugging mute 50 # uncomment to debugging
Client config:
mode p2p remote my-openvpn-server.dyndns.com 1194 # hostname / external IP of another peer, port accordingly proto udp # protocol UDP, TCP: proto tcp-client dev tun # Â possibly tun0 Linux ifconfig 10.5.0.2 10.5.0.1 # Â Local IP <-> Remote IP # Here adjust the path to point to the generated Key secret /etc/openvpn/static.key ping 10 # Sends every 10 seconds a ping to the remote site ping-restart # 180 after 3 minutes without pings reconnecting the remote ping-timer-rem # only after we've let another peer ping-restart verb 3 # increase to debugging mute 50 # uncomment to debugging
Now with the config’s in place, remembering to save with the filenames ‘server.conf’ and ‘client.conf’ in the /etc/openvpn directory, I was ready to restart the OpenVPN service (service openvpn restart) and now I could ping!
tun1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
inet addr:10.5.0.2 P-t-P:10.5.0.1 Mask:255.255.255.255
and a quick ping…
root@Office-OpenVPN:/etc/openvpn# ping 10.5.0.1
PING 10.5.2.1 (10.5.2.1) 56(84) bytes of data.
64 bytes from 10.5.0.1: icmp_req=1 ttl=64 time=1.66 ms
64 bytes from 10.5.0.1: icmp_req=2 ttl=64 time=3.39 ms
Now for the routing protocol.  I went with quagga, as it is descended from zebra, and one that I’ve used before.
Configuration is pretty straight forward. Â first the daemons.conf file needs to be edited for what services you are going to run. Â In this case I want zebra & bgpd.
zebra=yes
bgpd=yes
ospfd=no
ospf6d=no
ripd=no
ripngd=no
isisd=no
babeld=no
Next, the zebra.conf file. Â The passwords are plaintext, I wouldn’t of course paste my real passwords:
hostname office
password zebra
enable password zebra
And next is my bgpd.conf file, for my office:
hostname office
password zebra
router bgp 8888
bgp router-id 192.168.1.49
network 192.168.1.0/24
network 10.1.0.0/24
network 10.1.1.0/24
neighbor 10.5.0.1 remote-as 555
log file /var/log/quagga/bgpd.log
!log stdout
Everything is the same on the VPS, except for it’s BGP config, which is the following:
hostname vps1
password zebra
router bgp 555
bgp router-id 10.13.0.1
network 10.13.0.0/24
neighbor 10.5.0.2 remote-as 8888
log file /var/log/quagga/bgpd.log
!log stdout
So now I’ve setup a p2p connection, and now defined the networks that I’m going to share from my office, in this case it’s 192.168.1.0/24, 10.1.0.0/24, and 10.1.1.0/24. Â The VPS is going to share it’s 10.13.0.0/24 network.
Now to start up the router with a ‘service quagga restart’ and all being well I can now talk to the BGPD.
telnet localhost 2605
Trying ::1…
Trying 127.0.0.1…
Connected to localhost.
Escape character is ‘^]’.
Hello, this is Quagga (version 0.99.22.4).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
User Access Verification
Password:
office>
Now to check for my bgp neigbours
office> ena
office# show bgp neighbors
BGP neighbor is 10.5.0.1, remote AS 555, local AS 8888, external link
BGP version 4, remote router ID 127.0.0.2
BGP state = Established, up for 3d21h32m
Last read 00:00:33, hold time is 180, keepalive interval is 60 seconds
Neighbor capabilities:
4 Byte AS: advertised and received
Route refresh: advertised and received(old & new)
Address family IPv4 Unicast: advertised and received
Message statistics:
Inq depth is 0
Outq depth is 0
Sent Rcvd
Opens: 1 0
Notifications: 0 0
Updates: 18 1
Keepalives: 5613 5612
Route Refresh: 0 0
Capability: 0 0
Total: 5632 5613
Minimum time between advertisement runs is 30 seconds
For address family: IPv4 Unicast
Community attribute sent to this neighbor(both)
1 accepted prefixes
Connections established 1; dropped 0
Last reset never
Local host: 10.5.0.2, Local port: 179
Foreign host: 10.5.0.1, Foreign port: 35722
Nexthop: 10.5.0.2
Nexthop global: ::
Nexthop local: ::
BGP connection: non shared network
Read thread: on Write thread: off
office#
And how about the routes?
office# show ip bgp
BGP table version is 0, local router ID is 192.168.1.49
Status codes: s suppressed, d damped, h history, * valid, > best, i – internal,
r RIB-failure, S Stale, R Removed
Origin codes: i – IGP, e – EGP, ? – incomplete
Network Next Hop Metric LocPrf Weight Path
*> 10.1.0.0/24 0.0.0.0 0 32768 i
*> 10.1.1.0/24 0.0.0.0 0 32768 i
*> 10.13.0.0/24 10.5.13.1 0 0 555 i
*> 192.168.1.0 0.0.0.0 0 32768 i
Total number of prefixes 4
Well isn’t that great! Â For each additional connection on my client side, I change the client port. Â It doesn’t matter what number I choose as my client VPN machine isn’t exposed on the internet, only the OpenVPN servers on the VPSes. Â I can also combine this with a traditional OpenVPN setup where my clients get addresses on my Office Lan, and can now access all of my VPSes at once.
All I have left to do is define the additional servers into the mesh, and add in the BGP peers. Â And doing it this way two VPSes in the same data centre now have a 1ms ping, instead of traversing the internet to my office, and back up. Â Plus they can stay in communication if my office, or even their internet is down, as long as the internal communications of the data centre is fine.