Difference between revisions of "User:Saul/linode"

From Organic Design wiki
(Added SSL And Git sections.)
m (Servers Rejecting Mail)
 
(73 intermediate revisions by the same user not shown)
Line 92: Line 92:
 
=== Install And Configure PHP ===
 
=== Install And Configure PHP ===
 
<source lang="bash">
 
<source lang="bash">
sudo apt-get install php7.0 php-pear # PHP may update - change php7.0 to the current version number
+
sudo apt-get install php7.0 php-pear php7.0-mysql # PHP may update - change php7.0 to the current version number
sudo apt-get install php7.0-mysql
+
sudo mkdir -p /var/log/php # create the folder for error logging
mkdir -p /var/log/php # create the folder for error logging
+
sudo chown www-data /var/log/php # changes the group of the file we created with the group www-data
chown www-data /var/log/php # changes the group of the file we created with the group www-data
+
sudo service apache2 restart
service apache2 restart
+
 
 +
# linux mint needs this package isntalled to get php working on apache2:
 +
sudo apt-get install libapache2-mod-php5
  
 
# Optional install php gd - this is an add-on allows php to manipulate image files - often used by gallery plugins in Wordpress.
 
# Optional install php gd - this is an add-on allows php to manipulate image files - often used by gallery plugins in Wordpress.
 
sudo apt-get install php7.0-gd
 
sudo apt-get install php7.0-gd
 
</source>
 
</source>
 +
 +
== Nginx ==
 +
=== Install ===
 +
<source lang="bash">
 +
sudo apt-get install nginx
 +
sudo /etc/init.d/nginx start
 +
sudo apt-get install php7.0 php-pear php7.0-mysql php-fpm
 +
</source>
 +
 +
=== Configure ===
 +
<source lang="bash">
 +
sudo nano /etc/nginx/sites-enabled/default
 +
 +
# Basic configuration
 +
server {
 +
        listen 80 default_server;
 +
        listen [::]:80 default_server;
 +
 +
        root /var/www/public_html;
 +
 +
        index index.html index.htm index.nginx-debian.html index.php;
 +
 +
        server_name _;
 +
 +
        # This solves the permalink problem
 +
        if (!-e $request_filename) {
 +
                rewrite ^.*$ /index.php last;
 +
                break;
 +
        }
 +
 +
        location / {
 +
                try_files $uri $uri/ /index.php?$args =404;
 +
        }
 +
 +
        location ~ \.php$ {
 +
                include snippets/fastcgi-php.conf;
 +
 +
                fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
 +
        }
 +
 +
        location ~ /\.ht {
 +
                deny all;
 +
        }
 +
}
 +
 +
sudo /etc/init.d/nginx reload
 +
sudo nginx -s reload
 +
</source>
 +
 
== Setting Up Wordpress ==
 
== Setting Up Wordpress ==
 
=== Creating The Database ===
 
=== Creating The Database ===
Line 111: Line 162:
 
quit; # exit mysql
 
quit; # exit mysql
 
</source>
 
</source>
 +
 
=== Install ===
 
=== Install ===
 
<source lang="bash">
 
<source lang="bash">
Line 127: Line 179:
 
=== Permalink 404 Error Fix ===
 
=== Permalink 404 Error Fix ===
 
<source lang="bash">
 
<source lang="bash">
sudo nano /var/www/.htaccess # Create an empty file here
+
sudo nano /var/www/example.com/public_html/.htaccess # Create an empty file here and make sure permissions are correct - wordpress should automatically do this if permissions are fine.
sudo nano example.com.conf
+
sudo nano /etc/apache2/sites-available/example.com.conf
 
# Append these lines:
 
# Append these lines:
 
<Directory /var/www/>
 
<Directory /var/www/>
Line 144: Line 196:
 
</Directory>
 
</Directory>
 
</source>
 
</source>
=== Emails Not Working ===
+
 
 +
=== Email ===
 +
==== Not Working ====
 
<source lang="bash">
 
<source lang="bash">
 
php -a # boot php
 
php -a # boot php
Line 152: Line 206:
 
sudo apt-get install sendmail
 
sudo apt-get install sendmail
 
</source>
 
</source>
 +
 +
==== Slow ====
 +
Email sending can be real slow if hostnames are not set up correctly, to fix this edit this file:
 +
<source lang="bash">
 +
sudo nano /etc/hosts
 +
</source>
 +
Edit the (first?) line that says:
 +
<source>
 +
127.0.0.1    localhost
 +
</source>
 +
Change to:
 +
<source>
 +
127.0.0.1    localhost localhost.localdomain
 +
</source>
 +
Then reload sendmail by running:
 +
<source lang="bash">
 +
sudo sendmailconfig # Answer yes to all questions
 +
</source>
 +
 +
==== Encryption ====
 +
To enable encryption on sendmail run
 +
<source lang="bash">
 +
sudo nano /etc/mail/sendmail.mc
 +
</source>
 +
And add this line to the end:
 +
<source>
 +
include(`/etc/mail/tls/starttls.m4')dnl
 +
</source>
 +
Then reload sendmail by running:
 +
<source lang="bash">
 +
sudo sendmailconfig # Answer yes to all questions
 +
</source>
 +
 +
==== Not Sending To Own Domain ====
 +
If your mail server is a different one from your web server and you try to send mail to your own domain your system may try to handle it internally.<br>
 +
If you test php sendmail and it does this you will see an output like:
 +
<source>
 +
/home/user/dead.letter... Saved message in /home/user/dead.letter
 +
</source>
 +
To fix simply edit this file:
 +
<source lang="bash">
 +
sudo nano /etc/mail/sendmail.mc
 +
</source>
 +
and Inject the following lines:
 +
<source>
 +
define(`MAIL_HUB', `example.com.')dnl
 +
