People usually use PAM(Pluggable Authentication Module) on Nginx for Basic Authentication using the OS account. While it is very straightforward, it is very not safe practice in terms of security practice if you use the same user & password for the application and the OS.
People can visit your site again and again until they can break the password. And What if they can break the password? They can log in freely to your OS. Of course, you didn’t want this to happen.
There is a better way of using PAM Authentication on Nginx. It is by using MySQL database for managing the user account instead of using OS account.
Let’s see how we can do it.
Check Prerequisite
Before we start, let’s check the prerequisite first to make sure you can follow this tutorial
- Nginx installed, if you don’t have the Nginx yet, you can install it using 
apt install nginx, or you can Install Nginx from Source if you want. - Mysql installed, if you don’t have MySQL yet, you can install it using 
apt install mysql-server - Sudo Privilege, make sure you execute 
sudo sufirst to make sure we have no permission issue on the installation & configuration. 
Install Nginx PAM Dependencies
We need to install some dependencies to make Nginx able to use PAM module.
apt install nginx-extras libpam-mysql
Add Configuration on NGINX
Open your virtual host config file on the Nginx folder
nano /etc/nginx/sites-available/my-site
Add auth_pam and auth_pam_service_name configuration on your server block or location block level to using pam authentication on Nginx. For example, if I want to use it at location block level:
. . .
location /secure {
    auth_pam "Restricted Zone";
    auth_pam_service_name "secure-nginx";
    . . .
}
location /user {
    . . .
}
. . .
This configuration will secure the /secure location block, but not the other. If a request comes to the /secure location block, Nginx will read secure-nginx service on the PAM folder to perform a basic authentication first before serving the request.
Add Configuraion on PAM
Create a file on /etc/pam.d/ that match auth_pam_service_name directive on the Nginx configuration file. In my case, it is secure-nginx.
nano /etc/pam.d/secure-nginx
Add this config to the file:
auth required pam_mysql.so user=your_db_user passwd=your_db_pass host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=password crypt=3 account sufficient pam_mysql.so user=your_db_user passwd=your_db_pass host=127.0.0.1 db=mail table=users usercolumn=email passwdcolumn=password crypt=3
Change the highlighted text to suit your MySQL setup:
useris the MySQL usernamepasswdis the MySQL passwordhostis the ip address of the MySQL Serverdbis the database nametableis the table name that contains the user and passwordusercolumnis the column name that contains the userpasswdcolumnis the column name that contains the user’s passwordcryptis the encryption method used on the password. the3is usingmd5encryption. It is the most recommended one. I suggest you still use this value.
Restart NGINX
After the configuration is done, you can restart the Nginx.
service nginx restart
That’s it! Now you can create MySQL authentication on Nginx using PAM, a better way to use PAM authentication.