Title: A simple multiports VPN with ferm and OpenVPN
Date: 2016-11-11 21:00

[OpenVPN]( https://openvpn.net/ )'s standard port is 1194,
unfortunately, it's rarely open on shitty networks,
where you actually **do want** to use a VPN, precisely because you're on a
shitty network that you don't trust.

Now you have to pick a port to run your VPN on it, but there is no right
choice, since you may want to use several: 53-udp, 80-tcp, 443-tcp, 22-tcp,
53-tcp, 123-udp, …
But running one OpenVPN instance per port <s>sounds</s> is idiotic.

Fortunately, by using `DNAT` and `SNAT`, you can use something like the
following [ferm]( http://ferm.foo-projects.org ) rules,
make your TCP instead of OpenVPN listen on `1194` and the UDP one on
`1195`, and connect to them using whatever port you specify:

```ferm
@hook post  "echo 1 >| /proc/sys/net/ipv4/ip_forward";
@hook flush "echo 0 >| /proc/sys/net/ipv4/ip_forward";

@def $ADDR_WAN = (W.X.Y.Z);
@def $ADDR_VPN = (A.B.C.D);

@def $NET_VPN = (10.10.0.0/24 10.11.0.0/24);

table filter {
    chain INPUT {
        interface tun+ ACCEPT;

        mod state state NEW daddr @ipfilter($ADDR_VPN) proto (tcp udp) dport (1194 1195) ACCEPT;
    }

    chain FORWARD {
        outerface eth0 saddr $NET_VPN ACCEPT;
    }
}

domain ip table nat {
    chain PREROUTING daddr $ADDR_VPN proto tcp dport (ftp ssh telnet smtp http https pop3 openvpn) DNAT to "$ADDR_VPN:1194";
    chain PREROUTING daddr $ADDR_VPN proto udp dport (ntp domain) DNAT to "$ADDR_VPN:1195";

    chain POSTROUTING saddr $NET_VPN outerface eth0 SNAT to $ADDR_WAN;
}
```
