Restricting access – Nginx

In the previous article, we explored ways to limit abusive access to websites running under NGINX. Now, we will take a look at ways to restrict access to a whole website or certain parts of it. Access restriction can take two forms here: restricting a certain set of IP addresses, or restricting a certain set of users. These two methods can also be combined to satisfy requirements that some users can access the website either from a certain set of IP addresses or if they are able to authenticate with a valid username and password.

The following directives will help us achieve these goals:

HTTP access module directives

Explanation

allow

This directive allows access from this IP address, network, or the all value.

auth_basic

This directive enables authentication using HTTP Basic Authentication. The string parameter is used as the realm name. If the special value, off, is used, this indicates that the auth_basic value of the parent configuration level is negated.

auth_basic_user_file

This directive indicates the location of a file of username:password:comment tuples used to authenticate users. The password field needs to be encrypted with the crypt algorithm. The comment field is optional.

deny

This directive denies access from this IP address, network, or the all value.

satisfy

This directive allows access if all or any of the preceding directives grant access. The default value, all, indicates that a user must come from a specific network address and enter the correct password.

To restrict access to clients coming from a certain set of IP addresses, the allow and deny directives can be used as follows:

location /stats {

  allow 127.0.0.1;
  deny all;

}

This configuration will allow access to the /stats URI only from localhost.

To restrict access to authenticated users, the auth_basic and auth_basic_user_file directives are used as follows:

server {

  server_name restricted.example.com;

  auth_basic "restricted";

  auth_basic_user_file conf/htpasswd;

}

Any user wanting to access restricted.example.com would need to provide credentials matching those in the htpasswd file located in the conf directory of NGINX’s root. The entries in the htpasswd file can be generated using any available tool that uses the standard UNIX crypt() function. For example, the following Ruby script will generate a file of the appropriate format:

#!/usr/bin/env ruby

# setup the command-line options
require 'optparse'

OptionParser.new do |o|

o.on('-f FILE') { |file| $file = file }

o.on('-u', "--username USER") { |u| $user = u }

o.on('-p', "--password PASS") { |p| $pass = p }

o.on('-c', "--comment COMM (optional)") { |c| $comm = c }

o.on('-h') { puts o; exit }

o.parse!

if $user.nil? or $pass.nil?
puts o; exit

end

end

# initialize an array of ASCII characters to be used for the salt
ascii = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a + [ ".", "/" ]

$lines = []

begin

# read in the current http auth file
File.open($file) do |f|

f.lines.each { |l| $lines << l }

end

rescue Errno::ENOENT

# if the file doesn't exist (first use), initialize the array
$lines = ["#{$user}:#{$pass}\n"]

end

# remove the user from the current list, since this is the one we're editing
$lines.map! do |line|

unless line =~ /#{$user}:/

line

end

end

# generate a crypt()ed password
pass = $pass.crypt(ascii[rand(64)] + ascii[rand(64)])
# if there's a comment, insert it
if $comm

$lines << "#{$user}:#{pass}:#{$comm}\n"

else

$lines << "#{$user}:#{pass}\n"

end

# write out the new file, creating it if necessary

File.open($file, File::RDWR|File::CREAT) do |f|

$lines.each { |l| f << l}

end

Save this file as http_auth_basic.rb and give it a filename (-f), a user (-u), and a password (-p), and it will generate entries appropriate to use in the auth_basic_user_file directive of NGINX:

$ ./http_auth_basic.rb -f htpasswd -u testuser -p 123456

To handle scenarios where a username and password should only be entered if not coming from a certain set of IP addresses, NGINX has the satisfy directive. The any parameter is used here for this either/or scenario:

server {

  server_name intranet.example.com;

  location / {

    auth_basic "intranet: please login";

    # select a user/password combo from this file
    auth_basic_user_file conf/htpasswd-intranet;

    # unless coming from one of these networks
    allow 192.168.40.0/24;

    allow 192.168.50.0/24;

    # deny access if these conditions aren't met
    deny all;

    # if either condition is met, allow access
    satisfy any;
  }
}

If, instead, the requirements are for a configuration in which the user must come from a certain IP address and provide authentication, the all parameter is the default. So, we omit the satisfy directive itself and include only allow, deny, auth_basic, and auth_basic_user_file:

server {

  server_name stage.example.com;

  location / {

    auth_basic "staging server";

    auth_basic_user_file conf/htpasswd-stage;

    allow 192.168.40.0/24;

    allow 192.168.50.0/24;

    deny all;
  }
}

Related Articles

How to add swap space on Ubuntu 21.04 Operating System

How to add swap space on Ubuntu 21.04 Operating System

The swap space is a unique space on the disk that is used by the system when Physical RAM is full. When a Linux machine runout the RAM it use swap space to move inactive pages from RAM. Swap space can be created into Linux system in two ways, one we can create a...

read more

Lorem ipsum dolor sit amet consectetur

0 Comments

Submit a Comment

Your email address will not be published. Required fields are marked *

15 − five =