Raspberry Pi Email Server Part 3: Squirrelmail

Squirrelmail Logo

This is the third part of a five part tutorial that will show you how to install a full featured email server on your Raspberry Pi. This tutorial covers how to set up Webmail with Squirrelmail.

The parts are:
The Introduction & Contents Page (read first)
Raspberry Pi Email Server Part 1: Postfix
Raspberry Pi Email Server Part 2: Dovecot
Raspberry Pi Email Server Part 3: Squirrelmail
Raspberry Pi Email Server Part 4: Spam Detection with Spamassassin
Raspberry Pi Email Server Part 5: Spam Sorting with LMTP & Sieve

Installing Apache

If you don't already have apache installed (you might if you've followed my wordpress tutorial), then install it now.

sudo apt-get update
sudo apt-get install apache2

Enable the SSL apache module so that you can use HTTPS:

sudo a2enmod ssl

There are some "pre-made" virtualhost configurations that come with apache. This command will enable the "default-ssl" virtualhost, by creating a symbolic link from /etc/apache2/sites-available/default-ssl to /etc/apache2/sites-enabled/default-ssl:

sudo a2ensite default-ssl

Now reload apache to make the changes take effect:

sudo service apache2 reload

If you type the IP address or hostname of the pi into a web browser now, you should see the default Apache test page:

apache2-test-page.png

If you try the https version, you'll get a certificate error because you are using a self-signed SSL certificate. If you like, you can follow my CAcert tutorial to get a free SSL certificate for your domain, or you can just store an exception for the certificate and generate a proper one later.

apache2-test-page-https.png

That's it for Apache. If you want to know more about setting up Apache for multiple websites, subdomains, and SSL configurations, I suggest you read my tutorial explaining Apache's VirtualHost files.

Installing Squirrelmail

Now we need to install squirrelmail:

sudo apt-get update
sudo apt-get install squirrelmail

The basic configuration for squirrelmail is really easy, and can be done with the setup script. To run the script, use this command:

sudo squirrelmail-configure

Squirrelmail configuration menu

Choose “D” for pre-defined settings

Choose pre-defined server configuration

Now type “dovecot” and hit enter

Accept pre-defined configuration for use with Dovecot

Press enter to continue, then save and quit (press Q and save when prompted, or press S then Q).

The configuration script creates a configuration file for apache in /etc/squirrelmail/apache.conf. You need to create a symbolic link so that Apache2 will load your Squirrelmail apache configuration file when it starts up.

On Raspbian Wheezy, the command is:

sudo ln -s /etc/squirrelmail/apache.conf /etc/apache2/conf.d/squirrelmail.conf

On Raspbian Jessie, the apache configuration directory structure is more like ubuntu, with separate folders for configuration files that are available and files that are enabled. This command will create a symlink from the directory where enabled configuration is stored, to squirrelmail's apache configuration file:

sudo ln -s /etc/squirrelmail/apache.conf /etc/apache2/conf-enabled/squirrelmail.conf

On a related note, there's a convenience command a2enconf that works similarly to a2ensite: it creates a symlink from the conf-available directory to the conf-enabled directory. You should use this in situations where config already exists in conf-available, e.g. sudo a2enconf squirrelmail would create a symlink for a file called squirrelmail.conf.

Now reload Apache one more time so that it reads the config file we just symlinked:

sudo service apache2 reload

Now visit the IP address or hostname of your Pi again, but add /squirrelmail to the path, e.g. 192.168.1.174/squirrelmail, you should see the login page:

squirrelmail-login_0.png

The squirrelmail configuration file just adds an alias that should affect every virtualhost, so if you install a wordpress site or something like that on your pi, you will be able to get to the squirrelmail login page by visiting yourdomain.com/squirrelmail.

Redirect http to https for secure login

Since you don't want to send your login details and confidential information over the internet without SSL, it's best to redirect all http URLs to https.

The default squirrelmail apache configuration file at /etc/squirrelmail/apache.conf contains some rewrite rules we can use, we just need to uncomment them. Open the file and uncomment the lines by removing the # at the start of each so that it looks like this:

<IfModule mod_rewrite.c>
  <IfModule mod_ssl.c>
    <Location /squirrelmail>
      RewriteEngine on
      RewriteCond %{HTTPS} !^on$ [NC]
      RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI}  [L]
    </Location>
  </IfModule>
</IfModule>

This configuration makes sure that the rewrite and ssl modules are enabled, and does nothing if they aren't. We already enabled the ssl module earlier, so all we need to do now is enable the rewrite module:

sudo a2enmod rewrite

And reload Apache:

sudo service apache2 reload

