Goal: Restrict content access through username and password entry on an Nginx server.
1: Apache Utilities Package
First, update your server’s package index:
sudo apt update
Check if the utilities package exists in your environment by executing the command
dpkg --get-selections | grep apache
Response:
apache2-utils install
libapache-pom-java install
So it exists. But what do you do if it doesn't exist?
How come I need to install apache-utils? To restrict access you will be using a utility called htpasswd, which is part of the apache2-utils package. To install execute the command:
sudo apt install apache2-utils
With this installed, you now have access to the htpasswd command.
2 Create the Password File
Now you can create a password file using the htpasswd or OpenSSL. Create a hidden file for this purpose called .htpasswd within your /etc/nginx configuration directory.
Note - you only need one approach. Either select htpasswd or OpenSSL.
Using htpasswd
For the initial use of this tool, you need to add the -c option to create the .htpasswd file. In doing so, enter a username replacing {username} with your own:
sudo htpasswd -c /etc/apache2/.htpasswd {username}
You will be prompted to enter and re-type a password for the user, as follows:
New password:
Re-type new password:
Remember when you create more user's to leave out the -c argument so you don’t overwrite the file:
sudo htpasswd /etc/apache2/.htpasswd {next_user}
You can check the .htpasswd file contents to confirm its contents by using the command:
cat /etc/apache2/.htpasswd
The response will show the usernames and passwords. However, the passwords are encrypted.
Using OpenSSL Utilities
You must have OpenSSL installed on your server to achieve this approach. You can create a password file with no additional packages. To check if you have OpenSSL, execute the following command:
openssl version
All working well, the response will something like
OpenSSL 1.1.1f 31 Mar 2020
Add a username to the file by executing the command:
sudo sh -c "echo -n '{yourname}:' >> /etc/nginx/.htpasswd"
Replacing {your name} with what you require. Next, add an encrypted password entry for the username by typing:
sudo sh -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd"
On executing the above command, you will need to enter the password twice against the following prompts
Password:
Verifying - Password:
You can see how the usernames and encrypted passwords are stored within the file by typing:
cat /etc/nginx/.htpasswd
The response will show the usernames and passwords. However, the passwords are encrypted.
3 Configuring Nginx password authentication
By opening the server block configuration file that you wish to add a restriction. As I'm working on CKAN, with nothing else installed, the default wasn't an option, and CKAN is. That said, ckan is pointing to the sites-available directory. So I'll adjust my location. Normally you would edit
sudo nano /etc/nginx/sites-enabled/default
But I'll be using
sudo nano /etc/nginx/sites-available/default
or
sudo nano /etc/nginx/sites-available/ckan
For setting up authentication, begin by deciding on the context to restrict. The auth_basic directive turns on authentication and a realm name is displayed to the user when prompting for credentials. You'll use the auth_basic_user_file directive to point Nginx to the password file you created:
server {
listen 80 default_server;
. . .
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
}
But as I'm using CKAN, the file will be
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache:30m max_size=250m;
proxy_temp_path /tmp/nginx_proxy 1 2;
server {
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_cache cache;
proxy_cache_bypass $cookie_auth_tkt;
proxy_no_cache $cookie_auth_tkt;
proxy_cache_valid 30m;
proxy_cache_key $host$scheme$proxy_host$request_uri;
# In emergency comment out line to force caching
# proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
Where I've added the final copy of lines
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
CKAN adding SSL
Adding SSL wildcard to the server, I actioned the following
Add the certificate and corresponding key files to the following locations
ssl_certificate /etc/ssl/certs/{certificate-name}.crt;
ssl_certificate_key /etc/ssl/private/{certificate-key-name}.key;
Changed the CKAN config by adding the following lines to the config file located
sudo nano /etc/nginx/sites-available/ckan
Addition to the file to pick up the certificate and key:
listen 443 ssl;
ssl_certificate /etc/ssl/certs/{certificate-name}.crt;
ssl_certificate_key /etc/ssl/private/{certificate-key-name}.key;
# Redirect non-https traffic to https
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
So the complete CKAN config file is now
proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache:30m max_size=250m;
proxy_temp_path /tmp/nginx_proxy 1 2;
server {
client_max_body_size 100M;
listen 443 ssl;
ssl_certificate /etc/ssl/certs/{certificate-name}.crt;
ssl_certificate_key /etc/ssl/private/{certificate-key-name}.key;
# Redirect non-https traffic to https
if ($scheme != "https") {
return 301 https://$host$request_uri;
}
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_cache cache;
proxy_cache_bypass $cookie_auth_tkt;
proxy_no_cache $cookie_auth_tkt;
proxy_cache_valid 30m;
proxy_cache_key $host$scheme$proxy_host$request_uri;
# In emergency comment out line to force caching
# proxy_ignore_headers X-Accel-Expires Expires Cache-Control;
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
You will also need to check the CKAN ini file ckan.site_url parameter as located in
## Site Settings
ckan.site_url = http://ckan.{domain}
#ckan.use_pylons_response_cleanup_middleware = true
# Default timeout for Requests
#ckan.requests.timeout = 10
Update the scheme from http to https
## Site Settings
ckan.site_url = https://ckan.{domain}
Restart Nginx
Use either of the following commands to restart Nginx
sudo systemctl restart nginx
OR
sudo service nginx restart
Reference for OpenSSL
-help | Print out a usage message |
-crypt | Use the crypt algorithm (default) |
-1 | Use the MD5-based BSD password algorithm 1 |
-apr1 | Use the apr1 algorithm (Apache variant of the BSD algorithm) |
-aixmd5 | Use the AIX MD5 algorithm (AIX variant of the BSD algorithm) |
-5 -6 |
Use the SHA256 / SHA512 based algorithms defined by Ulrich Drepper. See https://www.akkadia.org/drepper/SHA-crypt.txt |
-salt string | Use the specified salt. When reading a password from the terminal, this implies -noverify |
-in file | Read passwords from file |
-stdin | Read passwords from stdin |
-noverify | Don't verify when reading a password from the terminal |
-quiet | Don't output warnings when passwords given at the command line are truncated |
-table | In the output list, prepend the cleartext password and a TAB character to each password hash |
-rand file... | A file or files containing random data used to seed the random number generator. Multiple files can be specified separated by an OS-dependent character. The separator is ; for MS-Windows, , for OpenVMS, and : for all others |