Installing LEMP on Ubuntu 18.04 LTS

Just got a new box setup which needs a LEMP-stack. So here we go: install the packages for nginx, php, mariaDB:

$ sudo apt install nginx mariadb-server php-fpm php-mysql

Configure nginx

In /etc/nginx/nginx.conf replace SSL Settings part:

##
# SSL Settings
##

ssl_protocols TLSv1.2 TLSv1.3; 
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 180m;
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH;
ssl_dhparam /etc/nginx/cert/dhparam.pem;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=31536000" always;

And my custom Logging Settings:

##
# Logging Settings
##

log_format combined_ssl '$time_local $status $host:$server_port $remote_user@$remote_addr $ssl_protocol/$ssl_cipher "$request" $body_bytes_sent ref:$http_referer "$http_user_agent"';
access_log /var/log/nginx/access.log combined_ssl;
error_log /var/log/nginx/error.log;

And redirect everybody to https:

##
# Redirect everybody to https
##

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}

Lastly let’s generate some Diffie Hellman parameters, disable the default site and restart nginx:

$ sudo openssl dhparam -out /etc/nginx/cert/dhparam.pem 4096
$ sudo rm /etc/nginx/sites-enabled/default
$ sudo service nginx restart

You should now have a working nginx installation that redirects all traffic to https, but you’ll need to configure at least one virtual host with working SSL certificates to get something to display in your browser.

MariaDB Hardening

$ sudo mysql_secure_installation

You should be using sudo to connect to mariaDB with root, which will cause a problem when you want to be able to connect thru phpMyAdmin. You can fix this by changing the authentication plugin for root to mysql_native_password:

$ sudo mysql -u root -p
MariaDB [(none)]> use mysql;
MariaDB [mysql]> update user set plugin='mysql_native_password' where user='root';
MariaDB [mysql]> flush privileges;

PHP

In /etc/php/7.2/fpm/php.ini set your timezone:

date.timezone = Europe/Amsterdam

phpMyAdmin

I tried installing the phpMyAdmin package via apt but never got that working, so I just download the source and use that. In the directory /var/www/ download the latest ENGLISH only version of phpMyAdmin from their website at https://www.phpmyadmin.net/downloads/

$ wget https://files.phpmyadmin.net/phpMyAdmin/4.9.0.1/phpMyAdmin-4.9.0.1-english.tar.gz
$ tar -xvzf phpMyAdmin-4.9.0.1-english.tar.gz
$ cp config.sample.inc.php config.inc.php

Let’s configure phpMyAdmin by editting config.inc.php:

Add a blowfish secret and play around with ‘host’; when connecting to a unix-socket, use localhost, when connecting using TCP/IP use 127.0.0.1.

You can give any of your virtual hosts access to phpMyAdmin by creating a symlink in it’s websroot to /var/www/phpMyAdmin-4.9.0.1-english/. I also limit access to it in the nginx configuration of that vhost:

location /phpmyadmin {
	allow 10.1.0.0/16;	# example
	deny all;
}

When you are able to login as root phpMyAdmin will give some pointers to improve your installation, like adding a tmp directory, adding missing php-modules, etc.

Hardening Ubuntu 18.04 LTS

Just got a new box setup and delivered to me by the company’s IT department. They setup a user-account with sudo privileges and included my public ssh-key. But in case you only have a root account you should create a user-account with sudo privileges yourself:

$ adduser username
$ usermod -aG sudo username

And from your local machine upload your public key:

$ ssh-copy-id -i .ssh/id_rsa user@hostname

So let’s start hardening. First let’s set a new password:

$ passwd

After that I needed to set another hostname, since the one I got from IT was not what I asked for:

$ sudo nano hostname
$ sudo nano hosts
$ sudo reboot 

ssh & sshd

In /etc/ssh/sshd_config set:

PermitRootLogin no 
PasswordAuthentication no 

In /etc/ssh/ssh_config set:

HashKnownHosts yes

firewall

Use a firewall to block all unwanted traffic to your machine. Only open up the ports you want publicly available and limit access to your ssh-port to known IP’s only.

$ sudo ufw allow from 10.2.0.0/16
$ sudo ufw allow http 
$ sudo ufw allow https
$ sudo ufw enable
$ sudo ufw status numbered

unattended updates

Make sure the package is installed and running:

$ sudo apt install unattended-upgrades
$ sudo service unattended-upgrades status

Edit /etc/apt/apt.conf.d/50unattended-upgrades to do only security updates on production machines. Only out-comment the following lines:

"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
"${distro_id}ESM:${distro_codename}";

Security updates may need dependencies from non-security origins. EMS, or extended security maintenance is for releases that have reached end of life, like 14.04 LTS.

Further you can play with settings like:

Unattended-Upgrade::Mail "your@email.com";
Unattended-Upgrade::MailOnlyOnError "false";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";

Doing automatic-reboots at night are at your own risk, I don’t do that on production machines, but really think it is perfectly fine on private, personal and development boxes. And I have never had anything go wrong with them, ever…

Add/edit /etc/apt/apt.conf.d/20auto-upgrades:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";

The unattended upgrades are initiated by your daily crontab, in my case this runs at 06:25 by default, which I think is a little late to also do a reboot, so I changed the time my daily crontab runs by editing /etc/crontab:


# m h dom mon dow user	command
17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly
0  3	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

Test

$ sudo unattended-upgrades --dry-run --debug

Checkrestart

Another great way to see whether you need to reboot a machine or are just fine with reload/restarting services is the checkrestart command. It is not on the machine by default so you install it yourself:

$ sudo apt install debian-goodies

I added it to my .bash_profile so everytime I log into the machine I get to see which processes still use old versions of upgraded files.

echo 'Type password for checkrestart report'
sudo checkrestart

More stuff…

This list is of course incomplete and could be updated and expended over time… Things like fail2ban or appArmor might be added….

But for now let’s install that LEMP stack!

First post!

Hi there! This is my first blogpost in my new WordPress install.

$ cat /etc/motd
OpenBSD 6.5 (GENERIC) #1: Mon May 27 17:37:06 CEST 2019

Welcome to the AODW.NL network, this is host:

                    $$\                           
                    $$ |                          
 $$$$$$$\ $$\   $$\ $$$$$$$\   $$$$$$\   $$$$$$\  
$$  _____|$$ |  $$ |$$  __$$\ $$  __$$\ $$  __$$\ 
$$ /      $$ |  $$ |$$ |  $$ |$$$$$$$$ |$$ |  \__|
$$ |      $$ |  $$ |$$ |  $$ |$$   ____|$$ |      
\$$$$$$$\ \$$$$$$$ |$$$$$$$  |\$$$$$$$\ $$ |      
 \_______| \____$$ |\_______/  \_______|\__|      
          $$\   $$ |                              
          \$$$$$$  |                              
           \______/                               

source: http://www.patorjk.com/software/taag/#p=display&h=1&f=Big%20Money-nw&t=cyber