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.

15 KiB

Optimized configuration for Ubuntu server with WordOps

Server Stack

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



As EasyEngine v3 will no longer receive any updates, configurations available in this repository are going to be updated for WordOps (EEv3 fork).

All previous configurations are still available in the branch easyengine-v3.

We are already working on a bash script wo-nginx-setup to handle the migration from EEv3 to WordOps with all custom configurations of this repository. We will update the README with all informations about the migration as soon as the script is ready.

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 $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 'tcp_bbr' >> /etc/modules-load.d/bbr.conf
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_bbr && echo 'tcp_htcp' >> /etc/modules-load.d/htcp.conf
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 - --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 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

Setup cronjob to optimize your MySQL databases and repair them if needed

Open the crontab editor

sudo crontab -e

Then add the following cronjob

@weekly /usr/bin/mysqlcheck -Aos --auto-repair > /dev/null 2>&1

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 && 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:' >> /etc/aliases

Install Composer - Fix phpmyadmin install issue

cd ~/ ||exit
curl -sS | 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/
cp -rf $HOME/ubuntu-nginx-web-server/etc/php/7.1/cli/* /etc/php/7.1/cli/
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/
cp -rf $HOME/ubuntu-nginx-web-server/etc/php/7.2/cli/* /etc/php/7.2/cli/
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/
cp -rf $HOME/ubuntu-nginx-web-server/etc/php/7.3/cli/* /etc/php/7.3/cli/
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 via unix socket) : upstream.conf
  • webp image mapping : webp.conf
  • new fastcgi_cache_bypass mapping for wordpress : map-wp-fastcgi-cache.conf
  • stub_status configuration on : 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 - || curl -sL

Custom configurations

Nginx optimized configurations

# TLSv1.2 TLSv1.3 only (recommended)
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


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


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}')

# 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 it and disable it :

sudo systemctl stop memcached
sudo systemctl disable memcached.service



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 FTP 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


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

  • subdomain support
  • ivp6 support
  • wildcards certificates support
chmod +x

# enable & ee-acme-sh
source .bashrc


Github repository

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

# install netdata
bash <(curl -Ss all --dont-wait

# 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 (cheat)

Github repository

curl > /usr/bin/
chmod +x /usr/bin/

echo "alias cheat=''" >> $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 -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

# 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/.* /var/www/

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

Custom Nginx error pages

Github Repository


# clone the github repository
sudo -u www-data -H git clone /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