Showing posts with label LNMP. Show all posts
Showing posts with label LNMP. Show all posts

24 January, 2016

How to secure your phpMyAdmin site with NGINX

Secure your phpMyAdmin

The phpMyAdmin instance installed on our server should be completely usable at this point. However, by installing a web interface, we have exposed our MySQL system to the outside world.
Even with the included authentication screen, this is quite a problem. Because of phpMyAdmin's popularity combined with the large amount of data it provides access to, installations like these are common targets for attackers.
We will implement two simple strategies to lessen the chances of our installation being targeted and compromised. We will change the location of the interface from /phpmyadmin to something else to sidestep some of the automated bot brute-force attempts. We will also create an additional, web server-level authentication gateway that must be passed before even getting to the phpMyAdmin login screen.

Changing the Application's Access Location

In order for our Nginx web server to find and serve our phpMyAdmin files, we created a symbolic link from the phpMyAdmin directory to our document root in an earlier step.
To change the URL where our phpMyAdmin interface can be accessed, we simply need to rename the symbolic link. Move into the Nginx document root directory to get a better idea of what we are doing:
$ cd /usr/share/nginx/html
$ ls -l
total 8
-rw-r--r-- 1 root root 537 Mar  4 06:46 50x.html
-rw-r--r-- 1 root root 612 Mar  4 06:46 index.html
lrwxrwxrwx 1 root root  21 Aug  6 10:50 phpmyadmin -> /usr/share/phpmyadmin


As you can see, we have a symbolic link called phpmyadmin in this directory. We can change this link name to whatever we would like. This will change the location where phpMyAdmin can be accessed from a browser, which can help obscure the access point from hard-coded bots.
Choose a name that does not indicate the purpose of the location. In this guide, we will name our access location /nothingtosee. To accomplish this, we will just rename the link:

$ sudo mv phpmyadmin nothingtosee
$ ls -l
total 8
-rw-r--r-- 1 root root 537 Mar  4 06:46 50x.html
-rw-r--r-- 1 root root 612 Mar  4 06:46 index.html
lrwxrwxrwx 1 root root  21 Aug  6 10:50 nothingtosee -> /usr/share/phpmyadmin


Now, if you go to the previous location of your phpMyAdmin installation, you will get a 404 error:


http://server_domain_or_IP/phpmyadmin



phpMyAdmin 404 error




However, your phpMyAdmin interface will be available at the new location we selected:

http://server_domain_or_IP/nothingtosee


phpMyAdmin login screen



Setting up a Web Server Authentication Gate

The next feature we wanted for our installation was an authentication prompt that a user would be required to pass before ever seeing the phpMyAdmin login screen.
Fortunately, most web servers, including Nginx, provide this capability natively. We will just need to modify our Nginx configuration file with the details.
Before we do this, we will create a password file that will store our the authentication credentials. Nginx requires that passwords be encrypted using the crypt() function. The OpenSSL suite, which should already be installed on your server, includes this functionality.
To create an encrypted password, type:

$ openssl passwd


You will be prompted to enter and confirm the password that you wish to use. The utility will then display an encrypted version of the password that will look something like this:

O5az.RSPzd.HE


Copy this value, as you will need to paste it into the authentication file we will be creating.
Now, create an authentication file. We will call this file pma_pass and place it in the Nginx configuration directory:

$ sudo nano /etc/nginx/pma_pass


Within this file, you simply need to specify the username you would like to use, followed by a colon (:), followed by the encrypted version of your password you received from the openssl passwd utility.

We are going to name our user demo, but you should choose a different username. The file for this guide looks like this:

demo:O5az.RSPzd.HE

Save and close the file when you are finished.
Now, we are ready to modify our Nginx configuration file. Open this file in your text editor to get started:

$ sudo nano /etc/nginx/sites-available/default

Within this file, we need to add a new location section. This will target the location we chose for our phpMyAdmin interface (we selected /nothingtosee in this guide).
Create this section within the server block, but outside of any other blocks. We will put our new location block below the location / block in our example:

server {
    . . .

    location / {
        try_files $uri $uri/ =404;
    }

    location /nothingtosee {
    }

    . . .
}

Within this block, we need to set the value of a directive called auth_basic to an authentication message that our prompt will display to users. We do not want to indicate to unauthenticated users what we are protecting, so do not give specific details. We will just use "Admin Login" in our example.

We then need to use a directive called auth_basic_user_file to point our web server to the authentication file that we created. Nginx will prompt the user for authentication details and check that the inputted values match what it finds in the specified file.
After we are finished, the file should look like this:

server {
    . . .

    location / {
        try_files $uri $uri/ =404;
    }

    location /nothingtosee {
        auth_basic "Admin Login";
        auth_basic_user_file /etc/nginx/pma_pass;
    }

    . . .
}

Save and close the file when you are finished.
To implement our new authentication gate, we must restart the web server:

$ sudo service nginx restart

Now, if we visit our phpMyAdmin location in our web browser (you may have to clear your cache or use a different browser session if you have already been using phpMyAdmin), you should be prompted for the username and password you added to the pma_pass file:

http://server_domain_or_IP/nothingtosee

Nginx authentication page


Once you enter your credentials, you will be taken to the normal phpMyAdmin login page. This added layer of protection will help keep your MySQL logs clean of authentication attempts in addition to the added security benefit.

Conclusion


You can now manage your MySQL databases from a reasonably secure web interface. This UI exposes most of the functionality that is available from the MySQL command prompt. You can view databases and schema, execute queries, and create new data sets and structures.

23 January, 2016

Easy WebServer setup NGINX, PHP-FPM, MariaDB on Debian 8

WEB-SERVER on Debian 8 easy setup

Debian, MariaDB SQL set up guide

This guide will show you how to correctly install and configure an "alternative" LAMP stack on Debian 8 utilizing NGINX, PHP Fast Process Manager, and MariaDB.

NGINX

NGINX is a "reverse proxy first, web server second". It is a popular and growing alternative to Apache, offering greater flexibility and better performance in many instances. In this tutorial, we will be using it as our web server.
Fire up your favorite SSH client and login to your server. For Windows users, "PuTTY" is a free and lightweight SSH client. Linux and Mac users can use the terminal included by default with their operating system. For this tutorial, we will assume that you are logged in to your server as the "root" user.

For starters, let's just make sure everything is up to date. Type the following to check for and then install updates.

$apt-get update && apt-get upgrade

We'll be editing our configuration files in vim. Vim is not installed by default, so let's install it!

$ apt-get install vim

Now it's time to install NGINX. We'll want to install the latest version of NGINX from the official NGINX Debian repository.

$ wget http://nginx.org/keys/nginx_signing.key
$ apt-key add nginx_signing.key
$ echo 'deb http://nginx.org/packages/debian/ jessie nginx' >> /etc/apt/sources.list
$ echo 'deb-src http://nginx.org/packages/debian/ jessie nginx' >> /etc/apt/sources.list
$ apt-get update && apt-get install nginx

Now we need to tweak the NGINX configuration some. Navigate to the configuration directory.

$ cd /etc/nginx

A quick vim lesson
Use the arrow keys to navigate the text document. To begin making edits, press the "insert" button on your keyboard. If your keyboard doesn't have an insert button, then press the "i" key. Towards the bottom of vim you'll notice it now says "INSERT". Insert mode will let you delete via backspace or insert new characters by typing them.

Let's open up our nginx.conf and poke around:

$ vi nginx.conf

Let's change the default user, check the number of worker processes, and turn off the access log.
The directives "user" and "worker_processes" are near the top. Try the values below:
Note that you'll want to set "worker_processes" to the number of CPU cores available on your server. In this example, we have 1, which is the NGINX default.

/user www-data;
/worker_processes 1;

We'll also want to disable the access log, for sake of improving I/O performance. Navigate downwards with the arrow keys until you find "access_log". Modify it to the following:

/access_log off;

And lastly, we'll set the "client_max_body_size" to correspond with some changes made to PHP later on. Let's save the trouble and do it now. Add just below "access_log":

client_max_body_size 12m;

When you've finished up editing, press "Esc" on your keyboard. Vim will no longer say "INSERT" towards the bottom of the file.

To save our changes and quit vim, press the following key sequence:
SHIFT :(colon)
wq
Press "Enter"
The above vim kung fu will write your changes to disk and exit vim, dropping you back into the bash shell.

Now, we need to make a site-specific configuration for our example! We'll also delete the other example configurations. Try the following:

$ cd conf.d
$ rm example_ssl.conf default.conf
$ vi my_site.conf

We'll make a short and simple default.conf based loosely on the default NGINX configuration, but with a few tweaks. Press insert and you can copy/paste the below example.
Don't forget to edit the "root" directive to point to the root directory of your website, and "server_name" to correspond to your domain.

server {
    listen 80;

    root /path/to/your/website;
    index index.php index.html index.htm;

    server_name mydomainname.com www.mydomainname.com;

    location / {
            try_files $uri $uri/ /index.php;
    }

    location ~ \.php$ {
            try_files $uri =404;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
    }
}


Now we're done with the NGINX configuration section of this tutorial. We'll restart NGINX in a little bit, right after we install PHP.


