My Home-made PC Router and NAS Server

Note: This project has been rebuilt and full information is available here.
I suggest reading about the rebuild first. Information below is for reference purposes and no longer recommended.

VPN setup - Host Base

One of my requirements was to be able to connect to my home network from outside, securely. This gives me the ability to access files stored on my server, and any other services, as well as appear to online services as my home location whilst I am away abroad (mainly to allow access of catch-up TV services!).

Open VPN is a great piece of software to do this, and although there is complicated forwarding, it works nicely.

The VPN would be installed on the host, and a pinhole through the guest out to the internet will be made to it. This is because I want to use the VPN to access my full LAN and NAS share too.

Before continuing though, check with your Internet Service Providers (ISP) that you are not behind a NAT of their own. Due to the lack of public IP v4 addresses on the Internet now, many ISPs are now putting multiple customers behind a single public IP. I know mine was and I had to pay a little extra on top of my bill to get a single public IP address.

Having a single public IP is required for you to connect to your VPN from outside your home. When will they support a single IP v6 address? I don't know!

To set up the VPN, I followed mainly the guide on digital ocean, linked below. Here are the details:

sudo apt-get update
sudo apt-get install openvpn
sudo gunzip /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz
sudo mv /usr/share/doc/openvpn/examples/sample-config-files/server.conf /etc/openvpn
sudo nano /etc/openvpn/server.conf

In this file, uncomment these lines (they are in different areas of the file):

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

user nobody
group nogroup

In order for the VPN to work, we need to do port forwarding (permantly), similar to how the router was setup. Edit /etc/sysctl.conf

sudo nano /etc/sysctl.conf

 

Uncomment the line (remove hash) #net.ipv4.ip_forward=1

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

# Uncomment the next line to enable packet forwarding for IPv6
#  Enabling this option disables Stateless Address Autoconfiguration
#  based on Router Advertisements for this host
#net.ipv6.conf.all.forwarding=1

 

Save and Exit (Ctrl+O, Ctrl+X)

Reload the parameters by running:

sudo sysctl -p

Now let's edit out iptables rules (a variation of the UFW setup used at digital ocean).

sudo nano /etc/network/iptables

Load the IP tables rules:

nano /etc/network/if-pre-up.d/iptables

Now, let's generate VPN keys

sudo cp -r /usr/share/easy-rsa/ /etc/openvpn
sudo mkdir /etc/openvpn/easy-rsa/keys

sudo nano /etc/openvpn/easy-rsa/vars

Change these variables as preferred:

export KEY_COUNTRY="UK"
export KEY_PROVINCE="London"
export KEY_CITY="London"
export KEY_ORG="My Company Name"
export KEY_EMAIL="dan@example.com"
export KEY_OU="None"
export KEY_NAME="server"

Generate the Diffie-Hellman parameters:

sudo openssl dhparam -out /etc/openvpn/dh2048.pem 2048

sudo -s
. ./vars
./clean-all
./build-ca   (press enter at each prompt)
./build-key-server server   (press enter at each prompt, including password, then y to each question)

cp /etc/openvpn/easy-rsa/keys/{server.crt,server.key,ca.crt} /etc/openvpn
exit

sudo service openvpn start
sudo service openvpn status

Generate certificates for clients to use:

sudo -s
cd /etc/openvpn/easy-rsa
. ./vars

For each certificate required:

./build-key client1
./build-key client2
./build-key client3   ...etc

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/easy-rsa/keys/client.ovpn
exit

Now I will create a folder in my shared ssd drive for the files I need for clients to be able to connect to obtain them. On my local laptop, once I've setup the NAS, it is easy to copy these files. For testing though, you will need some other way of transferring them - using SSH (SFTP) with e.g. WinSCP for a Windows client will work.

mkdir /mnt/ssd/openvpn
cd /mnt/ssd/openvpn
Copy each client crt and key file:
sudo cp /etc/openvpn/easy-rsa/keys/client1.{key,crt} .
sudo cp /etc/openvpn/easy-rsa/keys/client2.{key,crt} .       ...etc

Then copy the CA and client conf files:

sudo cp /etc/openvpn/ca.crt .
sudo cp /etc/openvpn/easy-rsa/keys/client.ovpn .

