Linux hints: linux multihomed routing and vpn (part 1)
routing in multihomed networks in linux, vps uplinks via vpn
some time ago i am faced interesting task, i needed to route some traffic via different uplinks (incoming and outgoing both). in linux it’s possible to use source based routing, uid/gid based routing via iproute2 and iptables.
- define additional routing tables in
file already contain few predefined routing tables in following format:
you can add something like:
you can ad as many table as you need.
- add needed rules to routing table,
now you can add rules to added routing tables, you need to add one more argument to “ip route” - table like:
ip route add default via 10.10.10.1 dev tap13 table my_table ip route add 192.168.0.0/24 dev eth0 table my_table
something like this, second rule necessary for apps to be able to reach local network, if it’s needed.
- rules (something interesting begins here)
ip rule add from 10.10.10.2/32 table my_table
this will route traffic from address 10.10.10.2 via “my_table” routing table
ip rule add fwmark 3 table my_table
this will route all traffic marked with “3” via “my_table” routing table, how to mark traffic will be explained later
i have used iptables for traffic marking.
most simple and efficient enough is marking based on uid/gid, you can do this like this:
iptables -t mangle -A OUTPUT -m owner --uid-owner pleroma -j MARK --set-mark 3
in step 3 i added rule to route all traffic marked with “3” via “my_table” routing table,
and now i marked all traffic from uid pleroma with “3” so it will go via routing table as well.
here required little hack for this to work, as by default “default” routing table is used, source address for this marked traffic most probably be incorrect and routing will be confused and nothing work, to prevent this we need to change source address like this:
iptables -t nat -A POSTROUTING -o tap13 -j SNAT --to-source=10.10.10.2
as you may already noticed, i am using tap interface, it’s used by vpn implementation and as vpn implementation i using openvpn, i will not write much about openvpn here, instead i will post working openvpn configs for server and client, as it maybe a little tricky to write one:
mode server tls-server port 12345 proto udp4 dev-type tap dev tap13 ca /etc/openvpn/server/vps-ca.crt cert /etc/openvpn/server/vps-server.crt key /etc/openvpn/server/vps-server.key dh /etc/openvpn/server/vps/dh4096.pem server 10.10.10.0 255.255.255.0 push "route 10.10.10.0 255.255.255.0" client-config-dir /etc/openvpn/server/vps/ccd client-to-client keepalive 30 240 max-clients 10 persist-key persist-tun status /var/log/openvpn/vps-status.log verb 4 mute 20 tls-cipher "DHE-RSA-AES128-GCM-SHA256" cipher AES-128-GCM ncp-ciphers AES-128-GCM tls-crypt /etc/openvpn/server/vps/shared_key compress lzo float fast-io verify-client-cert require
tls-client remote 127.0.0.1 #write server ip here instead port 12345 proto udp4 dev-type tap dev tap13 ca /etc/openvpn/client/vps-ca.crt cert /etc/openvpn/client/vps-user.crt key /etc/openvpn/client/vps-user.key dh /etc/openvpn/dh4096.pem keepalive 30 240 persist-key persist-tun verb 4 mute 20 tls-cipher "DHE-RSA-AES128-GCM-SHA256" cipher AES-128-GCM ncp-ciphers AES-128-GCM tls-crypt /etc/openvpn/client/vps3-shared_key compress lzo float fast-io verify-client-cert require
aes cipher is used here because hw crypto available on cpu on both sides of connection, without hw crypto it’s better to set chacha20 for tls and cammelia for blocks instead of aes, 128 bit key size used for performance, if you need better security, set 256.
most probably few options is useless in client config, like dh , compress, verify-client,keep-alive .
- conclusion, notes, hints
this short article does not cover firewall rules to route traffic from vps to client (this machine which we configuring in this article), it’s as trivial as FORWARD + PREROUTING, figure out it yourself as part of homework )
also, now exists another vpn implementations like wireguard https://www.wireguard.com/, which is kernel-space and should be more efficient than openvpn, also here is ipsec, l2tp and even pptp, i choose openvpn because it flexible and because i do not need very high bandwidth, so openvpn performance is suffice for me.