Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vanpariyar/1ca5278e3cedbf6316c27028e31879f5 to your computer and use it in GitHub Desktop.
Save vanpariyar/1ca5278e3cedbf6316c27028e31879f5 to your computer and use it in GitHub Desktop.
Full Installation and Configuration of Apache2, Multiple PHP, MariaDB, phpMyAdmin, LetsEncrypt, HTTP/2, IonCube, Postfix, Dovecot, SPF, DKIM, Roundcube Webmail and Files Permission Commands on Ubuntu 18.04 and 18.10 Web Server
Complete Installation and Configuration of Apache2, Multiple PHP, MariaDB, phpMyAdmin, LetsEncrypt,
HTTP/2, IonCube, Postfix, Dovecot, SPF, DKIM, Roundcube Webmail and
Files Permission Commands on Ubuntu 18.04 and 18.10 Web Server
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
This is a complete Ubuntu Linux based web server for Website, PHP, SSL, TLS, Database and Email hosting purpose.
Built with the below components for good performance. Also, I tried to make it as secure as possible.
DISCLAIMER: I'm making this guide just for my own purpose and needs. But, If it meets your requirements,
please feel free to use those commands below. Remember, I'm not liable if any bad thing happens to your server.
My recommendation is to you that use this on a testing server before using it on a production server.
Just kidding; do whatever you like, at your own risk.
Please contact me: If you need Linux server maintenance and installation help.
MY CONTACT:
EMAIL: bd.mhrubel@gmail.com
SKYPE: panpiedgroup
MOBILE: +8801734998405 (Bangladesh)
FACEBOOK: www.fb.me/bd.mhrubel
Software Lists:
01. Apache2
02. PHP
03. HTTP/2 [OPTIONAL]
04. MariaDB
05. phpMyAdmin [OPTIONAL]
06. LetsEncrypt [OPTIONAL]
07. IonCube [OPTIONAL]
08. Postfix
09. Dovecot
10. SPF
11. DKIM
12. Roundcube [OPTIONAL]
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
## Lets Update The Ubuntu Linux Server before creating the web serevr
sudo apt update && sudo apt upgrade -y && sudo apt dist-upgrade && sudo apt autoremove && sudo apt update
01. Apache2
-------------------
## Lets Install Apache2 Web Server
sudo apt install apache2 libapache2-mod-fcgid -y
# # # # # # # # # # # # # # # # # # # # # #
## Commands below can be used to stop, start and enable Apache2 service
sudo systemctl stop apache2.service
sudo systemctl start apache2.service
sudo systemctl enable apache2.service
# # # # # # # # # # # # # # # # # # # # # #
## Let's add a domain .conf file with PHP7.2-FPM enabled
sudo nano /etc/apache2/sites-available/example.com.conf
## Add below lines into the example.com.conf file and save it.
# # # # # # # # # # # # # # # # # # # # # #
<VirtualHost *:80>
ServerAdmin admin@example.com
DocumentRoot /var/www/html/example.com
ServerName example.com
ServerAlias www.example.com
<Directory /var/www/html/example.com/>
Options +FollowSymlinks
AllowOverride All
Require all granted
</Directory>
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php7.2-fpm.sock|fcgi://localhost/"
</FilesMatch>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
# # # # # # # # # # # # # # # # # # # # # #
sudo mkdir /var/www/html/example.com
sudo ln -s /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-enabled/
sudo systemctl restart apache2.service
02. PHP
-------------------
## Add Extra Repository for PHP
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ondrej/php
sudo apt update
### Lets Install Multiple PHP or Install Just One Version!!!
## Install PHP based modules that are not found in various versions! [OPTIONAL]
sudo apt install php-common php-cgi php-mbstring php-xmlrpc php-soap php-gd php-xml php-intl php-mysql php-cli php-zip php-curl php-imap php-memcached php-memcache php-ldap php-redis php-tidy php-ssh2 php-oauth php-imagick php-bz2 php-apcu php-geoip
## Install PHP 5.6 and FPM and it's modules
sudo apt install php5.6 php5.6-fpm php5.6-common php5.6-cgi php5.6-mbstring php5.6-xmlrpc php5.6-soap php5.6-gd php5.6-xml php5.6-intl php5.6-mysql php5.6-cli php5.6-zip php5.6-curl php5.6-imap php5.6-opcache php5.6-memcached php5.6-memcache php5.6-ldap php5.6-redis php5.6-tidy php5.6-ssh2 php5.6-oauth php5.6-imagick php5.6-bz2 php5.6-apcu php5.6-geoip php5.6-gettext
## Install PHP 7.0 and FPM and it's modules
sudo apt install php7.0 php7.0-fpm php7.0-common php7.0-cgi php7.0-mbstring php7.0-xmlrpc php7.0-soap php7.0-gd php7.0-xml php7.0-intl php7.0-mysql php7.0-cli php7.0-zip php7.0-curl php7.0-imap php7.0-opcache php7.0-memcached php7.0-memcache php7.0-ldap php7.0-redis php7.0-tidy php7.0-ssh2 php7.0-oauth php7.0-imagick php7.0-bz2 php7.0-apcu php7.0-geoip php7.0-gettext
## Install PHP 7.1 and FPM and it's modules
sudo apt install php7.1 php7.1-fpm php7.1-common php7.1-cgi php7.1-mbstring php7.1-xmlrpc php7.1-soap php7.1-gd php7.1-xml php7.1-intl php7.1-mysql php7.1-cli php7.1-zip php7.1-curl php7.1-imap php7.1-opcache php7.1-memcached php7.1-memcache php7.1-ldap php7.1-redis php7.1-tidy php7.1-ssh2 php7.1-oauth php7.1-imagick php7.1-bz2 php7.1-apcu php7.1-geoip php7.1-gettext
## Install PHP 7.2 and FPM and it's modules
sudo apt install php7.2 php7.2-fpm php7.2-common php7.2-cgi php7.2-mbstring php7.2-xmlrpc php7.2-soap php7.2-gd php7.2-xml php7.2-intl php7.2-mysql php7.2-cli php7.2-zip php7.2-curl php7.2-imap php7.2-opcache php7.2-memcached php7.2-memcache php7.2-ldap php7.2-redis php7.2-tidy php7.2-ssh2 php7.2-oauth php7.2-imagick php7.2-bz2 php7.2-apcu php7.2-geoip php7.2-gettext
## Install PHP 7.3 and FPM and it's modules
sudo apt install php7.3 php7.3-fpm php7.3-common php7.3-cgi php7.3-mbstring php7.3-xmlrpc php7.3-soap php7.3-gd php7.3-xml php7.3-intl php7.3-mysql php7.3-cli php7.3-zip php7.3-curl php7.3-imap php7.3-opcache php7.3-memcached php7.3-memcache php7.3-ldap php7.3-redis php7.3-tidy php7.3-ssh2 php7.3-oauth php7.3-imagick php7.3-bz2 php7.3-apcu php7.3-geoip php7.3-gettext
## Install PHP 7.4 and FPM and it's modules
sudo apt install php7.4 php7.4-fpm php7.4-common php7.4-cgi php7.4-mbstring php7.4-xmlrpc php7.4-soap php7.4-gd php7.4-xml php7.4-intl php7.4-mysql php7.4-cli php7.4-zip php7.4-curl php7.4-imap php7.4-opcache php7.4-memcached php7.4-memcache php7.4-ldap php7.4-redis php7.4-tidy php7.4-ssh2 php7.4-oauth php7.4-imagick php7.4-bz2 php7.4-apcu php7.4-geoip php7.4-gettext
# # # # # # # # # # # # # # # # # # # # # #
## Check Avaliable PHP7.2 Extensions / Modules [OPTIONAL]
sudo apt-cache search php7.2
# # # # # # # # # # # # # # # # # # # # # #
## Let's Configure PHP7.2-FPM with Apache2
sudo a2enmod actions fcgid alias proxy_fcgi
sudo a2enconf php5.6-fpm php7.0-fpm php7.1-fpm php7.2-fpm php7.3-fpm
sudo a2dismod mpm_prefork
## Below Commands is only for just to make sure that php7.2 is disables. May show errors that php7.2 is not exist...
sudo a2dismod php7.2
sudo a2enmod mpm_event
sudo systemctl restart apache2.service
sudo systemctl restart php5.6-fpm.service
sudo systemctl restart php7.0-fpm.service
sudo systemctl restart php7.1-fpm.service
sudo systemctl restart php7.3-fpm.service
sudo systemctl restart php7.3-fpm.service
## Configure PHP.ini file
sudo nano /etc/php/7.2/fpm/php.ini
# # # # # # # # # # # # # # # # # # # # # #
## Make the changes on the following lines below in the file and save...
cgi.fix_pathinfo=0
file_uploads = On
allow_url_fopen = On
date.timezone = Asia/Dhaka
upload_tmp_dir = /var/tmp
post_max_size = 4096M
upload_max_filesize = 4096M
max_execution_time = 5000
max_input_time = 5000
memory_limit = 1024M
max_input_vars = 5000
# # # # # # # # # # # # # # # # # # # # # #
## Check installed php extensions
php -m
## Lets restart the service
sudo systemctl restart php7.2-fpm.service
03. HTTP/2 [OPTIONAL]
----------------------
## Prerequisites
### Enable HTTPS on your server. All major browsers allow using of HTTP/2 only over HTTPS.
### TLS protocol version >= 1.2 with modern cipher suites is required.
### Ensure that you are running Apache 2.4.17 or above because HTTP/2 is supported from this version and upwards.
### If you run PHP in Apache via mod_php, you need to switch to FPM. That is not a bad thing. FPM is newer and faster.
## Switching Apache’s PHP Module from MPM Prefork to Event
sudo apt-get install php7.2-fpm (not required if already installed)
sudo a2enmod proxy_fcgi
sudo a2enconf php7.2-fpm
sudo a2dismod php7.2 (not required if not installed)
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo systemctl restart apache2.service
## Lets enable the module mod_http2
sudo a2enmod http2
sudo systemctl restart apache2.service
sudo systemctl restart php7.2-fpm.service
## Enable the HTTP/2 protocol by adding the following to /etc/apache2/apache2.conf:
Protocols h2 http/1.1
sudo nano /etc/apache2/sites-available/example.com.conf
## Examples of adding apache2.conf file Protocols h2 http/1.1
# # # # # # # # # # # # # # # # # # # # # #
## Don not forget to put the below code inside the both SSL and HTTP conf for the domain
<VirtualHost *:443>
Protocols h2 http/1.1
...
...
...
</VirtualHost>
# # # # # # # # # # # # # # # # # # # # # #
## Lets restart few services
sudo systemctl restart apache2.service
sudo systemctl restart php7.2-fpm.service
## Verify that HTTP/2 is Working from here: https://tools.keycdn.com/http2-test
04. MariaDB
-------------------
## Lets Install MariaDB Database Server
sudo apt-get install mariadb-server mariadb-client -y
# # # # # # # # # # # # # # # # # # # # # #
## Commands below can be used to stop, start and enable MariaDB service
sudo systemctl stop mariadb.service
sudo systemctl start mariadb.service
sudo systemctl enable mariadb.service
# # # # # # # # # # # # # # # # # # # # # #
## Secure MariaDB server
sudo mysql_secure_installation
# # # # # # # # # # # # # # # # # # # # # #
## Answer the questions below by following the guide.
Enter current password for root (enter for none): Just press the Enter
Set root password? [Y/n]: Y
New password: Enter password
Re-enter new password: Repeat 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
# # # # # # # # # # # # # # # # # # # # # #
## Let's restart MariaDB server
sudo systemctl restart mariadb.service
05. phpMyAdmin [OPTIONAL]
---------------------------
## Lets Install phpMyAdmin
sudo apt install phpmyadmin -y
# # # # # # # # # # # # # # # # # # # # # #
## When prompted to choose "Configuring phpmyadmin"
Web server to reconfigure automatically: select apache2 and continue.
Configure database for phpmyadmin with dbconfig-common: Yes
Create a password for phpMyAdmin: Please provide a password for phpmyadmin to register with the database…
# # # # # # # # # # # # # # # # # # # # # #
## Lets restart
sudo systemctl restart apache2.service
## Now browse yourdomain.com/phpmyadmin and try to use (root) user login and password.
## Can't login there? Because, (root) user login is not permitted! Lets fix it below...
sudo mysql -u root
use mysql;
update user set plugin='' where User='root';
flush privileges;
exit
sudo systemctl restart mariadb.service
06. LetsEncrypt [OPTIONAL]
---------------------------
## Let's make sure that the apache2 domain conf is avaliable
sudo nano /etc/apache2/sites-available/example.com.conf
sudo ln -s /etc/apache2/sites-available/example.com.conf /etc/apache2/sites-enabled/
# # # # # # # # # # # # # # # # # # # # # #
<VirtualHost *:80>
...
...
ServerName example.com
ServerAlias www.example.com
...
...
<VirtualHost>
# # # # # # # # # # # # # # # # # # # # # #
## Let's Install Let’s Encrypt Apache Client
sudo apt-get install python-certbot-apache -y
## Please repleace the below example.com text with your own domain name.
sudo certbot --apache --agree-tos --email admin@example.com --redirect --hsts -d example.com -d www.example.com
# # # # # # # # # # # # # # # # # # # # # #
## The commands options above are explained below:
### –apache: Use the Apache2 Let’s Encrypt installer
### –agree-tos: Agree to Let’s Encrypt terms of service
### –redirect: Adds 301 redirect.
### –email: Contact email address.
### –hsts: Adds the Strict-Transport-Security header to every HTTP response.
### – d flag is followed by domains you want to secure.
# # # # # # # # # # # # # # # # # # # # # #
## Now, the SSL client should install the cert and configure your website to redirect all traffic over HTTPS.
## A new configuration file for the domain should also be created named /etc/apache2/sites-available/example.com-le-ssl.conf.
## The below highlighted code block should be added to your website configuration file automatically by Let’s Encrypt certbot.
## Your site should be ready to be used over HTTPS.
# # # # # # # # # # # # # # # # # # # # # #
<VirtualHost *:80>
...
...
ServerName example.com
ServerAlias www.example.com
...
...
RewriteEngine on
RewriteCond %{SERVER_NAME} =example.com [OR]
RewriteCond %{SERVER_NAME} =www.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
...
...
<VirtualHost>
# # # # # # # # # # # # # # # # # # # # # #
## Let's add Let’s Encrypt certificate auto renewal process using crontab
sudo crontab -e
## Add the line below and save
# # # # # # # # # # # # # # # # # # # # # #
# Lets Encrypt Monthly Domain Auto Renewal
0 1 * * * /usr/bin/certbot renew & > /dev/null
# # # # # # # # # # # # # # # # # # # # # #
## Manual Let's Encrypt Renewal command is below
sudo certbot renew --dry-run
07. IonCube [OPTIONAL]
------------------------
## Create a php info file in html folder and use your IP to browse it.
## http://your_server_ip/info.php
sudo nano /var/www/html/info.php
## Then paste the below lines from the box without hashes and save and exit.
# # # # # # # # # # # # # # # # # # # # # #
<?php
phpinfo();
# # # # # # # # # # # # # # # # # # # # # #
## Lets Download and unzip IonCube Loader Zip file inside /tmp directory
cd /tmp && wget http://downloads3.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz && tar xfz ioncube_loaders_lin_*.gz
## Then paste the below lines from the box without hashes and save and exit.
# # # # # # # # # # # # # # # # # # # # # #
## Lets find the PHP extensions directory on the system
php -i | grep extension_dir
## example below of the result and remember the directory
extension_dir => /usr/lib/php/20180731 => /usr/lib/php/20180731
# # # # # # # # # # # # # # # # # # # # # #
## Now copy the ioncube loader inside the above extension_dir
sudo cp /tmp/ioncube/ioncube_loader_lin_5.6.so /usr/lib/php/20180731
sudo cp /tmp/ioncube/ioncube_loader_lin_7.0.so /usr/lib/php/20180731
sudo cp /tmp/ioncube/ioncube_loader_lin_7.1.so /usr/lib/php/20180731
sudo cp /tmp/ioncube/ioncube_loader_lin_7.2.so /usr/lib/php/20180731
sudo cp /tmp/ioncube/ioncube_loader_lin_7.3.so /usr/lib/php/20180731
## Lets create a file inside /etc/php/5.6/fpm/conf.d/ for php front end version
sudo nano /etc/php/5.6/fpm/conf.d/00-ioncube.ini
## Then paste the below lines and save. For PHP 5.6
zend_extension = /usr/lib/php/20180731/ioncube_loader_lin_5.6.so
## Lets create a file inside /etc/php/7.0/fpm/conf.d/ for php front end version
sudo nano /etc/php/7.0/fpm/conf.d/00-ioncube.ini
## Then paste the below lines and save. For PHP 7.0
zend_extension = /usr/lib/php/20180731/ioncube_loader_lin_7.0.so
## Lets create a file inside /etc/php/7.1/fpm/conf.d/ for php front end version
sudo nano /etc/php/7.1/fpm/conf.d/00-ioncube.ini
## Then paste the below lines and save. For PHP 7.1
zend_extension = /usr/lib/php/20180731/ioncube_loader_lin_7.1.so
## Lets create a file inside /etc/php/7.2/fpm/conf.d/ for php front end version
sudo nano /etc/php/7.2/fpm/conf.d/00-ioncube.ini
## Then paste the below lines and save. For PHP 7.2
zend_extension = /usr/lib/php/20180731/ioncube_loader_lin_7.2.so
## Lets create a file inside /etc/php/7.3/fpm/conf.d/ for php front end version
sudo nano /etc/php/7.3/fpm/conf.d/00-ioncube.ini
## Then paste the below lines and save. For PHP 7.3
zend_extension = /usr/lib/php/20180731/ioncube_loader_lin_7.3.so
## Lets create a symlink, inside the server (CLI) encryptrd files with ioncube will not work inside server if not created...
sudo ln -s /etc/php/5.6/fpm/conf.d/00-ioncube.ini /etc/php/5.6/cli/conf.d/
sudo ln -s /etc/php/7.0/fpm/conf.d/00-ioncube.ini /etc/php/7.0/cli/conf.d/
sudo ln -s /etc/php/7.1/fpm/conf.d/00-ioncube.ini /etc/php/7.1/cli/conf.d/
sudo ln -s /etc/php/7.2/fpm/conf.d/00-ioncube.ini /etc/php/7.2/cli/conf.d/
sudo ln -s /etc/php/7.3/fpm/conf.d/00-ioncube.ini /etc/php/7.3/cli/conf.d/
## Lets restart the web server to take effect.
sudo systemctl restart apache2.service
sudo systemctl restart php5.6-fpm.service
sudo systemctl restart php7.0-fpm.service
sudo systemctl restart php7.1-fpm.service
sudo systemctl restart php7.2-fpm.service
sudo systemctl restart php7.3-fpm.service
## Lets Verify the ionCube Installation on browser
# Go Back on the http://your_server_ip/info.php page, refresh the page and search for the "ionCube" keyword.
## Use the below command to see is it working or not.
php -v
08. Postfix
----------------------
# Set A Correct Hostname for Ubuntu Server
hostname -f
sudo hostnamectl set-hostname example.com
# Set System Time
sudo dpkg-reconfigure tzdata
# To let your system read RTC time in UTC standard
timedatectl set-local-rtc 0
# To let your system read RTC time in local time zone
timedatectl set-local-rtc 1
# Now check status
timedatectl status
# Set up DNS Records for Your Mail Server
## EXAMPLE: MX record
MX record @ mail.example.com
## EXAMPLE: A record
mail.example.com <IP-address>
# Lety's check PTR record
dig -x <IP> +short
# Lets Install Postfix
sudo apt-get update
sudo apt-get install postfix -y
#############################################################
##You will be asked
### General type of mail configuration: Internet Site
### System mail name: example.com
#############################################################
# Let's check postfix version
sudo postconf mail_version
# Let's check the port
sudo netstat -lnpt
# Lety's check your server open Port
sudo apt install nmap
sudo nmap your-server-ip
# Send Test Email
echo "test email" | sendmail your-account@gmail.com
# The inbox for each user is located at
postconf mail_spool_directory
# Using the mail program to Send and Read Email
sudo apt-get install mailutils
# To send email
mail username@gmail.com
###############################################################
user@mail:~$ mail username@gmail.com
Cc:
Subject: 2nd test email
I'm sending this email using the mail program.
### Enter subject line and the body text.
### Press Ctrl+D and mail will send this email message for you.
### To read incoming emails, just type "mail"
### To read the first email message, type 1.
### If only parts of the message is displayed, press Enter to show the remaining part of the message.
### To display message headers starting from message 1, type h.
### To show the last screenful of messages, type h$ or z.
### To read the next email message, type n.
### To delete message 1, type d 1.
### To delete message 1, 2 and 3, type d 1 2 3.
### To delete messages from 1 to 10, type d 1-10.
### To replay to message 1, type reply 1.
### To exit out of mail, type q.
###############################################################
## EXTRAS : Setting up Postfix as a Forward Only Mail Host
# Forward every incoming email to another email service like Gmail
nano ~/.forward
###############################################################
### and add an email address in the file.
your-account@gmail.com
### Save and close the file. That’s all you have to do.
###############################################################
09. Dovecot
----------------------
# Install Dovecot IMAP server and Enable TLS Encryption
sudo apt install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install certbot
sudo apt install python3-certbot-apache
sudo apt install python3-certbot-nginx
# Obtaining TLS Certificate with Apache Web Server
sudo nano /etc/apache2/sites-available/mail.example.com.conf
###########################################################
### Then paste the following text into the file.
<VirtualHost *:80>
ServerName mail.example.com
DocumentRoot /var/www/html/mail.example.com
</VirtualHost>
### Save and close the file
###########################################################
# Create the web root directory
sudo mkdir /var/www/html/mail.example.com
sudo chown www-data:www-data /var/www/html/mail.example.com -R
# Enable this virtual host
sudo a2ensite mail.example.com.conf
# Reload Apache
sudo systemctl reload apache2
# Obtain and install Let’s Encrypt TLS certificate
sudo certbot --apache --agree-tos --redirect --hsts --email your-email-address -d mail.example.com
# Configuring Postfix
# Enable the submission service of Postfix
sudo nano /etc/postfix/master.cf
###########################################################
### In submission section, uncomment or add the following lines.
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_tls_wrappermode=no
-o smtpd_sasl_auth_enable=yes
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject
-o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth
### The above configuration enables the submission daemon of Postfix and requires TLS encryption.
### The submission daemon listens on TCP port 587.
### STARTTLS is used to encrypt communications between email client and the submission daemon.
###########################################################
# Let's Postfix know where TLS certificate and private key are.
sudo nano /etc/postfix/main.cf
###########################################################
### Edit the TLS parameter as follows: change the example.com with your domain
smtpd_tls_cert_file=/etc/letsencrypt/live/mail.example.com/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/mail.example.com/privkey.pem
smtpd_tls_security_level=may
smtpd_tls_protocols = !SSLv2, !SSLv3 !TLSv1
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_security_level = may
smtp_tls_loglevel = 1
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
###########################################################
# Reload Postfix
sudo postfix reload
# See port 587 is now open
sudo netstat -lnpt
# Installing Dovecot IMAP Server
sudo apt install dovecot-core dovecot-imapd
# Check Dovecot version
sudo dovecot --version
# Configuring Dovecot
# Edit main config file.
sudo nano /etc/dovecot/dovecot.conf
###########################################################
### Add the following line to enable IMAP protocol.
protocols = imap
###########################################################
# Configuring Mailbox Location
## By default, Postfix uses mbox format to store emails.
## Each user’s emails is stored in a single file /var/mail/username
## Find the mail spool directory
postconf mail_spool_directory
###########################################################
### Sample output:
mail_spool_directory = /var/mail
###########################################################
# The config file for mailbox location is /etc/dovecot/conf.d/10-mail.conf
sudo nano /etc/dovecot/conf.d/10-mail.conf
###########################################################
### The default configuration is as follows, which is fine for a small email server.
mail_location = mbox:~/mail:INBOX=/var/mail/%u
### Add the following line in the file. (On Ubuntu 18.04, this line is already in the file.)
mail_privileged_group = mail
###########################################################
# Add dovecot to the mail group so that Dovecot can read the INBOX
sudo gpasswd -a dovecot mail
# Configuring Authentication Mechanism
# Edit the authentication config file.
sudo nano /etc/dovecot/conf.d/10-auth.conf
###########################################################
### Uncomment the following line.
disable_plaintext_auth = yes
### It will disable plaintext authentication when there’s no SSL/TLS encryption.
### And if you want to use full email address (username@your-domain.com) to login, add the following line in the file.
auth_username_format = %n
### Find the following line. and add "login" after "plain" as follows
auth_mechanisms = plain login
###########################################################
# Configuring SSL/TLS Encryption
# Edit SSL/TLS config file.
sudo nano /etc/dovecot/conf.d/10-ssl.conf
###########################################################
### Change ssl = no/yes to ssl = required.
ssl = required
### Specify the location of your SSL/TLS cert and private key.
### Don’t leave out < character. It’s necessary.
ssl_cert = </etc/letsencrypt/live/mail.example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/mail.example.com/privkey.pem
###########################################################
# SASL Authentication Between Postfix and Dovecot
# Edit the following file.
sudo nano /etc/dovecot/conf.d/10-master.conf
###########################################################
### Change "service auth" section to the following so that Postfix can find the Dovecot authentication server.
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}
###########################################################
# Auto-create Sent and Trash Folder
# Edit the below config file.
sudo nano /etc/dovecot/conf.d/15-mailboxes.conf
###########################################################
### To auto create a folder, simply add the following line in the mailbox section.
auto = create
### Example:
mailbox Trash {
auto = create
special_use = \Trash
}
###########################################################
# Dovecot will be listening on port 143 (IMAP) and 993 (IMAPS).
# If there’s a configuration error, dovecot will fail to restart.
# We also need to restart Postfix to allow the LOGIN authentication mechanism.
# Restart Dovecot and Postfix
sudo systemctl restart dovecot
sudo systemctl restart postfix
# The Final Step: Configure Desktop Email Client
# Now open up your desktop email client such as Mozilla Thunderbird and add a mail account.
###########################################################
### In the incoming server section, select IMAP protocol, enter mail.example.com as the server name,
### choose port 993 and SSL/TLS. Choose normal password as the authentication method.
### In the outgoing section, select SMTP protocol, enter mail.example.com as the server name,
###choose port 587 and STARTTLS. Choose normal password as the authentication method.
### Note: Linux matchine username and password will be used as user email and password
### Example: Username: root@example.com
###########################################################
10. SPF
----------------------
# Create an SPF Record in DNS
# Create a new TXT record like below.
TXT @ v=spf1 mx ~all
# Check if your SPF record is propagated to the public Internet,
# Use the dig utility on your Linux machine like below:
dig example.com txt
# Configuring SPF Policy Agent
sudo apt install postfix-policyd-spf-python
# Edit the Postfix master process configuration file.
sudo nano /etc/postfix/master.cf
###########################################################
### Add the following lines at the end of the file.
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf
###########################################################
# Edit Postfix main configuration file.
sudo nano /etc/postfix/main.cf
###########################################################
### Append the following lines at the end of the file.
### The first line specifies the Postfix policy agent timeout setting.
### The following lines will impose restriction on incoming emails by rejecting unauthorized email and checking SPF record.
policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
reject_unauth_destination,
check_policy_service unix:private/policyd-spf
###########################################################
# Restart Postfix.
sudo systemctl restart postfix
11. DKIM
----------------------
# Setting up DKIM
sudo apt install opendkim opendkim-tools
sudo gpasswd -a postfix opendkim
# Edit OpenDKIM main configuration file.
sudo nano /etc/opendkim.conf
###########################################################
### Uncomment the following lines. Replace simple with relaxed/simple.
Canonicalization simple
Mode sv
SubDomains no
### Then add the following lines below #ADSPAction continue line.
### If your file doesn’t have #ADSPAction continue line, then just add them below SubDomains no.
AutoRestart yes
AutoRestartRate 10/1M
Background yes
DNSTimeout 5
SignatureAlgorithm rsa-sha256
### Add the following lines at the end of this file.
### On Ubuntu 18.04, the UserID is already set to opendkim.
#OpenDKIM user
# Remember to add user postfix to group opendkim
UserID opendkim
# Map domains in From addresses to keys used to sign messages
KeyTable /etc/opendkim/key.table
SigningTable refile:/etc/opendkim/signing.table
# Hosts to ignore when verifying signatures
ExternalIgnoreList /etc/opendkim/trusted.hosts
InternalHosts /etc/opendkim/trusted.hosts
###########################################################
# Create Signing table, key table and trusted hosts file
# Create a directory structure for OpenDKIM
sudo mkdir /etc/opendkim
sudo mkdir /etc/opendkim/keys
# Change owner from root to opendkim and make sure only opendkim user can read and write to the keys directory.
sudo chown -R opendkim:opendkim /etc/opendkim
sudo chmod go-rw /etc/opendkim/keys
# Create the signing table.
sudo nano /etc/opendkim/signing.table
###########################################################
### Add this line to the file.
### Note that "example.com" and "example" is different.
### The latter should not contain the top-level domain.
*@example.com default._domainkey.example
###########################################################
# Create the key table.
sudo nano /etc/opendkim/key.table
###########################################################
### Add the following line.
default._domainkey.example example.com:default:/etc/opendkim/keys/example.com/default.private
###########################################################
# Configure Trusted Hosts
# Create the file.
sudo nano /etc/opendkim/trusted.hosts
###########################################################
### Add the following lines to the newly created file.
127.0.0.1
localhost
*.example.com
###########################################################
# Generate Private/Public Keypair
# Create a separate folder for the domain.
sudo mkdir /etc/opendkim/keys/your-domain.com
# Generate keys using opendkim-genkey tool.
sudo opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s default -v
# Make opendkim as the owner of the private key.
sudo chown opendkim:opendkim /etc/opendkim/keys/example.com/default.private
# Add Public Key in DNS Records
# Display the public key
# The string after the p parameter is the public key.
sudo cat /etc/opendkim/keys/example.com/default.txt
###########################################################
### In you DNS manager, create a TXT record, enter default._domainkey in the name field.
### Then copy everything in the parentheses and paste it into the value field.
### Delete all double quotes and white spaces. If you don’t delete them, then the key test in the next step will fail.
TXT default._domainkey v=DKIM1; h=sha256; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApFNEbyADBeibEJw0/0YKXFdMRd0xoekp0VWFJUvY6DokBfPhiuPHY6vzt5Q5TkbXLI1PJgWF6S4mIiLwZgyijkSRx8lIVrJSHNxR0GU2HYNQMnOzYjcznQHhZXYA4SB2FKnxaURP+LzkesGSkunf11dMlSm7+ZvkZLE8+f1nCAXNL4BppgLhI1WOM12SEYefl4XND269kGVBM2 fnW96aMC3/uYbr0+20WbfcVWx7U9o93NpUvIA/JGxfibF/hbKBcVNyCPnWnyFfjaSJapI4mXG0GfSRTDxuZfINLPmjckaw1SDEGIuOD2hOSYKHJZImfAFPVGGAVk/4Et+bqsuAwwIDAQAB
###########################################################
# Test your configuration
sudo opendkim-testkey -d example.com -s default -vvv
###########################################################
### If everything is OK, you will see
key OK
###########################################################
# Connect Postfix to OpenDKIM
# Create a directory to hold the OpenDKIM socket file and only allow opendkim user and postfix group to access it.
sudo mkdir /var/spool/postfix/opendkim
sudo chown opendkim:postfix /var/spool/postfix/opendkim
# Edit the socket configuration file.
# Note: On Ubuntu 18.04, the opendkim systemd service doesn’t use "/etc/default/opendkim" file.
# You need to change the socket file in "/etc/opendkim.conf" file.
sudo nano /etc/default/opendkim
###########################################################
### Find the following line:
SOCKET="local:/var/run/opendkim/opendkim.sock"
### Replace it with:
SOCKET="local:/var/spool/postfix/opendkim/opendkim.sock"
###########################################################
# Edit Postfix main configuration file.
sudo nano /etc/postfix/main.cf
###########################################################
### Add the following lines after "smtpd_recipient_restriction" section.
# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:/opendkim/opendkim.sock
non_smtpd_milters = $smtpd_milters
###########################################################
# Restart opendkim and postfix service.
sudo systemctl restart opendkim
sudo systemctl restart postfix
# SPF and DKIM Check
# use your desktop email client or webmail client to send a test email to "check-auth@verifier.port25.com"
12. Roundcube [OPTIONAL]
--------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment