How to setup Nginx to disable PATCH and TRACE HTTP request methods

How to setup Nginx to disable PATCH and TRACE HTTP request methods

Nginx_security_hardening

Test Environment

Fedora 32 installed

What is Nginx

Nginx Open Source is an all-in-one loadbalancer, content cache, and web server. It has one master server and several worker processes. Master process is used to read and evaluate configuration and maintain the worker processes. Worker process do the actual processing of the requests. Nginx consists of modules which are controlled by directives specified in the configuration file.

Here in this article we will see how we can install Nginx and Configure a basic Proxy Pass to serve our requests. Once the basic Nginx setup is completed we will see how we can restrict the PATCH and TRACE method request using the cURL to the Nginx server.

Procedure

Step1: Install Nginx server

Here we are going to install the Nginx server version shipped with the Fedora 32 linux machine. In my case i have a Nginx server v1.20.0 available in the repositoriy search as shown below.

[admin@fedser32 ~]$ sudo dnf search nginx -v
Loaded plugins: builddep, changelog, config-manager, copr, debug, debuginfo-install, download, generate_completion_cache, needs-restarting, playground, repoclosure, repodiff, repograph, repomanage, reposync
DNF version: 4.6.0
cachedir: /var/cache/dnf
Last metadata expiration check: 0:12:53 ago on Sunday 29 August 2021 08:16:28 AM.
========================================================== Name Exactly Matched: nginx ===========================================================
nginx.x86_64 : A high performance web server and reverse proxy server
Repo        : @System
Matched from:
Provide    : nginx = 1:1.20.0-2.fc32

========================================================= Name & Summary Matched: nginx ==========================================================

Lets go ahead and install the Nginx server.

[admin@fedser32 ~]$ sudo dnf install nginx

Verify that Nginx is installed onto the server.

[admin@fedser32 ~]$ rpm -qa | grep nginx
nginx-filesystem-1.20.0-2.fc32.noarch
nginx-1.20.0-2.fc32.x86_64
nginx-mimetypes-2.1.48-7.fc32.noarch

Step2: Configure Nginx to act as a proxy pass server

The Nginx configuration files are available at /etc/nginx location. The important file to look at in this folder is the nginx.conf file which contains the http server configuration directive blocks. Please take a back up of the original configuration file and replace it with the below for this testing purpose.

Here we are updating the coonfiguration in such a way that whenever a request comes with a content ending with *.gif, *.jpg or *.png the requests are servers as static content from the /data1 root directory. If there is any other request coming with a different context then it is being proxy passed to a service running on port 8080. In my case we have defined another server block which acts as a proxy server serving requests on port 8080. This server block serves the content from the /data1/up1 root directory for the requests that have been proxied.

[root@fedser32 nginx]# cat nginx.conf
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http{
	server{
		location / {
			proxy_pass http://localhost:8080;
		}

		location ~ \.(gif|jpg|png)$ {
			root /data1;
		}

	}

	server {
    		listen 8080;
    		root /data1/up1;

    		location / {
    		}
	}
}

Once your configuration is updated, please make sure to place some static context in the root context directory as shown below. As you can see i have placed an image file nginx.png and index.html file in /data1/images and /data1/up1 folders respectively.

[root@fedser32 /]# tree data1
data1
├── images
│   └── nginx.png
├── up1
│   └── index.html
└── www
    └── index.html

3 directories, 3 files
[root@fedser32 /]# cat data1/up1/index.html 
Welcome to the proxy server in nginx!!
[root@fedser32 /]# cat data1/www/index.html 
Welcome to Nginx Box!!

Step3: Start and Enable the Nginx service

As we have installed the nginx from the repository, we can start up the Nginx server as a service using the systemctl command line tool as shown below.

[root@fedser32 /]# systemctl start nginx.service 
[root@fedser32 /]# systemctl enable nginx.service

Make sure the nginx service has been started up without any issue. If you have issues starting up the nginx service. Please take a look at the nginx logs available at /var/log/nginx.

[root@fedser32 /]# systemctl status nginx.service 
● nginx.service - The nginx HTTP and reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
     Active: active (running) since Sun 2021-08-29 08:53:07 IST; 4s ago
    Process: 4772 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
    Process: 4773 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
    Process: 4774 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
   Main PID: 4775 (nginx)
      Tasks: 9 (limit: 18885)
     Memory: 8.6M
        CPU: 34ms
...

Nginx Log location for troubleshooting in case of any failures.

[root@fedser32 /]# ls -ltr /var/log/nginx/
-rw-r--r--. 1 nginx root    0 Aug 24 18:25 error.log
-rw-r--r--. 1 nginx root    0 Aug 24 18:25 access.log

Step4: Validate the Nginx service

To validate whether our nginx service is up and running, we can try to request for our static content image and index.html file as configured in the nginx configuraiton using the following urls.

For index.html request – http://localhost/
For nginx.png iamge request – http://localhost/images/nginx.png

In case you have any issues accessing your static content with the above URLS. Check if you have SE Linux security enable on your linux machine. If yes, please make sure to update httpd content location with the new path as shown below and enable the httpd_can_network_connect boolean for allowing nginx to make outbound connect requests.

[root@fedser32 /]# chcon -Rt httpd_sys_content_t /path/to/www
[root@fedser32 /]# setsebool -P httpd_can_network_connect on

Also the /data1/ directory serving the static content must be having the required read permissions set.

Step5: Disable PATCH and TRACE HTTP request method

Now that we have our Nginx serving the static, lets see how we can disable PATCH and TRACE request methods from being served by the Nginx server. For this we need to update our server block with the below if condition.

		if ($request_method ~ ^(PATCH|TRACE)$) { 
			return 405; 
		}

The updated nginx.conf http block will look like something below. Here we are making sure that if any request with request_method set to PATCH or TRACE is being requested we return a 405 Not allowed return code for them. This way we will be able to disable all the PATCH and TRACE request at the server level.

http{
	server{
		if ($request_method ~ ^(PATCH|TRACE)$) { 
			return 405; 
		}	
		location / {
			proxy_pass http://fedser32.stack.com:8080;
		}

		location ~ \.(gif|jpg|png)$ {
			root /data1;
		}

	}

	server {
                if ($request_method ~ ^(PATCH|TRACE)$) { 
                        return 405; 
                }
    		listen 8080;
    		root /data1/up1;

    		location / {
    		}
	}
}

Once the configuration is updated restart the nginx service again. Make sure there are no errors while restarting the service.

[root@fedser32 /]# systemctl restart nginx.service

Step6: Validate the PATCH and TRACE requests after Nginx security hardening

If all the configurations and restarts are done accordingly. You should bel able to see that the PATCH and TRACE request_methods are disable.

[root@fedser32 nginx]# curl -X GET http://fedser32.stack.com/
Welcome to the proxy server in nginx!!

[root@fedser32 nginx]# curl -X PATCH http://fedser32.stack.com/
<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.20.0</center>
</body>
</html>

[root@fedser32 nginx]# curl -X TRACE http://fedser32.stack.com/
<html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.20.0</center>
</body>
</html>

NOTE: As per change logs, nginx always returns the 405 status for the TRACE method ref – http://nginx.org/en/CHANGES-1.20.

As the TRACE method requests are already disable, you can remove the TRACE check from the If condition block or you can keep it as it is.

Hope you enjoyed reading this article. Tnank you..