How to use Nginx's map module on Ubuntu 16.04

Introduction

When configuring a server for a website, you may need to perform some common conditional operations. For example, some files may be cached by the user’s browser longer than others, or some parts of the website should only allow secure connections (such as anything that requires a user’s password), while other parts of the website should not .

Another simple common example is to ensure that when a new page is published instead of an old page, all old addresses will be redirected to the correct location. This is useful because it means that old links and bookmarks will not stop working, and it will also keep Google's cache.

Nginx's map module allows you to create variables in Nginx's configuration files whose values are conditional-that is, they depend on the values of other variables. In this guide, we will learn how to use Nginx's map module to implement two examples: how to set up a redirect list from an old website URL to a new website, and how to create a whitelist of countries/regions to control the traffic of your website.

Preparation

To follow this tutorial, you need:

Step 1-Create and test a sample webpage

First, we will create a test file that represents the newly published website. We will use this file to test our configuration.

Let's create a simple page index.html in the default Nginx website directory. This file has only a simple text description: the home page.

sudo sh -c 'echo "Home" > /var/www/html/index.html'

With this test file, next we will use curl to check whether it is used correctly. We don't need index.html to specify for this command, because if the exact file name is not provided, it will be provided by default.

curl http://localhost/

In response, you should see a word saying is like the following:

Home

Now let us try to access a file that does not exist in /var/www/html/, such as old.html.

curl -L http://localhost/old.html

The response will be a system error message, 404 Not Found, indicating that the page does not exist.

< html><head><title>404 Not Found</title></head><body bgcolor="white"><center><h1>404 Not Found</h1></center><hr><center>nginx/1.10.0(Ubuntu)</center></body></html>

We are only using a virtual website in this tutorial, but if old.html is a page that once existed and was deleted on the real website, returning 404 will mean that all links on that page are broken. This is not ideal, because these links may have been indexed by Google, printed or recorded, or shared by any other means.

In the next step, we will use the map module to ensure that this old address works again by automatically redirecting the viewer to the new replacement.

Step 2-Configure Redirection

For small sites with only a few pages, simple if conditional statements can be used for redirects and similar things. However, as the condition list becomes longer, this configuration is not easy to maintain or expand in the long run.

The map module is a more elegant and concise solution. It allows you to compare Nginx variable values with a list of conditions, and then associate the new value with the variable based on the match. In this example, we will compare the requested URL with the list of old pages we want to redirect to. For each old address, we will associate the new address.

The mapping module is the core Nginx module, which means it can be used without a separate installation. To create the necessary mapping and redirection configuration, please open the default server block Nginx configuration file with nano or your favorite text editor.

sudo nano /etc/nginx/sites-available/default

Find the server configuration block as shown below:

