HOWTO setup a Tilde server on a Raspberry Pi
Purpose
This HOWTO follows our own experience in setting up a server for web design students, so that they have access to their own web space and shells. Additionally, we wanted to have some particular features such as providing PHP.
This means that we are not (yet) planning to open this up to new users, and we know the people who are in. Your setup might require additional care if you want to create accounts for strangers. We hope to open our server up at some point, and update this document accordingly; in the meantime, keep in mind that this document presumes that you trust your users.
We’ll be actively updating this document from experience and feedback; see the Changelog at the bottom to see what’s changed.
Prerequisites
Besides trust in your users, this guide will assume that
- you have a basic understanding of the command line and SSH
- you have installed a Raspbian system (namely the Lite version) on your Raspberry Pi following the official install docs
- you have set up a domain name connecting to your server (or simply share its IP address), and configured your router forwards accordingly
- you are now logged in as user
pi
on your new system
Base configuration
Run sudo raspi-config
and go through these three steps.
- Network options: Choose “Hostname” to set your server’s name. I’ve read that this should be the registered domain name pointing to the server, but I’m using a random string and had no issue yet.
- Interfacing options: Make sure the “remote command line access to your Pi using SSH” option is enabled.
- Localisation options: Select “Change locale” to pick your locale, even if you want to keep the English language on everything.
Create your first user
It isn’t a great idea to keep the pi
user, as most worms and novice crackers will try that as a first entry point.
In this guide, we’ll work as user luther
. Change it according to your own preference when copy-pasting the below commands.
sudo adduser luther
sudo usermod -a -G adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,gpio,i2c,spi luther
We also want our new user to have sudo
access so that we can also disable the root account. Nevertheless, let’s ensure it always asks us for the password when running commands with sudo
– it’s not mandatory security-wise, but doesn’t hurt your chances to keep your server safe.
Edit the /etc/sudoers.d/010_pi-nopasswd
and change the line containing luther
to
luther ALL=(ALL) PASSWD: ALL
Copy your SSH key for password-less login
You won’t want to type in your password everytime, and you probably already have an SSH key on your computer for this. You can copy it over to your new server with one command:
ssh-copy-id luther@serveraddress.com
Disable access to the root
and pi
users
For root
, we’ll just disable remote SSH logins, by editing the file /etc/ssh/sshd_config
and changing the option PermitRootLogin
from yes
to no
.
If there’s no such line, type in a new one with PermitRootLogin no
.
For the pi
user, we’ll delete that user’s password so that login is not possible anymore.
sudo passwd -d pi
sudo usermod -s /usr/sbin/nologin pi
Change your SSH port
Most automated exploits will stick to the default SSH port (22). You can change it so that your server won’t be bothered by most scanners. Edit the /etc/ssh/sshd_config
file to change the line #Port 22
to Port 9999
or whatever number you prefer.
Do note that with this tweak, you lose the convenience of typing ssh server_address
(you would now need to add -P <port_number>
) and also have to highlight that additional detail for your users. On our own server we stuck with port 22 for this reason, and below you’ll find additional measures to secure and protect your server.
Apache
sudo apt install apache2
We’ll want to enable the option to have each user’s public_html
dir be served at /~username/
.
sudo a2enmod userdir
sudo systemctl restart apache2
Admins should be able to edit the main site at the root domain without needing sudo
. This is easy:
sudo adduser luther www-data
sudo chown -R www-data:www-data /var/www
sudo chmod -R g+rwX /var/www
Now the contents of /var/www/html
can be edited by any user that you add to the www-data
group.
PHP
We want our students to be able to write and run PHP scripts, and it’s rather easy to get that going.
sudo apt install php
Running PHP scripts in userdirs is disabled by default in Apache. We just have to turn it on by editing /etc/apache2/mods-enabled/php7.3.conf
(the file might have another name if you’re running a different PHP version.)
The file comments tell you exactly what needs to be done:
# Running PHP scripts in user directories is disabled by default
#
# To re-enable PHP in user directories comment the following lines
# (from <IfModule ...> to </IfModule>.) Do NOT set it to On as it
# prevents .htaccess files from disabling it.
<IfModule mod_userdir.c>
<Directory /home/*/public_html>
php_admin_flag engine Off
</Directory>
</IfModule>
So go ahead and comment those lines and restart Apache with sudo systemctl restart apache2
.
Prepare for your new inhabitants
Make a template for new home dirs
Before creating your new users, you might want to consider creating a base template for their home directories. Since this is a Tilde-like server, users will require a public_html
directory. You might also want to include a default index.html
, as well as other assets such as documentation.
This is easily done by adding these elements to /etc/skel
, which is a special directory in GNU/Linux systems. When a new user is created, the contents of this directory will be copied to the user’s new home directory. We can create a base public_html
directory containing a default index.html
file:
cd /etc/skel
sudo mkdir public_html
echo "Hello world" | sudo tee public_html/index.html
Feel free to make a more interesting default page for your users!
Create a new user
Simple:
sudo adduser janedoe
Create new users in bulk from a CSV file
In a teaching context, you’ll have many users to add at once. It’s boring – and thankfully unnecessary – to create all of them by hand. We can store their information in a CSV file that we can then feed the server to create all users at once.
For this to work, you’ll need to install the csvkit
package to read from CSV.
sudo apt install csvkit
Create a CSV file named accounts.csv
containing columns named username
and password
(it can have more fields, but these are the ones we need). After filling it with your username and password combinations, just run:
csvcut accounts.csv -c username,password | tail -n +2 | sed 's/,/:/; s/$/:::::/' > users.txt
sudo newusers < users.txt
rm users.txt
Be sure to block other users from reading accounts.csv
by changing its permissions:
chmod go-rw accounts.csv
[source for the bulk addition method]
Change a user’s password if they lost it
Another simple task; you won’t need their current password to be able to change it.
sudo passwd janedoe
Improvements and useful tweaks
Enable HTTPS with Let’s Encrypt
It’s now fast and simple to get HTTPS running on your server with the Let’s Encrypt initiative.
sudo apt-get install certbot python-certbot-apache
sudo certbot --apache
And follow the onscreen prompts to set up Apache with your new SSL certificates. Make sure you select the option to redirect all HTTP traffic to HTTPS!
Remove www.
from URLs
Edit the /etc/apache2/sites-enabled/000-default.conf
, which has already been tweaked by Certbot in the previous step. Find the lines
RewriteEngine on
RewriteCond %{SERVER_NAME} =example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
and change them to
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
RewriteCond %{SERVER_NAME} =example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
Enable CORS in Apache
While we’re editing Apache config files, we can enable CORS to ensure that server resources can be accessed from other sites. This will allow for easy loading of assets such as fonts from other domains. We use this to be able to have JSbin code demos load their fonts from our server.
We just need to edit /etc/apache2/sites-enabled/000-default-le-ssl.conf
(note that this is a different file from the previous example). Add these lines right before the </VirtualHost>
line:
Header set Access-Control-Allow-Origin "*"
Finally, run
sudo a2enmod headers
sudo systemctl restart apache
Set up fail2ban to fend off attacks
Once your server is up and the domain is live, you’ll begin to get visits from worms, bots and the occasional novice cracker, who are constantly scanning the web for new servers. Raspberry Pis are a more visible target since they’re often connected to the Internet without changing the default configuration.
Try checking your server log for failed login attempts to get a clue of what’s coming at you:
cat /var/log/auth.log | grep Failed
Thankfully, we dealt with the most common attacks by deactivating the root
and pi
users, but the knocks on your door will keep coming until you put up a way to ban repeat login failures. This is what the fail2ban
tool is really good at. It reads server logs and detects IP addresses which are trying to connect repeatedly, banning them according to the rules you set up.
Start by installing fail2ban and fetching our own config file that we built for our server. It contains sensible values and applications to monitor; be sure to take a look at that file and tweak it if needed.
sudo apt install fail2ban
wget https://tilde.pt/~rlafuente/files/jail.local
sudo mv jail.local /etc/fail2ban
Now confirm that your configuration is okay with
fail2ban-server --test
And if you get no errors, go ahead and start the server. It will run at startup after you reboot too.
sudo systemctl start fail2ban
Whitelisting IP’s
You will need to ensure that you or your students don’t get blocked out accidentally by an overzealous fail2ban. This can easily happen when many people on the same school network are trying to log in. The solution for this is whitelisting, which you can set in /etc/fail2ban/jail.local
:
ignoreip = 127.0.0.1 192.168.1.0/24 1.2.3.4
Replace 1.2.3.4
by your school’s (or home) IP address, and use spaces as a separator if you want to set more than one address. Once you’re done, run sudo systemctl restart fail2ban
to reload fail2ban’s configuration.
What now?
Your Tilde server is now in good shape – it’s time to have fun with it (if you haven’t already). Some ideas:
- edit
/var/www/html/index.html
to have a frontpage for your domain
- install
figlet
, toilet
and toilet-fonts
, and tell your users how to have fun with those
- set up a MOTD for your users, and include your own selection of welcome quotes
TODO
Our notes for sections that remain to be written.
- set up user disk quotas
- set up regular backups with Borgmatic
- set better bash defaults
Authors
This text by Ana Isabel Carvalho and Ricardo Lafuente is released under a Creative Commons-Attribution license.
Changelog
- 2019-11-05: Add authors and license note
- 2019-10-31: Add snippet to make /var/www writeable by admins; add section about changing the SSH port (thanks Andy Farnell)
- 2019-10-27: Add bit about enabling CORS in Apache
- 2019-10-19: First version published
HOWTO setup a Tilde server on a Raspberry Pi
Purpose
This HOWTO follows our own experience in setting up a server for web design students, so that they have access to their own web space and shells. Additionally, we wanted to have some particular features such as providing PHP.
This means that we are not (yet) planning to open this up to new users, and we know the people who are in. Your setup might require additional care if you want to create accounts for strangers. We hope to open our server up at some point, and update this document accordingly; in the meantime, keep in mind that this document presumes that you trust your users.
We’ll be actively updating this document from experience and feedback; see the Changelog at the bottom to see what’s changed.
Prerequisites
Besides trust in your users, this guide will assume that
pi
on your new systemBase configuration
Run
sudo raspi-config
and go through these three steps.Create your first user
It isn’t a great idea to keep the
pi
user, as most worms and novice crackers will try that as a first entry point.In this guide, we’ll work as user
luther
. Change it according to your own preference when copy-pasting the below commands.We also want our new user to have
sudo
access so that we can also disable the root account. Nevertheless, let’s ensure it always asks us for the password when running commands withsudo
– it’s not mandatory security-wise, but doesn’t hurt your chances to keep your server safe.Edit the
/etc/sudoers.d/010_pi-nopasswd
and change the line containingluther
toluther ALL=(ALL) PASSWD: ALL
Copy your SSH key for password-less login
You won’t want to type in your password everytime, and you probably already have an SSH key on your computer for this. You can copy it over to your new server with one command:
Disable access to the
root
andpi
usersFor
root
, we’ll just disable remote SSH logins, by editing the file/etc/ssh/sshd_config
and changing the optionPermitRootLogin
fromyes
tono
.If there’s no such line, type in a new one with
PermitRootLogin no
.For the
pi
user, we’ll delete that user’s password so that login is not possible anymore.# Delete user's password sudo passwd -d pi # And unset its login shell for additional peace of mind sudo usermod -s /usr/sbin/nologin pi
Change your SSH port
Most automated exploits will stick to the default SSH port (22). You can change it so that your server won’t be bothered by most scanners. Edit the
/etc/ssh/sshd_config
file to change the line#Port 22
toPort 9999
or whatever number you prefer.Do note that with this tweak, you lose the convenience of typing
ssh server_address
(you would now need to add-P <port_number>
) and also have to highlight that additional detail for your users. On our own server we stuck with port 22 for this reason, and below you’ll find additional measures to secure and protect your server.Install and configure base packages
Apache
We’ll want to enable the option to have each user’s
public_html
dir be served at/~username/
.Admins should be able to edit the main site at the root domain without needing
sudo
. This is easy:Now the contents of
/var/www/html
can be edited by any user that you add to thewww-data
group.PHP
We want our students to be able to write and run PHP scripts, and it’s rather easy to get that going.
Running PHP scripts in userdirs is disabled by default in Apache. We just have to turn it on by editing
/etc/apache2/mods-enabled/php7.3.conf
(the file might have another name if you’re running a different PHP version.)The file comments tell you exactly what needs to be done:
# Running PHP scripts in user directories is disabled by default # # To re-enable PHP in user directories comment the following lines # (from <IfModule ...> to </IfModule>.) Do NOT set it to On as it # prevents .htaccess files from disabling it. <IfModule mod_userdir.c> <Directory /home/*/public_html> php_admin_flag engine Off </Directory> </IfModule>
So go ahead and comment those lines and restart Apache with
sudo systemctl restart apache2
.Prepare for your new inhabitants
Make a template for new home dirs
Before creating your new users, you might want to consider creating a base template for their home directories. Since this is a Tilde-like server, users will require a
public_html
directory. You might also want to include a defaultindex.html
, as well as other assets such as documentation.This is easily done by adding these elements to
/etc/skel
, which is a special directory in GNU/Linux systems. When a new user is created, the contents of this directory will be copied to the user’s new home directory. We can create a basepublic_html
directory containing a defaultindex.html
file:cd /etc/skel sudo mkdir public_html echo "Hello world" | sudo tee public_html/index.html
Feel free to make a more interesting default page for your users!
Create a new user
Simple:
Create new users in bulk from a CSV file
In a teaching context, you’ll have many users to add at once. It’s boring – and thankfully unnecessary – to create all of them by hand. We can store their information in a CSV file that we can then feed the server to create all users at once.
For this to work, you’ll need to install the
csvkit
package to read from CSV.Create a CSV file named
accounts.csv
containing columns namedusername
andpassword
(it can have more fields, but these are the ones we need). After filling it with your username and password combinations, just run:csvcut accounts.csv -c username,password | tail -n +2 | sed 's/,/:/; s/$/:::::/' > users.txt sudo newusers < users.txt rm users.txt
Be sure to block other users from reading
accounts.csv
by changing its permissions:[source for the bulk addition method]
Change a user’s password if they lost it
Another simple task; you won’t need their current password to be able to change it.
Improvements and useful tweaks
Enable HTTPS with Let’s Encrypt
It’s now fast and simple to get HTTPS running on your server with the Let’s Encrypt initiative.
And follow the onscreen prompts to set up Apache with your new SSL certificates. Make sure you select the option to redirect all HTTP traffic to HTTPS!
Remove
www.
from URLsEdit the
/etc/apache2/sites-enabled/000-default.conf
, which has already been tweaked by Certbot in the previous step. Find the linesRewriteEngine on RewriteCond %{SERVER_NAME} =example.com RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
and change them to
RewriteEngine on # Remove www. RewriteCond %{HTTP_HOST} ^www\.example\.com$ RewriteRule ^(.*)$ https://example.com/$1 [R=301,L] # Redirect http to https RewriteCond %{SERVER_NAME} =example.com RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
Enable CORS in Apache
While we’re editing Apache config files, we can enable CORS to ensure that server resources can be accessed from other sites. This will allow for easy loading of assets such as fonts from other domains. We use this to be able to have JSbin code demos load their fonts from our server.
We just need to edit
/etc/apache2/sites-enabled/000-default-le-ssl.conf
(note that this is a different file from the previous example). Add these lines right before the</VirtualHost>
line:# Enable CORS Header set Access-Control-Allow-Origin "*"
Finally, run
Set up fail2ban to fend off attacks
Once your server is up and the domain is live, you’ll begin to get visits from worms, bots and the occasional novice cracker, who are constantly scanning the web for new servers. Raspberry Pis are a more visible target since they’re often connected to the Internet without changing the default configuration.
Try checking your server log for failed login attempts to get a clue of what’s coming at you:
cat /var/log/auth.log | grep Failed
Thankfully, we dealt with the most common attacks by deactivating the
root
andpi
users, but the knocks on your door will keep coming until you put up a way to ban repeat login failures. This is what thefail2ban
tool is really good at. It reads server logs and detects IP addresses which are trying to connect repeatedly, banning them according to the rules you set up.Start by installing fail2ban and fetching our own config file that we built for our server. It contains sensible values and applications to monitor; be sure to take a look at that file and tweak it if needed.
Now confirm that your configuration is okay with
fail2ban-server --test
And if you get no errors, go ahead and start the server. It will run at startup after you reboot too.
Whitelisting IP’s
You will need to ensure that you or your students don’t get blocked out accidentally by an overzealous fail2ban. This can easily happen when many people on the same school network are trying to log in. The solution for this is whitelisting, which you can set in
/etc/fail2ban/jail.local
:ignoreip = 127.0.0.1 192.168.1.0/24 1.2.3.4
Replace
1.2.3.4
by your school’s (or home) IP address, and use spaces as a separator if you want to set more than one address. Once you’re done, runsudo systemctl restart fail2ban
to reload fail2ban’s configuration.What now?
Your Tilde server is now in good shape – it’s time to have fun with it (if you haven’t already). Some ideas:
/var/www/html/index.html
to have a frontpage for your domainfiglet
,toilet
andtoilet-fonts
, and tell your users how to have fun with thoseTODO
Our notes for sections that remain to be written.
Authors
This text by Ana Isabel Carvalho and Ricardo Lafuente is released under a Creative Commons-Attribution license.
Changelog