Home > Applications & Tools > Nginx with PAM Authentication

Nginx with PAM Authentication

January 7th, 2014 Leave a comment Go to comments

As I introduced in last article, Nginx is a lightweight Web and reversed proxy server that is gaining momentum. If you have URLs to be accessed only by authenticated users, you can have many options. In this article, I just introduce a very easy way for the Nginx to leverage the PAM (Pluggable Authentication Module) for user authentication. We will use OS user for authentication (there are many more methods supported by PAM). If you have a valid user with the Linux on which Nginx runs, your request will pass through; otherwise, it would be blocked.

Better than authenticating in Web applications, using Nginx allows multiple Web applications to share same set of user credentials. In some sense, you can think of this as single sign on (SSO).

Lost VMs or Containers? Too Many Consoles? Too Slow GUI? Time to learn how to "Google" and manage your VMware and clouds in a fast and secure HTML5 App.

Before moving forward, make sure you have nginx-extras installed on your system. The command is listed in last article.

Open Access to Nginx User

Because we will use the OS user name and password for user authentication, we need to open the access of the related password file to the user that runs Nginx server which is www-data. One simple Linux command can achieve it as follows:

# usermod -a -G shadow www-data

Change configurations

Within the /etc/pam.d create a new file called nginx. You can change the file name as long as you reference the new name in later configuration file.

# more /etc/pam.d/nginx
@include common-auth

Then, we need to modify the Nginx configuration file: /etc/nginx/nginx.conf

http
{
    server
    {
        listen          443;
        ssl             on;
 
        ### SSL log files ###
        access_log      /var/log/nginx/ssl-access.log;
        error_log       /var/log/nginx/ssl-error.log;
 
        ### SSL cert files ###
        ssl_certificate      ssl/server.crt;
        ssl_certificate_key  ssl/server.key;
 
        ### Add SSL specific settings here ###
        ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers RC4:HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
        keepalive_timeout    60;
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  10m;
 
        location /
        {
            auth_pam    "Secure Zone";
            auth_pam_service_name   "nginx";
            proxy_pass  http://localhost:8080;
 
            ### force timeouts if one of backend is died ##
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
 
            ### Set headers ####
            proxy_headers_hash_max_size 51200;
            proxy_headers_hash_bucket_size 6400;
            proxy_set_header        Accept-Encoding   "";
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
 
            proxy_set_header        X-Forwarded-Proto $scheme;
            add_header              Front-End-Https   on;
 
            proxy_redirect     off;
        }
    }
}

Exclude certain URLs

If you, most likely you would, have certain resources to be excluded from user authentication, you can do as the follows. It would open up overview.html and /help/helps.zip without user authentication.

    location ~ (/overview\.html|/help/helps\.zip)
    {
        auth_basic off;
        proxy_pass  http://localhost:8000;
        allow all; # Allow all to see content
    }

Nginx is really powerful and flexible. We just scratched the surface in last post and this one. For more info, check out its Web site and the commercial company behind it.

Categories: Applications & Tools Tags: , , ,
  1. Not SSO
    May 22nd, 2014 at 15:12 | #1

    This isn’t “Single” Sign On, it is single credential but I still have to login to every vhost separately and there are no cookies to leverage for a “Remember me” kind of functionality.

  2. Bruno
    September 9th, 2014 at 07:10 | #2

    Hey!, thanks for the tutorial, it was very useful, I’m actually trying to implement it with google 2 factor authentication, the point is it doesn’t recognize the password and it fails on authentication… everything works perfect with apache and pwauth, but no for nginx, any idea?.

    Thanks!

  3. September 9th, 2014 at 15:03 | #3

    Glad you find it useful. I haven’t played with Google 2 factor authentication, so cannot comment. Sorry and good luck.

  4. April 8th, 2015 at 08:27 | #4

    Hi,

    I’m concerned about this line:

    usermod -a -G shadow www-data

    If your code is ever subject to a directory traversal attack then the above permissions would allow an attacker to get a full list of all the usernames and password hashes and thereby gain access to your system.

    I’d recommend finding another way of doing this other than allowing your web server processes to access /etc/shadow.

    Cheers,

    Matt

  5. April 8th, 2015 at 18:10 | #5

    Thanks Matt,

    Could you elaborate more on the “another” way? Thanks!

    Steve

  6. July 4th, 2016 at 01:00 | #6

    This results in an all or nothing authentication. There’s no further access control or authorisation controls after NGINX passes the user request through PAM. In fact, after a user passes through PAM, they are executing the arbitrary handler at the proxy passed upstream. Which is most likely setup to run as www-data. A continuation of this technique would be drop privileges and use setuid setgid to the user that was authenticated with PAM at the proxy upstream, this would require passing the uid and gid as proxy headers.

  1. February 19th, 2014 at 22:18 | #1