<!doctype html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div class="default-style">
I'm getting a "405 Method Not Allowed" message whenever I do a POST via an nginx reverse proxy. Any help or suggestions would be much appreciated. I've been all over stackoverflow.com, but so far none of the suggestions have born fruit.
</div>
<div class="default-style">
</div>
<div class="default-style">
My client was running the following setup:
</div>
<div class="default-style">
</div>
<div class="default-style">
1. WWW is running Ubuntu 20.04 and has a PHP program that accepts DXF files and captures customer input regarding materials, dimensions, quantity, etc.
</div>
<div class="default-style">
</div>
<div class="default-style">
2. TestFS is running Ubuntu 8 (yes ... ouch!) with an extremely complex black-box C program that drives machines on a factory floor producing custom made-to-order gaskets. TestFS is configured for HTTP basic authentication (double ouch! I know!!!) and listens on port 10080.
</div>
<div class="default-style">
</div>
<div class="default-style">
The client's ISP very kindly upgraded WWW (without tell him, of course) and now WWW and TestFS refuse to talk to each other. I isolated the problem down to a TLS issue. TestFS can only go up to TLS 1.0 whereas WWW now will accept nothing less than TLS 1.2.
</div>
<div class="default-style">
</div>
<div class="default-style">
The solution was to introduce a generic off-the-shelf server which I'll refer to as GS. This server has Ubuntu 22.04 and nginx 1.24. GS. It has two Ethernet NICs: one is Internet-facing with a permanent static IP address. The other is attached to a LAN using 192.169.0.x. TestFS is assigned an IP address of 192.168.0.102.
</div>
<div class="default-style">
</div>
<div class="default-style">
Now here's my problem. The reverse proxy works perfectly well when I do a GET request ... but returns a 405 Method Not Allowed error when I try to do a POST from WWW to TestFS via GS. The POST is necessary because WWW produces an XML file (yes ... triple ouch!) that contains the base64 encoded DXF file.
</div>
<div class="default-style">
</div>
<div class="default-style">
Here's the nginx configuration for GS:
</div>
<div class="default-style">
</div>
<div class="default-style">
<div class="default-style">
<strong># /etc/nginx/conf.d/gs.conf</strong>
<br>server {
<br> listen 443 ssl;
<br> listen [::]:443 ssl;
<br> ssl on;
<br> include snippets/self-signed.conf;
<br> include snippets/ssl-params.conf;
<br> root /var/www/html;
<br> index index.html;
<br> server_name _;
<br> error_page 405 =200 $uri;
<br> location / {
<br> try_files $uri /index.html $uri/ =404;
<br> }
<br> location /testfs {
<br> proxy_method POST;
<br> proxy_pass http://testfs.rapidgasket.local:10080;
<br> # Pass Host Header to the downstream server
<br> proxy_set_header Host $host;
<br> # Set the real IP
<br> proxy_set_header X-Real-IP $remote_addr;
<br> # Set the forwarded for header
<br> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
<br> # Most POST requests won't be cacheable by Nginx, but if you have some that are
<br> # you might want to comment out the following line
<br> proxy_no_cache $http_pragma $http_authorization;
<br> # This enables Nginix to handle the POST request
<br> proxy_http_version 1.1;
<br> proxy_set_header Connection "";
<br> proxy_set_header Authorization $http_authorization;
<br> proxy_pass_header Authorization;
<br> }
<br>}
</div>
</div>
<div class="default-style">
</div>
<div class="default-style">
<strong># snippets/self-signed.conf</strong>
</div>
<div class="default-style">
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
<br>ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
</div>
<div class="default-style">
</div>
<div class="default-style">
<strong># snippets/ssl-params.conf;</strong>
</div>
<div class="default-style">
ssl_dhparam /etc/nginx/dhparam.pem;
<br>ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
<br>ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256;
<br>ssl_prefer_server_ciphers on;
<br>ssl_ecdh_curve secp384r1;
<br>ssl_session_timeout 10m;
<br>ssl_session_cache shared:SSL:10m;
<br>ssl_session_tickets off;
<br>ssl_stapling on;
<br>ssl_stapling_verify on;
<br>resolver 8.8.8.8 8.8.4.4 valid=300s;
<br>resolver_timeout 5s;
<br># Disable strict transport security for now. You can uncomment the following
<br># line if you understand the implications.
<br>#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
<br>add_header X-Frame-Options DENY;
<br>add_header X-Content-Type-Options nosniff;
<br>add_header X-XSS-Protection "1; mode=block";
</div>
<div class="default-style">
</div>
<div class="default-style">
<strong>Test GET curl request:</strong>
</div>
<div class="default-style">
</div>
<div class="default-style">
$ curl --insecure -X GET -d test=TEST \
</div>
<div class="default-style">
-H "Authorization: Basic ==base64EncodedUserAndPassword==" \
</div>
<div class="default-style">
https://ip.addr.of.gs/testfs
</div>
<div class="default-style">
</div>
<div class="default-style">
<strong>Response:</strong>
</div>
<div class="default-style">
</div>
<div class="default-style">
<html>
<br><body>
<br><h1>Factory Server</h1>
<br><ul>
<br><li><a href="FactoryServer">Transaction Web Service</a>
<br><li><a href="BusinessDefinitions/BusinessDefinitions.html">Business Definitions Data</a>
<br></ul>
<br><hr/>
<br><h1>Other Tests</h1>
<br><ul>
<br><li><a href="hello">Hello World service</a>
<br><li><a href="echo">Echo request information</a>
<br><li><a href="log">Log event service</a>
<br></ul>
<br></body>
<br></html>
</div>
<div class="default-style">
</div>
<div class="default-style">
</div>
<div class="default-style">
<div class="default-style">
<strong>Test POST curl request:</strong>
</div>
<div class="default-style">
</div> $ curl --insecure -X POST -d test=TEST \
</div>
<div class="default-style">
-H "Authorization: Basic ==base64EncodedUserAndPassword==" \
</div>
<div class="default-style">
https://ip.addr.of.gs/testfs
</div>
<div class="default-style">
</div>
<div class="default-style">
<strong>Response:</strong>
</div>
<div class="default-style">
</div>
<div class="default-style">
<strong><html><head></strong>
<br><strong><title>405 Method Not Allowed</title></strong>
<br><strong></head><body></strong>
<br><strong><h1>Not Allowed</h1></strong>
<br><strong><p>The requested method POST is not allowed on this server.</p></strong>
<br><strong></body></html></strong>
</div>
<div class="default-style">
</div>
<div class="default-style">
Any help is appreciated!
</div>
<div class="default-style">
</div>
<div class="default-style">
Doug Bierer
</div>
<div class="default-style">
SFLUG member since 2007
</div>
<div class="default-style">
Now Living the Life in Thailand :-)
</div>
<div class="default-style">
</div>
</body>
</html>