You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

14 KiB

Optimized configuration for Ubuntu server with EasyEngine

Server Stack

  • Ubuntu 16.04/18.04 LTS
  • Nginx 1.15.x / 1.14.x
  • PHP-FPM 7.x
  • MariaDB 10.3
  • REDIS 5.0
  • Memcached
  • Fail2ban
  • Netdata
  • UFW

Ubuntu-Nginx-web-server is now available (in beta) as bash script to automate Optimized EasyEngine Setup. Checkout EE-NGINX-SETUP


Configuration files with comments available by following the link source

Initial configuration

System update and packages cleanup

apt-get update && apt-get upgrade -y && apt-get autoremove --purge -y && apt-get clean

Install useful packages

sudo apt-get install haveged curl git unzip zip fail2ban htop nload nmon ntp gnupg gnupg2 wget pigz tree ccze mycli -y

Clone the repository

git clone https://github.com/VirtuBox/ubuntu-nginx-web-server.git $HOME/ubuntu-nginx-web-server

Tweak Kernel & Increase open files limits

source sysctl.conf - limits.conf source

cp $HOME/ubuntu-nginx-web-server/etc/sysctl.d/60-ubuntu-nginx-web-server.conf /etc/sysctl.d/60-ubuntu-nginx-web-server.conf

Ubuntu 16.04 LTS do not support the new tcp congestion control algorithm bbr, we will use htcp instead.

# On ubuntu 18.04 LTS
modprobe tcp_bbr
echo -e '\nnet.ipv4.tcp_congestion_control = bbr\nnet.ipv4.tcp_notsent_lowat = 16384' >> /etc/sysctl.d/60-ubuntu-nginx-web-server.conf

# On ubuntu 16.04 LTS
modprobe tcp_htcp
echo 'net.ipv4.tcp_congestion_control = htcp' >> /etc/sysctl.d/60-ubuntu-nginx-web-server.conf

Then to apply the configuration :

sysctl -e -p /etc/sysctl.d/60-ubuntu-nginx-web-server.conf

Increase openfiles limits

sudo bash -c 'echo -e "*         hard    nofile      500000\n*         soft    nofile      500000\nroot      hard    nofile      500000\nroot      soft    nofile      500000\n"  >> /etc/security/limits.conf'

disable transparent hugepage for redis

echo never > /sys/kernel/mm/transparent_hugepage/enabled

EasyEngine Setup

Install MariaDB 10.3

Instructions available in VirtuBox Knowledgebase

