From 1a98f7a163d47617b2484d079d72ca0887cb7d95 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Sun, 11 Apr 2021 07:13:30 +0000 Subject: [PATCH] Add bypassing ports article --- content/bypassing-ports.md | 380 +++++++++++++++++++++++++++++++++++++ 1 file changed, 380 insertions(+) create mode 100644 content/bypassing-ports.md diff --git a/content/bypassing-ports.md b/content/bypassing-ports.md new file mode 100644 index 0000000..8034908 --- /dev/null +++ b/content/bypassing-ports.md @@ -0,0 +1,380 @@ +Title: Bypassing ISP Blocked Ports +Date: 2021-04-10 +Category: Writing +Summary: Bypass ISP blocked ports using VPN port forwarding for public access. +Wide: true + +[TOC] + +My residential ISP blocks inbound traffic to common ports like 22, 80, and 443. +I use an OpenVPN tunnel to forward these ports so that I can self-host a +public media server. It does __not__ require users to be on the VPN. + +This article explains how I set it up and is targeted towards Linux sysadmins. + +## Overview + +I have a cheap $5 per month virtual server with [Digital +Ocean](https://digitalocean.com) that runs Debian GNU/Linux 10. An OpenVPN +server is running on this virtual server. + +My media server at home has an OpenVPN client connected to the server and is +assigned a static IP on the VPN network. + +The virtual server has routing enabled and forwards inbound traffic __from the +internet__ to my media server at home. This allows me to have external HTTP and SSH +access. + +## Server Setup + +Spin up a Debian 10 virtual server on your favourite hosting provider and set +your user up as you would normally. You should probably harden this server. +Assign a subdomain to it like `vpn.example.com`. + +Install the following requirements: + +``` +$ sudo apt update +$ sudo apt install openvpn ufw +``` + +### OpenVPN Server + +These steps roughly follow [this +guide](https://wiki.debian.org/OpenVPN#TLS-enabled_VPN). + +Generate TLS certificates and keys: + +``` +$ cd /etc/openvpn +$ sudo openvpn --genkey --secret static.key +$ sudo make-cadir easy-rsa/ +$ sudo chown -R tanner:tanner easy-rsa/ +``` + +Replace `tanner` with your own username, this is temporary. + +The `.rnd` file prevents a warning + +``` +$ cd easy-rsa/ +$ ./easyrsa init-pki +$ head /dev/urandom > pki/.rnd +$ ./easyrsa build-ca +``` + +Enter a password you won't forget in case you want to add another client later. +The Common Name you choose is not important. + +Generate Diffie–Hellman params: + +``` +$ ./easyrsa gen-dh +``` + +Generate a server cert: + +``` +$ ./easyrsa build-server-full server nopass +``` + +Generate a client cert: + +``` +$ ./easyrsa build-client-full mediaserver nopass +``` + +We make a `mediaserver` client because we want to assign a static IP to it. You +need to make a different one for each client you want with a static IP. + +Also, if you want generic clients that all get dynamic IPs for use on your +laptop, phone, etc. to protect you from public WiFi, create only a single extra one: + +``` +$ ./easyrsa build-client-full client nopass # optional +``` + +Leave off `nopass` if you want to password protect the config file when you set +up a new client. + +Create the server config file `/etc/openvpn/server.conf`: + +``` +port 1194 +proto udp +dev tun +topology subnet +ca /etc/openvpn/easy-rsa/pki/ca.crt +cert /etc/openvpn/easy-rsa/pki/issued/server.crt +key /etc/openvpn/easy-rsa/pki/private/server.key +dh /etc/openvpn/easy-rsa/pki/dh.pem +tls-auth /etc/openvpn/static.key 0 +client-config-dir /etc/openvpn/ccd +server 10.8.0.0 255.255.255.0 +client-to-client +duplicate-cn +keepalive 10 120 +cipher AES-256-GCM +auth SHA256 +comp-lzo +max-clients 10 +user nobody +group nogroup +persist-key +persist-tun +``` + +Assign a static IP + chmod: + +``` +$ cd /etc/openvpn +$ sudo chown -R root:root easy-rsa/ +$ sudo mkdir ccd +$ sudo touch ccd/mediaserver +``` + +Replace `mediaserver` with whatever client name you used above. Edit it like so: + +Your home server will be `10.8.0.100` + +``` +ifconfig-push 10.8.0.100 255.255.255.0 +``` + +Test your config by running: + +``` +sudo openvpn --config /etc/openvpn/server.conf +``` + +If you run `ip addr` in another terminal, you should see an entry like this: + +``` +5: tun0: stuff + link/none + inet 10.8.0.1/24 brd 10.8.0.255 scope global tun0 + valid_lft forever preferred_lft forever + inet6 fe80::d9fc:b2f9:34e6:5ed2/64 scope link stable-privacy + valid_lft forever preferred_lft forever +``` + +### systemd + +If it works fine, persist OpenVPN with systemd: + +``` +$ sudo systemctl enable openvpn@server +$ sudo systemctl start openvpn@server +$ sudo systemctl daemon-reload +$ sudo service openvpn restart +``` + +Test it works by rebooting: + +``` +$ sudo reboot +$ ssh vpn.example.com +$ ip addr +``` + +### Port Forwarding + +I use `ufw` to handle the iptables rules because I use it anyway as a firewall +when I harden my servers. + +Enable routing: + +``` +$ sudo sysctl net.ipv4.ip_forward=1 +``` + +Edit `/etc/sysctl.conf` to set: + +``` +net.ipv4.ip_forward=1 +``` + +Edit `/etc/default/ufw` to set: + +``` +DEFAULT_FORWARD_POLICY="ACCEPT" +``` + +Add this to the top of `/etc/ufw/before.rules`: + +``` +*nat +:POSTROUTING ACCEPT [0:0] + +# ssh port forwarding +-A PREROUTING -d 123.123.123.123 -p tcp --dport 2222 -j DNAT --to-dest 10.8.0.100:2222 +-A POSTROUTING -d 10.8.0.100 -p tcp --dport 2222 -j SNAT --to-source 10.8.0.1 + +# Allow traffic from OpenVPN client to eth0 +-A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE +COMMIT +``` + +Replace `123.123.123.123` with your VPN server's external IP address and `eth0` +with the external interface. + +This will forward TCP traffic on port 2222 to your home server. If you want to use +port 22, then you need to set the VPN SSH server to something else. + +A full example of `/etc/ufw/before.rules` with other ports included can be found +here: + +[https://txt.t0.vc/URUG](https://txt.t0.vc/URUG) + +Apply the changes to `ufw`: + +``` +$ sudo ufw disable && sudo ufw enable +``` + +## Client Setup + +Switch to your home server or client machine. + +Install openvpn: + +``` +$ sudo apt update +$ sudo apt install openvpn +``` + +### Client Configs + +For static IP clients (like your home server), create the config file `/etc/openvpn/client.conf`: + +``` +client +dev tun +proto udp +remote vpn.example.com 1194 +resolv-retry infinite +nobind +persist-key +persist-tun +remote-cert-tls server +cipher AES-256-GCM +auth SHA256 +comp-lzo +key-direction 1 + +[server /etc/openvpn/easy-rsa/pki/ca.crt] + + +[server /etc/openvpn/easy-rsa/pki/issued/mediaserver.crt] + + +[server /etc/openvpn/easy-rsa/pki/private/mediaserver.key] + + +[server /etc/openvpn/static.key] + +``` + +Replace the `[server ...]` lines with the contents of that file on the VPN +server, for example: + +``` +$ sudo cat /etc/openvpn/easy-rsa/pki/ca.crt +---> copy & paste result +``` + +Also replace `vpn.example.com` with the subdomain you assigned earlier. + +For device clients (like your laptop and phone), create the config file `client.ovpn`: + +`redirect-gateway def1` forces traffic over the VPN + +``` +client +dev tun +proto udp +remote vpn.example.com 1194 +resolv-retry infinite +nobind +persist-key +persist-tun +remote-cert-tls server +cipher AES-256-GCM +auth SHA256 +comp-lzo +key-direction 1 +redirect-gateway def1 + +[server /etc/openvpn/easy-rsa/pki/ca.crt] + + +[server /etc/openvpn/easy-rsa/pki/issued/client.crt] + + +[server /etc/openvpn/easy-rsa/pki/private/client.key] + + +[server /etc/openvpn/static.key] + +``` + +The `client.ovpn` file is ready to be imported into your VPN clients. + +Test your config by running: + +``` +sudo openvpn --config /etc/openvpn/client.conf +``` + +If you run `ip addr` in another terminal, you should see an entry like this: + +``` +7: tun0: stuff + link/none + inet 10.8.0.100/24 brd 10.8.0.255 scope global tun0 + valid_lft forever preferred_lft forever + inet6 fe80::b2:ed71:6c98:4bc9/64 scope link stable-privacy + valid_lft forever preferred_lft forever +``` + +Try pinging the server: + +``` +$ ping 10.8.0.1 +PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data. +64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=71.5 ms +64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=73.0 ms +... etc +``` + +### systemd + +If it works fine, persist OpenVPN with systemd: + +``` +$ sudo chown root:root /etc/openvpn/client.conf +$ sudo chmod 600 /etc/openvpn/client.conf +$ sudo systemctl enable openvpn@client +$ sudo systemctl start openvpn@client +$ sudo systemctl daemon-reload +$ sudo service openvpn restart +``` + +### Client Apps + +On Android I use "OpenVPN for Android" and on Linux I use the +`network-manager-openvpn-gnome` Debian package. + +To add your VPN on Gnome, open VPN settings, import file, and select +`client.ovpn`. If the private key is missing, select it from +`~/.cert/nm-openvpn/`. + +## Closing Thoughts + +You should now be fine to access your home server from over the internet. + +To forward additional ports, just edit the `/etc/ufw/before.rules` file like +above. + +Finally, make sure any server programs are listening / bound to `10.8.0.100` or +`0.0.0.0` so that they can get traffic from that interface.