Home VPN with OpenVPN

Here are step to run a simple OpenVPN service at home, so that I can access home network easily while not at home.

First, clone the git repo for OpenVPN docker container:

git clone https://github.com/kylemanna/docker-openvpn.git

I can use the pre-built docker image from docker hub but it has just been breached so I’d rather build it myself:

cd docker-openvpn && docker build -t openvpn .

Create a docker volume to persist data if the OpenVPN container to be rebuilt:

export $OVPN_DATA=ovpn_data
docker volume create --name $OVPN_DATA

Generate OpenVPN configurations, if there’s no DNS record for the server, use the public IP of the home broadband alternatively.

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm openvpn ovpn_genconfig -u udp://VPN.SERVERNAME.COM

Build a new secret key which will be used to generate user keys. I’d advise to use a strong password which can be saved in a password manager or vault. This is needed everytime when I create a new user.

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it openvpn ovpn_initpki

Then the OpenVPN server container can be run as a service:

docker run -v $OVPN_DATA:/etc/openvpn -d -p 1194:1194/udp --cap-add=NET_ADMIN openvpn

Generate the first user profile. The password for secret key will be needed. Then retrieve the OpenVPN configuration with the 2nd command.

docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm -it openvpn easyrsa build-client-full <username> nopass
docker run -v $OVPN_DATA:/etc/openvpn --log-driver=none --rm openvpn ovpn_getclient <username> > <username>.ovpn

This .ovpn file can be used to configure OpenVPN client softwares on laptops or phones.

At last, ensure UDP 1194 port is forwarded to the host of the docker container. This is usually done in the home broadband router.

Don’t Need Ngrok When I Have SSH

I was trying to create a Slack app. In order to let Slack send REST requests to my dev environment, eg. http://localhost:9000, I searched a bit and saw ngrok. Ngrok is very handy for this kind of setup:

Slack -> xyz.ngrok.io -> localhost

However I just don’t want to install anything so I turned to Google and to my surprise SSH can exactly do this(for who knows how many years). I know I can forward a local port to a remote host to connect to a service behind firewall such as databases, this is my first attempt to forward a remote port to local so Slack API can contact my localhost.

Here’s a better article which explained how to do port forwarding in both directions with SSH.

In short, to forward a remote port to my localhost, I need to

1, update the sshd_config on remote host and have GatewayPorts enabled and then restart SSH service

GatewayPorts yes

2, in a local terminal, run the following command replacing my.remote.host with your server’s domain or IP.

ssh -nNT -R 9800:localhost:9000 my.remote.host

Then test it with

curl -i http://my.remote.host:9800

The request should be forwarded to your localhost:9000.

🙂

Resolved: Arch Linux WiFi issue

When I connected my laptop running Arch Linux to a new WiFi this morning, it worked for a brief moment then all connections were dropped. Connecting to the same WiFi with phone or Macbook works fine so the problem is at Arch LInux(AL)’s end.

Then I noticed if I do a route it actually showed 2 entries for the LAN. I took a closer look and saw there were 2 IPs for the wireless interface!

Strange enough if I connect to the hotspot of my phone, AL will also have 2 IPs but the connection is still working.

So I googled a bit why there will be 2 IPs, here’s what I got:

https://raspberrypi.stackexchange.com/questions/13359/where-does-my-secondary-ip-come-from

Finally, after I shutdown and disabled the dhcpcd service with

sudo systemctl disable dhcpcd
sudo systemctl stop dhcpcd

and restarted NetworkManager, the problem is fixed. Guess some WiFi AP is more tolerant than others.

🙂

Gotcha AWS NAT instance

It’s quite straight forward when creating an NAT instance for a private subnet in AWS, eg. search for amzn-ami-vpc-nat-hvm for the AMI then launch it into a public subnet.

However I need to disable source/destination check before the NAT instance becomes available in the drop down list of destinations of a route table:

🙂