Lock down jail egress to specific TLS SNI hostnames

Hello - I would like to get some feedback how to achieve this kind of filtering with FreeBSD.

Ideally, I have a jail with a service running. I know the service needs to make HTTPS calls to a given set of upstream hosts. I would like to filter the outbound connections, such that only these connections are allowed.

In a non-FreeBSD setup, I saw this solved by
1. Setting a custom DNS resolver answering the service (or here, probably the whole jail), returning a fixed IP (see next point) for any request.
2. The fixed IP was pointing to a TCP proxy outside the sandbox (here jail), which had capability to observe TLS SNI (for example https://www.haproxy.com/documentation/haproxy-configuration-manual/latest/#req_ssl_sni)

I assume a similar setup could work in FreeBSD, but if there's a more direct approach, I would be interested. For example, I don't know if one of the firewalls have ability to match on SNI.

Thank you!
 
Firewalls, more specifically, packet filters (IPFW, IPFilter, PF), operate on layer 3. What you want to filter is on layer 7. In other words, use a proxy, which is what net/haproxy is. Then you can filter on layer 7. Though, HAProxy is more for reverse proxy (handling incoming connections), not so much for proxying outgoing connections. www/squid is quite popular, so is www/varnish.
 
You can use a packet filter like PF to forward any packet to a proxy, something like this:
Code:
rdr on $int_if from $int_if:network to any port 443 -> 127.0.0.1 port 443
There's also a way to "stealth" proxy, but with SSL/TLS this is a bit of problem because it relies on the fact the client and server can only talk to each other, so you'll need a technique called SSL interception. This basically works as a man-in-the-middle. Finicky, and also a bit of a privacy intrusion (you can intercept someone's online banking for example).

But I would just block any and all outgoing traffic which will force people to use a proxy if they want to connect to the outside world. So within the application you must set HTTP_PROXY or else it simply won't be able to connect to anything.
 
Back
Top