Now if you visit the HTTP page, you should be redirected to HTTPS.

Optional: Configuring Apache to serve Squirrelmail on a subdomain

If you would like to move the login page to the root of your domain (i.e. so that yourdomain.com would serve the login page for squirrelmail), or if you would like to serve it on a subdomain like mail.yourdomain.com, you can edit the configuration file. If not, you can skip this section.

By default, this line in /etc/squirrelmail/apache.conf means that http://www.yourdomain.com/squirrelmail will load squirrelmail:

Alias /squirrelmail /usr/share/squirrelmail

If you would rather have webmail on a subdomain like mail.yourdomain.com then you could edit the /etc/squirrelmail/apache.conf file to look like this (comment out the rest):

<VirtualHost *:80>
  DocumentRoot /usr/share/squirrelmail
  ServerName mail.yourdomain.com


<Directory /usr/share/squirrelmail>
  Options FollowSymLinks
  <IfModule mod_php5.c>
    php_flag register_globals off
  </IfModule>
  <IfModule mod_dir.c>
    DirectoryIndex index.php
  </IfModule>

  # access to configtest is limited by default to prevent information leak
  <Files configtest.php>
    order deny,allow
    deny from all
    allow from 127.0.0.1
  </Files>
</Directory>
</VirtualHost>

Note that if you want to serve mail on a subdomain, then that subdomain needs a DNS record, so edit your records with your DNS provider accordingly.

However, the virtualhost code above only does HTTP. You also want an HTTPS virtualhost for the subdomain on port 443:

<IfModule mod_ssl.c>
<VirtualHost *:443>
  DocumentRoot /usr/share/squirrelmail
  ServerName mail.yourdomain.com

<Directory /usr/share/squirrelmail>
  Options FollowSymLinks
  <IfModule mod_php5.c>
    php_flag register_globals off
  </IfModule>
  <IfModule mod_dir.c>
    DirectoryIndex index.php
  </IfModule>

  # access to configtest is limited by default to prevent information leak
  <Files configtest.php>
    order deny,allow
    deny from all
    allow from 127.0.0.1
  </Files>
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined

SSLEngine on
SSLCertificateFile    /etc/ssl/certs/your-ssl-certificate.crt
SSLCertificateKeyFile /etc/ssl/private/your-ssl-certificate-keyfile.key


</VirtualHost>
</IfModule>

If you use this configuration, the rewrite rules from the "rewrite to HTTPS" section (the ones from the default config file) won't work. If you want an HTTPS-only solution, you can replace the virtualhost for port 80 with this:

<VirtualHost *:80>
ServerName mail.yourdomain.com
<IfModule mod_rewrite.c>
  <IfModule mod_ssl.c>
    <Location />
      RewriteEngine on
      RewriteCond %{HTTPS} !^on$ [NC]
      RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI}  [L]
    </Location>
  </IfModule>
</IfModule>
</VirtualHost>

As before, make sure you have the rewrite module enabled:

sudo a2enmod rewrite

Now reload apache:

sudo service apache2 restart

If you get an error like this:

[....] Restarting web server: apache2[Fri Dec 06 15:54:04 2013] [warn] _default_ VirtualHost overlap on port 443, the first has precedence

Then add NameVirtualHost *:443 to the start of the SSL VirtualHost block, i.e.:

NameVirtualHost *:443
<IfModule mod_ssl.c>
<VirtualHost *:443>
  DocumentRoot /usr/share/squirrelmail
  ServerName mail.yourdomain.com
...

For more info on HTTP and HTTPS VirtualHost configuration on Apache2, see this tutorial of mine.

