Suricata rules for blocking IP-based calls do not work (DNS coercion)

Hello everyone,

I would like to ensure that no one on my network can access a website using just an IP address. Instead, everyone should only access via DNS names. I have therefore created the following rules in Suricata to block all IP-based HTTP/HTTPS connections:

# Blockt HTTP-Verbindungen, bei denen der Host-Header eine IPv4-Adresse enthält
alert http any any -> any any (msg:"HTTP request with IPv4 address in Host header blocked"; flow:established,to_server; content:"Host:"; nocase; pcre:"/^Host:\\s*((\\d{1,3}\\.){3}\\d{1,3})(:\\d+)?(\\r?\\n)?$/Hmi"; classtype:policy-violation; sid:1000100; rev:1;)

# Blockt HTTP-Verbindungen, wenn der Host-Header eine IPv6-Adresse enthält
alert http any any -> any any (msg:"HTTP request with IPv6 address in Host header blocked"; flow:established,to_server; content:"Host:"; nocase; pcre:"/^Host:\\s*\\[[0-9A-Fa-f:]+\\](:\\d+)?(\\r?\\n)?$/Hmi"; classtype:policy-violation; sid:1000101; rev:1;)

# Blockt TLS-Verbindungen mit IPv4-Adresse im SNI
alert tls any any -> any any (msg:"TLS connection with IPv4 address in SNI blocked"; flow:established,to_server; tls_sni; pcre:"/^((\\d{1,3}\\.){3}\\d{1,3})(:\\d+)?$/"; classtype:policy-violation; sid:1000102; rev:1;)

# Blockt TLS-Verbindungen mit IPv6-Adresse im SNI
alert tls any any -> any any (msg:"TLS connection with IPv6 address in SNI blocked"; flow:established,to_server; tls_sni; pcre:"/^\\[[0-9A-Fa-f:]+\\](:\\d+)?$/"; classtype:policy-violation; sid:1000103; rev:1;)

Problem:

These rules do not work as desired. For example, if I test via curl http://1.2.3.4 or curl https://1.2.3.4, I can still access the website. There are no alert or block messages from Suricata.
BUT - if I create a test rule that blocks a specific IP, it works fine, e.g:

drop tcp any any -> 1.2.3.4 80 (msg:"Block all traffic to 1.2.3.4 on port 80"; sid:1000200; rev:1;)

This blocks the connection directly. This shows me that Suricata is basically active and can block. Only my IP-based host/SNI rules are not taking effect.

The goal is and remains: Nobody should be able to simply access http://x.x.x.x or https://x.x.x.x. If you have any tips on how I can best enforce this “DNS-only” policy, I would be very pleased.

Thank you very much for your help!

Can you share your suricata.yaml config and how you run Suricata? Ideally also at stats.log and suricata.log.

Also keep in mind that you set flow:established,to_server; which would wait for the connection to be established. You could try to run without it.