Password authentication for webserver using NGINX on specific VPS port

Hi everyone,

Very new to Nginx so please be patient. We have just acquired a VPS and are starting to run Docker-based webservers on it. However, some of those webservers should not be publicly accessible. While I believe that we could restrict the IP address allowed to connect to the webservers, it seems more convenient to simply set up a password-based authentification and we want to use Nginx for this.

First of all, we got the Nginx-based authentification to work for the general port 80 access to the VPS. However, despite looking around for help, we cannot find a way to also password-protect access to <vps-ip>:<webserver-port> (port 5000, in our case).

Here is what our config file currently looks like:

server {
listen 80 default_server;
listen [::]:80 default_server;

root /var/www/html;

index index.html index.htm index.nginx-debian.html;

server_name _;

location / {
	# First attempt to serve request as file, then
	# as directory, then fall back to displaying a 404.
	try_files $uri $uri/ =404;
            auth_basic "Restricted Content";
            auth_basic_user_file /etc/nginx/.htpasswd;
}

}

server {
listen 80;
server_name _;

location / {
    auth_basic "Restricted Access";  
    auth_basic_user_file /etc/nginx/.htpasswd;  

    proxy_pass http://localhost:5000;
    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;
}

}

When checking the syntax, everything seems ok and we can successfully restart nginx. However, the webserver is still accessible and there is no request for a password.

Any ideas what we are overlooking?

Hello,

not an nginx expert either but:

The ‘listen 80’ directive specify port at which your web server is accessible.

So if i understood you correctly, you could change your config to ‘listen 5000’ if you want all services served from this port like:

:5000/service1
:5000/service2
:5000/service3

Or you can specify separate listen port for each service:

:5000
:5001
:5002

This way if someone try to access your :500x you can configure nginx ‘server { }’ for that particular service.

Something like:

server {
   listen 5000;

   index index.html;

   root /var/www/html;

   location /service1 {
      try_files $uri $uri/ =404;
      auth_basic "Restricted content";
      auth_basic_user_file /etc/nginx/.htpasswd;
   }

   location /service2 {
      try_files $uri $uri/ =404;
      auth_basic "Restricted content";
      auth_basic_user_file /etc/nginx/.htpasswd;
   }
}

Or port-separated:

server {
   listen 5000;
   root /var/www/html/service1;

   index index.html;

   location / {
      try_files $uri $uri/ =404;
      auth_basic “Restricted content”;
      auth_basic_user_file /etc/nginx/.htpasswd;
   }
}

server {
   listen 5001;
   root /var/www/html/service2;

   index index.html;

   location / {
      try_files $uri $uri/ =404;
      auth_basic “Restricted content”;
      auth_basic_user_file /etc/nginx/.htpasswd;
   }
}

Besides that, it is often better idea to not make any service publicly accessible unless it’s necessary. So where applicable - instead of blocking public access to specific service one way or another, you can ie. make it accessible only locally/internally by listening on loopback address like:

server {
   listen 127.0.0.1:9001;
   root /var/www/html/service;

   index index.html;

   location / {
      try_files $uri $uri/ =404;
      auth_basic “Restricted content”;
      auth_basic_user_file /etc/nginx/.htpasswd;
   }
}

This way services can talk to each other, but they can’t be accessed from internet.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.