Setup Letsencrypt SSL on raspberry pi

I love letsencrypt. It’s free SSL, it’s saver because of the auto-renewal and it’s so easy to setup. No more emailing around validating company name and whatnot.

If you’ve followed the previous steps you would not have installed git, check with git --version When it gives an error install git first with sudo apt-get install -y git

Now get the letsencrypt software and prepare the folder which letsencrypt will use.

sudo git clone https://github.com/certbot/certbot /opt/letsencrypt
sudo mkdir /var/www/letsencrypt
sudo chown www-data:www-data /var/www/letsencrypt

Add the first part of the letsencrypt config to nginx sudo nano /etc/nginx/sites-enabled/example.com
Before the final } add this:

location /.well-known/acme-challenge {
    root /var/www/letsencrypt;
}

And reload nginx sudo nginx -t && sudo service nginx reload

Getting the ssl certificate

So now we can generate and validate the ssl certificates. With the command below.
The email-address is used only for checks and warnings so I recommend an email which you do check. And of course change the domain. We will get a certificate for both www and non-www domain.

sudo /opt/letsencrypt/certbot-auto certonly -a webroot --webroot-path=/var/www/letsencrypt/ --rsa-key-size=4096 -m letsencrypt@example.com -d example.com -d www.example.com

When running this the first time It might take a long time, just be patient. When it is done we add the certificates to the nginx configuration: sudo nano /etc/nginx/sites-enabled/example.com

listen 443 ssl default_server;

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

sudo service nginx reload

Test if ssl is working on both www and non-www. If it’s working then the next step is forcing ssl all the time.

replace:

