---
title: >-
  Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
  by Default
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > OOTB Rules > Enable Kernel Parameter to Use Reverse
  Path Filtering on all IPv4 Interfaces by Default
---

> For the complete documentation index, see [llms.txt](https://docs.datadoghq.com/llms.txt).

# Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces by Default
 
## Description{% #description %}

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

```
$ sudo sysctl -w net.ipv4.conf.default.rp_filter=1
```

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.rp_filter = 1
```

## Rationale{% #rationale %}

Enabling reverse path filtering drops packets with source addresses that should not have been able to be received on the interface they were received on. It should not be used on systems which are routers for complicated networks, but is helpful for end hosts and routers serving small networks.

## Remediation{% #remediation %}

### Shell script{% #shell-script %}

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

```bash
#!/bin/bash

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}' 'linux-base' 2>/dev/null | grep -q '^installed$'; then

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

SYSCONFIG_FILE="/etc/sysctl.conf"


# Comment out any occurrences of net.ipv4.conf.default.rp_filter from /etc/sysctl.d/*.conf files

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


  # skip systemd-sysctl symlink (/etc/sysctl.d/99-sysctl.conf -> /etc/sysctl.conf)
  if [[ "$(readlink -f "$f")" == "/etc/sysctl.conf" ]]; then continue; fi

  if [[ "$(readlink -f "$f")" == "$(readlink -f "${SYSCONFIG_FILE}")" ]]; then
    # entries starting with net.ipv4.conf.default.rp_filter in the file this remediation writes to
    # are replaced in place below, commenting them out would make the remediation non-idempotent
    matching_list=$(grep -P '^(?!#)(?!net.ipv4.conf.default.rp_filter\b).*[\s]*net.ipv4.conf.default.rp_filter.*$' $f | uniq )
  else
    matching_list=$(grep -P '^(?!#).*[\s]*net.ipv4.conf.default.rp_filter.*$' $f | uniq )
  fi
  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.rp_filter" matches to preserve user data
      sed -i --follow-symlinks "s/^${escaped_entry}$/# &/g" $f
    done <<< "$matching_list"
  fi
done
sysctl_net_ipv4_conf_default_rp_filter_value='1'


#
# Set runtime for net.ipv4.conf.default.rp_filter
#
if ! /bin/false ; then
    /sbin/sysctl -q -n -w net.ipv4.conf.default.rp_filter="$sysctl_net_ipv4_conf_default_rp_filter_value"
fi

#
# If net.ipv4.conf.default.rp_filter present in /etc/sysctl.conf, change value to appropriate value
#	else, add "net.ipv4.conf.default.rp_filter = 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.rp_filter")

# shellcheck disable=SC2059
printf -v formatted_output "%s = %s" "$stripped_key" "$sysctl_net_ipv4_conf_default_rp_filter_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.rp_filter\\>" "${SYSCONFIG_FILE}"; then
    escaped_formatted_output=$(sed -e 's|/|\\/|g' <<< "$formatted_output")
    LC_ALL=C sed -i --follow-symlinks "s/^net.ipv4.conf.default.rp_filter\\>.*/$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{% #ansible-playbook %}

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

```gdscript3
- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter
- name: XCCDF Value sysctl_net_ipv4_conf_default_rp_filter_value # promote to variable
  set_fact:
    sysctl_net_ipv4_conf_default_rp_filter_value: !!str 1
  tags:
    - always

- name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
    by Default - Set fact for sysctl paths
  ansible.builtin.set_fact:
    sysctl_paths:
    - /etc/sysctl.d/
    - /run/sysctl.d/
    - /usr/local/lib/sysctl.d/
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter

- name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
    by Default - Find all files that contain net.ipv4.conf.default.rp_filter
  ansible.builtin.shell:
    cmd: |-
      set -o pipefail
      find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep -HP '^\s*net.ipv4.conf.default.rp_filter\s*=\s*.*$'
    executable: /bin/bash
  register: find_all_values
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter

- name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
    by Default - Find all files that set net.ipv4.conf.default.rp_filter to correct
    value
  ansible.builtin.shell:
    cmd: |-
      set -o pipefail
      find -L {{ sysctl_paths | join(" ") }} -type f -name '*.conf' | xargs grep -HP '^\s*net.ipv4.conf.default.rp_filter\s*=\s*{{ sysctl_net_ipv4_conf_default_rp_filter_value }}$'
    executable: /bin/bash
  register: find_correct_value
  check_mode: false
  changed_when: false
  failed_when: false
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter

- name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
    by Default - Comment out any occurrences of net.ipv4.conf.default.rp_filter from
    config files
  ansible.builtin.replace:
    path: '{{ item | split(":") | first }}'
    regexp: ^[\s]*net.ipv4.conf.default.rp_filter
    replace: '#net.ipv4.conf.default.rp_filter'
  loop: '{{ find_all_values.stdout_lines }}'
  when:
  - '"linux-base" in ansible_facts.packages'
  - find_correct_value.stdout_lines | length == 0 or find_all_values.stdout_lines
    | length > find_correct_value.stdout_lines | length
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter

- name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
    by Default - Comment out any occurrences of net.ipv4.conf.default.rp_filter from
    /etc/ufw/sysctl.conf
  ansible.builtin.replace:
    path: /etc/ufw/sysctl.conf
    regexp: (^[\s]*net.ipv4.conf.default.rp_filter.*$)
    replace: '# \1'
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter

- name: Enable Kernel Parameter to Use Reverse Path Filtering on all IPv4 Interfaces
    by Default - Ensure sysctl net.ipv4.conf.default.rp_filter is set
  ansible.posix.sysctl:
    name: net.ipv4.conf.default.rp_filter
    value: '{{ sysctl_net_ipv4_conf_default_rp_filter_value }}'
    sysctl_file: /etc/sysctl.conf
    state: present
    reload: true
  when: '"linux-base" in ansible_facts.packages'
  tags:
  - NIST-800-53-CM-6(a)
  - NIST-800-53-CM-7(a)
  - NIST-800-53-CM-7(b)
  - NIST-800-53-SC-7(a)
  - disable_strategy
  - low_complexity
  - medium_disruption
  - medium_severity
  - reboot_required
  - sysctl_net_ipv4_conf_default_rp_filter
```