Then give permissions:

sudo chmod 755 *

Pinhole through router (on the guest)

Our router (on the guest VM), should be set to block all incoming traffic. This will, however, prevent the VPN from being accessible from the outside

See the below example of how we can edit the iptables script to create

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

# enp0s3 is WAN interface, enp0s8 is LAN interface
-A POSTROUTING -o enp0s3 -j MASQUERADE

# NAT pinhole: Open VPN to LAN server
-A PREROUTING -p udp -m udp -i enp0s3 --dport 1194 -j DNAT --to-destination 10.0.1.100

COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# Service rules

# basic global accept rules - ICMP, loopback, traceroute, established all accepted
-A INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT

# enable traceroute rejections to get sent out
-A INPUT -p udp -m udp --dport 33434:33523 -j REJECT --reject-with icmp-port-unreachable

# DNS - accept from LAN
-A INPUT -i enp0s8 -p tcp --dport 53 -j ACCEPT
-A INPUT -i enp0s8 -p udp --dport 53 -j ACCEPT

# SSH - accept from LAN
-A INPUT -i enp0s8 -p tcp --dport 22 -j ACCEPT

# DHCP client requests - accept from LAN
-A INPUT -i enp0s8 -p udp --dport 67:68 -j ACCEPT

# drop all other inbound traffic
-A INPUT -j DROP

# Forwarding rules

# forward packets along established/related connections
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# forward from LAN (enp0s8) to WAN (enp0s3)
-A FORWARD -i enp0s8 -o enp0s3 -j ACCEPT

# Open VPN traffic allow
-A FORWARD -p udp -d 10.0.1.100 --dport 1194 -j ACCEPT

# drop all other forwarded traffic
-A FORWARD -j DROP

COMMIT

To apply the rules, run the script created earlier:

sudo /etc/network/if-pre-up.d/iptables

Connecting a client

I'll attempt to connect my phone, with wifi disconnected using my 4G signal to my home network.

Before I do, first I need to prepare the files to transfer to the phone.

These files are needed (assume earlier I created a client key for a device named myphone):

  • myphone.crt
  • myphone.key
  • ca.crt
  • client.ovpn

Now we will create a unified profile file, using the same method described at Digital Ocean:

Copy and paste client.ovpn, named it myphone.ovpn.

  1. Near the top, edit the line
    
    remote my-server-1 1194
    Replace my-server-1 with the public IP so your connection (or if you use dynamic DNS, then that)
  2. Downgrade privileges to nobody
    
    # Downgrade privileges after initialization (non-Windows only)
    user nobody
    group nogroup
    
  3. Comment out these ares:
    
    #ca ca.crt
    #cert client.crt
    #key client.key
    
  4. Now carefully paste the contents of the other files (including the BEGIN and END sections) into an XML syntax at the bottom of the file:
    
    <ca>
    (insert contents of ca.crt here)
    </ca>
    <cert>
    (insert contents of myphone.crt here)
    </cert>
    <key>
    (insert contents of myphone.key here)
    </key>
    

I then transferred my final ovpn file to my Android phone (in the /sdcard directory), installed the OpenVPN app and imported the profile. I was able to connect immediately.

A quick visit to whatismyipaddress.com shows that the IP is the same as my server's IP address on my home network, even though I am connected to the mobile network using 4G.

The same can be done with my laptop, installing the OpenVPN windows client https://openvpn.net/index.php/open-source/downloads.html

Make a copy of myphone.ovpn, named mylaptop.ovpn (or a better name as you prefer).

This time you only need to update the <cert> and <key> sections with the crt and key files you generated earlier.

Drop the ovpn file into C:\Program Files\OpenVPN\config

Run OpenVPN.

You will not be able to connect to the VPN if you are already connected to the WiFi network. To test it, I just tethered to my phone's connection and used the laptop through there.

If you're not so lucky though, the only way to fully check it works through the firewall is to use someone else's connection.

Once connected, OpenVPN will assign you an IP and the forwarding rules we setup earlier will grant us access to our local network, as if we were there (only slower of course). You should be able to SSH to your server, see your shared files and whatever else!

Page 4 - NAS, power saving and conclusion