User Tools

Site Tools


Raspberry Pi 3 Model B+ Setup

1.0 --- Sources.list update

First we are going to update the /etc/apt/sources.list with fastest mirror. We are going to install a package called netselect-apt:

sudo apt-get update
sudo apt-get install netselect-apt

Before changing the /etc/apt/sources.list file, we will make a backup:

cd /etc/apt
sudo cp sources.list sources.list.bak

Now we will run netselect-apt to find the fastest mirror to you:

cd /tmp
sudo netselect-apt -a armhf -t 20 -s -n stretch

This will output a /etc/apt/sources.list file listing the fastest 20 mirrors, once you are happy with the selected mirror, we will copy the file into /etc/apt:

sudo cp /tmp/sources.list /etc/apt/sources.list

Lets check the sources.list file. NOTE: Please add rpi option at the end of the mirror line like the following:

sudo nano /etc/apt/sources.list
# Debian packages for stretch
deb stretch main contrib non-free rpi
# Uncomment the deb-src line if you want 'apt-get source'
# to work with most packages.
deb-src stretch main contrib non-free rpi

# Security updates for stable
# deb stable/updates main contrib non-free rpi

Sometimes the keys might not get updated for the modified sources.list file, therefore we fix that by:

sudo apt-get install debian-archive-keyring
sudo apt-key update
sudo apt-get update

Now lets upgrade the raspbian distribution, packages and firmware:

sudo apt-get dist-upgrade
sudo apt-get upgrade
sudo rpi-update
sudo reboot

1.1 --- Locale, Date/Time, Timezone, Hostname

You can check the locale by:


If you would like to change locale, then:

sudo dpkg-reconfigure locales

Once any new locales have been generated, you can edit /etc/default/locale to change default locale:

sudo nano /etc/default/locale
#  File generated by update-locale

Now lets reconfigure the timezone:

sudo dpkg-reconfigure tzdata

Keep the time synced from the internet through NTP:

sudo apt-get install ntp

To check the date and time:


The hostname of your raspberry pi should be a subdomain like “”. The line should be: “IP Address - space - full hostname incl. domain - space - subdomain part”. The file shall look like this:

sudo nano /etc/hosts       localhost
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters       raspberrypi rpi rpi

Then edit the /etc/hostname file:

sudo nano /etc/hostname

It shall contain only the subdomain part:


Finally, reboot the raspberry pi to apply the change:

sudo reboot

Log in again and check if the hostname is correct now with these commands:

hostname -f

Change the default shell. /bin/sh is a symlink to /bin/dash, however we need /bin/bash, not /bin/dash. Therefore we do this:

sudo dpkg-reconfigure dash
  • Use dash as the default system shell (/bin/sh)? ←– no

If you don't do this, the ISPConfig installation later on will fail.

2.0 --- Postfix, Dovecot, MariaDB, etc...

sudo apt-get install postfix postfix-mysql postfix-doc mariadb-client mariadb-server openssl getmail4 rkhunter binutils dovecot-imapd dovecot-pop3d dovecot-mysql dovecot-sieve dovecot-lmtpd sudo

You will be asked the following questions:

  • General type of mail configuration: ←– Internet Site
  • System mail name: ←–

To secure the MariaDB / MySQL installation and to disable the test database, run this command:

sudo mysql_secure_installation

Answer the questions as follows:

  • Change the root password? [Y/n] ←– y
  • New password: ←– Enter a new MariaDB root password
  • Re-enter new password: ←– Repeat the MariaDB root password
  • Remove anonymous users? [Y/n] ←– y
  • Disallow root login remotely? [Y/n] ←– y
  • Remove test database and access to it? [Y/n] ←– y
  • Reload privilege tables now? [Y/n] ←– y

Next, open the TLS/SSL and submission ports in Postfix:

sudo nano /etc/postfix/

Uncomment the submission and smtps sections as follows and add lines where necessary so that this section of the file looks exactly like the one below:

submission inet n - - - - smtpd
 -o syslog_name=postfix/submission
 -o smtpd_tls_security_level=encrypt
 -o smtpd_sasl_auth_enable=yes
 -o smtpd_client_restrictions=permit_sasl_authenticated,reject
# -o smtpd_reject_unlisted_recipient=no
# -o smtpd_client_restrictions=$mua_client_restrictions
# -o smtpd_helo_restrictions=$mua_helo_restrictions
# -o smtpd_sender_restrictions=$mua_sender_restrictions
# -o smtpd_recipient_restrictions=
# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
smtps inet n - - - - smtpd
 -o syslog_name=postfix/smtps
 -o smtpd_tls_wrappermode=yes
 -o smtpd_sasl_auth_enable=yes
 -o smtpd_client_restrictions=permit_sasl_authenticated,reject
