I'm building a UTM using ubuntu, How can I block HTTPS traffic using URL filtering? (For example I want to block https://facebook.com)

I'm using Squid as a transparent proxy server. Solutions I don't want to use: Blocking websites by IP's, Squid-in-the-middle SSL Bump

  • What about blocking ports instead of URLs? Allow port 80 but block 443?
    – schroeder
    Commented Aug 10, 2015 at 23:15

4 Answers 4


The orthodox way to accomplish this would be to use SSL interception, such as SSLBump, with Squid.

If you don't want to intercept SSL traffic, you can do this via DNS. This would have the effect of blocking the entire website regardless of protocol, e.g. http vs https vs ftp, based on DNS. So you could blacklist "facebook.com" and have your DNS server redirect it to a "This page is blocked" site hosted on an internal IP. An example of a service for such DNS filtering is OpenDNS.

Such a DNS workaround could be avoided by users if they have the ability to edit their workstation DNS settings to use another DNS server, or edit a hosts file. They could also use a number of web sites which offer a proxy to facebook and other sites (which are questionable since they may intercept the users' password) to relay the connection.

Because of the weaknesses of using a DNS-based setup, when looking to inspect HTTPS traffic it is generally more effective to use your squid proxy as a ssl-man-in-the-middle engine and inspect traffic decrypted, this will lead to much better filtering.


I have seen at least two commercial firewalls operating SSL TLS filtering based on server certificate (or client SNI request). My answer will be from the protocol point of view: no code supplied.

Basically the proxy will not try to intercept the TLS conversation itself, but rather judge from the handshake conversation that mandatorily occurs in plaintext.

enter image description here Diagram of SSL handshake Image credits

When a client wants to establish an encrypted session with a server, the two must start a conversation in plaintext and then switch to encrypted. It is my personal technological opinion that the process could be improved in order not to leak certain information in this phase.

The goal of a TLS handshake is to authenticate the server versus the client, i.e. there is no MiTM proxy sniffing traffic. Rewording: once the client is negotiating (I won't go into details) an encryption key with the server, they must be sure that the agreed secret key is known only by themselves and the legitimate example.org.

As you can see in the diagram, that phase is "Cryptographic parameters & key exchange", which I won't describe further. In order to perform such exchange correctly, the cryptographic parameters must be linked to the server certificate, which, in turn, contains details about the visited site. The certificate is not just publicly available (so that the proxy could try to connect independently and test the server), but is transmitted in plaintext in this phase.

Without SNI, the server transmits in plaintext the certificate(s) it operates. They are in plaintext, so example.org is clearly visible in the CN (Common Name) attribute.

In TLS 1.3 (disclaimer: information comes from experimenting and the linked article, please highlight incorrect information) and particularly when SNI is enabled, the client requests for the target server example.org in plaintext.

The idea behind a TLS content filtering based on URL filtering, with the only constraint that the filtering is done up to the domain level and not single-url level, is the following:

  1. Allow the client to initiate a TCP/TLS connection, monitor it
  2. If during the handshake the firewall detects a blocked DNS, kill the connection
  3. Otherwise let the conversation continue, without sniffing

I have experimented using Wireshark and found that, apparently, the remote host was killing the connection to my workstation.

In reality, the firewall was simply injecting TCP packets with RST flag on and dropping packets related to that TCP stream. That results in an abnormal TLS termination, but serves for the purpose.


filter the incoming http requests based on HTTP "Host" headers to block access to certain websites.

as you are using linux, you can use the IPTABLES to block access to IP addresses link

again, the question seems a bit too vague, but this is my best attempt to answer.

  • Thanks for your answer, but as mentioned I don't want to block websites by IP, because I have a blacklist of URLs not the IPs
    – Masry
    Commented Jun 2, 2015 at 13:29
  • sorry , i missed the key word "don't" there. the Host header is the one you need to filter out.
    – JOW
    Commented Jun 2, 2015 at 14:11

When traffic is HTTPS, you can't see the full url visited by the user without doing a MiTM (sslbump).

That's said, you can see the domain requested either by looking at the string after the "CONNECT" sent to your proxy by the client or by inspecting the beginning of the TLS handshake (thanks to the SNI extension).

You can also block using DNS.

You need to install a DNS server if you are not using your own one (bind for example) and recurse all domains except the ones you want to block (redirect them to


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .