Changeset - 41e53eb08518
[Not reviewed]
0 4 0
Branko Majic (branko) - 2 months ago 2025-02-05 03:22:21
branko@majic.rs
MAR-240: Tag dropped packet messages in system log (due to rate-limiting):

- Improves visibility of such messages, making it easier to
distinguish them from other firewall-related messages.
- Update documentation to mention that the messages are logged.
4 files changed with 40 insertions and 3 deletions:
0 comments (0 inline, 0 general) First comment
docs/releasenotes.rst
Show inline comments
 
@@ -44,6 +44,11 @@ Upgraded to Ansible 10.4.x. Dropped support for Debian 11
 
  * Switched to using Paramiko + SFTP backend (instead of pexpect +
 
    SFTP), which should improve the backup performance.
 

	
 
* ``common`` role
 

	
 
  * TCP packets dropped due to incoming connection rate-limiting are
 
    now logged with the ``RATELIMIT`` prefix in the system logs.
 

	
 
* ``ldap_server`` role
 

	
 
  * TLSv1.3 is now enabled by default (with RFC-defined mandatory
docs/rolereference.rst
Show inline comments
 
@@ -261,7 +261,10 @@ The role implements the following:
 
  which allows ICMP echo requests (PING), incoming connection on TCP port 22
 
  (SSH), and also introduces rate-limitting for incoming ICMP echo request
 
  pacakges and (new) TCP connections. The rate-limitting is based on the source
 
  IP address, using the ``iptables hashlimit`` module.
 
  IP address, using the ``iptables hashlimit`` module. Incoming TCP packets
 
  that have been dropped due to rate-limiting are logged in the system log with
 
  message prefix ``RATELIMIT``. No logging is done for the dropped ICMP
 
  packets.
 
* Sets-up system for performing checks on certificates (currently only if they
 
  expire within less than 30 days). Roles that want their certificates checked
 
  should deploy a ``.conf`` to directory ``/etc/check_certificate/`` with paths
roles/common/molecule/default/tests/test_default.py
Show inline comments
 
import ipaddress
 
import os
 
import re
 

	
 
@@ -492,3 +493,31 @@ def test_legacy_iptables_removal_script(host):
 
    assert script.user == "root"
 
    assert script.group == "root"
 
    assert script.mode == 0o755
 

	
 

	
 
@pytest.mark.parametrize('ip_protocol', [4, 6])
 
def test_tcp_rate_limit_dropped_packet_message_tagging(host, ip_protocol):
 
    """
 
    Tests log message tagging for dropped incoming TCP packets
 
    (due to rate-limiting).
 
    """
 

	
 
    ansible_runner = testinfra.utils.ansible_runner.AnsibleRunner(os.environ['MOLECULE_INVENTORY_FILE'])
 
    client = ansible_runner.get_host(ansible_runner.get_hosts('client-allowed')[0])
 

	
 
    hostname = host.run("hostname").stdout.strip()
 
    timestamp = host.run("date '+%b %d %H:%M:%S'").stdout.strip()
 
    ip_address = client.run("getent ahostsv%s %s", str(ip_protocol), hostname).stdout.strip().split("\n")[-1].split()[0]
 
    ip_address_exploded = ipaddress.ip_address(ip_address).exploded
 

	
 
    expected_message = re.compile(r"%s kernel: RATELIMIT .* DST=%s .* PROTO=TCP .* DPT=22" % (re.escape(hostname), re.escape(ip_address_exploded)))
 

	
 
    with host.sudo():
 

	
 
        # This should trigger the firewall rules and produce log entries.
 
        client.run("for i in $(seq 12); do nc.openbsd -%s -w 1 -z %s 22; done", str(ip_protocol), hostname)
 

	
 
        log = host.run("journalctl --dmesg --since %s", timestamp)
 

	
 
        assert log.rc == 0
 
        assert expected_message.search(log.stdout) is not None
roles/common/templates/00-base.conf.j2
Show inline comments
 
@@ -33,7 +33,7 @@ domain ip {
 
            proto tcp tcp-flags (FIN SYN RST ACK) SYN {
 
                mod hashlimit hashlimit {{ incoming_connection_limit }} hashlimit-burst {{ incoming_connection_limit_burst }}
 
                    hashlimit-mode srcip hashlimit-name icmp RETURN;
 
                LOG;
 
                LOG log-prefix 'RATELIMIT ';
 
                DROP;
 
            }
 
        }
 
@@ -89,7 +89,7 @@ domain ip6 {
 
            proto tcp tcp-flags (FIN SYN RST ACK) SYN {
 
                mod hashlimit hashlimit {{ incoming_connection_limit }} hashlimit-burst {{ incoming_connection_limit_burst }}
 
                    hashlimit-mode srcip hashlimit-name icmp RETURN;
 
                LOG;
 
                LOG log-prefix 'RATELIMIT ';
 
                DROP;
 
            }
 
        }
0 comments (0 inline, 0 general) First comment
You need to be logged in to comment. Login now