bash <(wget -qO - https://downloads.mariadb.com/MariaDB/mariadb_repo_setup) --mariadb-server-version=10.3 --skip-maxscale -y
sudo apt update && sudo apt install mariadb-server -y

Secure MariaDB after install by running the command :

mysql_secure_installation

MySQL Tuning

You can download my example of my.cnf, optimized for VPS with 4GB RAM. my.cnf source

cp -f $HOME/ubuntu-nginx-web-server/etc/mysql/my.cnf /etc/mysql/my.cnf

It include modification of innodb_log_file_size variable, so you need to use the following commands to apply the new configuration :

sudo service mysql stop

sudo mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bak
sudo mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile1.bak

sudo service mysql start

Increase MariaDB open files limits

echo -e '[Service]\nLimitNOFILE=500000' > /etc/systemd/system/mariadb.service.d/limits.conf

sudo systemctl daemon-reload
sudo systemctl restart mariadb

Install EasyEngine

# noninteractive install - you can replace $USER with your username & root@$HOSTNAME by your email
sudo bash -c 'echo -e "[user]\n\tname = $USER\n\temail = root@$HOSTNAME" > $HOME/.gitconfig'

wget -qO ee rt.cx/ee && bash ee

enable ee bash_completion

source /etc/bash_completion.d/ee_auto.rc

Install Nginx, php5.6, php7.0, postfix, redis and configure EE backend

ee stack install
ee stack install --php7 --redis --admin --phpredisadmin

Set your email instead of root@localhost

echo 'root: my.email@address.com' >> /etc/aliases
newaliases

Install Composer - Fix phpmyadmin install issue

cd ~/ ||exit
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/bin/composer

chown www-data:www-data /var/www
sudo -u www-data -H composer update -d /var/www/22222/htdocs/db/pma/

Allow shell for www-data for SFTP usage

usermod -s /bin/bash www-data

PHP 7.1 - 7.2 - 7.3 Setup

Install php7.1-fpm

# php7.1-fpm
apt update && apt install php7.1-fpm php7.1-cli php7.1-zip php7.1-opcache php7.1-mysql php7.1-mcrypt php7.1-mbstring php7.1-json php7.1-intl \
php7.1-gd php7.1-curl php7.1-bz2 php7.1-xml php7.1-tidy php7.1-soap php7.1-bcmath -y php7.1-xsl

# copy php-fpm pools & php.ini configuration
cp -rf $HOME/ubuntu-nginx-web-server/etc/php/7.1/fpm/* /etc/php/7.1/fpm/
service php7.1-fpm restart

git -C /etc/php/ add /etc/php/ && git -C /etc/php/ commit -m "add php7.1 configuration"

Install php7.2-fpm

# php7.2-fpm
apt update && apt install php7.2-fpm php7.2-xml php7.2-bz2 php7.2-zip php7.2-mysql php7.2-intl php7.2-gd php7.2-curl php7.2-soap php7.2-mbstring php7.2-bcmath -y

# copy php-fpm pools & php.ini configuration
cp -rf $HOME/ubuntu-nginx-web-server/etc/php/7.2/fpm/* /etc/php/7.2/fpm/
service php7.2-fpm restart

git -C /etc/php/ add /etc/php/ && git -C /etc/php/ commit -m "add php7.2 configuration"

Install php7.3-fpm

# php7.3-fpm
apt update && apt install php7.3-fpm php7.3-xml php7.3-bz2 php7.3-zip php7.3-mysql php7.3-intl php7.3-gd php7.3-curl php7.3-soap php7.3-mbstring php7.3-bcmath -y

# copy php-fpm pools & php.ini configuration
cp -rf $HOME/ubuntu-nginx-web-server/etc/php/7.3/fpm/* /etc/php/7.3/fpm/
service php7.3-fpm restart

git -C /etc/php/ add /etc/php/ && git -C /etc/php/ commit -m "add php7.3 configuration"

Set the proper alternative for /usr/bin/php

If you want to choose which version of php to use with the command php, you can use the command update-alternatives

# php5.6
sudo update-alternatives --install /usr/bin/php php /usr/bin/php5.6 80

# php7.0
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.0 80

# php7.1
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.1 80

# php7.2
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.2 80

# php7.3
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.3 80

Then you can check php version with command php -v

NGINX Configuration

Additional Nginx configuration (/etc/nginx/conf.d)

  • New upstreams (php7.1, php7.2, php7.3 netdata and php socket) : upstream.conf
  • webp image mapping : webp.conf
  • new fastcgi_cache_bypass mapping for wordpress : map-wp-fastcgi-cache.conf
  • stub_status configuration on 127.0.0.1:80 : stub_status.conf
  • restore visitor real IP under Cloudflare : cloudflare.conf
# copy all common nginx configurations
cp -rf $HOME/ubuntu-nginx-web-server/etc/nginx/conf.d/* /etc/nginx/conf.d/

# commit change with git
git -C /etc/nginx/ add /etc/nginx/ && git -C /etc/nginx/ commit -m "update conf.d configurations"

EE common configuration

  • mitigate WordPress DoS attack (wpcommon-phpX.conf)
  • webp image conditional rewrite (wpcommon-phpX.conf)
  • additional directives to prevent hack (locations-phpX.conf)
cp -rf $HOME/ubuntu-nginx-web-server/etc/nginx/common/* /etc/nginx/common/

# commit change with git
git -C /etc/nginx/ add /etc/nginx/ && git -C /etc/nginx/ commit -m "update common configurations"

Compile last Nginx mainline release with nginx-ee script

bash <(wget -O - https://raw.githubusercontent.com/VirtuBox/nginx-ee/master/nginx-build.sh)

Custom configurations

clean php-fpm php.ini configuration

# PHP 7.0
cp -rf $HOME/ubuntu-nginx-web-server/etc/php/7.0/* /etc/php/7.0/
service php7.0-fpm restart

git -C /etc/php/ add /etc/php/ && git -C /etc/php/ commit -m "add php7.2 configuration"

Nginx optimized configurations

# TLSv1.2 TLSv1.3 only
cp -f $HOME/ubuntu-nginx-web-server/etc/nginx/nginx.conf /etc/nginx/nginx.conf

# TLS intermediate - TLS v1.0 v1.1 v1.2 v1.3
cp -f $HOME/ubuntu-nginx-web-server/etc/nginx/nginx.conf /etc/nginx/nginx-intermediate.conf

# TLSv1.2 only
cp -f $HOME/ubuntu-nginx-web-server/etc/nginx/nginx.conf /etc/nginx/nginx-tlsv12.conf

# commit change with git
git -C /etc/nginx/ add /etc/nginx/ && git -C /etc/nginx/ commit -m "update nginx.conf configurations"

Nginx configuration for netdata

# add nginx reverse-proxy for netdata on https://yourserver.hostname:22222/netdata/
cp -f $HOME/ubuntu-nginx-web-server/etc/nginx/sites-available/22222 /etc/nginx/sites-available/22222

# commit change with git
git -C /etc/nginx/ add /etc/nginx/ && git -C /etc/nginx/ commit -m "update 22222 configuration"

Increase Nginx open files limits

sudo mkdir -p /etc/systemd/system/nginx.service.d
echo -e '[Service]\nLimitNOFILE=500000' > /etc/systemd/system/nginx.service.d/limits.conf

sudo systemctl daemon-reload
sudo systemctl restart nginx.service

Security

Harden SSH Security

WARNING : SSH Configuration with root login allowed using SSH keys only source

cp -f $HOME/ubuntu-nginx-web-server/etc/ssh/sshd_config /etc/ssh/sshd_config

UFW

Instructions available in VirtuBox Knowledgebase

# enable ufw log - allow outgoing - deny incoming
ufw logging low
ufw default allow outgoing
ufw default deny incoming

# allow incoming traffic on SSH port
CURRENT_SSH_PORT=$(grep "Port" /etc/ssh/sshd_config | awk -F " " '{print $2}')
ufw allow $CURRENT_SSH_PORT

# DNS - HTTP/S - FTP - NTP - RSYNC - DHCP - EE Backend
ufw allow 53
ufw allow http
ufw allow https
ufw allow 21
ufw allow 123
ufw allow 68
ufw allow 546
ufw allow 873
ufw allow 22222


# enable UFW
echo "y" | ufw enable

Custom jails for fail2ban

  • wordpress bruteforce
  • ssh
  • recidive (after 3 bans)
  • backend http auth
  • nginx bad bots
cp -rf $HOME/ubuntu-nginx-web-server/etc/fail2ban/filter.d/* /etc/fail2ban/filter.d/
cp -rf $HOME/ubuntu-nginx-web-server/etc/fail2ban/jail.d/* /etc/fail2ban/jail.d/

fail2ban-client reload

Secure Memcached server

echo '-U 0' >> /etc/memcached.conf
sudo systemctl restart memcached

If you do not use memcached, you can safely stop and disable it :

sudo systemctl stop memcached
sudo systemctl disable memcached.service

Optional

proftpd

Install proftpd

apt-get install proftpd -y

secure proftpd and enable passive ports

sed -i 's/# DefaultRoot/DefaultRoot/' /etc/proftpd/proftpd.conf
sed -i 's/# RequireValidShell/RequireValidShell/' /etc/proftpd/proftpd.conf
sed -i 's/# PassivePorts                  49152 65534/PassivePorts                  49000 50000/' /etc/proftpd/proftpd.conf

restart proftpd

sudo service proftpd restart

Allow FTP ports with UFW

# ftp active port
sudo ufw allow 21

# ftp passive ports
sudo ufw allow 49000:50000/tcp

Enable fail2ban proftpd jail

echo -e '\n[proftpd]\nenabled = true\n' >> /etc/fail2ban/jail.d/custom.conf

fail2ban-client reload

Adding users

# create user without shell access in group www-data
adduser --home /var/www/yourdomain.tld/ --shell /bin/false --ingroup www-data youruser

# allow group read/write on website folder
chmod -R g+rw /var/www/yourdomain.tld

ee-acme-sh

Github repository - Script to setup letsencrypt certificates using acme.sh on EasyEngine servers

  • subdomain support
  • ivp6 support
  • wildcards certificates support
wget-qO install-ee-acme.sh https://raw.githubusercontent.com/VirtuBox/ee-acme-sh/master/install.sh
chmod +x install-ee-acme.sh
./install-ee-acme.sh

# enable acme.sh & ee-acme-sh
source .bashrc

netdata

Github repository


bash <(curl -Ss https://my-netdata.io/kickstart.sh) all

# save 40-60% of netdata memory
echo 1 >/sys/kernel/mm/ksm/run
echo 1000 >/sys/kernel/mm/ksm/sleep_millisecs

# increase open files limits for netdata
sudo mkdir -p /etc/systemd/system/netdata.service.d
echo -e '[Service]\nLimitNOFILE=500000' > /etc/systemd/system/netdata.service.d/limits.conf

sudo systemctl daemon-reload
sudo systemctl restart netdata.service

# disable email notifications
sudo sed -i 's/SEND_EMAIL="YES"/SEND_EMAIL="NO"/' /usr/lib/netdata/conf.d/health_alarm_notify.conf
service netdata restart

cht.sh (cheat)

Github repository

curl https://cht.sh/:cht.sh > /usr/bin/cht.sh
chmod +x /usr/bin/cht.sh


echo "alias cheat='cht.sh'" >> $HOME/.bashrc
source $HOME/.bashrc

usage : cheat <command>

root@vps:~ cheat cat
# cat

# Print and concatenate files.

# Print the contents of a file to the standard output:
  cat file

# Concatenate several files into the target file:
  cat file1 file2 > target_file

# Append several files into the target file:
  cat file1 file2 >> target_file

# Number all output lines:
  cat -n file

nanorc - Improved Nano Syntax Highlighting Files

Github repository

wget https://raw.githubusercontent.com/scopatz/nanorc/master/install.sh -qO- | sh

Add WP-CLI & bash-completion for user www-data

# download wp-cli bash_completion
wget -qO /etc/bash_completion.d/wp-completion.bash https://raw.githubusercontent.com/wp-cli/wp-cli/master/utils/wp-completion.bash

# change /var/www owner
chown www-data:www-data /var/www

# download .profile & .bashrc for www-data
cp -f $HOME/ubuntu-nginx-web-server/var/www/.profile /var/www/.profile
cp -f $HOME/ubuntu-nginx-web-server/var/www/.bashrc /var/www/.bashrc

# set owner
chown www-data:www-data /var/www/{.profile,.bashrc}

Custom Nginx error pages

Github Repository

Installation

# clone the github repository
sudo -u www-data -H git clone https://github.com/alexphelps/server-error-pages.git /var/www/error

Then include this configuration in your nginx vhost by adding the following line

include common/error_pages.conf;

Published & maintained by VirtuBox