Debian GNU/Linux · Network

Drop and log packets with spoofed source addresses

When it fails: The kernel accepts packets whose source address cannot be genuine, without logging them. Spoofed packets are used to bypass address-based filtering and to hide the origin of attacks.

CB-DEB-NET-011mediumactiveautomatedautomated fixprofile core

Description

These kernel settings handle packets whose source address is impossible or suspicious:

  • rp_filter (reverse path filtering): drop a packet when the reply to its source would not leave through the interface it came in on (1, strict) or through any interface (2, loose);
  • log_martians: log packets with impossible addresses ("martians") to the kernel log;
  • route_localnet = 0: never route packets from or to 127.0.0.0/8 on real interfaces;
  • accept_local = 0: drop packets arriving from outside with one of the host's own addresses as source.

rp_filter and log_martians are set for all and for default (interfaces created later).

Debian 13 ships default.rp_filter = 2 and sets rp_filter = 2 on every existing interface through /usr/lib/sysctl.d/50-default.conf. The kernel applies the higher of the all and per-interface values, so those interfaces stay in loose mode until their own value is changed. ufw, when active, writes log_martians = 0 from /etc/ufw/sysctl.conf at each start; the fix changes that file to 1.

Rationale

Reverse path filtering is the host side of ingress filtering (RFC 3704): it drops most spoofed packets before any service sees them, which defeats attacks that rely on trusted source addresses. Logging martians shows misconfigurations and spoofing attempts. Loopback and local source addresses must never come from the network.

Impact

Strict reverse path filtering drops legitimate traffic on hosts with asymmetric routing (several interfaces on overlapping networks, policy routing, some VPNs). Set the rp_filter parameter to 2 (loose) on such hosts. Martian logging can add kernel log lines on noisy networks.

Setting

Locationsysctl `net.ipv4.conf.{all,default}.rp_filter`, `net.ipv4.conf.{all,default}.log_martians`, `net.ipv4.conf.all.route_localnet`, `net.ipv4.conf.all.accept_local`, persisted in `/etc/sysctl.d/`
Defaultrp_filter 0 (Debian 12) or 2 (Debian 13), log_martians 0
Recommendedrp_filter {{ rp_filter }}, log_martians 1, route_localnet 0, accept_local 0

Parameters

ParameterCoreServerServer hardenedDesktopDesktop hardenedBounds
rp_filterinteger. Reverse path filtering mode, 1 strict, 2 loose for hosts with asymmetric routing.111111 to 2

The value used is your override (tailoring file), else the profile's, else the one of the profile it extends, else the default. Bounds limit what an override may set.

Audit

Run sysctl net.ipv4.conf.all.rp_filter net.ipv4.conf.default.rp_filter net.ipv4.conf.all.log_martians net.ipv4.conf.default.log_martians net.ipv4.conf.all.route_localnet net.ipv4.conf.all.accept_local. rp_filter must be {{ rp_filter }}, log_martians 1, the others 0. Check that no sysctl file sets other values, and, with ufw, that /etc/ufw/sysctl.conf does not set log_martians=0.

Automated: every check must pass. Scanners report each check by its id.

all-rp-filter

net.ipv4.conf.all.rp_filter.

key: net.ipv4.conf.all.rp_filter
value: '{{ rp_filter }}'

default-rp-filter

net.ipv4.conf.default.rp_filter.

key: net.ipv4.conf.default.rp_filter
value: '{{ rp_filter }}'

all-log-martians

net.ipv4.conf.all.log_martians.

key: net.ipv4.conf.all.log_martians
value: 1

default-log-martians

net.ipv4.conf.default.log_martians.

key: net.ipv4.conf.default.log_martians
value: 1

route-localnet

net.ipv4.conf.all.route_localnet.

key: net.ipv4.conf.all.route_localnet
value: 0

accept-local

net.ipv4.conf.all.accept_local.

key: net.ipv4.conf.all.accept_local
value: 0

ufw-log-martians

ufw does not turn martian logging off when it starts.

path: /etc/ufw/sysctl.conf
pattern: ^\s*net/ipv4/conf/(all|default)/log_martians\s*=\s*0
expect: no_match

Remediation

  1. Add to /etc/sysctl.d/60-cirsec.conf:
    net.ipv4.conf.all.rp_filter = {{ rp_filter }}
    net.ipv4.conf.default.rp_filter = {{ rp_filter }}
    net.ipv4.conf.all.log_martians = 1
    net.ipv4.conf.default.log_martians = 1
    net.ipv4.conf.all.route_localnet = 0
    net.ipv4.conf.all.accept_local = 0
    
    remove other assignments, then run sysctl --system.
  2. With ufw, set the log_martians lines of /etc/ufw/sysctl.conf to 1.
Restartnone
Disruptionlow

Rollback

Remove the lines from /etc/sysctl.d/60-cirsec.conf, restore /etc/ufw/sysctl.conf from the backup, and set the previous values with sysctl -w.

all-rp-filter

Generated from check all-rp-filter: the engine writes the fix for every output, it sets the expected value and the check runs again after.

default-rp-filter

Generated from check default-rp-filter: the engine writes the fix for every output, it sets the expected value and the check runs again after.

all-log-martians

Generated from check all-log-martians: the engine writes the fix for every output, it sets the expected value and the check runs again after.

default-log-martians

Generated from check default-log-martians: the engine writes the fix for every output, it sets the expected value and the check runs again after.

route-localnet

Generated from check route-localnet: the engine writes the fix for every output, it sets the expected value and the check runs again after.

accept-local

Generated from check accept-local: the engine writes the fix for every output, it sets the expected value and the check runs again after.

ufw-log-martians

f=/etc/ufw/sysctl.conf
[ -f "$f" ] || exit 0
grep -Eq '^[[:space:]]*net/ipv4/conf/(all|default)/log_martians[[:space:]]*=[[:space:]]*0' "$f" || exit 0
cb_backup "$f"
sed -i -E 's#^([[:space:]]*net/ipv4/conf/(all|default)/log_martians[[:space:]]*=[[:space:]]*)0#\11#' "$f"

Handwritten code reads parameters from CB_<NAME> environment variables. Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.

References

Mappings

FrameworkIDRelationNote
ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0R12partialR12 lists many IPv4 settings; this control covers anti-spoofing ones. ANSSI does not ask for log_martians.
NIST SP 800-53 Rev. 55.1.1SC-7related

How this control relates to the other framework's: equivalent, stricter, looser, partial or related.

Threats mitigated

People and lifecycle

Authors
Verified2026-10-18 by Sn0wAlice on 12, Proxmox VM 921, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64. Generated sysctl fixes plus the ufw sysctl.conf fix; log_martians stays 1 after reboot with ufw active.
Verified2026-10-18 by Sn0wAlice on 13, Proxmox VM 931, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64. Generated sysctl fixes plus the ufw sysctl.conf fix; log_martians stays 1 after reboot with ufw active.
Introduced inv0.1.0
Created, updated2026-10-18, 2026-10-18
Translationsfr