...
# Default server configuration
#
​
server {
 listen 80 default_server;
 listen [::]:80 default_server;
​
...

We will add two new parts: one before the server block and one in it.

The part before the server block is a new map block, which uses the map module to define the mapping between the old URL and the new URL. The part inside the server block is redirection.

...
# Default server configuration
#
​
# Old website redirect map
#
map $uri $new_uri {/old.html /index.html;}
​
server {
 listen 80 default_server;
 listen [::]:80 default_server;
​
 # Old website redirect
 if($new_uri){
  rewrite ^ $new_uri permanent;}...

The map $uri $new_uri command gets the contents of the system $uri variable, which contains the URL address of the requested page, and compares it with the condition list in braces. Each item in the condition list has two parts: the value to match, and if it matches, the new value assigned to the variable.

The line/old.html /index.html in the map block means that if the value of $uri is /old.html, $new_uri will be changed to /index.html. If it does not match, it will not be changed. Here, we only define one condition, but you can define any number of conditions in the map.

Then, use another if conditional statement in the server block to check whether the value of the $new_uri variable is set. If it is, it means that the conditions in the map are met and we should redirect to the new website using the rewrite command. The permanent keyword ensures that the redirect will be a 301 Moved Permanently HTTP redirect, which means that the old address is no longer valid and will not be back online.

Save and close the file to exit.

To enable the new configuration, restart Nginx.

sudo systemctl restart nginx

To test the new configuration, perform the same request as before:

curl -L http://localhost/old.html

There will be no 404 Not Found errors in the output this time. Instead, you will see the simple home page we created in step 1.

Home

This means that the map is properly configured and you can use it to redirect the URL by adding more entries to the map.

Redirect URL is a useful application of the map module. Another, we will explore in the next step, filtering traffic based on the geographic location of visitors.

Step 3-Restrict website access to certain countries/regions

Sometimes, the server may receive too many automated malicious requests. This may be a DDoS attack, an attempt to force a password on the website management panel, or an attempt to exploit a known vulnerability in the software to attack the website and use it to send spam or modify the content of the website.

Such automated attacks can come from many different distributed servers in many different countries, so it is difficult to stop. One solution to mitigate the impact of such attacks is to create a whitelist of countries/regions where the website can be accessed.

This is not a perfect solution, but when restricting access to the website based on the visitor's geographic location is a wise choice and does not limit the audience of the website, this solution has the advantage of being fast and not prone to errors.

Filtering at the server level is faster than filtering at the website level and also covers all requests (including static files such as images). This filtering also prevents requests from reaching the website software, which makes vulnerabilities more difficult to exploit.

To use geographic filtering, we first create a new profile.

sudo nano /etc/nginx/conf.d/geoip.conf

Paste the following content into the file. This tells Nginx where to find the GeoIP database containing the mapping between the visitor's IP address and their respective country/region. This database is pre-installed with Ubuntu 16.04.

...
# GeoIP database path
#
​
geoip_country /usr/share/GeoIP/GeoIP.dat;

The next step is to create the necessary mapping and restriction configurations. Open the default server block Nginx configuration.

sudo nano /etc/nginx/sites-available/default

Find the server configuration block, after the modification in steps 1 and 2, as shown below:

...
# Default server configuration
#
​
# Old website redirect map
#
map $uri $new_uri {/old.html /index.html;}
​
server {
 listen 80 default_server;
 listen [::]:80 default_server;
​
 # Old website redirect
 if($new_uri){
  rewrite ^ $new_uri permanent;}...

We will add two new parts: one before the server block and one in it.

The part in front of the server block is a new map block, which defines the default operation (no access allowed) and a list of country/region codes that are allowed to access the website. If the result of map is so, the part inside the server block refuses to access the website.

...
# Default server configuration
#
​
# Allowed countries
#
map $geoip_country_code $allowed_country {default no;
 country_code_1 yes;
 country_code_2 yes;}
​
# Old website redirect map
#
map $uri $new_uri {/old.html /index.html;}
​
server {
 listen 80 default_server;
 listen [::]:80 default_server;
​
 # Disallow access based on GeoIP
 if($allowed_country = no){return444;}
​
 # Old website redirect
 if($new_uri){
  rewrite ^ $new_uri permanent;}...

Save and close the file to exit.

Here, we use country_code_1 and country_code_2 as placeholders. Replace these variables with the two-character country code of the country you want to whitelist. You can use [ISO's complete, searchable list of all country/region codes] (https://www.iso.org/obp/ui/#search) to find it. For example, the two-character code for the United States is US.

Unlike the first example, in this map block, the $allowed_country variable will always be set to a certain value. By default, it is set to no; if the $geoip_country_code variable matches a certain country code in the block, it is set to yes. If the $allowed_country variable is no, we will return 444 Connection Closed Without Response instead of serving the actual website.

To enable the new configuration, restart Nginx.

sudo systemctl restart nginx

If you did not add the country/region to the whitelist, when you try to access http://your_server_ip, you will see an error message such as The page is invalid or The page does not send any data . If you do add the country to the whitelist, you will see Home as before.

in conclusion

Although it may be a very simple example of how to use the map module, it shows the mechanism that can be used in many other different ways. The map module not only allows simple comparisons, but also supports regular expressions that allow more complex matching. If multiple conditions must be evaluated, this is a good way to make the profile clearer.

Another very popular use case for the map module is to conditionally redirect the secure part of a website in a non-SSL environment. Setting a mandatory SSL connection only for forms that require password input is a good example. How to apply the map module in a real world scenario, I encourage you to try such a setting.

More detailed information can be found in the official map module documentation of Nginx](http://nginx.org/en/docs/http/ngx_http_map_module.html).

To learn more about the related tutorials about using the map module of Nginx, please go to [Tencent Cloud + Community] (https://cloud.tencent.com/developer?from=10680) to learn more.


Reference: "How to Use Nginx's map Module on Ubuntu 16.04"

Recommended Posts

How to use Nginx&#39;s map module on Ubuntu 16.04
How to use Samba server on Ubuntu 16.04
How to install and use Docker on Ubuntu 20.04
How to install and use Curl on Ubuntu 18.04
How to install and use Composer on Ubuntu 18.04
How to install and use Wine on Ubuntu 18.04
How to use Docker data volumes on Ubuntu 14.04
How to install and use Composer on Ubuntu 20.04
How to install and use BaasBox on Ubuntu 14.04
How to use Jenkins to build automatically on Ubuntu
How to install and use PostgreSQL on Ubuntu 16.04
How to add logging module to Nginx on Ubuntu 16.04
How to install and use Docker on Ubuntu 16.04
How to use LVM to manage storage devices on Ubuntu 18.04
How to add the gzip module to Nginx on Ubuntu 14.04
How to install and use MySQL Workbench on Ubuntu 18.04
How to install Ruby on Ubuntu 20.04
How to install Java on Ubuntu 20.04
How to use hanlp in ubuntu
How to install VirtualBox on Ubuntu 20.04
How to install Elasticsearch on Ubuntu 20.04
How to install Protobuf 3 on Ubuntu
How to install Nginx on Ubuntu 20.04
How to install Apache on Ubuntu 20.04
How to install Git on Ubuntu 20.04
How to install Node.js on Ubuntu 16.04
How to install Vagrant on Ubuntu 20.04
How to install Bacula-Web on Ubuntu 14.04
How to install PostgreSQL on Ubuntu 16.04
How to install Git on Ubuntu 20.04
How to install Anaconda3 on Ubuntu 18.04
How to install Memcached on Ubuntu 18.04
How to install Jenkins on Ubuntu 16.04
How to install MemSQL on Ubuntu 14.04
How to install Go on Ubuntu 20.04
How to install MongoDB on Ubuntu 16.04
How to install Mailpile on Ubuntu 14.04
How to install PrestaShop on Ubuntu 16.04
How to upgrade to PHP 7 on Ubuntu 14.04
How to install Skype on Ubuntu 20.04
How to install Jenkins on Ubuntu 20.04
How to install Python 3.8 on Ubuntu 18.04
How to install KVM on Ubuntu 18.04
How to install KVM on Ubuntu 20.04
How to install opencv3.0.0 on ubuntu14.04
How to install Anaconda on Ubuntu 20.04
How to install Prometheus on Ubuntu 16.04
How to install Jenkins on Ubuntu 18.04
How to deploy Django on Ubuntu 14.04
How to install Apache on Ubuntu 20.04
How to install R on Ubuntu 20.04
How to install Moodle on Ubuntu 16.04
How to install Solr 5.2.1 on Ubuntu 14.04
How to install Teamviewer on Ubuntu 16.04
How to secure Nginx on Ubuntu 14.04
How to install MariaDB on Ubuntu 20.04
How to install Nginx on Ubuntu 20.04
How to install Mono on Ubuntu 20.04
How to install Go on Ubuntu 20.04
How to install Zoom on Ubuntu 20.04
How to uninstall software on Ubuntu