LEMP Stack (Linux, Nginx, MySQL, PHP) and PHPMyAdmin under Centos7

Nginx is also sometimes poetically called as the “unsinkable Webserver”. Thanks to the thread pool it can serve many concurrent TCP connections (even very slow ones from smartphones) using minimal system resources.
Nginx performs better than Apache web server under high load but Apache is better in security and compatibility, there are more WAF’s (Web Application Firewall) available for Apache. It is a good Idea to use nginx as reverse proxy with apache backend in order to combine both advantages. This will be handle in a separate howto.
The individual steps were tested using CentOS 7.4 with SELINUX=enforcing.

1. Preparation

a) Firewall: IPv4 and IPv6 is enabled by default in Centos 7.4, it is always a good idea to verify that your server is well protected.
For the CentOS template we have prepared in /root two shell scripts for You. Please revise our scripts according to your requirements or use a firewall software of your choice. Check your firewall using the commands:

 # IPV4 - firewall check
iptables -n -L -v
# IPV6 - firewall check
ip6tables -n -L -v 

b) System update:

 yum update 

3) Apache: Since CentOS 7.4 apache is not installed by default. If it is running nginx can not bind to port 80 in order to provide web service. You can uninstall Apache, with:

 # Apache Deinstallieren
yum remove httpd 

Or Apache is reconfigured to a different port, so nginx can later on offer its services on port 80. Edit the file /etc/httpd/conf/httpd.conf and change the line with “listen” into this:

 # SELinux: by default http can be bound to 80, 443, 8008, 9000, ...
# Using semange you can list ports for protocol http or make new one available for web server
listen 8008; 

Restart apache:

 service httpd restart 

2. MySQL Server

It’s cool that Centos has the Maria DB in Repos. This server is a drop-in replacement and in many points faster than the MySQL server. The installation is very easy with:

yum install mariadb-server mariadb
systemctl enable mariadb
systemctl start mariadb

Secure your SQL instance. The DB root password is not set, enter a blank password and set a new SQL root password. All other questions can be answered with “Yes”.

 /usr/bin/mysql_secure_installation 

3. NGINX

Option 1: In order to install PHPMyadmin in a later step we need the EPEL repository.

yum install epel-release
yum install nginx
systemctl enable nginx
service nginx restart

Option 2:Downloadthe yum configuration file with the PGP public-key. You get a warning that this rpm is not signed. The signature of nginx packages are checked during the installation.

 wget nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
rpm -i nginx-release-centos-7-0.el7.ngx.noarch.rpm 

Option 3: Edit the new file /etc/yum.repos.d/nginx.repo with the following content like it is described on the nginx homepage (the signature of the nginx packages are not checked during installation):

 [nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1 

Then install nginx with:

 yum install nginx 

Now port 80 is not occupied anymore and we can start the nginx server now:

 service nginx restart 

Test: With ifconfig You can display the address of your server. Check the URL http://meine-ip-adressse/ (or make sure that your DNS settings are correct and use http://www.meine-domain.de/ instead of an IP-address) and You will be greeted with the following message:

 Welcome to nginx! 

Configure ngninx for the cooperation with php5-fpm:
Edit the default server block in /etc/nginx/nginx.conf as followed, then restart nginx.

server {
	listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /var/www/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

	error_page 404 /404.html;
            location = /40x.html {
        }

	error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
	location ~ .php$ {
                try_files $uri =404;
                fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }
    }

Nginx needs to be restarted:

service nginx restart

4. PHP

For php5-fpm only a few packages have to be specified, the rest is controlled by dependencies:

yum install php php-mysql php-fpm

Konfiguration: cgi.fix_pathinfo is set by default to 1. This may lead to a security breach. For help, see the comments in the configuration file php.ini. Edit the file /etc/php.ini and look for the line with cgi.fix_pathinfo and change it as follows:

cgi.fix_pathinfo=0

php5-fpm should already run with the fast Unix Socket. Change the listen statement in /etc/php-fpm.d/www.conf like this:

; listen = 127.0.0.1:9000
listen = /var/run/php-fpm/php-fpm.sock

Enable php5-fpm to auto start at boot and start it now:

systemctl enable php-fpm.service
systemctl start php-fpm

PHP-Info Page
Edit a new file:nano /var/www/html/info.php with the following content:

< ?php phpinfo(); ?> // Please delete space before ?php

Test: Browse your URL http://my-ip-or-hostname/info.php. The output of info.php should look like this (the PHP version depends on the point of time at installation):

5. PHPMyAdmin

It’s just nice to be able to manage your database server with a graphical user interface. Below phpMyAdmin is installed so that You only can access it on localhost and your database is protected from attacks from the Internet. For an occasional access to your database, building a SSH tunnel is much more convenient than fiddling with SQL commands.
The main advantage of using SSH tunnel is that it can be setup quickly and provides less target for hackers than any web application (secure passwords assumed).
First, we perform the installation with a standard configuration for apache2 so PHPMyAdmin can create the necessary MySQL tables.

yum install epel-release
yum install phpmyadmin

Now create /etc/nginx/conf.d/phpmyadmin.conf in order to provide PHPMyadmin using nginx. We used localhost:9000 to hide it from the internet.

server {
    listen       localhost:9000;
    server_name  localhost;

    index  index.html index.htm index.php;
    root   /usr/share/phpMyAdmin;
    location / {
           try_files $uri $uri/ =404;
    }


    location ~ .php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+.php)(/.+)$;
                fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
    }
}

To access we need the SSH tunnel:

# Create a new user used to establisch a ssh tunnel
useradd -m test
passwd test

# Under Windows you can use putty to create ssh tunnel

# SSH-Tunnel (replace www.meine-domain.tld with your hostname or IP-address)
# The following command should be run on your local machine (also where your
# favorite browser is running)
ssh -fCN test@my-ip-or-hostname  -L 9000:localhost:9000

Restart the services and test

service nginx restart
service php-fpm restart

Browse http://localhost:9000/ in order to access PHPMyadmin.
Mysql root password can be set using /usr/bin/mysql_secure_installation .