Table of Contents
A LEMP stack refers to (L)inux, (E)Nginx, (M)ySQL, and (P)HP.
The following document is based on this DigitalOcean tutorial with minor and major improvements and further explanation for Ubuntu 18.04.
A NOTE ABOUT FIREWALLS⌗
Ubuntu ships with
ufw disabled by default. I recommend enabling it:
First, we allow the standard
$ ufw allow 22/tcp
Then we enable
$ sudo ufw enable
At this point,
ufw will only allow access to your system via the
SSH port and nothing else. You should allow access for
NGINX to be able to receive web connections.
Needless to say, if you have some other application firewall or a hardware one you will have to do it yourself.
Certbot requires an open
HTTP port to be able to renew and issue your certificates, so allow port
$ sudo ufw allow 80/tcp
Since we are going to do a LEMP stack, we also assume we will set-up
HTTPS later, and so you should configure your firewall to allow
HTTPS access to your server:
$ sudo ufw allow 443/tcp
I recommend opening the least number of ports you need for the outside world.
To install nginx execute:
$ sudo apt install nginx
You should now be able to reach your domain (or public IP) and see NGINX’s welcome page in
MySQL is a database to store site or app data. It is vital in most situations. I.E: WordPress.
$ sudo apt install mysql-server
Once installed, we should execute the mysql_secure_installation command to edit security configurations within our MySQL installation.
In here you can:
- Set a password for ROOT accounts.
- Remove root accounts that are accessible from outside the localhost.
- Remove anonymous user accounts
- Remove the test database
Execute it with:
$ sudo mysql_secure_installation
The first thing which we will be asked is if we want to enable the
VALIDATE PASSWORD plugin, it is safer to allow this and make sure to use strong passwords otherwise MySQL WILL REJECT WEAK PASSWORDS AND CAUSE PROBLEMS
The script will then ask what kind of requirements we want.
0 is ANY 8-character long passwords. 1 is ANY 8-character long passwords containing numbers, mixed case, and special characters. 2 is ANY 8-character long passwords containing numbers, mixed case, special characters, and dictionary words.
I recommend going with 1 because 2 is overkill and might cause problems later on.
Enter your root password when asked. Please avoid special characters like
After you’ve set the root password, you will be asked to confirm a set of options:
- Remove anonymous users; this will remove and deny the creation of anonymous users from the database, allowing only valid users to log in to the database.
Confirm this setting.
- Disallow remote login; this asks you if you will be making use of remote login on the root account, which is everything except login from
The most secure option for this is to disable it so we will reply with
Y.. Unless you need to login remotely.
- Remove and disable test database; this is not needed, so we will remove it.
The last question is if we want to reload the privilege tables, which will ensure that all of these settings we just changed will be loaded, so we will answer with
auth_socket or native password⌗
By default, MySQL will be installed and configured to let the root user access via the auth_socket plugin which authenticates a client from localhost using the Unix socket file
SO_PEERCRED as explained here
When getsockopt is invoked with the SO_PEERCRED option, it accepts the struct ucred structure as a further parameter (cr). This structure has three elements: PID, uid, and gid. After calling getsockopt with a pointer to this structure, these fields will contain the process, user and group ids of the party on the other end of the socket connection.
And so will let the plugin know which user invoked an authentication command.
For example, this is what happens when you invoke login using
sudo mysql so
auth_socket will know that
root invoked the command and will automatically log you inside the root user. While useful in several ways, such as scalability, utility, and security, it might generate errors for applications that try to automatically login inside the root account (phpMyAdmin).
Not that I recommend using the root account for everything, this is avoidable by giving each application its own user and password.
Since phpMyAdmin will not be able to use
root credentials, it won’t be able to use this login schema, and every attempt will fail.
You have two possible solutions:
- You disable
auth_socketand enable login via password for the
- You create a specific phpMyAdmin account with any required privilege with a strong password for phpMyAdmin to use.
It depends on your workflow, but in this guide, I will disable
auth_socket from root inside MySQL, and in doing so, we will lose access to the database using
Disabling auth_socket in favour of mysql_native_password⌗
Log in using
sudo mysql and your LINUX root password.
Inside execute this query:
SELECT user,authentication_string,plugin,host FROM mysql.user;
This query will tell you what user is using which authentication method.
We can change how
root will behave using the ALTER command as such:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
password should be changed to a secure password of your choosing.
And finally, execute
FLUSH PRIVILEGES; which will reload grant tables and apply changes.
From now on, you will only be able to access the root user of MySQL using the regular
mysql -u root -p command.
The last part of a LEMP stack is PHP-FPM.
PHP-FPM is a module we can use with NGINX, and it stands for “fastCGI process manager.”
CGI scripts are a way to run a webserver when HTTP requests come, which are usually very slow.
So FastCGI is a much faster version of these processors, obviously in terms of PHP, PHP-FPM is then the “FastCGI” implementation of PHP, which can run with NGINX to handle PHP dynamic content generation much faster.
It is a deamon that can handle an incredible amount of PHP requests, even under heavy loads.
Installing it is fairly easy:
sudo apt install php-fpm php-mysql
php-mysql is the backend helper handler of connections with your mysql database.
You might need to enable Ubuntu’s
sudo add-apt-repository universe.If you aren’t able to execute the command, then you need to install
software-properties-commonand then do a
sudo apt updateand try again.
NGINX will have no idea php-fpm is installed until you properly configure it for PHP requests inside your server/location blocks.
Thank you for reading.
Want to support me?⌗
Find all information right here
You can also support me here:
- My mom