SSH with Certificates

Using certificates to login via SSH is safer than using a password. And it’s more convenient if you’re using the same device to login. Here is the steps:

First, we need to generate certificates. You can generate SSH key pairs directly from PuTTY with PuTTYgen on Windows, or use OpenSSH integrated in the terminal for Mac OS.

On Windows, Run PuTTYgen as administrator, select SHA-1 RSA for key type and 2048 bits for length, and generate a key pair. Then fill in key comment and a passphase. A passphase is like a password for your private key, it’s not compulsory but recommended. Then save both of you public key and private key.

On Mac OS, use the following command in the terminal to generate key pairs:

  • ssh-keygen -t rsa

Leave the save location blank to save at default location, which is recommended (or you can specify a location if you want). Enter a passphase and verify (or you can leave them blank for no passphase). The key will be saved automatically.

Second, we need to copy the public key from PC to Raspberry Pi. Login to Raspberry Pi with SSH, then edit authorszed_keys file:

  • nano ~/.ssh/authorized_keys

Open your public key file. Paste the key in the file and save and exit nano. You can have multiple public keys each line in the file if you need to login to your Raspberry Pi from more than one device.

On Mac OS, the public key ends with “.pub”. You can use cat command to view and copy:

  • cat ~/.ssh/id_rsa.pub (if you save at default location)

Never share your private key!

Third, we need to edit sshd_config of Raspberry Pi, to disable login via password, open the file with the following command:

  • sudo nano /etc/ssh/sshd_config

Find the following lines:

  • #PasswordAuthentication yes no

We would like to delete the hash key at the front, and change yes to no. Then save and exit, and restart ssh service:

  • sudo service ssh restart

Now we can login to Pi using certificate. Only client with certificate that is registered on authorized_keys is allowed.

On Windows, you need to select your private key as login credential. Select SSH – Auth on the left menu and choose your private key, then enter your passphase if you have one. Then connect as normal.

On Mac OS, terminal will automatically use your private key to attempt to login, if there’s one in the default location. If you saved you private key in a different location, use “-i <private key file>” parameter on SSH command.

Note that if you lost all your keys, you will lose access via SSH. In such case, you need to use a keyboard and monitor to access just like the first time setup. You can edit the sshd_config to allow password login again.

Remote Desktop – VNC

We were dealing with command line from the start. In fact Raspberry Pi also has desktop environment. It can be started one-off by command “startx”, or it can be launched on boot, which can be set on raspi-config:

  • sudo raspi-config

Select Option 3 Boot Option, go to Desktop/CLI and choose Desktop. Exit raspi-config and reboot, now we can see it boots into desktop environment.

Virtual Network Computing (VNC) is the remote login to desktop. The latest disk image has RealVNC preinstalled, but it’s not turned on by default. This is also set on raspi-config. Go to Advance Option, select VNC and choose yes to allow remote desktop. Then reboot the device.

On the PC side, RealVNC client is available at https://www.realvnc.com/download/vnc/. After installation of VNC Viewer, we can connect to Raspberry Pi with its IP address, username and password.

Now we can access command line and desktop remotely, which is a lot more flexible than sitting on a monitor. For even more flexibility, we can  setup access over the internet next.

Access from the Internet

You might find all the settings before work only on LAN. We cannot access our LAN from internet because our router has NAT and firewall. To go over this limit, we can use port forwarding/port mapping. Port forwarding is to bind a port to a host and all packets arrives at that port is redirected to that host. This is set in the router.

First, login to your router and select port forwarding, this is normal in advance option near firewall.

Then, add some new rules in. You’ll need to specific incoming port, destination private address and destination port. You may also specific source IP address to prevent malicious attack.

For security, open minimal ports to the internet. For public servers, such as web server and mail server, we may use its standard port. For other servers, never use its standard port. Never ever open port 22 for SSH or port 5900 for VNC from the internet, use some others (I used 2200, but don’t try it because it’s closed now) and map it to port 22.

Now if you try to access your public IP address from the internet (you may use cellular connection to test, remember to use correct port number as well), you should be able to connect as you were in your LAN. If you don’t know your public IP, you may look at WAN address in your router. Note that if your WAN address is also a private address, you cannot configure to connect from the internet.