server {
    listen 80;
    server_name example.com www.example.com;

And replace it with:

server {
    listen      80;
    server_name home.janw.me www.home.janw.me;
    rewrite     ^   https://$server_name$request_uri? permanent;
}
server {
    listen 443 ssl;
    server_name home.janw.me www.home.janw.me;

    ssl_certificate /etc/letsencrypt/live/home.janw.me/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/home.janw.me/privkey.pem;

As usual reload sudo nginx -t && sudo service nginx reload

Autorenewel

certbot renew

https://caatest.co.uk/home.jwon.nl
https://michael.lustfield.net/nginx/getting-a-perfect-ssl-labs-score

Installing Mysql/MariaDB on a Rapsberry Pi

Here we will install MariaDB. The performance is better and it’s more open source. There are a few differences but nothing you will notice during normal daily use.

Installing mariadb:

sudo apt-get install -y mariadb-server-10.0

Alternative if you don’t want to get out of your comfort zone use mysql:

sudo apt-get install -y mysql-server

During this install you will get asked for a SQL root password. Choose a long secure password. You will need it later to make a database so also store it somewhere save.

After it’s done check the version with mysql --version. It should be 10.0.30-MariaDB or higher.

Creating a database and user

To create a database we are going to login to MySQL with the following command.

mysql -uroot -p

It will ask for the mysql password. After that the commandline will be different. We are going to create a database and a user and connect them.

CREATE DATABASE raspimain_db;

Next we create a user, be sure to replace the password!

CREATE USER 'raspimain_user'@'localhost' IDENTIFIED BY '%%SAFE_PASSWORD%%';

Then we need to connect the user to that database.

GRANT ALL PRIVILEGES ON `raspimain_db`.* TO `raspimain_user`@`localhost`;

Next we 2 commands are pretty self explanatory.

FLUSH PRIVILEGES;
EXIT;

To test if it worked login in to mysql with that user.

mysql -u raspimain_user raspimain_db -p

This time use the password you used to create the user. Check if the raspimain_db is in the list of databases.

SHOW DATABASES;

If it is use EXIT; to exit the mysql promt.

Installing Nginx on a Rapsberry Pi

In this step we are going to install a webserver (nginx). For those who are bit familiar with webservers you might wonder why we are not using apache? I myself are far more familiar with Apache but Nginx just has better performance. And on the not that powerful pi that is important.

Install Nxing

Like with php we want a newer version. So again we will use the buster source. It should install 1.13 (although 1.13 is the newest) To install nginx run the command:

sudo apt-get install -y -t buster nginx

Check the version nginx -v it should be version nginx/1.13.3 or higher

To test if it works enter the IP address in the browser. You should see this page. nginx-default-page

If you see an error most likely IPv6 isn’t supported. Open the nginx config file.

sudo nano /etc/nginx/sites-enabled/default

At the top you should see these lines

    listen 80 default_server;
    listen [::]:80 default_server;

Change them to:

    listen 80 default_server;
    #listen [::]:80 default_server;

Save then restart nginx.

sudo nginx -t && sudo service nginx reload

Then test the page again in the browser.

Setting up a site with php and url

First we will do some global settings open: sudo nano /etc/nginx/nginx.conf
At this part add the last line.

http {

        ##
        # Basic Settings
        ##

        client_max_body_size 64M;

Next open: sudo nano /etc/nginx/sites-enabled/default
Add at the end

upstream php {
    server unix:/tmp/php-cgi.socket;
    server 127.0.0.1:9000;
}

Note: for the example I use example.com replace that with the url you want to use. If you don’t have the url setup yet you can add it to you own host file. Or instead of the url use the IP-address of the Pi.

We will create our own vhost files. PS I’ll be using example.com but use whatever you intend to use. Create the vhost file: sudo nano /etc/nginx/sites-enabled/example.com.conf

server {
    listen 80;

    server_name example.com;
    root /var/www/example.com/public_html;

    index index.php index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
    }
}

Next create the folders needed. Set the rights of those files and add a test page.

sudo mkdir /var/www/example.com
sudo mkdir /var/www/example.com/public_html
sudo touch /var/www/example.com/public_html/index.php
sudo chown www-data:www-data /var/www/example.com -R
sudo nginx -t && sudo service nginx reload

In that file add sudo nano /var/www/example.com/public_html/index.php

<?php
phpinfo();

Save and reload the webpage you should see this:

Now we have a basic and functioning webserver with php.
For security sake delete the index.php file

sudo rm /var/www/example.com/public_html/index.php 

Next we will install mysql and configure a database.

Installing PHP7.1 on a Rapsberry Pi

To get a big performance boost we will use PHP 7.1 instead of the older 5.6 which Rasbian still uses by default. But because this is the default we will need to do a few extra tweaks.

In the file sudo nano /etc/apt/sources.list at the end we add:

deb http://mirrordirector.raspbian.org/raspbian/ buster main contrib non-free rpi

After saving create the next file sudo nano /etc/apt/preferences. With the content:

Package: *
Pin: release n=jessie
Pin-Priority: 600

Again save. Make the system aware of this source list with

sudo apt-get update

Now we are ready to install PHP7 with all it’s modules:

sudo apt-get install -y -t buster php7.1-fpm php7.1-curl php7.1-gd php7.1-intl php7.1-mcrypt php7.1-mbstring php7.1-mysql php7.1-opcache php7.1-sqlite3 php7.1-xml php7.1-zip php-apcu

When done check it with php -v it should show a PHP 7.1.8 (or higher).
Now we need to add a few fpm things for nginx to work properly.

sudo nano /etc/php/7.1/fpm/conf.d/90-pi-custom.ini

And add:

cgi.fix_pathinfo=0

upload_max_filesize=64m
post_max_size=64m
max_execution_time=600

Save and next open sudo nano /etc/php/7.0/fpm/pool.d/www.conf Search for $HOSTNAME and change.

;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp

remove the ‘;’ at the start

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

request_terminate_timeout

Apply these changes sudo service php7.1-fpm reload

Now PHP is ready to use

RaspberryPi, Only allow ssh key login

This is the followup of Opening a Raspberry Pi to the outside world On the internet bots constantly try to hack servers. The Raspberry Pi is popular target. That’s why by default ssh is disabled nowadays.
To make this more secure we will only allow login by ssh key instead of a password. Ssh keys are a lot safer and you also won’t need to type/paste the password on login.

Open file: sudo nano /etc/ssh/sshd_config

Look for PasswordAuthentication
remove the # at the front and change the value to no.

PasswordAuthentication no

As a fall-back we will allow login in from the home network. So at the bottom of the file add. (the 4 spaces in front of the line matter)

Match address 192.168.*.*
    PasswordAuthentication yes

Restart the ssh service. sudo service ssh restart

ssh keys

Generate keys on the raspberry pi: ssh-keygen -t rsa -b 4096 -C "pi-webserver"
Just press enter for both the location and password.
Add your local key. Form your own machine mac/linux/windows.

Open File: sudo nano .ssh/authorized_keys

Paste your public key in this file.
For linux/mac you can find your public key with: cat ~/.ssh/id_rsa.pub

In a new terminal tab/window, try to login again. This way you can change things in the current tab. If something went wrong. You should login without needing to type the password. To check if the password is disabled you should try login in from a different computer and a different ip.

Opening a Raspberry Pi to the outside world

This part is a bit tricky. Because it’s depending on third parties. And they all work a bit different. The big stokes are the same for everyone but the how will differ a bit. This step can also be done later.

Opening the router to the outside world.

You need to login into your modem which your ISP provided to you. How to do that might differ per modem. But usually it will be an ip which start with 192.168.. To help you get started. A few pointers.

  • Inspect the modem. Look for passwords and model type.
  • Google the modem type, this will help with the ip and maybe the default login credentials.
  • Some still have default passwords, instead of random generated.
  • Call your ISP, it’s there modem they should be able to help.

Once you are in the modem settings we are going to do a thing called port-forwarding. I had a lot of problems figuring this out. Because of that I’m going to refer you else where. Keep in mind the following.

  • You will need to forward it to the hostname or the internal IP used by the Pi. If you need the IP see below to give a static IP. The hostname you can get with hostname.
  • The ports we are talking about should be 80 for http and 443 for https.
  • If you want too login to ssh remote secure your remote and forward port 22 for ssh.
  • You might need something called “TCP”
  • I needed to fiddle with a setting “DMZ Host”network
  • If you are struggling google port-forwarding with your modem

As I said this is really not my piece of pi, so here is a better guide: HowToGeek guide

Adding a domain name

First you will need to register a domain name. There are a lot of these registrars as they are called. I’m not going to recommend any because I registered all my domains at a Dutch company. One registered you will need to add a DNS A-record that will point to your home IP.

You can get your home network IP with the following command:

wget http://ipinfo.io/ip --timeout=3 --tries=1  -qO -

To test if your url is working run: ping example.com -c 5
It should return something like this, with your home IP:

5 packets transmitted, 5 received, 0% packet loss, time 1000ms

Giving the raspberry a static IP

Your modem probably needs a ip for port-forwarding. You will want a static IP so you don’t need to change the IP after a power outage or whatever. First we need to collect some IP addresses. Be sure to make note them while collecting them.

ifconfig
netstat -nr

raspberry-internal-ips

The interesting line is the second. Note all 3 of those. The first one is the one I’m changing in this example.

inet addr:192.168.2.10  Bcast:192.168.2.255  Mask:255.255.255.0

Also note the destination ‘192.168.2.0’ and Gateway ‘192.168.2.254’.

I will change the current 192.168.2.10 to 192.168.2.90 The last digit can be changed to anything between from 0 to 255. But It is better to use a big number. Lets say we would change it to ‘192.168.2.1’. But your desktop uses that same IP address. Then neither will be able to connect. So change it to a higher number, which is less likely to be used.

We now have all information, let’s apply the changes.
open file: sudo nano /etc/network/interfaces

This will open the file

Switch these lines

auto lo

to

#auto lo
auto eth0

Put a # in front of the line:

iface eth0 inet manual

Below that add:

iface eth0 inet static
address 192.168.2.90
netmask 255.255.255.0
network 192.168.2.0
broadcast 192.168.2.255
gateway 192.168.2.254

My final interfaces file:
final-interfaces-file

Now reboot and login with the new IP address

Troubleshooting

  • If for some reason you can’t login, try the old IP.
  • Go directly to the Pi hookup a screen and keyboard and check the IP ifconfig
  • Else open the interfaces file again directly on the pi itself.
    sudo nano /etc/network/interfaces
    And undo all changes.

RaspberryPi up and running

This guide will help you set up a Raspberry Pi with Rasbian. Ready to do pretty much whatever you want.

What hardware do you need?

  • First off a Raspberry Pi of course, for this tutorial I’m using a Model 2B. A 3B should have the same steps. I just don’t have it. A 3B just cost about as much and is faster and has wifi.
  • Second I have a network cable, even if I had a Pi 3B I would still use the cable, it will cost less power. But of course you need to get the network cable to the right location in the house.
  • a micro SD card, at least class 10 for speed and with 8GB or more. The SD card will serve as the main harddrive for the pi. An micro SD adapter is also needed to install the image on the SD card.
  • A micro USB power source. This can get a bit tricky. Recommended is at least 2A with 5V. A normal smartphone adapter won’t give that. Using less will slow down your raspberry.

Installing Rasbian

First off download Raspbian Jessie Lite from the Raspberry pi website. When It’s done flash the image on the SD card. There is an official guide that explains it better then what I could do.

Flashing the image can take a while. You could set up all the wires and put things in place.

When the writing of the SD card is done. Put a file with the name ssh in the root of the boot partition. If you need wifi place a file named wpa_supplicant.conf also in the boot partition. And add the following:

network={
    ssid="YOUR_SSID_WIFI_NAME"
    psk="YOUR_PASSWORD"
    key_mgmt=WPA-PSK
}

I haven’t tried myself so more information here

Then plug in the SD card and powerup. Check the IP address guide to get the ip-address of the pi. Do wait ~5minutes before actually trying. The raspberry has to setup stuff for the first time. If after 20max you still can’t find an IP. The flashing of the SD card has gone wrong and you’ll have to restart.

Go to your own computer and open the terminal (or Putty for the windows users) Login with the command ssh pi@192.168.*.* Use the IP address you noted before. If it asks if you want to continue choose yes. and use the default password: raspberry Putty agian will work a bit different.

You should see something like this:
raspberry-remote-login

Now you are logged-in remote on the raspberry pi. Time to configure some stuff with the command sudo raspi-config.
On this menu we can configure some basic settings. Let’s change some settings.

  1. Change User Password CHANGE THE PASSWORD. Longer is better and safer
  2. Hostname I advise to change the Hostname so it will be easier to find, I named mine pi-webserver.
  3. Boot options Chose the ‘Console Autologin’ of ‘Console’ option. Don’t choose auto login if someone else might have physical access to the pi. This will disable the desktop so it won’t waste power.
    Wait for Network at Boot Just turn this off to be safe.
  4. Internationalisation Options Here you can change the timezone to your current one. You could change the language of the PI and the keyboard layout if you need to. Keep in mind I will be using English. 5 Interfacing Options we don’t need this.
  5. Overclock Set this to the highest setting. It won’t hurt and will make the Pi a faster.
  6. Advanced Options Change the Memory split to 16. Because we don’t have a interface we won’t need memory for that. Do Expand Filesystem Because the image is made for a 4GB sd card it will only take about 4GB. This option will make sure all available space is used.

When this is finished the pi might download some language packs. It it doesn’t reboot. you have to do it yourself. sudo reboot

Wait about a minute and login in again like before.

updates

This might take a while but first we are going to update.

sudo apt-get update && sudo apt-get upgrade -y

It will ask for conformation to update, say yes. As I said it will take long, and at times It might appear to hang. It Unless it’s stuck on one thing 15 minutes it’s probably fine. Give it half an 15 to 30 minutes

When it’s done reboot again just to be sure.

You now have a Raspberry Pi ready for use.

This blogs blueprint

I’ve had the idea for a blog for years. But actually bloging keeping it up is hard. So here is another go. This blog had no restrictions for me. So when setting this up I did some things I would(/could) never do anywhere else.
The biggest sin I commit is not having a development environment.
So how I this blog (being?) build:

Continue reading