Filter TLS traffic with IPtables
Switch branches/tags
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
.gitignore Working matching of SSL client hellos Nov 21, 2016
LICENSE Relicense under GPLv3 Nov 20, 2017
Makefile Update Nov 21, 2018


xt_tls is an extension for netfilter/IPtables that allows you to filter traffic based on TLS hostnames.


  • Filter TLS traffic based on the SNI extension


  • Add more advanced matching features (i.e. wildcard matching)
  • Add support for matching on the server certificate

Manual Installation


  • Kernel headers (apt install linux-headers-$(uname -r) or yum install kernel-devel)
  • IPtables devel (apt install iptables-dev or yum install iptables-devel)
  • Glob kernel module
  • Netfilter defrag modules: nf_defrag_ipv4 and nf_defrag_ipv6
git clone
cd xt_tls
sudo make install

DKMS Installation

Additional Prerequisites

  • DKMS (apt install dkms or yum install dkms (from EPEL) )
git clone
cd xt_tls
sudo make dkms-install


You can block traffic to Facebook using the following command.

sudo iptables -A OUTPUT -p tcp --dport 443 -m tls --tls-host "" -j DROP

You can also match subdomains using wildcards like this.

sudo iptables -A OUTPUT -p tcp --dport 443 -m tls --tls-host "\*" -j DROP


If you encounter a bug please make sure to include the following things in your bug report:

  • The application used for sending the request
  • The domain your trying to allow/block - Debug output (see the debugging section below)
  • If possible, a TCPDump capture containing the TLS "Client/Server Hello's"


Since xt_tls is not thoroughly tested, sometimes weird things happen. This might be caused by an application that sends packets xt_tls can't parse. For example cURL and wget (or the TLS libary they use) doesn't send a session ID in the "Client Hello", and xt_tls didn't understand that, so I had to change some things to make it work.

By default xt_tls doesn't print anything to the syslog, as there seems to be quite some overhead in doing that. However you can enable debug output by compiling xt_tls like below.

make debug

If you've sent a TLS request, you can now use dmesg to see if everything works as expected.


[ 2013.959415] [xt_tls] Session ID length: 32
[ 2013.974006] [xt_tls] Cipher len: 42
[ 2013.974292] [xt_tls] Offset (1): 119
[ 2013.974583] [xt_tls] Compression length: 1
[ 2013.974915] [xt_tls] Offset (2): 122
[ 2013.975211] [xt_tls] Extensions length: 38
[ 2013.977016] [xt_tls] Name type: 0
[ 2013.977675] [xt_tls] Name length: 10
[ 2013.978664] [xt_tls] Parsed domain:
[ 2013.979068] [xt_tls] Domain matches: false, invert: false


I would like to thank the people behind the nDPI project, as the parsing function is inspired by their work.