nginx proxy_pass over https_proxy
Asked Answered
R

2

14

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>
Racecourse answered 18/10, 2017 at 5:36 Comment(7)
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?Grimes
@TarunLalwani ps auxe | grep nginx shows https_proxy being used by nginx: worker process. I'm starting nginx using systemctl start nginxRacecourse
Can post the exact error logs from Nginx?Grimes
Also I notice there is a redirect happening in the proxy_pass backend (backend.mygreat.server.com). I've updated my question with error logRacecourse
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 workGrimes
@TarunLalwani my corp proxy is working. I have updated my question with output from curl when I run it on the terminal.Racecourse
Let us continue this discussion in chat.Grimes
G
23

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

Grimes answered 19/10, 2017 at 7:14 Comment(7)
I didn't use proxy_redirect but your suggestion worked beautifully. Thanks a lot for your help and tips. I learnt quite a bit.Racecourse
Here is the ticket opened on nginx - trac.nginx.org/nginx/ticket/1399#ticketRacecourse
Depending on the use case you may also need to include the Host in the SNI extension for the request going to socat.Mansell
Thanks. Another tool which doesn't respect http_proxy is ssh when you use -R for port forwarding. The socat trick worked for me.Lota
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 ?Dematerialize
@FlorentThiery were you able to find a way to go through SSL/TLS. I am getting 502 with above solution.Intersidereal
Although i did not try, it should be possible to chain 2 socat instances (we eventually gave up because we did not want to depend on it)Dematerialize
S
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

Subscription answered 28/9, 2018 at 11:38 Comment(2)
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_depthCeramist
I did not understand this as a complete answer and also not the linked answer alone, but reading also the question helped: serverfault.com/q/583743/149716Moitoso

© 2022 - 2024 — McMap. All rights reserved.