# -o smtpd_reject_unlisted_recipient=no
# -o smtpd_client_restrictions=$mua_client_restrictions
# -o smtpd_helo_restrictions=$mua_helo_restrictions
# -o smtpd_sender_restrictions=$mua_sender_restrictions
# -o smtpd_recipient_restrictions=
# -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING

Restart Postfix afterwards:

sudo systemctl restart postfix
sudo systemctl enable postfix

We want MariaDB to listen on all interfaces, not just localhost. Therefore, we edit /etc/mysql/mariadb.conf.d/50-server.cnf and comment out the line bind-address = and add the line sql-mode=“NO_ENGINE_SUBSTITUTION”:

sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
#bind-address           =


Edit the file /etc/mysql/debian.cnf and set the MariaDB root password there twice in the rows that start with password:

sudo nano /etc/mysql/debian.cnf
# Automatically generated for Debian scripts. DO NOT TOUCH!
host = localhost
user = root
password = password
socket = /var/run/mysqld/mysqld.sock
host = localhost
user = root
password = password
socket = /var/run/mysqld/mysqld.sock
basedir = /usr

To prevent the error 'Error in accept: Too many open files' we will set higher open file limits for MariaDB now:

sudo nano /etc/security/limits.conf

and add these lines at the end of the file:

mysql soft nofile 65535
mysql hard nofile 65535
sudo mkdir -p /etc/systemd/system/mysql.service.d
sudo nano /etc/systemd/system/mysql.service.d/limits.conf

Paste the following lines into that file:


Then we reload systemd and restart MariaDB:

sudo systemctl daemon-reload
sudo systemctl restart mysql
sudo systemctl enable mysql

Now check that networking is enabled. Run:

sudo netstat -tap | grep mysql

The output should look like this:

tcp6       0      0 [::]:mysql              [::]:*                  LISTEN      5890/mysqld

2.1 --- Amavisd-new, SpamAssassin, ClamAV, UFW

To install amavisd-new, SpamAssassin and UFW, we run:

sudo apt-get install amavisd-new spamassassin zoo unzip bzip2 arj nomarch lzop cabextract apt-listchanges libnet-ldap-perl libauthen-sasl-perl clamav-docs daemon libio-string-perl libio-socket-ssl-perl libnet-ident-perl zip libnet-dns-perl libdbd-mysql-perl postgrey ufw

Lets setup UFW first. We will add rules to allow incoming and outgoing traffic for SSH (port 22), HTTP (port 80) and HTTPS (port 443):

sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https

You can also do: sudo ufw allow 22 or sudo ufw allow 22/tcp Now we start UFW (Make sure you allow the port you are connected from else will get disconnected and may not be able to log back in):

sudo ufw enable
sudo ufw logging on
sudo ufw status

Your UFW status should look something like this:

Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443/tcp                    ALLOW       Anywhere
22/tcp (v6)                ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
443/tcp (v6)               ALLOW       Anywhere (v6)

The ISPConfig 3 setup uses amavisd which loads the SpamAssassin filter library internally, so we can stop SpamAssassin to free up some RAM:

sudo service spamassassin stop
sudo systemctl disable spamassassin

3.0 --- Apache2 with PHP7.2

Raspbian being based on Debian Stretch ships with PHP 7.0 by default. This works fine, but there is a new and better supported PHP 7.2 release available. To install this newer PHP version however, we must tap into the testing branch of Raspbian, commonly known by the codename buster. We must credit a new buster.list file used by Aptitude (apt-get):

sudo nano /etc/apt/sources.list.d/10-buster.list

Add this line:

deb buster main contrib non-free rpi

Now, by adding this and referencing -t buster in our apt-get commands, it wil use the newer versions of files available in the buster release which is not considered 100% stable. To facilitate this we need to create a buster preferences file:

sudo nano /etc/apt/preferences.d/10-buster

And paste in the follwing:

Package: *
Pin: release n=stretch
Pin-Priority: 900

Package: *
Pin: release n=buster
Pin-Priority: 750

Save this file and update:

sudo apt-get update

Now you are ready to install Apache2 and PHP 7.2 from the buster release including all the common PHP packages:

