Reverse proxy with http inbound, https outbound, and parent proxy - nginx

I have an application that needs to use a proxy (call it proxy1) to access some https endpoints outside of its network. The application doesn't support proxy settings, so I'd like to provide it a reverse proxy url, and I would prefer not to provide tls certs for proxy1, so I would use http for application -> proxy1.
I don't have access to the application host or forward proxy mentioned below, so I cannot configure networking there.
The endpoints the application needs are https, so proxy1 must make its outbound connections via https.
Finally, this whole setup is within a corporate network that requires a forward proxy (call it proxy2) for outbound internet, so my proxy1 needs to chain to proxy2 / use it as a parent.
I tried squid and it worked well for http only, but I couldn't get it to accept http inbound while using https outbound. Squid easily supported the parent proxy2.
I tried haproxy, but had the same result as with squid.
I tried nginx and it did what I wanted with http -> proxy -> https, but doesn't support a parent proxy. I considered setting up socat as in this answer, or using proxy_pass and proxy_set_header as in this answer, but I can't shake the feeling there's a cleaner way to achieve the requirements.
This doesn't seem like an outlandish setup, is it? Or is there a preferred approach for it? Ideally one using squid or nginx.

You can achive this without the complexity by using a port forwarder like socat. Just install it on a host to do the forwarding (or locally on the app server if you wish to) and create a listener that forwards connections through the proxy server. Then on your application host use a local name resolution overide to map the FQDN to the forwarder.
So, the final config should be the app server using a URI that points to the forwarding server (using its address if no name resolution excists), which has a socat listener that points to the the corporate proxy. No reverse proxy required.
socat TCP4-LISTEN:443,reuseaddr,fork \
PROXY:{proxy_address}:{endpoint_fqdn}:443,proxyport={proxy_port}
Just update with your parameters.

Related

Kubernetes Ingress/Reverse and Forward Proxy with ssl interception

I have a requirement that incoming as well as outgoing SSL traffic to a POD in a Namespace has to terminate at a proxy (the same), this proxy should look at a special part in the header of the packet and decide if the packet is allowed for out or in, if not the proxy has to send an 403.
I already took look at Istio and Envoy, but I couldn't find a solution for my problem.
Now I decided to start a separate NGINX-POD in my namespace and always route the traffic through it. So I'll be able to create a custom python module that does the Checks for me.
But I would rather work with native methods, if possible. Now I wanted to ask you, if you have an idea, what to use for this scenario.
Client -> nginx ingress (ssl pathrough) -> nginx (reverse/forward) proxy -> app
app -> nginx (reverse/forward) proxy -> Client
EDIT: or should I take a look at squid or something like that? :O

How to make Kubernetes service load balance based on client IP instead of NGINX reverse proxy IP

I have configured NGINX as a reverse proxy with web sockets enabled for a backend web application with multiple replicas. The request from NGINX does a proxy_pass to a Kubernetes service which in turn load balances the request to the endpoints mapped to the service. I need to ensure that the request from a particular client is proxied to the same Kubernetes back end pod for the life cycle of that access, basically maintaining session persistence.
Tried setting the sessionAffinity: ClientIP in the Kubernetes service, however this does the routing based on the client IP which is of the NGINX proxy. Is there a way to make the Kubernetes service do the affinity based on the actual client IP from where the request originated and not the NGINX internal pod IP ?
This is not an option with Nginx. Or rather it's not an option with anything in userspace like this without a lot of very fancy network manipulation. You'll need to find another option, usually an app-specific proxy rules in the outermost HTTP proxy layer.

Is it possible to have client certificates with HTTP (not HTTPS)?

I have an application set up like this:
There is a server, with a reverseproxy/load balancer that acts as the HTTPS termination (this is the one that has a server certificate), and several applications behind it(*)
However, some applications require authentication of the client with a certificate. Authentication cannot happen in the reverse proxy. Will the application be able to see the user certificate, or will it be jettisoned by the HTTPS->HTTP transfer?
(*) OK, so this is a Kubernetes ingress, and containers/pods.
It will be lost. I think you need to extract it in the reverse proxy (i.e. Nginx) and pass it in as a HTTP header if you really must. See for example https://serverfault.com/questions/788895/nginx-reverse-proxy-pass-through-client-certificate. Not very secure as the cert is passed in the clear!
I don't know if we have that level of control over the ingress, personally I'm using a normal Nginx server for incoming traffic instead.

Sending http request behind nginx

I am not sure how to formulate my question but here we go:
I have 2 servers, one is the nginx reverse proxy and one is the app server.
In my app server, I am developing a simple http client using jerseyclient that will send a request to another server. I can do this now but the traffic goes from the app server and directly to the destination. Is it possible to it from the app server, passes through the reverse proxy server and goes to the destination?
And, is this design ok or is it an abomination?
nginx reverse proxy works only for requests outside your network.
To configure your system works as you described you have to configure firewall NAT or caching HTTP proxy like squid etc.
If you have no reasons why your servers should look as single computer - your configuration is OK.

Transparent proxy through another proxy using HTTP CONNECT

I have a few legacy clients that don't "speak" HTTPS which I've connected to an upstream server serving content only over HTTPS using nginx as a reverse proxy. This is the flow:
(1) client -> (2) nginx:80 redirects to https -> (3) upstream server
The problem now is in front of (3) there is a forwarding proxy I have to go through, proxy which does HTTPS over HTTP Connect and I have a hard time finding a way to somehow bridge (or replace completely) nginx over HTTP Connect:
(1) client -> (2) nginx:80 redirects to https -> (3) proxy HTTP CONNECT -> (4) upstream
Any ideas what should go in or instead of the bold component ?
I've looked at tinyproxy but that expects HTTP Connect directly (which nginx does not support) and squid which I cannot figure out how to configure to do HTTPS over HTTP CONNECT.
I am essentially looking for a way to bridge http to https through a proxy, please ignore any product names and feel free to suggest anything - including code samples. The clients as well as the server are part of my application.

Resources