PHP-FPM

PHP-FPM is the PHP Fast Process Manager. It's required when using NGINX, because unlike Apache, NGINX doesn't run PHP as a module. This was done to reduce NGINX's memory footprint. Remember that part about NGINX being a reverse proxy first and foremost? Here's where that comes into play; PHP requests sent to NGINX are fed to PHP-FPM to do the heavy lifting.

Let's install PHP-FPM.

$ apt-get install php5-fpm php5-mysqlnd

Note that depending on what your PHP scripts require, you may have to install other PHP modules not included by default. Popular ones are php5-gd and php5-mcrypt. You can install these with the following command.

$ apt-get install php5-module_name_here

Now that we've got PHP-FPM installed, we'll want to make a few quick edits to enhance security and functionality.

$ cd /etc/php5/fpm
$ vi php.ini

Time for another quick vim lesson! The php.ini file is absolutely huge. Looking for a few key values will take all day. So since we know what we're looking for, we'll search. Type the following:

/upload_max_filesize

This, by default, is set to 2 megabytes. If you want to allow users to upload files to your PHP applications greater than 2 megabytes, you will need to change this. 10M is probably a safe bet for now, but higher values are also acceptable. This setting will vary among configurations. For sake of tutorial:

/upload_max_filesize = 10M

One more glaring security flaw. Scroll down a little further or search. We need to turn "allow_url_fopen" to "Off". This will prevent PHP from running PHP files hosted REMOTELY, otherwise known as RFI (Remote File Inclusion). Many servers are hacked this way.

/allow_url_fopen = Off

And because we changed "upload_max_filesize", we now have to change "post_max_size". This value should be a little bigger than "upload_max_filesize", because we have to take into account the overhead associated with our requests processed by PHP.

Let's search one more time with "/post_max_size".

/post_max_size = 12M

Note that you'll have to go back to your NGINX configuration and edit "client_max_body_size" if you decide to go with larger values than these examples for your PHP file sizes.
That's about it for now. Make sure you aren't in edit mode by pressing "Esc". Save and exit vim.
SHIFT :(colon)
wq
Press 'Enter'
PHP-FPM setup is complete.


MariaDB (SQL)

Even in a world continuously moving towards NoSQL or MongoDB, some of us still find it easier to just stick with MySQL. This is especially true for many web applications. Fortunately, there now exist a number of "drop-in" replacements for Oracle MySQL. Debian 8 now includes the ever popular MariaDB. MariaDB is a fork of Oracle MySQL based on version 5.5. MariaDB, for all intents and purposes, calls this MariaDB 10. It is considered a FULL replacement for Oracle MySQL. Think of it as MySQL at heart, sans the Oracle branding, and some new features.

$ apt-get install mariadb-server

IMPORTANT: You absolutely, positively, need to pick a strong root password for MariaDB. Save it somewhere secure. You'll need to enter it twice during the MariaDB installation.

Let's tweak the MariaDB configuration slightly. We're going to disable MariaDB listening via the network interface. Instead, as with PHP-FPM earlier, we'll stick only to a UNIX socket. Most PHP applications should support connecting to the database server via a UNIX socket instead of the local loopback interface.

$ cd /etc/mysql
$ vi my.cnf

Look for "bind-address = 127.0.0.1". Comment that line out. Above or below it add "skip-networking".

/ #bind-address = 127.0.0.1
/skip-networking

We're done with MariaDB! Eventually, you may want to tweak your MariaDB configuration depending on if you'll be using primarily the MyISAM or InnoDB storage engines, but also for the number of CPU cores and RAM available to your server. The defaults will get us up and running in the mean time.

Let's restart each of the services for which configuration files were modified in this tutorial.

$ systemctl restart nginx.service
$ systemctl restart php5-fpm.service
$ systemctl restart mysql.service


Install phpMyAdmin

if you wanna install phpMyAdmin use this command:

$ sudo apt-get install phpmyadmin

when the phpMyAdmin installation has been completed,
Create a symbolic link between phpMyAdmin and the website root directory.
Here will be website root document directory /usr/share/nginx/html/.

$ sudo ln -s /usr/share/phpmyadmin/ /usr/share/nginx/html

Restart nginx server again
with command:

$ sudo service nginx restart

Now manage your databases from phpMyAdmin web interface.

That's it - we're all done. At this point, you have a fully functional LNMP ( LEMP ) server online!

This guide was to serve as a general rule of thumb for getting started with with the above services with minimal tweaking. For further information, read the documentation for the above packages. While this example setup should work well right "out of the box", adjustments can, and most likely will need to be made to better suit your needs.