define(`LOCAL_RELAY', `example.com.')dnl
 +
</source>
 +
Immediately before these lines (near the end)
 +
<source>
 +
MAILER(local)
 +
MAILER(smtp)
 +
</source>
 +
Then run:
 +
<source lang="bash">
 +
sudo sendmailconfig # Answer yes to all questions
 +
</source>
 +
 +
==== Servers Rejecting Mail ====
 +
Some servers will reject mail without this defined in /etc/mail/sendmail.mc
 +
<source>
 +
define(`confDOMAIN_NAME', `example.com')dnl
 +
</source>
 +
 +
=== Multisite ===
 +
[https://www.wpbeginner.com/wp-tutorials/how-to-install-and-setup-wordpress-multisite-network/#multisitecons Setting up muilti-sites]
 +
[https://www.brianshim.com/webtricks/wordpress-multisite-separate-domain-names/ Unique domains]
 +
 +
Edit the '''wp-config.php''' file and add the following lines just above the ''/* That’s all, stop editing! Happy blogging. */'' line:
 +
<source lang="php">
 +
/* Multisite */
 +
define( 'WP_ALLOW_MULTISITE', true );
 +
</source>
 +
Then deactivate all plugins.<br>
 +
Then go to '''Tools » Network Setup''' and follow the instructions.
 +
 
== Setting Up SSL ==
 
== Setting Up SSL ==
 
=== Installing Certbot For Let's Encrypt On Apache ===
 
=== Installing Certbot For Let's Encrypt On Apache ===
Line 158: Line 288:
 
# append to file to enable backports
 
# append to file to enable backports
 
deb http://ftp.debian.org/debian stretch-backports main
 
deb http://ftp.debian.org/debian stretch-backports main
 +
sudo apt-get update # to update the backports
 
sudo apt-get install python-certbot-apache -t stretch-backports
 
sudo apt-get install python-certbot-apache -t stretch-backports
 
sudo certbot --authenticator webroot --installer apache
 
sudo certbot --authenticator webroot --installer apache
 
</source>
 
</source>
 +
 
=== Auto Renew The Certificate ===
 
=== Auto Renew The Certificate ===
 
<source lang="bash">
 
<source lang="bash">
 
sudo certbot renew --dry-run # test SSL autorenewal
 
sudo certbot renew --dry-run # test SSL autorenewal
 
cd /etc/cron.daily
 
cd /etc/cron.daily
sudo nano certbot #Create file with contents:
+
sudo cp dpkg certbot
 +
sudo nano certbot # remove the contents and replace with
 
#!/bin/sh
 
#!/bin/sh
 
certbot renew --renew-hook "service restart apache2"
 
certbot renew --renew-hook "service restart apache2"
Line 171: Line 304:
 
</source>
 
</source>
 
[https://certbot.eff.org/#debianstretch-apache See Also]
 
[https://certbot.eff.org/#debianstretch-apache See Also]
 +
 +
=== Installing Certbot For Let's Encrypt On Node.js ===
 +
Certbot creates files and folders in the root directory for testing, this means node has to be able to get domain.com/SOMEFILENAME so the root dir has to be set up as a directory.<br>
 +
A repository for a good file to achieve this can be found [https://raw.githubusercontent.com/alexnitta/node-https-example/master/server/server.js/ Here].<br>
 +
If you are using express you may want to add something like this:
 +
<source lang="javascript">
 +
app.use('/.well-known', express.static(path.join(__dirname, "/../.well-known/")));
 +
</source>
 +
Make sure the node server is running while you run the cert!
 +
<source lang="bash">
 +
sudo nano /etc/apt/sources.list
 +
# append to file to enable backports
 +
deb http://ftp.debian.org/debian stretch-backports main
 +
sudo apt-get update # to update the backports
 +
sudo apt-get install certbot -t stretch-backports
 +
sudo certbot certonly --webroot -w /var/www/avikar.io -d www.avikar.io -d avikar.io
 +
</source>
 +
Auto-renew is pretty much the same but without the hook.
 +
 +
[http://alexnitta.com/setting-up-https-in-node-js-with-lets-encrypt/ See Also]
 +
 +
=== Wildcard Certs (Unfinished) ===
 +
This does not work on Debian 9 (Yet)
 +
<source lang="bash">
 +
sudo certbot certonly --manual -d *.YOUR_DOMAIN_NAME --agree-tos --no-bootstrap --manual-public-ip-logging-ok --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory
 +
</source>
 +
[https://asknetsec.com/generate-lets-encrypt-free-wildcard-certificate-using-certbot-ubuntu-16-04/ See also.]
 +
 
== Setting Up Git ==
 
== Setting Up Git ==
 
=== Github ===
 
=== Github ===
Line 194: Line 355:
 
git clone github.link.git
 
git clone github.link.git
 
sudo nano /somelocation/under/your/domain/fileName.php # Create the file with the contents below:
 
sudo nano /somelocation/under/your/domain/fileName.php # Create the file with the contents below:
<?php
+
</source>
if( array_key_exists( 'HTTP_X_HUB_SIGNATURE', $_SERVER ) ) {
+
<source lang="php">
$sig = $_SERVER['HTTP_X_HUB_SIGNATURE'];
+
<?php
$body = file_get_contents( 'php://input' );
+
if( array_key_exists( 'HTTP_X_HUB_SIGNATURE', $_SERVER ) ) {
$hmac = hash_hmac( 'sha1', $body, 'SECRET' );
+
$sig = $_SERVER['HTTP_X_HUB_SIGNATURE'];
if( $sig === "sha1=$hmac" ) {
+
$body = file_get_contents( 'php://input' );
$repo = json_decode( $body )->repository->name;
+
$hmac = hash_hmac( 'sha1', $body, 'SECRET' );
exec( "cd /PATH/TO/LOCAL/CLONES/$repo && sudo git pull --no-edit" );
+
if( $sig === "sha1=$hmac" ) {
}
+
$repo = json_decode( $body )->repository->name;
 +
exec( "cd /PATH/TO/LOCAL/CLONES/$repo && sudo git pull --no-edit" );
 
}
 
}
        ?>
+
}
 +
?>
 +
</source>
 +
<source lang="bash">
 
sudo visudo # might not be needed?
 
sudo visudo # might not be needed?
 
# Add this to the end of the file
 
# Add this to the end of the file
Line 211: Line 376:
 
# Check the log under the site folder for php errors
 
# Check the log under the site folder for php errors
 
</source>
 
</source>
 +
 
=== Github ===
 
=== Github ===
 
<source lang="bash">
 
<source lang="bash">
 
# On github add a webhook under settings, type: json, make sure secret (use a good password) aligns with the script (from on the server), and paste a link to the script url (from on the server)
 
# On github add a webhook under settings, type: json, make sure secret (use a good password) aligns with the script (from on the server), and paste a link to the script url (from on the server)
 +
</source>
 +
== Setting Up Node.js ==
 +
=== Node.js ===
 +
<source lang="bash">
 +
curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
 +
sudo apt-get install nodejs
 +
sudo apt-get install build-essential # install the optional add-ons
 +
</source>
 +
 +
=== Express ===
 +
<source lang="bash">
 +
sudo npm install -g express-generator # install express
 +
express PROJECT_NAME # create an express project called PROJECT_NAME
 +
cd PROJECT_NAME
 +
npm i # install dependancies
 +
</source>
 +
=== Vue Router ===
 +
<source lang="bash">
 +
sudo npm install --global vue # install vue globally THIS MIGHT ACTUALLY BE vue-cli
 +
sudo vue init webpack-simple APPNAME # create a new project using the "webpack-simple" template
 +
# Make sure to say yes to vue-router or enter the project directory and install it via "npm i vue-router"
 +
cd APPNAME
 +
npm i # install dependencies
 +
</source>
 +
 +
=== Feathers.js ===
 +
<source lang="bash">
 +
npm install @feathersjs/cli -g # install feathers globally
 +
mkdir server && cd server
 +
feathers generate app # generate the feathers app
 +
</source>
 +
 +
== Mail Exim ==
 +
 +
For a in-depth guide on this please see [[Configure_mail_server|this]]<br>
 +
Ensure that you have a reverse DNS setup.
 +
 +
=== Install And Setup Exim ===
 +
 +
<source lang="bash">
 +
sudo apt-get install exim4-daemon-heavy dovecot-common dovecot-imapd spamassassin spamc spf-tools-perl # install required packages
 +
dpkg-reconfigure exim4-config
 +
# no splitting configuration files
 +
# internet
 +
# Maildir
 +
# set your domain and anything else that is obvious
 +
# everything else default
 +
 +
sudo nano /etc/mailname
 +
# ensure this is your domain name
 +
 +
hostname -b command YOU_DOMAIN_NAME # set your domain as hostname for mail
 +
sudo /etc/init.d/exim4 restart
 +
</source>
 +
 +
If you require multiple domain set up on the one server please refer to [[Configure_mail_server#Main_configuration_for_multiple_domains|this]]<br>
 +
To test if you have setup this correctly run these commands:
 +
 +
<source lang="bash">
 +
sudo -v 'user@domain'
 +
SOME MESSAGE
 +
(Control D)
 +
 +
cd ~/Maildir/new
 +
ls
 +
# Check that a file(s) exists -if not check ~/Maildir/cur or another user account.
 +
nano SOMEFILE
 +
# you should see test mail you sent yourself.
 +
</source>
 +
 +
=== Install And Setup SMTP ===
 +
 +
==== SMTP Certificates ====
 +
 +
===== Lets Encrypt =====
 +
To setup exim for an existing lets encrypt cert:
 +
 +
<source lang="bash">
 +
certbot certonly --standalone -d smtp.DOMAIN.com -d imap.DOMAIN.com -d mail.DOMIAN.com
 +
sudo nano /etc/exim4/exim4.conf.template
 +
# add these lines to the top of the "main/03_exim4-config_tlsoptions" section
 +
MAIN_TLS_CERTIFICATE = /etc/letsencrypt/live/YOUDOMAIN/fullchain.pem
 +
MAIN_TLS_PRIVATEKEY = /etc/letsencrypt/live/YOURDOMAIN/privkey.pem
 +
 +
# add these lines to the top of the file.
 +
MAIN_TLS_ENABLE = true
 +
daemon_smtp_ports = 25 : 2525
 +
 +
sudo /etc/init.d/exim4 restart
 +
</source>
 +
 +
The permissions on the following files need read and execute for everyone or the certs cannot be read by exim:
 +
*/etc
 +
*/etc/letsencrypt
 +
*/etc/letsencrypt/live
 +
*/etc/letsencrypt/live/YOUCERTFOLDER
 +
*/etc/letsencrypt/archive
 +
*/etc/letsencrypt/archive/YOURCERTFOLDER
 +
 +
===== Self Signed =====
 +
For SSL setup with exim cert (preferable to do it with letsencrypt rather than selfsigned)
 +
<source lang="bash">
 +
sudo /usr/share/doc/exim4-base/examples/exim-gencert # gen a cert
 +
sudo nano /etc/exim4/exim4.conf.template
 +
# add these lines to the beginning of the file:
 +
MAIN_TLS_ENABLE = true
 +
daemon_smtp_ports = 25 : 2525
 +
 +
sudo /etc/init.d/exim4 restart
 +
</source>
 +
 +
==== Accounts ====
 +
Accounts will be authenticated with the default linux accounts.
 +
 +
<source lang="bash">
 +
sudo chgrp Debian-exim /etc/shadow # change the group for access
 +
sudo chmod g+r /etc/shadow # and the permissions
 +
sudo nano /etc/exim4/exim4.conf.template
 +
# find the plain_server section and configure like this:
 +
plain_server:
 +
driver = plaintext
 +
public_name = PLAIN
 +
server_condition = "${if crypteq{$auth3}{${extract{1}{:}{${lookup{$auth2}lsearch{/etc/shadow}{$value}}}}}{1}{0}}"
 +
server_set_id = $auth2
 +
server_prompts = :
 +
 +
sudo /etc/init.d/exim4 restart
 +
</source>
 +
 +
===== Testing =====
 +
To test if its working run on the client:
 +
 +
<source lang="bash">
 +
telnet smtp.avikar.io 2525
 +
</source>
 +
 +
If this doesn't work check that you have a wildcard (*) record on your DNS.<br>
 +
If it still doesn't work check that the port is open on the server by running:
 +
 +
<source lang="bash">
 +
netstat -nlp
 +
</source>
 +
 +
If a result like below is returned the port isn't opened:
 +
 +
<source>
 +
tcp        0      0 127.0.0.1:2525          0.0.0.0:*              LISTEN
 +
</source>
 +
 +
To open it run:
 +
 +
<source lang="bash">
 +
sudo cp /etc/exim4/update-exim4.conf.conf /etc/exim4/update-ex
 +
im4.conf.conf.backup # backup before changing
 +
sudo nano /etc/exim4/update-exim4.conf.conf
 +
# make this file looks like this:
 +
dc_eximconfig_configtype='internet'
 +
dc_other_hostnames=''
 +
dc_local_interfaces=''
 +
dc_readhost=''
 +
dc_relay_domains=''
 +
dc_minimaldns='false'
 +
dc_relay_nets=''
 +
dc_smarthost=''
 +
CFILEMODE='644'
 +
dc_use_split_config='false'
 +
dc_hide_mailname=''
 +
dc_mailname_in_oh='true'
 +
dc_localdelivery='maildir_home'
 +
 +
sudo /etc/init.d/exim4 restart
 +
 +
netstat -nlp # test again
 +
</source>
 +
 +
You should see a result like this if the port is opened:
 +
 +
<source>
 +
tcp        0      0 0.0.0.0:2525            0.0.0.0:*              LISTEN 
 +
</source>
 +
 +
And this should now work:
 +
 +
<source lang="bash">
 +
telnet smtp.avikar.io 2525
 +
</source>
 +
==== Copy Mail To The Sent Folder ====
 +
See [[Configure_mail_server#Copying_emails_into_the_Sent_folder|this]] as to why.
 +
 +
<source lang="bash">
 +
sudo nano /etc/exim4/exim4.conf.template
 +
# Add these lines under the other settings at the top:
 +
system_filter = /var/www/tools/exim-copy-to-sent
 +
system_filter_directory_transport = copy_to_sent
 +
system_filter_pipe_transport = copy_to_sent_pipe
 +
 +
# Insert this after the "end transport/30_exim4-config_mail_spool" header:
 +
copy_to_sent:
 +
driver = appendfile
 +
delivery_date_add
 +
envelope_to_add
 +
return_path_add
 +
group = Debian-exim
 +
user = ${if match {${local_part:${lookup{$sender_address_local_part@$sender_address_domain}lsearch*@{/etc/exim4/virtual.users}}}}{(.+)}{$1}{Debian-exim}}
 +
mode = 0660
 +
maildir_format
 +
directory = /home/${local_part:${lookup{$sender_address_local_part@$sender_address_domain}lsearch*@{/etc/exim4/virtual.users}}}/Maildir/.Sent/
 +
create_directory
 +
 +
copy_to_sent_pipe:
 +
driver = pipe
 +
user = Debian-exim
 +
group = Debian-exim
 +
 +
sudo nano /var/www/tools/exim-copy-to-sent
 +
# Add this content:
 +
if
 +
$sender_address_local_part is not "root"
 +
and
 +
"${if def:h_X-Spam-Status {def}{undef}}" is "undef"
 +
and
 +
"${if match {${lookup{$sender_address}lsearch{/etc/exim4/virtual.users}}}{@localhost}{yes}{}}" is "yes"
 +
then
 +
unseen save $home/Maildir/.Sent/
 +
unseen pipe "/var/www/tools/copy-to-sent.pl \"$recipients\""
 +
endif
 +
</source>
 +
 +
=== DoveCot IMAP Server ===
 +
<source lang="bash">
 +
sudo mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.backup
 +
sudo nano /etc/dovecot/dovecot.conf
 +
# Create the file with these contents:
 +
log_path = /var/log/dovecot.log
 +
 +
protocols = imap
 +
 +
service imap-login {
 +
inet_listener imap {
 +
address = localhost
 +
}
 +
}
 +
 +
mail_location = maildir:~/Maildir
 +
maildir_very_dirty_syncs = yes
 +
 +
userdb {
 +
driver = passwd
 +
}
 +
 +
passdb {
 +
driver = pam
 +
}
 +
 +
ssl = required
 +
ssl_prefer_server_ciphers = yes
 +
ssl_cipher_list = EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4
 +
ssl_protocols = !SSLv3 # SSLv2 has been removed from OpenSSL so is not even a valid name to disable
 +
ssl_cert = </etc/letsencrypt/live/imap.avikar.io/fullchain.pem
 +
ssl_key = </etc/letsencrypt/live/imap.avikar.io/privkey.pem
 +
</source>
 +
=== Spam Assassin ===
 +
<source lang="bash">
 +
sudo nano /etc/default/spamassassin
 +
# change the values like so:
 +
ENABLED=1
 +
CRON=1
 +
 +
sudo service spamassassin start # start spam assassin
 +
sudo nano /etc/exim4/exim4.conf.template
 +
# go to the "end router/800_exim4-config_maildrop" section and insert the following lines:
 +
# 850: Spamcheck router
 +
spamcheck_router:
 +
no_verify
 +
check_local_user
 +
condition = "${if and { {!def:h_X-Spam-Flag:} {!eq {$received_protocol}{spam-scanned}}} {1}{0}}"
 +
driver = accept
 +
transport = spamcheck_transport
 +
 +
# add the following lines just BEFORE the section "end transport/30_exim4-config_remote_smtp_smarthost":
 +
# 30: Spamcheck transport
 +
spamcheck_transport:
 +
debug_print = "T: spamassassin_pipe for $local_part@$domain"
 +
driver = pipe
 +
command = /usr/sbin/exim4 -oMr spam-scanned -bS
 +
use_bsmtp
 +
transport_filter = /usr/bin/spamc
 +
home_directory = "/tmp"
 +
current_directory = "/tmp"
 +
user = Debian-exim
 +
group = Debian-exim
 +
return_fail_output
 +
message_prefix =
 +
message_suffix =
 +
 +
# go to this section: "600_exim4-config_userforward" and uncomment this line like so (this may already be uncommented:
 +
userforward:
 +
debug_print = "R: userforward for $local_part@$domain"
 +
driver = redirect
 +
domains = +local_domains
 +
check_local_user
 +
file = $home/.forward
 +
require_files = $local_part:$home/.forward
 +
no_verify
 +
no_expn
 +
check_ancestor
 +
allow_filter # enusre this line isn't commented out
 +
 +
sudo /etc/init.d/exim4 restart
 +
sudo -u MAILUSER nano .forward # create this file in the home directory of the mail user
 +
# add the following lines to the fiile BUT not this line:
 +
# Exim filter
 +
if
 +
$h_X-Spam-Status: CONTAINS "Yes"
 +
or
 +
"${if def:h_X-Spam-Flag {def}{undef}}" is "def"
 +
then
 +
save $home/Maildir/.Trash/
 +
finish
 +
endif
 +
</source>
 +
=== Webmail ===
 +
=== Hotmail Whitelisting ===
 +
You will have to fill out [https://support.microsoft.com/en-us/getsupport?oaspworkflow=start_1.0.0.0&wfname=capsub&productkey=edfsmsbl3&ccsid=636439172081694532 this] to stop hotmail bouncing messages back.
 +
 +
== Mail Postfix (Unfinished) ==
 +
First of all make sure that your DENS servers are working and you have a [https://www.linode.com/docs/networking/dns/configure-your-linode-for-reverse-dns/ reverse DNS setup.]<br>
 +
Then make sure you get a SSL Cert for the domain.<br>
 +
There are two main mail servers exim and postfix - this setup shows how to use the latter.
 +
=== Install and setup mail servers: ===
 +
<source lang="bash">
 +
sudo apt-get install net-tools sendmail dovecot-imapd dovecot-lmtpd postfix postgrey postfix-policyd-spf-python # install mail dependancies
 +
sudo apt-get purge exim4 exim4-* # remove the unnecessary mail packages.
 +
sudo nano /etc/postfix/master.cf
 +
# Uncomment the following line:
 +
submission inet n      -      -      -      -      smtpd
 +
 +
sudo nano /etc/postfix/main.cf
 +
# change the 2 following lines to the relevant info:
 +
smtpd_tls_cert_file = /etc/letsencrypt/live/www.avikar.io/cert.pem
 +
smtpd_tls_key_file = /etc/letsencrypt/live/www.avikar.io/fullchain.pem
 +
 +
# comment out the following line like so:
 +
#smtpd_use_tls=yes
 +
 +
# add the following lines:
 +
smtpd_tls_security_level = may
 +
smtp_tls_security_level = may
 +
 +
sudo -i # login into root
 +
doveconf -n > /etc/dovecot/dovecot.conf.new
 +
mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
 +
mv /etc/dovecot/dovecot.conf.new /etc/dovecot/dovecot.conf
 +
nano /etc/dovecot/dovecot.conf
 +
# comment out the line like so:
 +
#ssl = no
 +
 +
# add the following block to the end:
 +
service imap-login {
 +
inet_listener imap {
 +
port = 0
 +
}
 +
inet_listener imaps {
 +
port = 993
 +
}
 +
}
 +
 +
ssl = required
 +
 +
ssl_cert = </etc/letsencrypt/live/www.avikar.io/cert.pem
 +
ssl_key = </etc/letsencrypt/live/www.avikar.io/fullchain.pem
 +
 +
cp /lib/systemd/system/dovecot.socket /etc/systemd/system/
 +
systemctl reenable dovecot.socket
 +
sed -i '/:143$/s/^/#/' /etc/systemd/system/dovecot.socket
 +
systemctl restart postfix
 +
systemctl restart dovecot
 +
netstat -lnpt # check that the ports 25, 993, and 587 are in the local column
 +
exit # exit root
 +
</source>
 +
On your local computer run:
 +
<source lang="bash">
 +
openssl s_client -starttls smtp -crlf -connect <your_mail_server>:587
 +
openssl s_client -connect <your_mail_server>:993
 +
</source>
 +
Both of these should return "Verify return code: 0 (ok)" near the end if things are good.
 +
 +
=== Authentication ===
 +
<source lang="bash">
 +
sudo nano /etc/postfix/main.cf
 +
# append this following block to the file:
 +
smtpd_sasl_auth_enable = yes
 +
smtpd_sasl_type = dovecot
 +
# The path is relative to $queue_directory:
 +
#  # postconf |grep queue_directory
 +
#  queue_directory = /var/spool/postfix
 +
smtpd_sasl_path = private/auth
 +
# Do not accept SASL authentication over unencrypted connections
 +
smtpd_tls_auth_only = yes
 +
 +
sudo nano /etc/dovecot/dovecot.conf
 +
# Append the following code:
 +
# Allows plaintext authentication only when SSL/TLS is used first.
 +
#  http://wiki2.dovecot.org/Authentication
 +
auth_mechanisms = plain login
 +
disable_plaintext_auth = yes
 +
 +
service auth-worker {
 +
# Forbid to access /etc/shadow
 +
user = $default_internal_user
 +
}
 +
 +
service auth {
 +
# IMPORTANT: Match the path to smtpd_sasl_path of Postfix
 +
unix_listener /var/spool/postfix/private/auth {
 +
group = postfix
 +
user = postfix
 +
mode = 0666
 +
}
 +
}
 +
 +
# replace the mail_location varible with this:
 +
mail_location = maildir:/var/vmail/%d/%n
 +
 +
# replace the passdb varible with this:
 +
passdb {
 +
driver = passwd-file
 +
# The entire email address will be used as the username for email client.
 +
# Don't bother about the scheme here, will be overwritten by a strong scheme from file.
 +
#    (http://wiki2.dovecot.org/AuthDatabase/PasswdFile)
 +
args = scheme=CRYPT username_format=%u /etc/dovecot/users
 +
}
 +
 +
# replace the userdb varible with this:
 +
userdb {
 +
# For static type, LDA verify the user's existence by lookup passdb
 +
#  ( http://wiki2.dovecot.org/UserDatabase/Static )
 +
driver = static
 +
args = uid=vmail gid=vmail home=/var/vmail/%d/%n
 +
}
 +
 +
sudo adduser --system --home /var/vmail --uid 550 --group --disabled-login vmail # add the user vmail
 +
doveadm pw -s SHA512-CRYPT # generate a password hash
 +
sudo -i
 +
cat << EOF >> /etc/dovecot/users
 +
user1@example.com:{SHA512-CRYPT}$6$VaEOV5mzsbP1q2H9$Ctar1HzJCZGXmlXcJDluXEFjGdEwjDKIZ80I0KhG6YD4c2X13YDX/dIb1kGPLAwo7.fTnRaQpcsN5O5O9QjaJ0
 +
EOF
 +
chmod 640 /etc/dovecot/users
 +
chown root:dovecot /etc/dovecot/users
 +
systemctl restart postfix
 +
systemctl restart dovecot
 +
ls -l /var/spool/postfix/private/auth # check to see ig a file shows
 +
exit # exit root
 +
</source>
 +
On your local machine to test:
 +
<source lang="bash">
 +
openssl s_client -connect <your_mail_server>:993
 +
</source>
 +
=== Mail Delivery ===
 +
<source lang="bash">
 +
sudo nano /etc/postfix/main.cf
 +
# add these lines at the start
 +
mydomain = MYDOMAINNAME.com
 +
myhostname = mx.$mydomain
 +
myorigin = $mydomain
 +
mydestination = localhost
 +
 +
#Handing off local delivery to Dovecot's LMTP
 +
#http://wiki2.dovecot.org/HowTo/PostfixDovecotLMTP
 +
#
 +
# The path relative to $queue_directory, that is:
 +
#    /var/spool/postfix/private/dovecot-lmtp
 +
virtual_transport = lmtp:unix:private/dovecot-lmtp
 +
 +
# Check domains only, query users and aliases in Dovecot
 +
#
 +
# IMPORTANT: Don't overlap with $mydestination
 +
#virtual_mailbox_domains = example1.com, example2.com
 +
virtual_mailbox_domains = $mydomain
 +
 +
#virtual_alias_domains = $virtual_alias_maps
 +
virtual_alias_maps = hash:/etc/postfix/virtual_aliases
 +
 +
sudo nano /etc/postfix/virtual_aliases
 +
# insert the following lines into the file: (Replacing the relevant info with yours)
 +
# The input(left column) without domain, will match user@$myorigin
 +
#  and user@$mydestination (e.g. root@example.com, root@localhost)
 +
#
 +
# The result(right column) without domain, Postfix will append
 +
#  $myorigin as $append_at_myorigin=yes
 +
# So the user user1@YOURDOMAIN.ocm must exists in /etc/dovecot/users
 +
# See: The section TABLE FORMAT in manual virtual(5)
 +
 +
postmaster          root
 +
webmaster          root
 +
 +
# Person who should get root's mail
 +
root                user1
 +
 +
info@YOURDOMAIN.com    user1
 +
 +
# A catch-all address is at the risk of spam
 +
#@YOURDOMAIN.com      user1
 +
 +
sudo postmap /etc/postfix/virtual_aliases
 +
sudo postfix reload
 +
sudo nano /etc/dovecot/dovecot.conf
 +
# append the following info:
 +
service lmtp {
 +
unix_listener /var/spool/postfix/private/dovecot-lmtp {
 +
mode = 0666
 +
user = postfix
 +
group = postfix
 +
}
 +
}
 +
 +
sudo systemctl restart postfix
 +
sudo systemctl restart dovecot
 +
sudo ls -l /var/spool/postfix/private/dovecot-lmtp
 +
sudo sendmail -bv webmaster
 +
sudo ls -l /var/vmail/appbead.com/user1/new
 
</source>
 
</source>

Latest revision as of 22:32, 25 August 2019

Linode Setup Reference:

Initial Setup

Update And Configure Timezone

apt-get update
apt-get upgrade
dpkg-reconfigure tzdata

Creating A New User

adduser saul # create the user saul
adduser saul sudo # adds saul to the sudo group
sudo usermod -a -G www-data saul # add saul to the www-data group

Setting up Authentication Keys

ssh-keygen -b 4096 # create the keyfile - do this on the client (watch you don't overwrite your existing one if you have done this before!)
ssh-copy-id saul@LINODE_IP # uploads the public key to linode

Configure SSH

sudo nano /etc/ssh/sshd_config
	# Modify these lines to look like this:
	PermitRootLogin no # this stops root from logging in
	PasswordAuthentication no # this stops anyone from logging in without authentication keys
sudo service ssh restart # reboots ssh and applies changes

Setting Up The LAMP Stack

Install And Configure Apache

sudo apt-get install apache2
sudo cp /etc/apache2/apache2.conf /etc/apache2/apache2.backup.conf # backup the configuration file before editing
sudo nano /etc/apache2/apache2.conf
	# Modify this line like so:
	KeepAlive Off # keepalive allows fast connections to those who are already connected but may hold up other clients
	# Append these lines to the end of the file:
	<IfModule mpm_prefork_module>
		StartServers 4
		MinSpareServers 20
		MaxSpareServers 40
		MaxClients 200
		MaxRequestsPerChild 4500
	</IfModule>
sudo service apache2 restart # restart apache to apply changes

Configure Virtual Hosts For Apache

sudo a2dissite *default # Disable the default Apache virtual host
cd /var/www/
sudo mkdir example.com
sudo mkdir example.com/public_html
sudo mkdir example.com/log
sudo mkdir example.com/backups
sudo nano /etc/apache2/sites-available/example.com.conf
	# domain: example.com 
	# public: /var/www/example.com/public_html/ 
	
	<VirtualHost *:80>
		# Admin email, Server Name (domain name), and any aliases
		ServerAdmin webmaster@example.com
		ServerName example.com
		ServerAlias www.example.com
		
		# Index file and Document Root (where the public files are located) 
		DirectoryIndex index.html index.php
		DocumentRoot /var/www/example.com/public_html

		# Log file locations 
		LogLevel warn
		ErrorLog /var/www/example.com/log/error.log
		CustomLog /var/www/example.com/log/access.log combined
	</VirtualHost>
sudo a2ensite example.com.conf # adds a link in the correct location to the configuration file
sudo service apache2 restart
# Rince and repeat for any other websites to host.

# Optional:
#sudo nano /etc/hosts # This is to test the virtual hosts and is done on the local computer
	# Append a line like this
	IP.ADRRESS.OF.THE.LINODE example.com

Install And Configure MySQL

sudo apt-get install mysql-server
sudo mysql_secure_installation # set a unique password, remove anonymous user accounts, disable remote root login, and remove the test database
sudo nano /etc/mysql/my.cnf # for optimising mysql
	max_allowed_packet = 1M
sudo service mysql restart

Install And Configure PHP

sudo apt-get install php7.0 php-pear php7.0-mysql # PHP may update - change php7.0 to the current version number
sudo mkdir -p /var/log/php # create the folder for error logging
sudo chown www-data /var/log/php # changes the group of the file we created with the group www-data
sudo service apache2 restart

# linux mint needs this package isntalled to get php working on apache2:
sudo apt-get install libapache2-mod-php5

# Optional install php gd - this is an add-on allows php to manipulate image files - often used by gallery plugins in Wordpress.
sudo apt-get install php7.0-gd

Nginx

Install

sudo apt-get install nginx
sudo /etc/init.d/nginx start
sudo apt-get install php7.0 php-pear php7.0-mysql php-fpm

Configure

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

# Basic configuration
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/public_html;

        index index.html index.htm index.nginx-debian.html index.php;

        server_name _;

        # This solves the permalink problem
        if (!-e $request_filename) {
                rewrite ^.*$ /index.php last;
                break;
        }

        location / {
                try_files $uri $uri/ /index.php?$args =404;
        }

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;

                fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        }

        location ~ /\.ht {
                deny all;
        }
}

sudo /etc/init.d/nginx reload
sudo nginx -s reload

Setting Up Wordpress

Creating The Database

mysql -u root -p # OR:
sudo mysql --user=root --password="ROOTPASSWORD" # Enter the MYSQL database
	create database example.com; # create the database example.com (can be anything) for wordpress
	create user 'USER' identified by 'PASSWORD'; # create a user by the name of USER with the password PASSWORD
	grant all on example.com.* to 'USER' identified by 'PASSWORD'; # grant a user by the name of USER the permissions to modify the database with the password PASSWORD
	quit; # exit mysql

Install

cd /var/www/example.com/public_html/
sudo rm index.* # move or remove any index.* files
sudo chown -R www-data:www-data /var/www/ # ensure that the files are owned by the webserver
sudo wget http://wordpress.org/latest.tar.gz # download the latest wordpress
sudo -u www-data tar -xvf latest.tar.gz # extract it
sudo mv latest.tar.gz ../backups/wordpress-`date "+%Y-%m-%d"`.tar.gz # archive the compressed folder OR just delete it
sudo mv wordpress/* ./ # move the files out of the wordpress folder so the site will use them
sudo rm -R wordpress # delete the old wordpress folder

#Go to your domain and follow the instructions for the rest of the installation

See Also

Permalink 404 Error Fix

sudo nano /var/www/example.com/public_html/.htaccess # Create an empty file here and make sure permissions are correct - wordpress should automatically do this if permissions are fine.
sudo nano /etc/apache2/sites-available/example.com.conf
	# Append these lines:
	<Directory /var/www/>
		Options +ExecCGI
		Options Indexes FollowSymLinks MultiViews
		AllowOverride All
		Order allow,deny
		allow from all
	</Directory>
	<Directory /var/www/example.com/public_html/>
		Options Indexes FollowSymLinks MultiViews
		AllowOverride All
		Order allow,deny
		allow from all
	</Directory>

Email

Not Working

php -a # boot php
	mail ('YOUR@EMAIL', "Test Postfix", "Test mail from postfix"); # send test Email
	# Possible error: sh: 1: /usr/sbin/sendmail: not found
	exit # exit php
sudo apt-get install sendmail

Slow

Email sending can be real slow if hostnames are not set up correctly, to fix this edit this file:

sudo nano /etc/hosts

Edit the (first?) line that says:

127.0.0.1    localhost

Change to:

127.0.0.1    localhost localhost.localdomain

Then reload sendmail by running:

sudo sendmailconfig # Answer yes to all questions

Encryption

To enable encryption on sendmail run

sudo nano /etc/mail/sendmail.mc

And add this line to the end:

include(`/etc/mail/tls/starttls.m4')dnl

Then reload sendmail by running:

sudo sendmailconfig # Answer yes to all questions

Not Sending To Own Domain

If your mail server is a different one from your web server and you try to send mail to your own domain your system may try to handle it internally.
If you test php sendmail and it does this you will see an output like:

/home/user/dead.letter... Saved message in /home/user/dead.letter

To fix simply edit this file:

sudo nano /etc/mail/sendmail.mc

and Inject the following lines:

define(`MAIL_HUB', `example.com.')dnl
define(`LOCAL_RELAY', `example.com.')dnl

Immediately before these lines (near the end)

MAILER(local)
MAILER(smtp)

Then run:

sudo sendmailconfig # Answer yes to all questions

Servers Rejecting Mail

Some servers will reject mail without this defined in /etc/mail/sendmail.mc

define(`confDOMAIN_NAME', `example.com')dnl

Multisite

Setting up muilti-sites Unique domains

Edit the wp-config.php file and add the following lines just above the /* That’s all, stop editing! Happy blogging. */ line:

/* Multisite */
define( 'WP_ALLOW_MULTISITE', true );

Then deactivate all plugins.
Then go to Tools » Network Setup and follow the instructions.

Setting Up SSL

Installing Certbot For Let's Encrypt On Apache

sudo nano /etc/apt/sources.list
	# append to file to enable backports
	deb http://ftp.debian.org/debian stretch-backports main
sudo apt-get update # to update the backports
sudo apt-get install python-certbot-apache -t stretch-backports
sudo certbot --authenticator webroot --installer apache

Auto Renew The Certificate

sudo certbot renew --dry-run # test SSL autorenewal
cd /etc/cron.daily
sudo cp dpkg certbot
sudo nano certbot # remove the contents and replace with
	#!/bin/sh
	certbot renew --renew-hook "service restart apache2"
sudo run-parts -v /etc/cron.daily # test daily crons

See Also

Installing Certbot For Let's Encrypt On Node.js

Certbot creates files and folders in the root directory for testing, this means node has to be able to get domain.com/SOMEFILENAME so the root dir has to be set up as a directory.
A repository for a good file to achieve this can be found Here.
If you are using express you may want to add something like this:

app.use('/.well-known', express.static(path.join(__dirname, "/../.well-known/")));

Make sure the node server is running while you run the cert!

sudo nano /etc/apt/sources.list
	# append to file to enable backports
	deb http://ftp.debian.org/debian stretch-backports main
sudo apt-get update # to update the backports
sudo apt-get install certbot -t stretch-backports
sudo certbot certonly --webroot -w /var/www/avikar.io -d www.avikar.io -d avikar.io

Auto-renew is pretty much the same but without the hook.

See Also

Wildcard Certs (Unfinished)

This does not work on Debian 9 (Yet)

sudo certbot certonly --manual -d *.YOUR_DOMAIN_NAME --agree-tos --no-bootstrap --manual-public-ip-logging-ok --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory

See also.

Setting Up Git

Github

# Make a repository on github

Local

sudo apt-get install git
git clone github.link.git # download the repository OR use the alternative at the bottom to create a new repository
git add . # add all files for committing
git commit -am "COMMIT MESSAGE" # commit the changes locally
git push origin master # push changes to the server

# Alternative to git clone:
mkdir repositoryFolder
git init # creates a repository

Server

sudo apt-get install git
cd /to/the/folder/you/would/like/to/have/your/repository # maybe change to wordpress's theme directory?
git clone github.link.git
sudo nano /somelocation/under/your/domain/fileName.php # Create the file with the contents below:
<?php
	if( array_key_exists( 'HTTP_X_HUB_SIGNATURE', $_SERVER ) ) {
		$sig = $_SERVER['HTTP_X_HUB_SIGNATURE'];
		$body = file_get_contents( 'php://input' );
		$hmac = hash_hmac( 'sha1', $body, 'SECRET' );
		if( $sig === "sha1=$hmac" ) {
			$repo = json_decode( $body )->repository->name;
			exec( "cd /PATH/TO/LOCAL/CLONES/$repo && sudo git pull --no-edit" );
		}
	}
?>
sudo visudo # might not be needed?
	# Add this to the end of the file
	# Give www-data permissions to run git pull
	www-data ALL=(ALL) NOPASSWD : /usr/bin/git pull --no-edit
# Check the log under the site folder for php errors

Github

# On github add a webhook under settings, type: json, make sure secret (use a good password) aligns with the script (from on the server), and paste a link to the script url (from on the server)

Setting Up Node.js

Node.js

curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
sudo apt-get install nodejs
sudo apt-get install build-essential # install the optional add-ons

Express

sudo npm install -g express-generator # install express
express PROJECT_NAME # create an express project called PROJECT_NAME 
cd PROJECT_NAME
npm i # install dependancies

Vue Router

sudo npm install --global vue # install vue globally THIS MIGHT ACTUALLY BE vue-cli
sudo vue init webpack-simple APPNAME # create a new project using the "webpack-simple" template
# Make sure to say yes to vue-router or enter the project directory and install it via "npm i vue-router"
cd APPNAME
npm i # install dependencies

Feathers.js

npm install @feathersjs/cli -g # install feathers globally
mkdir server && cd server
feathers generate app # generate the feathers app

Mail Exim

For a in-depth guide on this please see this
Ensure that you have a reverse DNS setup.

Install And Setup Exim

sudo apt-get install exim4-daemon-heavy dovecot-common dovecot-imapd spamassassin spamc spf-tools-perl # install required packages
dpkg-reconfigure exim4-config
	# no splitting configuration files
	# internet
	# Maildir
	# set your domain and anything else that is obvious
	# everything else default

sudo nano /etc/mailname
	# ensure this is your domain name

hostname -b command YOU_DOMAIN_NAME # set your domain as hostname for mail
sudo /etc/init.d/exim4 restart

If you require multiple domain set up on the one server please refer to this
To test if you have setup this correctly run these commands:

sudo -v 'user@domain'
	SOME MESSAGE
	(Control D)

cd ~/Maildir/new
ls
	# Check that a file(s) exists -if not check ~/Maildir/cur or another user account.
nano SOMEFILE
	# you should see test mail you sent yourself.

Install And Setup SMTP

SMTP Certificates

Lets Encrypt

To setup exim for an existing lets encrypt cert:

certbot certonly --standalone -d smtp.DOMAIN.com -d imap.DOMAIN.com -d mail.DOMIAN.com
sudo nano /etc/exim4/exim4.conf.template
	# add these lines to the top of the "main/03_exim4-config_tlsoptions" section
	MAIN_TLS_CERTIFICATE = /etc/letsencrypt/live/YOUDOMAIN/fullchain.pem
	MAIN_TLS_PRIVATEKEY = /etc/letsencrypt/live/YOURDOMAIN/privkey.pem

	# add these lines to the top of the file.
	MAIN_TLS_ENABLE = true
	daemon_smtp_ports = 25 : 2525

sudo /etc/init.d/exim4 restart

The permissions on the following files need read and execute for everyone or the certs cannot be read by exim:

  • /etc
  • /etc/letsencrypt
  • /etc/letsencrypt/live
  • /etc/letsencrypt/live/YOUCERTFOLDER
  • /etc/letsencrypt/archive
  • /etc/letsencrypt/archive/YOURCERTFOLDER
Self Signed

For SSL setup with exim cert (preferable to do it with letsencrypt rather than selfsigned)

sudo /usr/share/doc/exim4-base/examples/exim-gencert # gen a cert
sudo nano /etc/exim4/exim4.conf.template
	# add these lines to the beginning of the file:
	MAIN_TLS_ENABLE = true
	daemon_smtp_ports = 25 : 2525

sudo /etc/init.d/exim4 restart

Accounts

Accounts will be authenticated with the default linux accounts.

sudo chgrp Debian-exim /etc/shadow # change the group for access
sudo chmod g+r /etc/shadow # and the permissions
sudo nano /etc/exim4/exim4.conf.template
	# find the plain_server section and configure like this:
	plain_server:
		driver = plaintext
		public_name = PLAIN
		server_condition = "${if crypteq{$auth3}{${extract{1}{:}{${lookup{$auth2}lsearch{/etc/shadow}{$value}}}}}{1}{0}}"
		server_set_id = $auth2
		server_prompts = :

sudo /etc/init.d/exim4 restart
Testing

To test if its working run on the client:

telnet smtp.avikar.io 2525

If this doesn't work check that you have a wildcard (*) record on your DNS.
If it still doesn't work check that the port is open on the server by running:

netstat -nlp

If a result like below is returned the port isn't opened:

tcp        0      0 127.0.0.1:2525          0.0.0.0:*               LISTEN

To open it run:

sudo cp /etc/exim4/update-exim4.conf.conf /etc/exim4/update-ex
im4.conf.conf.backup # backup before changing
sudo nano /etc/exim4/update-exim4.conf.conf 
	# make this file looks like this:
	dc_eximconfig_configtype='internet'
	dc_other_hostnames=''
	dc_local_interfaces=''
	dc_readhost=''
	dc_relay_domains=''
	dc_minimaldns='false'
	dc_relay_nets=''
	dc_smarthost=''
	CFILEMODE='644'
	dc_use_split_config='false'
	dc_hide_mailname=''
	dc_mailname_in_oh='true'
	dc_localdelivery='maildir_home'

sudo /etc/init.d/exim4 restart

netstat -nlp # test again

You should see a result like this if the port is opened:

tcp        0      0 0.0.0.0:2525            0.0.0.0:*               LISTEN

And this should now work:

telnet smtp.avikar.io 2525

Copy Mail To The Sent Folder

See this as to why.

sudo nano /etc/exim4/exim4.conf.template
	# Add these lines under the other settings at the top:
	system_filter = /var/www/tools/exim-copy-to-sent
	system_filter_directory_transport = copy_to_sent
	system_filter_pipe_transport = copy_to_sent_pipe

	# Insert this after the "end transport/30_exim4-config_mail_spool" header:
	copy_to_sent:
		driver = appendfile
		delivery_date_add
		envelope_to_add
		return_path_add
		group = Debian-exim
		user = ${if match {${local_part:${lookup{$sender_address_local_part@$sender_address_domain}lsearch*@{/etc/exim4/virtual.users}}}}{(.+)}{$1}{Debian-exim}}
		mode = 0660
		maildir_format
		directory = /home/${local_part:${lookup{$sender_address_local_part@$sender_address_domain}lsearch*@{/etc/exim4/virtual.users}}}/Maildir/.Sent/
		create_directory

	copy_to_sent_pipe:
		driver = pipe
		user = Debian-exim
		group = Debian-exim

sudo nano /var/www/tools/exim-copy-to-sent
	# Add this content:
	if
		$sender_address_local_part is not "root"
	and 
		"${if def:h_X-Spam-Status {def}{undef}}" is "undef"
	and
		"${if match {${lookup{$sender_address}lsearch{/etc/exim4/virtual.users}}}{@localhost}{yes}{}}" is "yes"
	then
		unseen save $home/Maildir/.Sent/
		unseen pipe "/var/www/tools/copy-to-sent.pl \"$recipients\""
	endif

DoveCot IMAP Server

sudo mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.backup
sudo nano /etc/dovecot/dovecot.conf
	# Create the file with these contents:
	log_path = /var/log/dovecot.log

	protocols = imap

	service imap-login {
		inet_listener imap {
			address = localhost
		}
	}

	mail_location = maildir:~/Maildir
	maildir_very_dirty_syncs = yes

	userdb {
		driver = passwd
	}

	passdb {
		driver = pam
	}

	ssl = required
	ssl_prefer_server_ciphers = yes
	ssl_cipher_list = EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4
	ssl_protocols = !SSLv3 # SSLv2 has been removed from OpenSSL so is not even a valid name to disable
	ssl_cert = </etc/letsencrypt/live/imap.avikar.io/fullchain.pem
	ssl_key = </etc/letsencrypt/live/imap.avikar.io/privkey.pem

Spam Assassin

sudo nano /etc/default/spamassassin
	# change the values like so:
	ENABLED=1
	CRON=1

sudo service spamassassin start # start spam assassin
sudo nano /etc/exim4/exim4.conf.template 
	# go to the "end router/800_exim4-config_maildrop" section and insert the following lines:
	# 850: Spamcheck router
	spamcheck_router:
		no_verify
		check_local_user
		condition = "${if and { {!def:h_X-Spam-Flag:} {!eq {$received_protocol}{spam-scanned}}} {1}{0}}"
		driver = accept
		transport = spamcheck_transport

	# add the following lines just BEFORE the section "end transport/30_exim4-config_remote_smtp_smarthost":
	# 30: Spamcheck transport
	spamcheck_transport:
		debug_print = "T: spamassassin_pipe for $local_part@$domain"
		driver = pipe
		command = /usr/sbin/exim4 -oMr spam-scanned -bS
		use_bsmtp
		transport_filter = /usr/bin/spamc
		home_directory = "/tmp"
		current_directory = "/tmp"
		user = Debian-exim
		group = Debian-exim
		return_fail_output
		message_prefix =
		message_suffix =

	# go to this section: "600_exim4-config_userforward" and uncomment this line like so (this may already be uncommented:
	userforward:
		debug_print = "R: userforward for $local_part@$domain"
		driver = redirect
		domains = +local_domains
		check_local_user
		file = $home/.forward
		require_files = $local_part:$home/.forward
		no_verify
		no_expn
		check_ancestor
		allow_filter # enusre this line isn't commented out

sudo /etc/init.d/exim4 restart
sudo -u MAILUSER nano .forward # create this file in the home directory of the mail user
	# add the following lines to the fiile BUT not this line:
	# Exim filter
	if
		$h_X-Spam-Status: CONTAINS "Yes"
		or
		"${if def:h_X-Spam-Flag {def}{undef}}" is "def"
	then
		save $home/Maildir/.Trash/
		finish
	endif

Webmail

Hotmail Whitelisting

You will have to fill out this to stop hotmail bouncing messages back.

Mail Postfix (Unfinished)

First of all make sure that your DENS servers are working and you have a reverse DNS setup.
Then make sure you get a SSL Cert for the domain.
There are two main mail servers exim and postfix - this setup shows how to use the latter.

Install and setup mail servers:

sudo apt-get install net-tools sendmail dovecot-imapd dovecot-lmtpd postfix postgrey postfix-policyd-spf-python # install mail dependancies
sudo apt-get purge exim4 exim4-* # remove the unnecessary mail packages.
sudo nano /etc/postfix/master.cf
	# Uncomment the following line:
	submission inet n       -       -       -       -       smtpd

sudo nano /etc/postfix/main.cf
	# change the 2 following lines to the relevant info:
	smtpd_tls_cert_file = /etc/letsencrypt/live/www.avikar.io/cert.pem
	smtpd_tls_key_file = /etc/letsencrypt/live/www.avikar.io/fullchain.pem

	# comment out the following line like so:
	#smtpd_use_tls=yes

	# add the following lines:
	smtpd_tls_security_level = may
	smtp_tls_security_level = may

sudo -i # login into root
doveconf -n > /etc/dovecot/dovecot.conf.new
mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot.conf.orig
mv /etc/dovecot/dovecot.conf.new /etc/dovecot/dovecot.conf
nano /etc/dovecot/dovecot.conf
	# comment out the line like so:
	#ssl = no
	
	# add the following block to the end:
	service imap-login {
		inet_listener imap {
			port = 0
		}
		inet_listener imaps {
			port = 993
		}
	}

	ssl = required

	ssl_cert = </etc/letsencrypt/live/www.avikar.io/cert.pem
	ssl_key = </etc/letsencrypt/live/www.avikar.io/fullchain.pem

cp /lib/systemd/system/dovecot.socket /etc/systemd/system/
systemctl reenable dovecot.socket
sed -i '/:143$/s/^/#/' /etc/systemd/system/dovecot.socket
systemctl restart postfix
systemctl restart dovecot
netstat -lnpt # check that the ports 25, 993, and 587 are in the local column
exit # exit root

On your local computer run:

openssl s_client -starttls smtp -crlf -connect <your_mail_server>:587
openssl s_client -connect <your_mail_server>:993

Both of these should return "Verify return code: 0 (ok)" near the end if things are good.

Authentication

sudo nano /etc/postfix/main.cf
	# append this following block to the file:
	smtpd_sasl_auth_enable = yes
	smtpd_sasl_type = dovecot
	# The path is relative to $queue_directory:
	#   # postconf |grep queue_directory
	#   queue_directory = /var/spool/postfix
	smtpd_sasl_path = private/auth
	# Do not accept SASL authentication over unencrypted connections
	smtpd_tls_auth_only = yes

sudo nano /etc/dovecot/dovecot.conf
	# Append the following code:
	# Allows plaintext authentication only when SSL/TLS is used first.
	#   http://wiki2.dovecot.org/Authentication
	auth_mechanisms = plain login
	disable_plaintext_auth = yes
	
	service auth-worker {
		# Forbid to access /etc/shadow
		user = $default_internal_user
	}

	service auth {
		# IMPORTANT: Match the path to smtpd_sasl_path of Postfix
		unix_listener /var/spool/postfix/private/auth {
			group = postfix
			user = postfix
			mode = 0666
		}
	}

	# replace the mail_location varible with this:
	mail_location = maildir:/var/vmail/%d/%n

	# replace the passdb varible with this:
	passdb {
		driver = passwd-file
		# The entire email address will be used as the username for email client.
		# Don't bother about the scheme here, will be overwritten by a strong scheme from file.
		#    (http://wiki2.dovecot.org/AuthDatabase/PasswdFile)
	args = scheme=CRYPT username_format=%u /etc/dovecot/users
	}

	# replace the userdb varible with this:
	userdb {
		# For static type, LDA verify the user's existence by lookup passdb
		#   ( http://wiki2.dovecot.org/UserDatabase/Static )
		driver = static
		args = uid=vmail gid=vmail home=/var/vmail/%d/%n
	}

sudo adduser --system --home /var/vmail --uid 550 --group --disabled-login vmail # add the user vmail
doveadm pw -s SHA512-CRYPT # generate a password hash
sudo -i
cat << EOF >> /etc/dovecot/users
	user1@example.com:{SHA512-CRYPT}$6$VaEOV5mzsbP1q2H9$Ctar1HzJCZGXmlXcJDluXEFjGdEwjDKIZ80I0KhG6YD4c2X13YDX/dIb1kGPLAwo7.fTnRaQpcsN5O5O9QjaJ0
	EOF
chmod 640 /etc/dovecot/users
chown root:dovecot /etc/dovecot/users
systemctl restart postfix
systemctl restart dovecot
ls -l /var/spool/postfix/private/auth # check to see ig a file shows
exit # exit root

On your local machine to test:

openssl s_client -connect <your_mail_server>:993

Mail Delivery

sudo nano /etc/postfix/main.cf
	# add these lines at the start
	mydomain = MYDOMAINNAME.com 
	myhostname = mx.$mydomain
	myorigin = $mydomain
	mydestination = localhost

	#Handing off local delivery to Dovecot's LMTP
	#http://wiki2.dovecot.org/HowTo/PostfixDovecotLMTP
	#
	# The path relative to $queue_directory, that is:
	#    /var/spool/postfix/private/dovecot-lmtp
	virtual_transport = lmtp:unix:private/dovecot-lmtp

	# Check domains only, query users and aliases in Dovecot
	#
	# IMPORTANT: Don't overlap with $mydestination
	#virtual_mailbox_domains = example1.com, example2.com
	virtual_mailbox_domains = $mydomain

	#virtual_alias_domains = $virtual_alias_maps
	virtual_alias_maps = hash:/etc/postfix/virtual_aliases

sudo nano /etc/postfix/virtual_aliases
	# insert the following lines into the file: (Replacing the relevant info with yours)
	# The input(left column) without domain, will match user@$myorigin
	#   and user@$mydestination (e.g. root@example.com, root@localhost)
	#
	# The result(right column) without domain, Postfix will append
	#   $myorigin as $append_at_myorigin=yes
	# So the user user1@YOURDOMAIN.ocm must exists in /etc/dovecot/users
	# See: The section TABLE FORMAT in manual virtual(5)

	postmaster          root
	webmaster           root

	# Person who should get root's mail
	root                user1

	info@YOURDOMAIN.com    user1

	# A catch-all address is at the risk of spam
	#@YOURDOMAIN.com       user1

sudo postmap /etc/postfix/virtual_aliases
sudo postfix reload
sudo nano /etc/dovecot/dovecot.conf
	# append the following info:
	service lmtp {
		unix_listener /var/spool/postfix/private/dovecot-lmtp {
			mode = 0666
			user = postfix
			group = postfix
		}
	}

sudo systemctl restart postfix
sudo systemctl restart dovecot
sudo ls -l /var/spool/postfix/private/dovecot-lmtp
sudo sendmail -bv webmaster
sudo ls -l /var/vmail/appbead.com/user1/new