Firewalld Configuration – How to Block ICMP Timestamp and Timestamp Reply

centosfirewalldicmptimestamp

OS: CentOS 7.0

Per the results of a security scan, it has been suggested that we block ICMP timestamp & timestamp reply messages using the firewall (CVE-1999-0524). I've used firewalld to set up some basic IP filtering for SSH as well as allowing HTTPS, but am stumped on this one.

The only thing I could think of was firewall-cmd --add-icmp-block, but I can't find an icmptype that seems to be relevant to timestamp or timestamp reply.

The available types (firewall-cmd --get-icmptypes) are as follows:
destination-unreachable echo-reply echo-request parameter-problem redirect router-advertisement router-solicitation source-quench time-exceeded.

How do I block ICMP timestamp requests with firewalld?

Best Answer

firewalld ships with a default set of predefined ICMP types you can use out of the box:

# firewall-cmd --get-icmptypes
destination-unreachable echo-reply echo-request parameter-problem redirect router-advertisement router-solicitation source-quench time-exceeded timestamp-reply timestamp-request

The parser (/usr/lib/python2.7/site-packages/firewall/core/io/icmptype.py) is not limited to these types, though, and allows to be extended:

First, as per man iptables-extensions(8), section icmp:

icmp (IPv4-specific) This extension can be used if `--protocol icmp' is specified. It provides the following option:

  [!] --icmp-type {type[/code]|typename}
          This allows specification of the ICMP type, which can be a numeric ICMP type, type/code pair, or one of the ICMP type names shown by the command
           iptables -p icmp -h

icmp6 (IPv6-specific) This extension can be used if --protocol ipv6-icmp' or--protocol icmpv6' is specified. It provides the following option:

  [!] --icmpv6-type type[/code]|typename
          This allows specification of the ICMPv6 type, which can be a numeric ICMPv6 type, type and code, or one of the ICMPv6 type names shown by the command
           ip6tables -p ipv6-icmp -h

The two types you refer are IPv4 specific, hence you should use the following to find out the appropriate names as recognized by iptables:

# iptables -p icmp -h | grep timestamp
timestamp-request
timestamp-reply

Now, if you check the contents of the firewalld package, you'll find where the predefined ICMP types are stored:

# rpm -ql firewalld | grep icmptype
/etc/firewalld/icmptypes
/usr/lib/firewalld/icmptypes/destination-unreachable.xml
/usr/lib/firewalld/icmptypes/echo-reply.xml
/usr/lib/firewalld/icmptypes/echo-request.xml
/usr/lib/firewalld/icmptypes/parameter-problem.xml
/usr/lib/firewalld/icmptypes/redirect.xml
/usr/lib/firewalld/icmptypes/router-advertisement.xml
/usr/lib/firewalld/icmptypes/router-solicitation.xml
/usr/lib/firewalld/icmptypes/source-quench.xml
/usr/lib/firewalld/icmptypes/time-exceeded.xml
/usr/lib/firewalld/xmlschema/icmptype.xsd
/usr/share/man/man5/firewalld.icmptype.5.gz

If you check the parser referenced above, you'll see it uses the XML file name as ICMP type when talking to iptables, so you need to write two new files for the ICMP types you want to use using the ICMP types found above. User created ICMP types should be stored in /etc/firewalld/icmptypes.

# cat timestamp-request.xml
<?xml version="1.0" encoding="utf-8"?>
<icmptype>
  <short>Timestamp Request</short>
  <description>This message is used for time synchronization.</description>
  <destination ipv4="yes"/>
  <destination ipv6="no"/>
</icmptype>
# cat timestamp-reply.xml
<?xml version="1.0" encoding="utf-8"?>
<icmptype>
  <short>Timestamp Reply</short>
  <description>This message is used to reply to a timestamp message.</description>
  <destination ipv4="yes"/>
  <destination ipv6="no"/>
</icmptype>

You'll end up with:

# ll -Z /etc/firewalld/icmptypes
-rw-r--r--. root root system_u:object_r:firewalld_etc_rw_t:s0 timestamp-reply.xml
-rw-r--r--. root root system_u:object_r:firewalld_etc_rw_t:s0 timestamp-request.xml

Validate them using the provided XSD:

# xmllint --schema /usr/lib/firewalld/xmlschema/icmptype.xsd timestamp-request.xml
timestamp-request.xml validates

# xmllint --noout --schema /usr/lib/firewalld/xmlschema/icmptype.xsd timestamp-reply.xml
timestamp-reply.xml validates

Reload the firewall:

# firewall-cmd --reload

And finally add them:

# firewall-cmd --add-icmp-block=timestamp-request
# firewall-cmd --add-icmp-block=timestamp-reply

# firewall-cmd --list-icmp-blocks
timestamp-reply timestamp-request

You can check they have been added looking at the iptables rules directly:

iptables -nvL | grep icmp
0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0
0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited
0     0 REJECT     all  --  *      virbr0  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
0     0 REJECT     all  --  virbr0 *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0
0     0 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited
0     0 REJECT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 13 reject-with icmp-host-prohibited
0     0 REJECT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 14 reject-with icmp-host-prohibited
0     0 REJECT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 13 reject-with icmp-host-prohibited
0     0 REJECT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            icmptype 14 reject-with icmp-host-prohibited

Types 13 and 14 are the newly added ICMP types.

For reference, you can read the firewalld.icmptypes(5) manpage.

These ICMP types have been included upstream.