Reject host(not ip) using firewalld / firewalld.richlanguage

5,056

The man page for firewall-cmd tells the facts:

A source address or address range is either an IP address or a network IP address with a mask for IPv4 or IPv6 or a MAC address or an ipset with the ipset: prefix. For IPv4, the mask can be a network mask or a plain number. For IPv6 the mask is a plain number. The use of host names is not supported.

There's a good reason for this. The firewalld is a packet filter. It compares the packet to the rules it has. The IP packet has both source and destination IP address, but not the host name. Therefore, using the host as a criteria would require gathering additional information from additional sources, namely the domain name system DNS. Such implementation would be vulnerable for denial-of-service attacks as it would be easy to make your server generate new traffic while trying to filter the packets.

Furthermore, while a host name is easy to translate to an IP address by querying for A records in DNS, detecting all host names for an IP address is not that straightforward. Sure an IP can have a reverse PTR record, but it's not mandatory nor trustworthy.

E.g. some unified threat management (UTM) solutions with content filters blocks HTTPS traffic based on forbidden host names without encrypting the TLS traffic. This means it can't use the URL, as the HTTP request and its Host: header are encrypted: it only sees the IP address, just like your firewall. Instead of filtering the content it blocks all HTTPS traffic to that IP address, using a pre-fetched list of IP addresses for that hostname. This is exactly what you must do.

If you really would like to use host names, you would need to query for the IP addresses, first. Say you would like to prevent your employees surfing on serverfault.com on their precious working hours.

  1. dig +short serverfault.com
  2. Block those destination IP addresses.
  3. Repeat this at regular intervals, starting from removing the outdated rules.
Share:
5,056
Sameer
Author by

Sameer

Updated on September 18, 2022

Comments

  • Sameer
    Sameer almost 2 years

    Is it possible to add a rule in linux firewalld to reject an entire host(not ip or ip range) ?

    For example, I wish to reject all connection coming from my133y.org.

    Using firewall rich language I can drop ip, but host rejection is not provided in man pages.

    Example to reject ip

    firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.100.4/24" drop'
    

    when modified to :

    firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="my133t.org" drop'
    

    I got the error:

    Error: INVALID_ADDR: my133t.org
    
  • kasperd
    kasperd over 5 years
    It is possible for a hostname to have multiple PTR records. And https traffic often has the domain name in clear through SNI. But regardless of that, this answer is still pretty much correct on why firewall rules based on hostnames isn't a good idea.
  • Esa Jokinen
    Esa Jokinen over 5 years
    Thanks, tweaked those details. In what phase of the TLS handshake the information on SNI hostname is shared? Is it possible to read it from the traffic without interfering at all?
  • kasperd
    kasperd over 5 years
    The SNI field is in the client-hello message which is the very first message send in a TLS connection. That message is sent from client to server and contains the hostname if SNI is supported by the client. The server does not send any data until it has received the client-hello message. The hostname sent from client to server this way is in clear, which useful because it allows a proxy to choose different backends to terminate the SSL connection depending on hostname requested by client.
  • Esa Jokinen
    Esa Jokinen over 5 years
    Then it's possible to use it on an application layer content filter, so my example wasn't the best choice. However, everything here applies to this L3 firewall in question.
  • Sameer
    Sameer over 5 years
    Which is not very efficient as it has to be done on a regular basis. Is there a way to block traffic permanently from a particular hostname?
  • Esa Jokinen
    Esa Jokinen over 5 years
    Using an IP address or subnet is also definitive and hard to circumvent. If you try to block traffic using a host name, your rule can be removed by removing the A record or by not answering to your DNS queries.
  • Nikita Kipriyanov
    Nikita Kipriyanov almost 3 years
    I must add to this: since the introduction of eSNI and its successor ECH, this is impossible again. You can't see requested hostname just eavesdropping a communication between client and server. This does not invalidate the answer, but augments that was said in comments.