sudo apt-get install -t buster apache2 apache2-doc apache2-utils libapache2-mod-php7.2 php7.2 php7.2-common php7.2-curl php7.2-gd php7.2-fpm php7.2-cli php7.2-opcache php7.2-mbstring php7.2-xml php7.2-zip php7.2-mysql php7.2-imap php7.2-cgi php7.2-pspell php7.2-recode php7.2-sqlite3 php7.2-tidy php7.2-xmlrpc php7.2-xsl php-memcache memcached php-imagick php7.2-soap php7.2-json php7.2-readline php-pear mcrypt php7.2-intl php7.2-tidy libapache2-mod-fcgid apache2-suexec-pristine php7.2-bz2

You can check Apache2 and PHP-7.2 version by:

apache2 -v
php -v

3.1 --- Tweak PHP7.2 and Apache2

Once fully installed (accept any defaults when prompted), we should now tweak our PHP 7.2 FPM pool to be better optimized:

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

And add:


Then simply restart php-fpm to ensure the new changes are picked up:

sudo systemctl restart php7.2-fpm

We will now disable mod_php for Apache and enable to use php-fpm. We will also switch from mod_prefork to mod_event. Do all this by:

sudo a2dismod php7.2 mpm_prefork
sudo a2enmod mpm_event proxy proxy_fcgi setenvif
sudo a2enconf php7.2-fpm
sudo a2enmod suexec rewrite ssl actions alias include cgid headers http2

To ensure that the server can not be attacked trough the HTTPOXY vulnerability, we will disable the HTTP_PROXY header in apache globally by adding the configuration file /etc/apache2/conf-available/httpoxy.conf:

sudo nano /etc/apache2/conf-available/httpoxy.conf

Paste the following content to the file:

<IfModule mod_headers.c>
    RequestHeader unset Proxy early

And enable the module by running:

sudo a2enconf httpoxy

Finally restart Apache2 to apply all the changes:

sudo systemctl restart apache2

3.2 --- Install LetsEncrypt SSL/TLS

ISPConfig 3.1 has support for the free SSL Certificate authority Let's encrypt. The Let's Encrypt function allows you to create free SSL certificates for your website from within ISPConfig:

sudo apt-get install -t buster certbot python-certbot-apache

After that run the commands below to obtain your free Let’s Encrypt SSL/TLS certificate for your site:

sudo certbot --apache -m -d

You should test your configuration at:

Let's Encrypt's certificates are only valid for ninety days. This is to encourage users to automate their certificate renewal process. The certbot package we installed takes care of this for us by adding a renew script to /etc/cron.d. This script runs twice a day and will automatically renew any certificate that's within thirty days of expiration. To test the renewal process, you can do a dry run with certbot:

sudo certbot renew --dry-run

4.0 --- Mailman, PureFTPd, Quota

ISPConfig allows you to manage (create/modify/delete) Mailman mailing lists. If you want to make use of this feature, install Mailman as follows:

sudo apt-get install mailman

Before we can start Mailman, a first mailing list called mailman must be created:

sudo newlist mailman

Enter the email of the person running the list: ←– admin email address, e.g. Initial mailman password: ←– admin password for the mailman list Open /etc/aliases afterwards:

sudo nano /etc/aliases

… and add the following lines:

## mailman mailing list
mailman:              "|/var/lib/mailman/mail/mailman post mailman"
mailman-admin:        "|/var/lib/mailman/mail/mailman admin mailman"
mailman-bounces:      "|/var/lib/mailman/mail/mailman bounces mailman"
mailman-confirm:      "|/var/lib/mailman/mail/mailman confirm mailman"
mailman-join:         "|/var/lib/mailman/mail/mailman join mailman"
mailman-leave:        "|/var/lib/mailman/mail/mailman leave mailman"
mailman-owner:        "|/var/lib/mailman/mail/mailman owner mailman"
mailman-request:      "|/var/lib/mailman/mail/mailman request mailman"
mailman-subscribe:    "|/var/lib/mailman/mail/mailman subscribe mailman"
mailman-unsubscribe:  "|/var/lib/mailman/mail/mailman unsubscribe mailman"


sudo newaliases

and restart Postfix:

sudo systemctl restart postfix

Finally, we must enable the Mailman Apache configuration:

sudo ln -s /etc/mailman/apache.conf /etc/apache2/conf-available/mailman.conf
sudo a2enconf mailman.conf
sudo systemctl restart apache2

Then start the Mailman daemon:

sudo systemctl start mailman
sudo systemctl enable mailman

PureFTPd and quota can be installed with the following command:

sudo apt-get install pure-ftpd-common pure-ftpd-mysql quota quotatool

Create the dhparam file for pure-ftpd:

sudo openssl dhparam -out /etc/ssl/private/pure-ftpd-dhparams.pem 2048

Edit the file /etc/default/pure-ftpd-common:

nano /etc/default/pure-ftpd-common

and make sure that the start mode is set to standalone and set VIRTUALCHROOT=true:


Now we configure PureFTPd to allow FTP and TLS sessions. FTP is a very insecure protocol because all passwords and all data are transferred in clear text. By using TLS, the whole communication can be encrypted, thus making FTP much more secure. If you want to allow FTP and TLS sessions, run:

sudo echo 1 > /etc/pure-ftpd/conf/TLS

In order to use TLS, we must create an SSL certificate. I create it in /etc/ssl/private/, therefore I create that directory first:

sudo mkdir -p /etc/ssl/private/

Afterwards, we can generate the SSL certificate as follows:

sudo openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem

Change the permissions of the SSL certificate:

sudo chmod 600 /etc/ssl/private/pure-ftpd.pem

Then restart PureFTPd:

sudo systemctl restart pure-ftpd-mysql

Edit /etc/fstab to include ,usrjquota=quota.user,,jqfmt=vfsv0 to the partition with the mount point /:

sudo nano /etc/fstab
# /etc/fstab: static file system information.
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/sda1 during installation
UUID=f539c5cb-624f-4c27-a149-1446a251a453 / ext4 errors=remount-ro,usrjquota=quota.user,,jqfmt=vfsv0 0 1
# swap was on /dev/sda5 during installation
UUID=8d3194e7-edb5-4492-937d-d066b4994baf none swap sw 0 0
/dev/sr0 /media/cdrom0 udf,iso9660 user,noauto 0 0

To enable quota, run these commands:

sudo mount -o remount /

To check:

quotacheck -avugm
quotaon -avug

4.1 --- BIND DNS, Jailkit, fail2ban

BIND can be installed as follows:

sudo apt-get install bind9 dnsutils haveged
sudo systemctl start haveged
sudo systemctl enable haveged

Jailkit is needed only if you want to chroot SSH users. It can be installed as follows:

sudo apt-get install build-essential autoconf automake libtool flex bison debhelper binutils
cd /tmp
tar xvfz jailkit-2.20.tar.gz
cd jailkit-2.20
echo 5 > debian/compat
sudo ./debian/rules binary

You can now install the Jailkit .deb package as follows:

cd ..
sudo dpkg -i jailkit_2.20-1_*.deb
sudo rm -rf jailkit*

Now we can install fail2ban:

sudo apt-get install fail2ban

To make fail2ban monitor PureFTPd and Dovecot, create the file /etc/fail2ban/jail.local:

sudo nano /etc/fail2ban/jail.local

And add the following configuration to it:

enabled = true
port = ftp
filter = pure-ftpd
logpath = /var/log/syslog
maxretry = 3

enabled = true
filter = dovecot
logpath = /var/log/mail.log
maxretry = 5

enabled = true
port = smtp
filter = postfix-sasl
logpath = /var/log/mail.log
maxretry = 3

Restart fail2ban afterwards:

sudo systemctl restart fail2ban
sudo systemctl enable fail2ban

4.2 --- RoundCube

Install RoundCube with this command:

sudo apt-get install roundcube roundcube-core roundcube-mysql roundcube-plugins

The installer will ask the following questions: Configure database for roundcube with dbconfig.common? ←– yes MySQL application password for roundcube: ←– press enter Password of the databases administrative user: ←– enter the MySQL root password here Then edit the RoundCube /etc/roundcube/ file and adjust a few settings:

sudo nano /etc/roundcube/

Then edit the Apache roundcube configuration file /etc/apache2/conf-enabled/roundcube.conf:

sudo nano /etc/apache2/conf-enabled/roundcube.conf

And add an alias line for the apache /webmail alias, you can add the line right at the beginning of the file. NOTE: Do not use /mail as alias or the ispconfig email module will stop working!

Alias /webmail /var/lib/roundcube

Then reload Apache:

sudo systemctl restart apache2

5.0 --- Install ISPConfig

To install ISPConfig 3 from the latest released version, do this:

cd /tmp
tar xfz ISPConfig*.tar.gz
cd ispconfig3_install/install/
sudo php -q install.php

x.x --- References

raspberry_pi_3_setup.txt · Last modified: 2019/02/08 18:44 by pi