10

I am trying to set up nginx with this config. To access backend.mygreat.server.com I have to go through my corporate proxy, which is myproxy.server.com:80.

Hence, I have added this in /etc/environment

https_proxy=myproxy.server.com:80

Yet, nginx is unable to reach https://backend.mygreat.server.com:443. I'm seeing 504 as HTTP status in nginx logs.

I could use wget or curl to load the page (goes via corporate proxy)

  server {
        listen  443;
        server_name  mygreat.server.com;
        ssl  on;
        ssl_protocols  TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!SEED:!DSS:!CAMELLIA;

        ssl_certificate /etc/nginx/ssl/mygreat.server.com.pem;
        ssl_certificate_key /etc/nginx/ssl/mygreat.server.com.key;

        access_log  /var/log/nginx/access.ssl.log;

        location / {
          proxy_set_header X-Real-IP  $remote_addr;
          proxy_set_header Host-Real-IP  $http_host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Real-Pcol http;

          proxy_intercept_errors on;
          error_page 301 302 307 = @handle_redirects;      

          proxy_pass https://backend.mygreat.server.com:443;
        }

        location @handle_redirects {
            set $saved_redirect_location '$upstream_http_location';
            proxy_pass $saved_redirect_location;
        }    
    }

Any help is greatly appreciated.

Thanks

Update :

Here is the sample error log from nginx

2017/10/18 06:55:51 [warn] 34604#34604: *1 upstream server temporarily disabled while connecting to upstream, client: <ip-address>, server: mygreat.server.com, request: "GET / HTTP/1.1", upstream: "https://<ip-of-backend>:443/", host: "mygreat.server.com" 

If I run curl -v https://backend.mygreat.server.com/ below is the response