If all went to plan then you can navigate to mail.yourdomain.com and you should see the squirrelmail login page (you might need to forward some ports on your router if you haven't already - see the next section):

Squirrelmail login page

Port Forwarding

Squirrelmail will log in to your IMAP server on port 143 to display your emails. It doesn’t need to authenticate because it’s in your network (remember the permit_mynetworks parameter from the previous tutorials?). You don’t need to worry about it being an unencrypted connection, because the data isn't actually travelling over any insecure networks (the connection is internal). Similarly, you don’t need to open port 143 (“plain” imap without SSL/TLS) on your router because the connection happens within the Pi, and the content is actually served to you, the user, on port 443 (https).

So you do need to open ports 80 and 443 for http and https like below:

Port forwarding rules

Testing

Before you start testing your webmail, make sure that the permit_mynetworks parameters are uncommented in your postfix confuguration file /etc/postfix/main.cf (in both your smtpd_recipient_restrictions and smtpd_helo_restrictions).

Now reload your postfix configuration:

sudo service postfix reload

Try sending and receiving emails from within Squirrelmail. You should have no problems, but if you do please post a comment and I’ll try to help you out.

Customising the Squirrelmail Login

To customise the login page, run the configuration wizard:

sudo squirrelmail-configure
  1. Select “1″ (organisation preferences)
  2. Select “7″ and change to your domain (e.g. http://www.samhobbs.co.uk)
  3. Select “8″ and change to you/your organisation’s name

Squirrelmail Plugins

There are loads of plugins available for Squirrelmail, for all kinds of things. On most systems, these plugins are installed by downloading a .zip file to your server, unzipping the plugin to the right location and then tinkering with the settings manually.

Thankfully, some of the most commonly used plugins are available from the Raspbian repositories, so installation is much simpler. Here is a list of the plugins in the repo:

  1. squirrelmail-compatibility
  2. squirrelmail-decode
  3. squirrelmail-locales
  4. squirrelmail-lockout
  5. squirrelmail-logger
  6. squirrelmail-quicksave
  7. squirrelmail-secure-login
  8. squirrelmail-sent-confirmation
  9. squirrelmail-spam-buttons
  10. squirrelmail-viewashtml

The one I think is most useful and the one I’m going to use as an example is lockout.

To use the lockout package, we need to install the compatibility package, which basically makes sure that plugins built for different versions of squirrelmail can still work with the version you are running.

sudo apt-get update
sudo apt-get install squirrelmail-compatibility

Now we need to enable the plugin:

sudo squirrelmail-configure
  1. select “8″
  2. select “compatibility”
  3. select “S” (to save)
  4. select “Q” (to quit)

That’s all you need to do for the compatibility plugin. Now we can install the lockout plugin:

sudo apt-get install squirrelmail-lockout

Now for the configuration:

sudo squirrelmail-configure

Make sure that lockout is enabled

Now we can manually edit some settings. Before starting, I like to back up the default config files for reference:

cd /etc/squirrelmail
sudo cp lockout-table.php lockout-table.php.BAK
sudo cp lockout-config.php lockout-config.php.BAK

Now edit the lockout-table.php file. Read the comments in the file for an explanation of how the table works. I wanted to disable logins for the user “admin”, so I commented out the examples at the end of the file and replaced them with this:

user:		admin		locked_out.php

Now edit lockout-config.php and set $use_lockout_rules = 1; to turn on lockouts.

Now try and log in as the user you locked out, and you should get this message: “Access Denied / Please contact your system administrator”.

We can also lock out IP addresses of users who enter incorrect username/password combinations repeatedly. To do this, open lockout-config.php and set $max_login_attempts_per_IP = '3:5:0'.

The first number in this parameter is the number of incorrect attempts that are allowed before a ban. The second number is the time frame for these incorrect attempts, and the last number is the amount of time the ban lasts for when activated (0 is forever).

So, the setting I gave you above means that anyone who makes 3 incorrect attempts to authenticate in 5 minutes is permanently banned.

When a successful login is made, the count is reset to 0.

Data on current bad login attempts and bans is stored here: /var/lib/squirrelmail/data/lockout_plugin_login_failure_information

The plugin will add entries like this to keep track of bad logins:

999.999.99.99_login_failure_times=1386774015:1386774034:1386774053
999.999.99.99_TOO_MANY_FAILED_LOGIN_ATTEMPTS=PERMANENT

…where 999.999.99.99 is the offending IP address

If you accidentally ban yourself, you’ll have to log in via SSH and edit this file to remove those lines.

That’s it, you’re done! Have fun exploring the other plugins!

The next two tutorials, Part 4 and Part 5 deal with spam detection and filtering.

Type: 

Comments

Well...

Worth mentioning it to the squirrelmail maintainer?

In my opinion, it shouldn't be in the repos at all if it really does depend on php5 and php5 isn't also in the repos.

For now, the "solution" is to use something else like roundcube or rainloop. I originally (2013!) chose squirrelmail because it's lightweight, but if you're using a pi 3 then that shouldn't be such a problem any more.

Sam

Hey Sam, thanks for the quick reply, and the exceptional tutorial. This happens to be one of the most well-written tutorials I have ever worked my way through. As one who is exceedingly Linux-ignorant, it never occurred to me to look at anything beyond what you're walking us through here. I'm pretty much following the script and absorbing as much as I can while doing so. That said, I'll look at one or both of the programs you suggest. Surely there will be some tutorials for installing them as well.

- damon

No problem, and thanks for the feedback. Worth noting that you can completely ignore this part of the tutorial if you don't need webmail, and everything else will work with a normal email client on your phone etc.

Of course webmail is nice to have, but you can come back to it later without breaking anything!

Sam

Great tutorial - thank you :)

I'm running Raspbian Strech and I suspect apache is now looking for PHP 7 rather than 5. If I follow the instructions as stated I receive an error as follows:

pi@WebProd:/usr/share/dovecot $ sudo apt-get install squirrelmail
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
squirrelmail : Depends: libapache2-mod-php5 but it is not installable or
php5 but it is not installable or
php5-cgi but it is not installable
Recommends: squirrelmail-locales but it is not going to be installed
Recommends: squirrelmail-viewashtml but it is not going to be installed
Recommends: php5-mhash but it is not installable
E: Unable to correct problems, you have held broken packages.

I've done some playing and can't find an obvious way around this. Are you able to offer any suggestions or pointers?

Thanks

Phil

Hi Phil,

Yeah squirrelmail shouldn't be in the repos any more in my opinion, since they have removed php5. You have to use something else like roundcube (see the other comments). No guide for that but the rest of the tutorial works fine without webmail, and you can add in any other webmail app in place of roundcube.

Sam

Thanks - it wasn't until after I posted my comment that I saw there were 10 pages of comments and I had only read page 1 and that my query had already been covered. I found additional detail at https://www.hackster.io/gulyasal/make-a-mail-server-out-of-your-rpi3-5829f0 that builds on your and implements rainloop which also works very nicely.

Thanks again for your very clear and detailed instructions - they're a fantastic learning tool.

Cheers

Phil

No worries, I wasn't expecting you to read every comment!

Thanks for the link, hopefully it will be useful for others.

Sam

About "Raspberry Pi Email Server Part 3: Squirrelmail"

1) PHP5 is not available anymore, I manually installed the PHP7 counterparts (php, php-cgi, apache module) to make it work again

