Disable Kernel Parameter for Accepting Source-Routed Packets on IPv4 Interfaces by Default

Classification:

compliance

Framework:

Control:

Description

To set the runtime status of the net.ipv4.conf.default.accept_source_route kernel parameter, run the following command:

$ sudo sysctl -w net.ipv4.conf.default.accept_source_route=0

To make sure that the setting is persistent, add the following line to a file in the directory /etc/sysctl.d:

net.ipv4.conf.default.accept_source_route = 0

Rationale

Source-routed packets allow the source of the packet to suggest routers forward the packet along a different path than configured on the router, which can be used to bypass network security measures.

Accepting source-routed packets in the IPv4 protocol has few legitimate uses. It should be disabled unless it is absolutely required, such as when IPv4 forwarding is enabled and the system is legitimately functioning as a router.

Remediation

Shell script

The following script can be run on the host to remediate the issue.

# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]; then

# Comment out any occurrences of net.ipv4.conf.default.accept\_source\_route from /etc/sysctl.d/\*.conf files

for f in /etc/sysctl.d/\*.conf /run/sysctl.d/\*.conf /usr/local/lib/sysctl.d/\*.conf /usr/lib/sysctl.d/\*.conf; do

 matching\_list=$(grep -P '^(?!#).\*[\s]\*net.ipv4.conf.default.accept\_source\_route.\*$' $f | uniq )
 if ! test -z "$matching\_list"; then
 while IFS= read -r entry; do
 escaped\_entry=$(sed -e 's|/|\\/|g' <<< "$entry")
 # comment out "net.ipv4.conf.default.accept\_source\_route" matches to preserve user data
 sed -i "s/^${escaped\_entry}$/# &/g" $f
 done <<< "$matching\_list"
 fi
done

#
# Set sysctl config file which to save the desired value
#

SYSCONFIG\_FILE="/etc/sysctl.conf"

sysctl\_net\_ipv4\_conf\_default\_accept\_source\_route\_value=''


#
# Set runtime for net.ipv4.conf.default.accept\_source\_route
#
/sbin/sysctl -q -n -w net.ipv4.conf.default.accept\_source\_route="$sysctl\_net\_ipv4\_conf\_default\_accept\_source\_route\_value"

#
# If net.ipv4.conf.default.accept\_source\_route present in /etc/sysctl.conf, change value to appropriate value
# else, add "net.ipv4.conf.default.accept\_source\_route = value" to /etc/sysctl.conf
#

# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped\_key=$(sed 's/[\^=\$,;+]\*//g' <<< "^net.ipv4.conf.default.accept\_source\_route")

# shellcheck disable=SC2059
printf -v formatted\_output "%s = %s" "$stripped\_key" "$sysctl\_net\_ipv4\_conf\_default\_accept\_source\_route\_value"

# If the key exists, change it. Otherwise, add it to the config\_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC\_ALL=C grep -q -m 1 -i -e "^net.ipv4.conf.default.accept\_source\_route\\>" "${SYSCONFIG\_FILE}"; then
 escaped\_formatted\_output=$(sed -e 's|/|\\/|g' <<< "$formatted\_output")
 LC\_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.default.accept\_source\_route\\>.\*/$escaped\_formatted\_output/gi" "${SYSCONFIG\_FILE}"
else
 if [[ -s "${SYSCONFIG\_FILE}" ]] && [[ -n "$(tail -c 1 -- "${SYSCONFIG\_FILE}" || true)" ]]; then
 LC\_ALL=C sed -i --follow-symlinks '$a'\\ "${SYSCONFIG\_FILE}"
 fi
 printf '%s\n' "$formatted\_output" >> "${SYSCONFIG\_FILE}"
fi

else
 >&2 echo 'Remediation is not applicable, nothing was done'
fi

Ansible playbook

The following playbook can be run with Ansible to remediate the issue.

- name: List /etc/sysctl.d/\*.conf files
 find:
 paths:
 - /etc/sysctl.d/
 - /run/sysctl.d/
 - /usr/local/lib/sysctl.d/
 - /usr/lib/sysctl.d/
 contains: ^[\s]\*net.ipv4.conf.default.accept\_source\_route.\*$
 patterns: '\*.conf'
 file\_type: any
 register: find\_sysctl\_d
 when: ansible\_virtualization\_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CJIS-5.10.1.1
 - NIST-800-171-3.1.20
 - NIST-800-53-CM-7(a)
 - NIST-800-53-CM-7(b)
 - NIST-800-53-SC-5
 - NIST-800-53-SC-7(a)
 - disable\_strategy
 - low\_complexity
 - medium\_disruption
 - medium\_severity
 - reboot\_required
 - sysctl\_net\_ipv4\_conf\_default\_accept\_source\_route

- name: Comment out any occurrences of net.ipv4.conf.default.accept\_source\_route from
 config files
 replace:
 path: '{{ item.path }}'
 regexp: ^[\s]\*net.ipv4.conf.default.accept\_source\_route
 replace: '#net.ipv4.conf.default.accept\_source\_route'
 loop: '{{ find\_sysctl\_d.files }}'
 when: ansible\_virtualization\_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CJIS-5.10.1.1
 - NIST-800-171-3.1.20
 - NIST-800-53-CM-7(a)
 - NIST-800-53-CM-7(b)
 - NIST-800-53-SC-5
 - NIST-800-53-SC-7(a)
 - disable\_strategy
 - low\_complexity
 - medium\_disruption
 - medium\_severity
 - reboot\_required
 - sysctl\_net\_ipv4\_conf\_default\_accept\_source\_route
- name: XCCDF Value sysctl\_net\_ipv4\_conf\_default\_accept\_source\_route\_value # promote to variable
 set\_fact:
 sysctl\_net\_ipv4\_conf\_default\_accept\_source\_route\_value: !!str 
 tags:
 - always

- name: Ensure sysctl net.ipv4.conf.default.accept\_source\_route is set
 sysctl:
 name: net.ipv4.conf.default.accept\_source\_route
 value: '{{ sysctl\_net\_ipv4\_conf\_default\_accept\_source\_route\_value }}'
 sysctl\_file: /etc/sysctl.conf
 state: present
 reload: true
 when: ansible\_virtualization\_type not in ["docker", "lxc", "openvz", "podman", "container"]
 tags:
 - CJIS-5.10.1.1
 - NIST-800-171-3.1.20
 - NIST-800-53-CM-7(a)
 - NIST-800-53-CM-7(b)
 - NIST-800-53-SC-5
 - NIST-800-53-SC-7(a)
 - disable\_strategy
 - low\_complexity
 - medium\_disruption
 - medium\_severity
 - reboot\_required
 - sysctl\_net\_ipv4\_conf\_default\_accept\_source\_route