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.