2) About the section "...if you would like to move the login page to the root of your domain..."
Yes I do, I like to move the login page to the root, but all the following parts are related to subdomain (which I do no want to use). Which configuration is needed to only move login page to root?

Thanks for the guide, I followed it very easily.
Regards

Nicola,

Glad you got squirrelmail working with php7, there are some other comments (and replies) from other people who had the same issue - in my opinion, squirrelmail shouldn't be in the repos with a php5 dependency if php5 isn't in the repo too.

You could use this config to serve everything on your root domain and rewrite HTTP to HTTPS (important bits highlighted):

# rewrite HTTP requests to HTTPS
<VirtualHost *:80>
ServerName yourdomain.com
<IfModule mod_rewrite.c>
  <IfModule mod_ssl.c>
    <Location />
      RewriteEngine on
      RewriteCond %{HTTPS} !^on$ [NC]
      RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI}  [L]
    </Location>
  </IfModule>
</IfModule>
</VirtualHost>

# HTTPS virtualhost
<IfModule mod_ssl.c>
<VirtualHost *:443>
  DocumentRoot /usr/share/squirrelmail
  ServerName yourdomain.com

<Directory /usr/share/squirrelmail>
  Options FollowSymLinks
  <IfModule mod_php5.c>
    php_flag register_globals off
  </IfModule>
  <IfModule mod_dir.c>
    DirectoryIndex index.php
  </IfModule>

  # access to configtest is limited by default to prevent information leak
  <Files configtest.php>
    order deny,allow
    deny from all
    allow from 127.0.0.1
  </Files>
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/ssl_access.log combined

SSLEngine on
SSLCertificateFile    /etc/ssl/certs/your-ssl-certificate.crt
SSLCertificateKeyFile /etc/ssl/private/your-ssl-certificate-keyfile.key


</VirtualHost>
</IfModule>

Understand that nothing is actually moved by doing this - the squirrelmail files stay in the same place, but setting the DocumentRoot for the virtualhost to a different folder means that apache treats that folder as the root of your domain. If there is an index.html or index.php file in that folder, it will be served as the default content when someone requests yourdomain.com.

Sam

Hi,
I do not have a domain, I simply call the apache server using the IP. I only want to "move" squirellmail pages from /squirrellmail to root of apache.

Thank you for the tip, at the end I installed RoundCube too, so I left the 2 separate paths for SquirrelMail and RoundCube, the root page is a simple HTML which displays both logos and let the user select.
I'm now having troubles installing RoundCube but is not related to your guide.

Hello,
about section "Raspberry Pi Email Server Part 3: Squirrelmail".

I enabled HTTPS as suggested, but now Google Chrome is giving me a certificate error: NET::ERR_CERT_COMMON_NAME_INVALID
Am I missing a configuration?