You’ll also need to check whether your public IP is static or dynamic. You may check with your ISP or reboot your router to see if WAN IP changed. If it’s static, that’s it we’re done, remember to update port forward when new service comes online. If your IP address is dynamic, it’s recommended to set up DDNS on router as well. There are many free DDNS service provider, such as https://www.noip.com. After you register and select a domain name, login to your account on your router and you can gain access from the internet using the domain name. This also applies to static WAN IP if you don’t want to use your IP address.

Now we have anywhere access from the internet. We can start to launch some services to the internet.

OpenVPN – Securely Access Home Network from Anywhere

OpenVPN was the first project I achieved on my Raspberry Pi. It is, actually, the reason why I bought my Pi. This is also the first tutorial on server application.

First, we need to enter root user and install OpenVPN server:

  • sudo su
  • apt-get install openvpn

The reason for using root user instead of sudo is, there are some command we can’t use sudo, e.g. sudo cd /etc would not work.

Then we need to copy EasyRSA sample file to /etc/openvpn:

  • cp -r /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn/easy-rsa

And edit setting parameter of EasyRSA:

  • cd /etc/openvpn/easy-rsa
  • nano vars

There are a few lines we need to change:

  • export EASY_RSA=”`pwd` /etc/openvpn/easy-rsa”
  • export KEY_SIZE=1024 2048
  • export CA_EXPIRE=3650 730
  • export KEY_EXPIRE=3650 365

The first line is to specify where the keys are stored. Then the length of the key, 2048 bits are a lot safer than initial 1024 bits. The third and fourth lines are the expiration date from issue, initial it’s 3650 days (10 years) but shorter is safer. These two lines can be changed to your preferences.

The next few lines need to be changed to your own information:

  • export KEY_COUNTRY
  • export KEY_PROVINCE
  • export KEY_CITY
  • export KEY_ORG
  • export KEY_EMAIL
  • export KEY_OU (can be blank)

Save and exit nano.

Then we need to configure OpenVPN config file. Download the files below and copy them to /etc/openvpn:

  • Server Config
  • Client Config

We need to edit config files to tell OpenVPN some settings and where all the keys are:

  • nano server.conf client.conf

For server.conf, replace the <Server Name> to your own server name. This can be whatever you like but we need it next step.

For client.conf, replace the <Server Address> to your static IP address or domain name.

If you like to know all the lines are about, visit https://openvpn.net/index.php/open-source/documentation/howto.html#server. If you decide to change the protocol or port number, remember to update both config files.

Save and exit nano.

Next we need to generate some keys. Here are two scripts I use for one click generate.

  • OpenVPN Server Key
  • OpenVPN Client Key

Download the two files and copy them to /etc/openvpn/easy-rsa, then change the owner and permission:

  • chown root:root build-server build-client
  • chmod 755 build-server build client

Then we can run it and generate the keys in one click:

  • ./build-server <Server Name>
  • ./build-client <Client Name> <Password>

Note we need one client key per client. The same key can be used on multiple devices. Challenge Password must be blank.

Then we need to copy the client file to your client device and connect.  The config file ends with ovpn. This can be done via scp, ftp or email. Or, I made a website for downloading config files.

OpenVPN client for can be downloaded at:

Then open the ovpn file on the client and enter your passphase to connect.

Now you should be able to connect to the VPN but you cannot do anything on the internet, because we need to forward VPN connection to ethernet.

We need to enable forwarding in the system first:

  • nano /etc/sysctl.conf

Find this line and uncomment it (remove the hash at the beginning):

  • net.ipv4.ip_forward=1

Save, exit and refresh the settings:

  • sysctl -p /etc/sysctl.conf

Next, we need to specify the forward rules:

  • nano /etc/openvpn-firewall.sh

Add this line in, replace the interface (eth0 for cable and wlan0 for wifi) and IP address:

  • iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o <interface> -j SNAT --to-source <pi's IP address>

Then set to load this config on network card:

  • nano /etc/network/interfaces

And add this line to the appropriate interface with indent (add a tab or 4 spaces before the line):

  • pre-up /etc/firewall-network.sh

Restart network card (or reboot pi) and openvpn should now work:

  • sudo ifdown <interface>
  • sudo ifup <interface>

That’s done! Now you may try to connect from internet (eg. mobile data) before go out and access your home network from anywhere!