My Home-made PC Router and NAS Server - Page 2 - The router

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.

The build - Host Base

Before you start, plug the PC into a monitor, keyboard and
mouse.

We're do most of the build connected to our existing router
and network, so we can test things and keep our Internet during the build.

Plug the network socket that you intend to use as your WAN
connection, into your existing router / LAN. Into the port intended for use as
the LAN, we can plug a cable directly into another PC or laptop for testing.

This assumes Ubuntu LTS 16.04 Desktop version.

Download the ISO, and write it to a DVD or USB drive (made
bootable by LinuxLive USB Creator).

Do the install. Countless resources on the web to guide you
through this, and it's easy.

I choose to partition manually (the 'something else' option)
- creating a 'special' kind of layout for partitioning. Here's the setup and
why:

Mont Point

Size

File System

Why?

8GB

SWAP

Swap is usually a good idea. I've made it the size of my RAM.

/boot

300MB

Ext2

Boot is a small and simple file system. Often 100MB but I've made it
bigger to hold more kernel images during upgrades

/

20GB

BTRFS

This is where the OS goes. 20GB should be more than enough. BTRFS
(B-Tree File System) is a fast filesystem.

/home

10GB

BTRFS

10GB for a separate home folder, in case I needed to format the OS in
future but easily keep my home folder

/mnt/ssd

70GB

XFS

An area to store files such as VMs that may run on this server. XFS
fits this better. Extents option should be used

Some free space is kept for over-provisioning to keep SSD performance
optimal

Once partitions are done, after a few easy questions, the
install completes, and boots.