Yes, if you don't have a domain and you don't have a valid HTTPS certificate, then the name on your default cert won't match the IP address you are using to access the server, and the default cert won't be trusted by your OS/browser anyway.

If you try the https version, you'll get a certificate error because you are using a self-signed SSL certificate. If you like, you can follow my CAcert tutorial to get a free SSL certificate for your domain, or you can just store an exception for the certificate and generate a proper one later.

Sam

Hi sam been working through your pi mailserver tutoral however i get up to edditing the dovecot master file and keep getting this error

pi@raspberrypi:/var/log $ sudo service dovecot start
Job for dovecot.service failed because the control process exited with error code.
See "systemctl status dovecot.service" and "journalctl -xe" for details.

#default_process_limit = 100
#default_client_limit = 1000

# Default VSZ (virtual memory size) limit for service processes. This is mainly
# intended to catch and kill processes that leak memory before they eat up
# everything.
#default_vsz_limit = 256M

# Login user is internally used by login processes. This is the most untrusted
# user in Dovecot system. It shouldn't have access to anything at all.
#default_login_user = dovenull

# Internal user is used by unprivileged processes. It should be separate from
# login user, so that login processes can't disturb other processes.
#default_internal_user = dovecot

service imap-login {
inet_listener imap {
#port = 143
}
inet_listener imaps {
#port = 993
#ssl = yes
}

# Number of connections to handle before starting a new process. Typically
# the only useful values are 0 (unlimited) or 1. 1 is more secure, but 0
# is faster. <doc/wiki/LoginProcess.txt>
#service_count = 1

# Number of processes to always keep waiting for more connections.
#process_min_avail = 0

# If you set service_count=0, you probably need to grow this.
#vsz_limit = $default_vsz_limit
}

service pop3-login {
inet_listener pop3 {
#port = 110
}
inet_listener pop3s {
#port = 995
#ssl = yes
}
}

service lmtp {
unix_listener lmtp {
#mode = 0666
}

# Create inet listener only if you can't use the above UNIX socket
#inet_listener lmtp {
# Avoid making LMTP visible for the entire internet
#address =
#port =
#}
}

service imap {
# Most of the memory goes to mmap()ing files. You may need to increase this
# limit if you have huge mailboxes.
#vsz_limit = $default_vsz_limit

# Max. number of IMAP processes (connections)
#process_limit = 1024
}

service pop3 {
# Max. number of POP3 processes (connections)
#process_limit = 1024
}

#service auth {
# auth_socket_path points to this userdb socket by default. It's typically
# used by dovecot-lda, doveadm, possibly imap process, etc. Users that have
# full permissions to this socket are able to get a list of all usernames and
# get the results of everyone's userdb lookups.
#
# The default 0666 mode allows anyone to connect to the socket, but the
# userdb lookups will succeed only if the userdb returns an "uid" field that
# matches the caller process's UID. Also if caller's uid or gid matches the
# socket's uid or gid the lookup succeeds. Anything else causes a failure.
#
# To give the caller full permissions to lookup all users, set the mode to
# something else than 0666 and Dovecot lets the kernel enforce the
# permissions (e.g. 0777 allows everyone full permissions).
#unix_listener auth-userdb {
# #mode = 0666
# #user =
# #group =
# }

# Postfix smtp-auth
#unix_listener /var/spool/postfix/private/auth {
# mode = 0666
#}

# Auth process is run as this user.
#user = $default_internal_user
#}

#service auth-worker {
# Auth worker process is run as root by default, so that it can access
# /etc/shadow. If this isn't necessary, the user should be changed to
# $default_internal_user.
#user = root
#}

#service dict {
# If dict proxy is used, mail processes should have access to its socket.
# For example: mode=0660, group=vmail and global mail_access_groups=vmail
# unix_listener dict {
#mode = 0600
#user =
#group =
# }
#}

service auth {
unix_listner /var/spool/postfix/private/auth {

user = postfix
group = postfix
}
}

please can see what iv done many thanks dean

Dean,

What's in the /var/log/mail.err log file for the time period immediately after you restarted dovecot?

Sam

wen i try to install squirrelmail i get this response

The following packages have unmet dependencies:
squirrelmail : Depends: libapache2-mod-php5 but it is not installable or
php5 but it is not installable or
php5-cgi but it is not installable
Recommends: squirrelmail-locales but it is not going to be installed
Recommends: squirrelmail-viewashtml but it is not going to be installed
Recommends: php5-mhash but it is not installable
Recommends: ispell but it is not going to be installed or
aspell but it is not going to be installed or
aspell-bin

I guess php5 is not installed???

Pages

Add new comment