* About to connect() to proxy corp-proxy.server.com port 80 (#0)
*   Trying <some-ip-address>...
* Connected to corp-proxy.server.com (<ip-of-proxy>) port 80 (#0)
* Establish HTTP proxy tunnel to backend.mygreat.server.com:443
> CONNECT backend.mygreat.server.com:443 HTTP/1.1
> Host: backend.mygreat.server.com:443
> User-Agent: curl/7.29.0
> Proxy-Connection: Keep-Alive
>
< HTTP/1.1 200 Connection established
<
* Proxy replied OK to CONNECT request
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*   subject: CN=backend.mygreat.server.com,OU=Technology Operations,O=MyCompany.,L=San Diego,ST=California,C=US
*   start date: Mar 15 00:00:00 2017 GMT
*   expire date: Mar 15 23:59:59 2020 GMT
*   common name: backend.mygreat.server.com
*   issuer: CN=Symantec Class 3 Secure Server CA - G4,OU=Symantec Trust Network,O=Symantec Corporation,C=US
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: backend.mygreat.server.com
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: openresty/1.11.2.5
< Date: Wed, 18 Oct 2017 14:03:10 GMT
< Content-Type: text/html;charset=UTF-8
< Content-Length: 5642
< Connection: keep-alive
< X-XSS-Protection: 1; mode=block
< Cache-Control: max-age=0, no-cache, no-store, must-revalidate, private
< Expires: 0
< P3P: policyref="http://backend.mygreat.server.com/w3c/p3p.xml" CP="CURa OUR STP UNI INT"
< Content-Language: en
< Set-Cookie: qboeuid=127.0.0.1.1508335390550307; path=/; expires=Thu, 18-Oct-18 14:03:10 GMT; domain=.server.com
< Set-Cookie: JSESSIONID=784529AA39C10C3DB4B0ED0D61CC8F31.c23-pe2ec23uw2apu012031; Path=/; Secure; HttpOnly
< Set-Cookie: something.blah_blah=testme; Domain=.server.com; Path=/; Secure
< Vary: Accept-Encoding
<
<!DOCTYPE html>
<html>
....
</html>
Arun Avanathan
  • 982
  • 4
  • 11
  • 26
  • Run `ps auxe | grep nginx` and see if your environment variable has actually reached the process or not. How are you launching nginx? Using systemd service or some other way? – Tarun Lalwani Oct 18 '17 at 11:38
  • @TarunLalwani `ps auxe | grep nginx` shows `https_proxy` being used by `nginx: worker` process. I'm starting nginx using `systemctl start nginx` – Arun Avanathan Oct 18 '17 at 13:53
  • Can post the exact error logs from Nginx? – Tarun Lalwani Oct 18 '17 at 13:56
  • Also I notice there is a redirect happening in the proxy_pass backend (`backend.mygreat.server.com`). I've updated my question with error log – Arun Avanathan Oct 18 '17 at 14:00
  • Can you first disable redirect handling and test? remove `error_page 301 302 307 = @handle_redirects;`. Handle one issue at a time, first check if the proxy is working or not and then work on getting redirects to work – Tarun Lalwani Oct 18 '17 at 14:17
  • @TarunLalwani my corp proxy is working. I have updated my question with output from `curl` when I run it on the terminal. – Arun Avanathan Oct 18 '17 at 14:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157008/discussion-between-tarun-lalwani-and-arun-avanathan). – Tarun Lalwani Oct 18 '17 at 14:22

2 Answers2

22

So first of all I am not sure if Nginx is suppose to respect http_proxy and https_proxy variables. I didn't find any documentation on the same. So I assume your issues is related to nginx not using proxy at a all

So now you have an option to use something which actually uses proxy. This is where socat comes to rescue.

Running socat forwarder

If you have a transparent proxy then run

socat TCP4-LISTEN:8443,reuseaddr,fork TCP:<proxysever>:<proxyport>

And if you have CONNECT proxy then use below

socat TCP4-LISTEN:8443,reuseaddr,fork PROXY:yourproxy:backendserver:443,proxyport=<yourproxyport>

Then in your nginx config use

    location / {
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_set_header Host-Real-IP  $http_host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Real-Pcol http;

      proxy_intercept_errors on;
      proxy_set_header Host backend.mygreat.server.com;
      proxy_pass https://127.0.0.1:8443;
      proxy_redirect https://backend.mygreat.server.com https://mygreat.server.com;
    }

You probably want to use Systemd service to launch the socat, so it runs on startup and is handled as a service

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
  • 1
    I didn't use `proxy_redirect` but your suggestion worked beautifully. Thanks a lot for your help and tips. I learnt quite a bit. – Arun Avanathan Oct 19 '17 at 07:27
  • 2
    Here is the ticket opened on nginx - https://trac.nginx.org/nginx/ticket/1399#ticket – Arun Avanathan Oct 19 '17 at 14:06
  • Depending on the use case you may also need to include the Host in the SNI extension for the request going to socat. – Chris Hunt Jun 25 '19 at 23:04
  • Thanks. Another tool which doesn't respect http_proxy is ssh when you use -R for port forwarding. The socat trick worked for me. – eric.frederich Mar 10 '20 at 20:39
  • Thanks for this response; unfortunately, it does not support SSL/TLS to the CONNECT proxy server (aka HTTPS proxy), any idea how to achieve it ? – Florent Thiery Jun 21 '23 at 16:42
0

Nginx's proxy_pass does not support https proxy. http proxy can be supported, but the request url only supports http.

this is a example:

server {
    listen       8880;
    server_name  localhost;
    location / {
        rewrite ^(.*)$ "://developer.android.com$1";
        rewrite ^(.*)$ "http$1" break;

        proxy_set_header Proxy-Connection Keep-Alive;
        proxy_set_header Host developer.android.com;

        proxy_pass http://127.0.0.1:1080;
        proxy_redirect ~^https?://developer\.android\.com(.*)$ http://$host:8080$1;
    }
}

see: https://serverfault.com/a/683955/418613

ipcjs
  • 2,082
  • 2
  • 17
  • 20
  • It doesn't? Can you tell me what all these Nginx directives do then? `proxy_ssl_certificate` `proxy_ssl_certificate_key` `proxy_ssl_ciphers` `proxy_ssl_crl` `proxy_ssl_name` `proxy_ssl_password_file` `proxy_ssl_protocols` `proxy_ssl_server_name` `proxy_ssl_session_reuse` `proxy_ssl_trusted_certificate` `proxy_ssl_verify` `proxy_ssl_verify_depth` – miknik Sep 28 '18 at 14:43
  • I did not understand this as a complete answer and also not the linked answer alone, but reading also the question helped: https://serverfault.com/q/583743/149716 – JonnyJD Oct 07 '20 at 19:38