Replacing a reverse proxy with Ziti Services

Hello,

I'm trying to understand how to terminate SSL using Ziti for services that do not natively support or have HTTPS capabilities. Typically, I use HAProxy as a reverse proxy in this configuration:

Client (HTTPS) > HAProxy (HTTPS) > Server (HTTP)

I thought, given I have an alt-cert setup under the web listener on the controller I could simply just set the target to the http port/ip and map the intercept to port 443 for https but it does not seem to work that way. This is the configuration I imagined:

Client (HTTPS) > Ziti Network > Server (HTTP)

It does seem like Browzer can do this for those external to the Ziti network, but I'd like to keep the access within the Ziti network if possible.

Any ideas on if this is possible and how it could be accomplished?

You can still do exactly this, just don't expose your services on the Internet and only bind the https services to 127.0.0.1 instead of the public IP/0.0.0.0

Then your traffic goes:
Client (https) -> haproxy (passthru) -> edge router -> haproxy (local binding) -> target service

You still use ha proxy to terminate the client TLS but you didn't expose them via public IP

I didn't quite follow this. BrowZer requires an OpenZiti identity so I wouldn't call that "external" to the ziti network....

zrok however I DO consider to be able to use from actually external people. You could run zrok to provide http to clients. So that's another toy you could play with if that sounds fun.. :rofl:

Sorry I don't follow. Are there two HAProxy instances in this case?

Also, even though haproxy is bound to 127.0.0.1, this setup would allow any identity that has access to HAProxy to gain access to all backend servers (whereas the whole point of ZTNA is least privilege).

For example

Jellyfin.domain.com
Nextcloud.domain.com

If both if these are on HAProxy then giving access to the HAProxy IP in ziti services would give access to both applications. Is there a way to do this within the ziti controller/router?

For BrowZer, I just meant that it's exposed to the internet (BrowZer itself) where as if I had the service only within the ziti network, there's no entry point that is public (Even if it does require a ziti identity).

Oh! I naively thought you only wanted this behavior from outside your network but your embracing zero trust fully! Most people in the forums never worry about actually using ziti for "internal" services, nice!!!

There's no way to do what you want with only the controller/router, nor haproxy. We have had two separate projects that do accomplish what you're after I think but you'd have to deploy either nginx or caddy.

I think those are more of what you're after? Even if that's what you were thinking, if you proxy and terminate TLS, won't your services still be available via http still? Maybe I'm too busy watching football to grok what you are doing fully... :rofl: My apologies if I miss the mark again... I might need a simple diagram that shows me what you're after if so.

No problem! It's really for any client inside or outside the LAN. I'm trying to see what I can do with Ziti and enhance my network security at the same time. I've done lots of VLAN segmentation and restrictive firewall rules but hoping OpenZiti can be the final piece of the puzzle.

I've attached a quick diagram showing the existing setup where HTTPS is used from the client's web browser up until the HAProxy instance which terminates the SSL connection, and then beyond that it's HTTP to the web servers.

In the ideal setup I'd like to have the tunnelers deployed on the clients (Internal or External) and they would connect to the Edge and then have another tunneler either on the servers or at least the VLAN containing the servers and clients would connect with HTTPS which would terminate somewhere in the Ziti network and then HTTP to the backend web servers.

I can definitely see how the NGINX and Caddy integrations would be helpful but there's one fundamental issue I can see - if you create a service pointing to the proxy, you've just allowed access to Web1 and Web2 when External Client 2 should only be allowed network access to Web2. The issue is the multiplexing done by the proxy, making both webservers accessible from one port on one IP, just a different SNI.


Blue = Ziti Overlay (mTLs + E2E) and HTTPS
Green = HTTPS
Red = HTTP
White = Internet (oubound only)

Let me know if anything else needs to be clarified... perhaps I didn't show the setup clearly - I tend to overcomplicate things sometimes!

Servers:
10.10.10.10: Reverse Proxy, terminating SSL
10.10.10.20: NGINX HTTP webserver hosting mywebsite
10.10.10.21: NGINX HTTP webserver hosting anotherwebsite

DNS records:
mywebsite.domain.net > 10.10.10.10
anotherwebsite.domain.net > 10.10.10.10

Open Ziti Services:
intercept mywebsite.domain.net > target 10.10.10.10
intercept anotherwebsite.domain.net > target 10.10.10.10

Given the above DNS records, it "appears" both sites are hosted at the same IP, even though it's just because of the reverse proxy. I would think for security this would be a bad practice given you could simply modify the host header and access either site given the identity has access to the reverse proxy, despite only being granted one of the services.

Maybe that is a clearer realistic example?

I might not be following. While yes, it's true that the proxy would have access to both Web1 and Web2, external client 2 would only have access to one intercept and would only be able to send traffic to one of the reverse proxied endpoints. I don't see how that client would be able to access Web1 (assuming external client 2 is allowed to access only Web2).

This is more what I was thinking of...

Here you have a green public Web1 that is proxied through one interface in the proxy that the firewall sends traffic through to. You also have two private Web2/Web3 that are exclusively accessible via the openziti router deployed in private address space. You add two services, one for web 2 and one for web 3, and you instruct the router to host/bind those services.

I think this might end up not working if Web2 and Web3 are hosted by the same machine? You might be able to send something like:

curl -H "host:Web2" https://web3.ziti 

and thus be able to trick the proxy but if you put the apps on different ports (same *.domain) i think that would solve that problem?

I'm not sure to be honest. I dunno if I'm even in the ballbark with what you're thinking and if I understand you correctly. I'd probably have to experiement with the actual environment to give a better answer than this though. :confused: dunno if this helps...

I'm looking more at what you have for Web 2 and Web 3 - so closed off, private to OpenZiti overlay.

I just ran a test with my network and I think perhaps I'm thinking more of how a VPN might function, where OpenZiti seems to be doing a little more for security.

I have tried to setup a host record in my host file that pointed to the resolved IP for an intercept hostname in OpenZiti (so basically, "faking" an intercept) and despite it being a valid domain on my reverse proxy it did not work (which is great!). So, my fears are put to rest with regards to being able to manipulate the intercept network if a reverse proxy is the "host".

Edge Client > (Ziti Tunnel) > HAProxy > Service1, Service2

I also tried your curl command, and it does not seem to "trick" it either! Not sure how Ziti is avoiding this compromise but that is great news!

1 Like