Community discussions

MikroTik App
 
Jassu
just joined
Topic Author
Posts: 2
Joined: Wed Jun 10, 2020 12:31 am

Whitelisting HTTPS wildcard hosts based on TLS SNI hostname

Wed Jun 10, 2020 4:42 pm

Hi all,

I tried to find ways to do a wildcard based whitelist for HTTPS traffic, but I ended up getting results for only HTTP connections that were based on the transparent proxy setup. The proxy doesn't work for HTTPS connections and I could not find any more relevant sources on how to manage to do what I needed to do. The firewall address-lists work only for specific hosts that can be directly resolved, while I needed to allow wildcard domains to comply with the specification. So, here is my take on how to whitelist only the specific HTTPS hosts while fully supporting wildcard matching.

Pros:
  • An actual wildcard matching support for HTTPS
  • Should not be too resource intensive for established connections
  • Does exactly what is needed in the perspective of the end user (everything but whitelisted things are blocked)
Cons:
  • It doesn't protect from targeted data exfiltration as some packets have to be let through to facilitate the SNI matching (this bit could probably be made better)
  • Bit of a hack, and might be hard to wrap your head around. You have been warned.

Please contribute any ideas on how to make this better & more secure.
/ip firewall filter
add action=drop chain=forward comment="Drop invalid connections" connection-state=invalid protocol=tcp
add action=accept chain=forward comment="Accept Established & related connections but HTTPS" connection-state=established,related packet-mark=no-mark
add action=accept chain=forward comment="Allow established HTTPS connections flagged as good by FW" connection-state=established,related packet-mark=allow-https
add action=jump chain=forward comment="Catch marked HTTPS packets for SNI inspection" jump-target=forward-https packet-mark=https
add action=reject chain=forward comment="Reset HTTPS connections that were not allowed" packet-mark=bad-https protocol=tcp reject-with=tcp-reset

# Following is the list of tls hosts allowed
add action=add-dst-to-address-list address-list=allow-https address-list-timeout=5s chain=forward-https comment="Allow Google" protocol=tcp tls-host=*.google.com
add action=add-dst-to-address-list address-list=allow-https address-list-timeout=5s chain=forward-https comment="Allow Google" protocol=tcp tls-host=*.googleusercontent.com
add action=add-dst-to-address-list address-list=allow-https address-list-timeout=5s chain=forward-https comment="Allow Google" protocol=tcp tls-host=*.gstatic.com

# We will have to allow the rest of the packets through at this stage from this matcher chain
add action=accept chain=forward-https port=443 protocol=tcp

/ip firewall mangle

add action=mark-connection chain=prerouting comment="Mark checked & allowed HTTPS connections" dst-address-list=allow-https dst-port=443 new-connection-mark=allow-https passthrough=yes protocol=tcp
add action=mark-packet chain=prerouting comment="Mark packets that are part of allowed HTTPS connections" connection-mark=allow-https new-packet-mark=allow-https passthrough=no

# Next we match the new HTTPS connections & mark packets that were not yet cleared by the matcher in the forward-https chain
add action=mark-connection chain=prerouting comment="Mark HTTPS connections" connection-state=new dst-port=443 new-connection-mark=https protocol=tcp
add action=mark-packet chain=prerouting comment="Mark HTTPS packets based on connection mark and only allow few through per connection" connection-mark=https dst-limit=1/1m,6,addresses-and-dst-port/1m new-packet-mark=https passthrough=no

# The rest of the HTTPS traffic must get flagged evil and shall not pass. The connections will be reset by the rule in fw filter.
add action=mark-connection chain=prerouting comment="Mark HTTPS connections bad after few packets have passed, if it was not marked good by previous rules" dst-port=443 log=yes log-prefix=BAD-HTTPS \
    new-connection-mark=bad-https protocol=tcp
add action=mark-packet chain=prerouting comment="Mark HTTPS packets bad by the bad-https connection mark" connection-mark=bad-https new-packet-mark=bad-https passthrough=no


So there. The basic idea goes like this:
  1. Match all new HTTPS connections and mark the connection
  2. Mark packets that are part of a specific connection until a limit is reached
  3.  Match those marked packets in the filter for desired tls-hosts
  4. Add the IP addresses of the matched tls-hosts to an address list
  5. Use the address list to override the previous connection mark with a mark that tells that the connection is good
  6. Mark packets of the good connections
  7. Allow the good packets through for established connections
  8. The connections that didn't get flagged by the tls-host filter will reach the packet count limit and pass the rule
  9. The next rule is for marking a connection as bad https connection
  10. Mark packets bad based on the connection mark
  11. Reset the connections on filter based on packet mark

I hope this helps out someone, and that I didn't forget to paste any relevant lines. :D

~Jassu

Who is online

Users browsing this forum: No registered users and 10 guests