When creating your user, choose to log in automatically
(we'll need this since no keyboard / monitor is plugged in most of the time).
Your computer name should be something simple and memorable. I used
"dan-server".

When asked, choose the correct primary interface when asked.
This should be where your WAN is plugged in.

Update:

Remote access.

For this build - the PC will be sitting with no monitor,
keyboard or mouse plugged in and placed in a cupboard where the Internet WAN
connection comes in.

When we need to connect and administer it though, we can use
terminal and GUI remote methods to connect in.

SSH

SSH is a great way to connect in and run terminal commands.
Most of the time, this is exactly what you'll need to administer the server,
including updates, reboots, backups, file manipulation and so on.

Open SSH Server does the job we need. To install it:

sudo apt-get install openssh-server
sudo nano /etc/ssh/sshd_config

In this file, uncomment the line 'PasswordAuthentication yes'. Then save and enter these commands:

sudo service ssh stop
sudo service ssh start

You should now be able to connect from another PC to this one. I use mRemoteNG, which comes with PuTTy.

GUI - TeamViewer

For the GUI, teamviewer I find easier and works better than
other methods I've tried. It's free for personal use. I found it a little hard
to setup, but this install seems to get the right pre-requisite binaries in
first.

This may not work first time - but after a short delay, on
the server's screen, will appear a licence agreement, which you will need to
accept.

Then rerun:

sudo teamviewer info

Info will print the details you need to connect to the
server.

The build - Guest Router

Install Virtual Box

Installing Oracle's Virtual Box is easy:

sudo apt-get install virtualbox

Now I will guide you through creating the server Virtual
Machine.

Note: If you want, you can do the VM install on another
machine (I did mine on a more powerful laptop) - as long as two NICs (LAN and
Wifi) are available, we can set it all up, then copy the VM directory to the
server later. This guide assumes installing directly on the server though.

Create VM, install Server OS

Open the Virtual Box GUI.

Create a new VM. One hard disk, dynamically allocated. The
8GB default is fine.

Configure some options that you will need to make the VM
operate as a router

Give it some RAM - I'd recommend 2GB or more

Give it CPU access - 2 cores will be good

Network

Adapter 1 - Bridged

Adapter 2 - Bridged

Audio - Untick

Choose an ISO for the hard drive, for example ubuntu-16.04.1-server-amd64.iso

Run the VM. The ISO should auto boot.

Choose "Install Ubuntu Server"

Choose your language, keyboard language

Choose enp0s3 as the primary interface

Enter a hostname - I used "dan-gateway" for example

Enter your username / password. This will be the admin user for
the system, so choose a strong password

Encryption of the home directory isn't necessary

Choose your timezone

When asked about partitioning, we can go manual again, but with a
simpler option:

Select the disk, choose Yes to create an empty partition table

Select the free space, create three new primary partitions, for
each, select "Beginning"

/boot partition will need the bootable flag

For / and /boot, you can select noatime and nodiratime

Mount Point

Size

File System

Why?

4GB

SWAP

Swap is usually a good idea. I've made it the size of my RAM.

/boot

300MB

Ext2

Boot is a small and simple file system. Often 100MB but I've made it
bigger to hold more kernel images during upgrades

/

4GB

XFS

This is where the OS goes. The remaining space will be enough. Choose
the same file system as that of the host, where the VM will be stored (in
this case /mnt/ssd is XFS)

If you want, you can create a separate home partition, but
for this O/S, we really don't expect to store much there and it can be
considered more disposable.

You may be asked for this information during the install
too:

Proxy server (enter for none)

Updates (auto security updates)

Configure the server with standard utilities only. We're not
using it for anything else.

Install Grub to the master boot loader - Yes

Update the software

SSH

Like the host, SSH is a great way to connect in and run
terminal commands, this time to our guest router. Once you connect to the guest
with SSH, we can copy / paste commands in instead of typing them in the VM
display.

For security, later we will prevent SSH listening on the WAN
IP, but for now it is all default:

Open SSH Server does the job we need. To install it:

sudo apt-get install openssh-server
sudo nano /etc/ssh/sshd_config

In this file, uncomment the line 'PasswordAuthentication yes'. Then save and enter these commands:

sudo service ssh stop
sudo service ssh start

Create network

We will use /etc/network/interfaces for configuring the
network

Our WAN interface (known as enp0s3) will be auto (DHCP),
whereas our LAN interface (known as enp0s8) will be manual.

To avoid any conflicts with your existing LAN setup during
configuration, we'll configure our new setup to use 10.0.1.x addresses. This is
within the reserved range, but I've not seen any home routers use them.

During our setup, the WAN port should be plugged into our
existing LAN, so the network card which will be the new WAN port, will receive
an IP of say 192.168.0.100 (or similar) from our old router.

The output of ifconfig should show an IP assigned by our old
router on enp0s3, and the static address 10.0.1.1 on enp0s8

NAT - enable forwarding

To enable port forwarding (permanently), 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

NAT - IP tables

I liked the ways Ars Technica did it, so this is a copy of
exactly that, but shortened!

Local DNS

The guest VM will hold local DNS caching. This can be done
by installing bind9:

sudo apt-get install bind9

And it's that simple.

Finally, let's reboot

The build - Host Router

Back to our host PC, we will now set this up to access the
Internet through our Router VM, instead of directly. We'll also setup a DHCP
server for handing out network details to our various clients.

Network Configuration

Like our router, we will use /etc/network/interfaces for
configuring the network.

Our WAN interface (for me, known as enp2s0) will be manual
shortly, but we will leave it unspecified for now (which means Ubuntu network
manager will care for it). LAN interface (known as enp4s0) will be manual.

The output of ifconfig should show an IP assigned by our old
router on enp0s3, and the static address 10.0.1.2 on enp0s8

DHCP server

At this stage, any client that needs to use the router, and
plugged into the LAN network card, would have to statically define an IP,
gateway and DNS.

We can use the host to run a DHCP server though. Why on the
host? Well initially I did it on the guest, but when Virtual Box updates or we
need to do anything with the router VM, all the clients lose access to the host
too, preventing reconnection unless we manually choose an IP and gateway.

To install the DHCP server, again just a copy from Ars
Technica, with modification:

Add this to the bottom. Note that in green I've highlighted
how to define a static assigned IP address to my VOIP ATA, this is to ensure
its IP does not change so the traffic is forwarded from the iptables rule to
the right place.

I've used 10.0.1.118 as an IP reserved for my VOIP ATA, using its specific MAC address. This is to ensure the port forwarding is always going to the right place (IP address). If you don't need this, remove the whole block host voip.

Here we have used "up ifconfig xxx up" for each interface to
make sure that they always come up, even with no IP assigned. This is so that
the VM can use the interfaces, and the interfaces work once the VM has finished
booting.

To doubly ensure that the host cannot connect directly, we
will use iptables to prevent it:

Auto VM Start

We'll need our router guest VM to auto-start when the server
is started, otherwise they'll be no internet access. Some scripts can do this,
and I hunted around for the most reliable means. Tombert's on askubuntu.com
(linked below) was a good start. I then combined it with a systemd script to
start and stop the VM on boot/shutdown.

I created these scripts in the same directory as the VM,
which for me is /mnt/ssd/Gateway

SSH security

Though we cannot connect to SSH from the internet unless we
open an iptables rule, as added safety it is still good to tell SSH to only
listen on the LAN adaptor, for both our guest router VM, and the host itself.

To get SSH from the outside, we can use Open VPN to access
the server, and then SSH to the relevant LAN IP instead.

To tell SSH to only listen on certain IPs, you can edit /etc/ssh/sshd_config

sudo nano /etc/ssh/sshd_config

ListenAddress 10.0.1.1

Uncomment the ListenAddress line and put the static IP for
the LAN address (10.0.1.1 for the gateway, 10.0.1.2 for the host).

We can see that in the Local Address column, port 22 (ending
with :22) only shows for 10.0.1.1.

0.0.0.0 or ::: indicates a port/service listening on all IP
addresses.

SSH is now only accessible on the LAN. Take care if
assigning a new static IP via SSH though - if you change it and do not update
the SSH configuration, you will lose access.

You can go further with SSH security and prevent password
authentication. This involves generating a public-private key pair and
authenticating with that instead of the password.

The main advantage of this is it prevents brute force
attacks as your SSH server would continue to listen for the right password. I
would say though just keep it off the Internet unless you really need it.

Feel free to print material you may need, but if you want to use information on your own sites and for business purposes, please E-mail me or link to my site using this address: www.electro-dan.co.uk

Information I supply on this site and by e-mail cannot be guaranteed to be correct - it will be to the best of my knowledge. If you do spot a mistake anywhere on this site - please let me know and it will be fixed.