Skip to main content

How to bypass ISP port blocking

Wow you just made your very own, very proud web service whether it be your personal webpage or a convenient API you wrote for your pleasure but there's one problem, you can't receive requests from port 80, you know where you're supposed to get requests?

ISPs already don't give you the privilege of free static IPs to use for your hosting project, to the extent of revoking reception on ports that matter.

With this cold indifference how would you expose your epic home server to the world? That's when get our old friends: Wireguard and any of your favorite VPS really

Create a VPS instance

Any VPS provider that can provision a debian-based distro should work. For the sake of simplicity we'll be using linode as our VPS.

  1. After you created your Linode account go to your dashboard and create a linode instance

    begin create linode
  2. Pick a debian-based distro, you may pick Ubuntu but Debian 11 can cook

    pick a debian-based distro
  3. Choose your region. Feel free to consult their speedtest to see what works for you

    pick your region
  4. Pick the cheapest plan, mine is $5

    pick the cheapest plan($5)
  5. Don't forget to set a root password

    decide a root password
  6. Review your configuration and hit Create

    finish create linode

Configure wireguard

Wireguard is a open source, highly configurable VPN software that establishes encrypted tunnels for secure communication

The following commands are to be executed for both your VPS and home server unless mentioned otherwise

  1. Make sure packages are up to date before installing wireguard

    $ apt update && apt upgrade
    	$ apt install wireguard -y
  2. Initiate our wireguard tunnel config

    This code creates a /etc/wireguard/wg0.conf file and writes preliminary text before where you're supposed to put your private key

    $ (umask 077 && printf "[Interface]\nPrivateKey = " | sudo tee /etc/wireguard/wg0.conf > /dev/null)
  3. Generate private and public keys

    Aside from appending our private key in wg0.conf and getting our public key from standard output, it's also stored on a publickey file. You'll need these to authenticate the peers

    $ wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey
  4. Finished /etc/wireguard/wg0.conf for VPS

    [Interface]
    PrivateKey = <generated private key>
    ListenPort = 55107
    Address = 192.168.4.1
    
    [Peer]
    PublicKey = <home server public key>
    AllowedIPs = 192.168.4.2/32
  5. Finished /etc/wireguard/wg0.conf for home server

    [Interface]
    PrivateKey = <generated private key>
    Address = 192.168.4.2
    
    [Peer]
    PublicKey = <VPS public key>
    AllowedIPs = 192.168.4.1/32
    Endpoint = <VPS IP>:55107
    PersistentKeepalive = 25
  6. Enable ipv4 forwarding by uncommenting this line in /etc/sysctl.conf on VPS

    # Uncomment the next line to enable packet forwarding for IPv4
    	net.ipv4.ip_forward=1
    $ sysctl --system
  7. Start and enable autostart systemd services on both

    $ systemctl start wg-quick@wg0
    	$ systemctl enable wg-quick@wg0

Testing tunnel

Moment of truth, if you did everything right up to this point, you should be able to observe signs of a working tunnel. For example, you should be able to SSH towards your peer using the internal IP as specified in wg0.conf

$ ping 192.168.4.1 # From home server
	$ ping 192.168.4.2 # From VPS
	

Forwarding traffic through your tunnel

Unfortunately receiving traffic from the VPS won't mean receiving it from the home server. So let's make it so

A few commands include a port `80`: feel free to add rules for other ports that you want, like 443 for https or even port 6443 for kubernetes remote access

# Drop all existing forwarding rules
	$ iptables -P FORWARD DROP
	
	# Forward traffic from VPS to Home through port 80 from your default network interface [eth0] to your wireguard tunnel [wg0]
	
	$ iptables -A FORWARD -i eth0 -o wg0 -p tcp --syn --dport 80 -m conntrack --ctstate NEW -j ACCEPT
	
	#
	$ iptables -A FORWARD -i eth0 -o wg0 -m conntrack --ctstate  ESTABLISHED,RELATED -j ACCEPT
	$ iptables -A FORWARD -i wg0 -o eth0 -m conntrack --ctstate  ESTABLISHED,RELATED -j ACCEPT
	
	# Prerouting
	$ iptables -t  nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.4.2
	
	# Postrouting
	$ iptables -t  nat -A POSTROUTING -o wg0 -p tcp --dport 80 -d 192.168.4.2 -j SNAT --to-source 192.168.4.1
	

Meow