Score:1

How can I forward-proxy https requests with Nginx?

co flag

I am running a local web app on my dev machine. And I want to reach my local web app from a test machine (a phone).

I set up Nginx to listen on port 8888. My test machine can reach my dev machine at this port.

Requests that should go the local web application are reverse-proxied from port 8888 to the local web app port 3000. These requests work fine.

Requests that should go to the internet are forward-proxied and resolved by 8.8.8.8. But these requests can only be HTTP. Nginx does not seem to be able to handle forward-proxy HTTPS requests.

This setup for HTTP works:

server {
        listen 8888;
        listen [::]:8888;

        server_name local.myapp.be myapp.com;

        access_log /var/log/nginx/myapp/access.log;
        error_log  /var/log/nginx/myapp/error.log;

        location / {
                proxy_pass http://local.myapp.be:3000;
                proxy_redirect http://local.myapp.be:3000 $scheme://$host:8888;
                proxy_set_header Host $host;
        }
}

server {
        listen 8888 default_server;
        listen [::]:8888 default_server;

        access_log /var/log/nginx/default/access.log;
        error_log  /var/log/nginx/default/error.log;

        location / {
                resolver 8.8.8.8;
                proxy_pass http://$http_host$uri$is_args$args;
        }
}

I then tried removing the second server block and adding this to nginx.conf at http block level:

stream {
    resolver 8.8.8.8;
    server {
        listen 8888;
        ssl_preread on;
        proxy_connect_timeout 5s;
        proxy_pass $ssl_preread_server_name:$server_port;
    }
}

But that does not seem to work.

How can I setup an Nginx proxy to handle both reverse-proxy and forward-proxy (http & https) requests correctly?

jabbson avatar
sb flag
i am not sure I understand the part where you said "But requests that should go to the internet cannot be resolved by the local development app". Could you elaborate? If you are looking to access a host from your dev server by domain name and this dev server cannot resolve this name into an IP address, you can create a host entry to point the domain to an ip.
Score:0
co flag

Nginx is not well-suited for forward-proxying https requests.

I was able to setup a reverse & forward proxy with Apache HTTPD:

httpd.conf

Find Apache httpd's main configuration file httpd.conf and open the file.

Load the following proxy modules by uncommenting them, e.g.

LoadModule proxy_module lib/httpd/modules/mod_proxy.so
LoadModule proxy_connect_module lib/httpd/modules/mod_proxy_connect.so
LoadModule proxy_http_module lib/httpd/modules/mod_proxy_http.so

proxy.conf

Include the proxy configuration by adding a reference to that config file, e.g.

Include /opt/homebrew/etc/httpd/extra/proxy.conf

Place a config file proxy.conf at the path specified in the Include directive.

Add a listen directive.

Listen 8888

Add a vhost config for reverse-proxied requests to your local resource, e.g. the web app on your dev machine.

<VirtualHost *:8888>
    ServerName reverse.io
    ServerAlias local.myapp.com myapp.com
    ProxyRequests Off
    <Proxy *>
        Order deny,allow
        Deny from all
        Allow from all
    </Proxy>
    ProxyPass        / "http://local.myapp.com:3000/"
    ProxyPassReverse / "http://local.myapp.com:3000/""
    ProxyTimeout 300
    ErrorLog "/opt/homebrew/var/log/httpd/myapp-reverse-error_log"
    CustomLog "/opt/homebrew/var/log/httpd/myapp-reverse-access_log" common
</VirtualHost>

Add a vhost config for forward-proxied requests to remote resources, e.g. domains, APIs, websites on the internet.

<VirtualHost *:8888>
    ServerName forward.io
    ServerAlias *
    ProxyRequests On
    ProxyVia On
    <Proxy *>
      Require ip 192.168.0
    </Proxy>
    ErrorLog "/opt/homebrew/var/log/httpd/myapp-forward-error_log"
    CustomLog "/opt/homebrew/var/log/httpd/myapp-forward-access_log" common
</VirtualHost>

Combining the listen directive and both vhosts, your configuration file should look something like:

Listen 8888

<VirtualHost *:8888>
    ServerName reverse.io
    ServerAlias local.myapp.com myapp.com
    ProxyRequests Off
    <Proxy *>
        Order deny,allow
        Deny from all
        Allow from all
    </Proxy>
    ProxyPass        / "http://local.myapp.com:3000/"
    ProxyPassReverse / "http://local.myapp.com:3000/"
    ProxyTimeout 300
    ErrorLog "/opt/homebrew/var/log/httpd/myapp-reverse-error_log"
    CustomLog "/opt/homebrew/var/log/httpd/myapp-reverse-access_log" common
</VirtualHost>

<VirtualHost *:8888>
    ServerName forward.io
    ServerAlias *
    ProxyRequests On
    ProxyVia On
    <Proxy *>
      Require ip 192.168.0
    </Proxy>
    ErrorLog "/opt/homebrew/var/log/httpd/myapp-forward-error_log"
    CustomLog "/opt/homebrew/var/log/httpd/myapp-forward-access_log" common
</VirtualHost>
Score:0
ws flag

nginx can proxy TLS just as easily as unencrypted HTTP, but it can't present a valid certificate to your client! You really don't want to be clicking through certificate warnings on every site you visit. (There are ways of achieving this, but they are very complicated).

There are 2 simple solutions.

EITHER:

  1. ditch nginx and use a conventional forward proxy like squid with additional logic to handle redirecting the application traffic (with squid you do this with an URL rewriter)

  2. Set up a proxy PAC file to only forward your application traffic to nginx.

jlanssie avatar
co flag
Thanks for the reply. I used Charles (supposedly that works similar to Squid and Fiddler), which works nicely, but I rather not use paid software. I will look into your proxy PAC solution too. But I did find an easy way to do this forward and reverse proxy-ing with Apache HTTPD.
ws flag
Do make sure you are not running an open proxy.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.