<!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>