CIS Hardening of a Debian Linux Server Part 3: Level 1 Network
This is the fourth entry in the series documenting the Debian 13 server CIS hardening project.
This entry covers sections 3.1 through 3.3 of the benchmark. This is a Level 1 pass. Level 2 recommendations are deferred.
3.1: Configure Network Devices #
This section covers 3.1.1 through 3.1.3 of the benchmark. The reduction of attack surface has been a recurring theme throughout this series, and here it takes the form of removing unused or unnecessary network device types.
3.1.1: Ensure IPv6 Status Is Identified #
The benchmark recommends that IPv6 remain enabled and configured unless local site policy says otherwise. That recommendation is followed here.
The benchmark’s stated rationale centers on IPv6’s much larger address space, along with its support for stateful and stateless configuration and its suitability for a growing number of networked and smart devices. Framed this way, the push toward IPv6 reads less like a security control in the traditional sense and more like encouragement to move onto the newer protocol ahead of IPv4 address exhaustion concerns.
#!/usr/bin/env bash
{
l_output=""
! grep -Pqs -- '^\h*0\b' /sys/module/ipv6/parameters/disable &&
l_output="- IPv6 is not enabled"
if sysctl net.ipv6.conf.all.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\b" && \
sysctl net.ipv6.conf.default.disable_ipv6 | grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\b"; then
l_output="- IPv6 is not enabled"
fi
[ -z "$l_output" ] && l_output="- IPv6 is enabled"
echo -e "\n$l_output\n"
}
- IPv6 is enabled
Pass.
3.1.2: Ensure Wireless Interfaces Are Not Available #
The benchmark’s stated impact for this recommendation concerns laptop and some desktop workstations, which typically require wireless interfaces to be available. That impact statement describes a workstation, not a server, so the underlying concern does not apply to this system.
#!/usr/bin/env bash
{
l_output="" l_output2=""
module_chk()
{
# Check how module will be loaded
l_loadable="$(modprobe -n -v "$l_mname")"
if grep -Pq -- '^\h*install \/bin\/(true|false)' <<< "$l_loadable"; then
l_output="$l_output\n - module: \"$l_mname\" is not loadable: \"$l_loadable\""
else
l_output2="$l_output2\n - module: \"$l_mname\" is loadable: \"$l_loadable\""
fi
# Check is the module currently loaded
if ! lsmod | grep "$l_mname" > /dev/null 2>&1; then
l_output="$l_output\n - module: \"$l_mname\" is not loaded"
else
l_output2="$l_output2\n - module: \"$l_mname\" is loaded"
fi
# Check if the module is deny listed
if modprobe --showconfig | grep -Pq -- "^\h*blacklist\h+$l_mname\b"; then
l_output="$l_output\n - module: \"$l_mname\" is deny listed in: \"$(grep -Pl -- "^\h*blacklist\h+$l_mname\b" /etc/modprobe.d/*)\""
else
l_output2="$l_output2\n - module: \"$l_mname\" is not deny listed"
fi
}
if [ -n "$(find /sys/class/net/*/ -type d -name wireless)" ]; then
l_dname=$(for driverdir in $(find /sys/class/net/*/ -type d -name wireless | xargs -0 dirname); do basename "$(readlink -f "$driverdir"/device/driver/module)";done | sort -u)
for l_mname in $l_dname; do
module_chk
done
fi
# Report results. If no failures output in l_output2, we pass
if [ -z "$l_output2" ]; then
echo -e "\n- Audit Result:\n ** PASS **"
if [ -z "$l_output" ]; then
echo -e "\n - System has no wireless NICs installed"
else
echo -e "\n$l_output\n"
fi
else
echo -e "\n- Audit Result:\n ** FAIL **\n - Reason(s) for audit failure:\n$l_output2\n"
[ -n "$l_output" ] && echo -e "\n- Correctly set:\n$l_output\n"
fi
}
- Audit Result:
** PASS **
- System has no wireless NICs installed
3.1.3: Ensure Bluetooth Services Are Not In Use #
# dpkg-query -s bluez &>/dev/null && echo "bluez is installed"
Nothing is returned. The bluez package is not installed, so this recommendation passes.
3.2: Configure Network Kernel Modules #
This section covers 3.2.1 through 3.2.6, addressing unused network kernel modules. It follows the same approach used for filesystem kernel modules earlier in the series: modules with no legitimate use on this server are disabled. The audit script used across this group is identical apart from the module name being checked, so it is shown once, for the first recommendation. The remaining recommendations in this section note only the substituted module name and the result.
3.2.1: Ensure ATM Kernel Module Is Not Available #
#!/usr/bin/env bash
{
l_mod_name="atm" l_mod_type="net"
while IFS= read -r l_mod_path; do
if [ -d "$l_mod_path/${l_mod_name//-/\/}" ] && \
[ -n "$(ls -A "$l_mod_path/${l_mod_name//-/\/}")" ]; then
printf '%s\n' "$l_mod_name exists in $l_mod_path"
fi
done < <(readlink -e /usr/lib/modules/**/kernel/$l_mod_type \
|| readlink -e /lib/modules/**/kernel/$l_mod_type)
}
The script returns nothing. The atm module is not available, so no remediation
is needed.
3.2.2: Ensure CAN Kernel Module Is Not Available #
The same script is run, substituting can for the module name. Nothing is
returned; the module is not available, and no remediation is needed.
3.2.3: Ensure DCCP Kernel Module Is Not Available #
Substituting dccp, the script returns:
dccp exists in /usr/lib/modules/6.12.86+deb13-cloud-amd64/kernel/net
dccp exists in /usr/lib/modules/6.12.94+deb13-cloud-amd64/kernel/net
Fail.
# lsmod | grep 'dccp'
Nothing is returned; the module is not currently loaded.
# modprobe --showconfig | grep -P -- '\b(install|blacklist)\h+dccp\b'
Nothing is returned either, so the recommendation still fails overall. The module is unloaded as a precaution before blocking it:
# modprobe -r dccp 2>/dev/null
# rmmod dccp 2>/dev/null
Both commands do approximately the same thing here. A configuration file is then created to block the module from loading, following the same pattern used for filesystem modules:
# printf '\n%s\n' "install dccp /bin/false" >> /etc/modprobe.d/60-dccp.conf
# printf '\n%s\n' "blacklist dccp" >> /etc/modprobe.d/60-dccp.conf
# modprobe --showconfig | grep -P -- '\b(install|blacklist)\h+dccp\b'
blacklist dccp
install dccp /bin/false
3.2.4: Ensure RDS Kernel Module Is Not Available #
Substituting rds, the script returns:
rds exists in /usr/lib/modules/6.12.86+deb13-cloud-amd64/kernel/net
rds exists in /usr/lib/modules/6.12.94+deb13-cloud-amd64/kernel/net
Fail.
# lsmod | grep 'rds'
Nothing is returned; rds is not loaded.
# modprobe --showconfig | grep -P -- '\b(install|blacklist)\h+rds\b'
Nothing is returned, so the recommendation fails. Unloading and blocking follow the same pattern:
# modprobe -r rds 2>/dev/null
# printf '\n%s\n' "install rds /bin/false" >> /etc/modprobe.d/60-rds.conf
# printf '\n%s\n' "blacklist rds" >> /etc/modprobe.d/60-rds.conf
# modprobe --showconfig | grep -P -- '\b(install|blacklist)\h+rds\b'
blacklist rds
install rds /bin/false
3.2.5: Ensure SCTP Kernel Module Is Not Available #
Substituting sctp, the script returns:
sctp exists in /usr/lib/modules/6.12.86+deb13-cloud-amd64/kernel/net
sctp exists in /usr/lib/modules/6.12.94+deb13-cloud-amd64/kernel/net
Fail.
# lsmod | grep 'sctp'
No output. Not loaded.
# modprobe --showconfig | grep -P -- '\b(install|blacklist)\h+sctp\b'
No output, so the recommendation fails. Same remediation:
# modprobe -r sctp 2>/dev/null
# printf '\n%s\n' "install sctp /bin/false" >> /etc/modprobe.d/60-sctp.conf
# printf '\n%s\n' "blacklist sctp" >> /etc/modprobe.d/60-sctp.conf
# modprobe --showconfig | grep -P -- '\b(install|blacklist)\h+sctp\b'
blacklist sctp
install sctp /bin/false
Pass.
3.2.6: Ensure TIPC Kernel Module Is Not Available #
Substituting tipc, the script returns:
tipc exists in /usr/lib/modules/6.12.86+deb13-cloud-amd64/kernel/net
tipc exists in /usr/lib/modules/6.12.94+deb13-cloud-amd64/kernel/net
Fail.
# lsmod | grep 'tipc'
No output. Not loaded.
# modprobe --showconfig | grep -P -- '\b(install|blacklist)\h+tipc\b'
No output, so the recommendation fails. Same remediation:
# modprobe -r tipc 2>/dev/null
# printf '\n%s\n' "install tipc /bin/false" >> /etc/modprobe.d/60-tipc.conf
# printf '\n%s\n' "blacklist tipc" >> /etc/modprobe.d/60-tipc.conf
# modprobe --showconfig | grep -P -- '\b(install|blacklist)\h+tipc\b'
blacklist tipc
install tipc /bin/false
Pass.
3.3: Configure Network Kernel Parameters #
This section covers 3.3.1 and 3.3.2, addressing IPv4 and IPv6 kernel network parameters set through sysctl.
Sysctl configuration is read from several directories in a fixed
order: /etc/sysctl.d/, /run/sysctl.d/, /usr/local/lib/sysctl.d/,
/usr/lib/sysctl.d/, /lib/sysctl.d/, and finally /etc/sysctl.conf. Files
are evaluated in lexicographic order regardless of which of these directories
they live in, and once a given filename has been loaded from a higher-priority
directory, a file of the same name found later in the order is ignored. In
practice, a parameter can be overridden either by a same-named file placed in
a higher-priority directory, or by a later file in the order that reassigns the
same key.
The recommendations in this section are numerous and largely share the same audit pattern, with only the parameter name and its expected value changing between them. The underlying audit script is shown once, as a representative example, the first time it appears. Later recommendations state the parameter, its observed value, and the outcome, without repeating the full script.
3.3.1: Configure IPv4 Parameters #
This subsection covers 3.3.1.1 through 3.3.1.18.
3.3.1.1: Ensure net.ipv4.ip_forward Is Configured #
Level 2, deferred to the Level 2 pass.
3.3.1.2: Ensure net.ipv4.conf.all.forwarding Is Configured #
# sysctl net.ipv4.conf.all.forwarding
net.ipv4.conf.all.forwarding = 0
Already passing, but the benchmark’s own note points out that this reflects
only the value currently applied by systemd-sysctl. If the file providing that
value is not under /etc/sysctl.d/, it is still recommended to add an explicit
.conf file there so the setting cannot silently drift on a future update. That
recommendation is followed for every parameter in this subsection.
#!/usr/bin/env bash
{
l_parameter_name="net.ipv4.conf.all.forwarding"
l_grep="${l_parameter_name//./(\\.|\\/)}" a_output=() a_files=()
l_systemdsysctl="$(readlink -e /lib/systemd/systemd-sysctl \
|| readlink -e /usr/lib/systemd/systemd-sysctl)"
l_ufw_file="$([ -f /etc/default/ufw ] && \
awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)"
[ -f "$(readlink -e "$l_ufw_file")" ] && \
a_files+=("$l_ufw_file"); a_files+=("/etc/sysctl.conf")
while IFS= read -r l_fname; do
l_file="$(readlink -e "${l_fname//# /}")"
[ -n "$l_file" ] && ! grep -Psiq -- '(^|\h+)'"$l_file"'\b' \
<<< "${a_files[*]}" && a_files+=("$l_file")
done < <("$l_systemdsysctl" --cat-config | tac | \
grep -Psio -- '^\h*#\h*\/[^#\n\r\h]+\.conf\b')
for l_file in "${a_files[@]}"; do
l_opt="$(grep -Psio '^\h*'"$l_grep"'\h*=\h*\H+\b' "$l_file" | tail -n 1)"
l_option_value="$(cut -d= -f2 <<< "$l_opt" | xargs)"
[ -n "$l_option_value" ] && \
a_output+=(" - \"$l_parameter_name = $l_option_value\" is set in: \"$l_file\"")
done
[ "${#a_output[@]}" -gt "0" ] && printf '%s\n' "" "${a_output[@]}" ""
}
No output is returned. Since the audit script already reports the setting clean, the benchmark’s own remediation script, which reviews existing files for a conflicting value, is skipped as unnecessary.
# printf '%s\n' "" "net.ipv4.conf.all.forwarding = 0" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
* Applying /usr/lib/sysctl.d/10-coredump-debian.conf ...
* Applying /usr/lib/sysctl.d/50-default.conf ...
* Applying /usr/lib/sysctl.d/50-pid-max.conf ...
* Applying /etc/sysctl.d/60-kernel_sysctl.conf ...
* Applying /etc/sysctl.d/61-ipv4_sysctl.conf ...
kernel.core_pattern = core
(...)
Re-running the audit script now returns:
- "net.ipv4.conf.all.forwarding = 0" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
Pass.
3.3.1.3: Ensure net.ipv4.conf.default.forwarding Is Configured #
# sysctl net.ipv4.conf.default.forwarding
net.ipv4.conf.default.forwarding = 0
Already passing. The audit script, substituting this parameter name, returns nothing. The value is written explicitly:
# printf '%s\n' "" "net.ipv4.conf.default.forwarding = 0" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv4.conf.default.forwarding = 0" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.4: Ensure net.ipv4.conf.all.send_redirects Is Configured #
# sysctl net.ipv4.conf.all.send_redirects
net.ipv4.conf.all.send_redirects = 1
Fail. It should be 0. The audit script returns nothing.
# printf '%s\n' "" "net.ipv4.conf.all.send_redirects = 0" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
# sysctl net.ipv4.conf.all.send_redirects
net.ipv4.conf.all.send_redirects = 0
The audit script now returns:
- "net.ipv4.conf.all.send_redirects = 0" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
Pass.
3.3.1.5: Ensure net.ipv4.conf.default.send_redirects Is Configured #
# sysctl net.ipv4.conf.default.send_redirects
net.ipv4.conf.default.send_redirects = 1
Fail. The audit script returns nothing.
# printf '%s\n' "" "net.ipv4.conf.default.send_redirects = 0" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
# sysctl net.ipv4.conf.default.send_redirects
net.ipv4.conf.default.send_redirects = 0
The audit script now returns:
- "net.ipv4.conf.default.send_redirects = 0" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.6: Ensure net.ipv4.icmp_ignore_bogus_error_responses Is Configured #
# sysctl net.ipv4.icmp_ignore_bogus_error_responses
net.ipv4.icmp_ignore_bogus_error_responses = 1
Already passing (the expected value here is 1). The audit script returns nothing, so the setting is still written explicitly:
# printf '%s\n' "" "net.ipv4.icmp_ignore_bogus_error_responses = 1" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv4.icmp_ignore_bogus_error_responses = 1" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.7: Ensure net.ipv4.icmp_echo_ignore_broadcasts Is Configured #
# sysctl net.ipv4.icmp_echo_ignore_broadcasts
net.ipv4.icmp_echo_ignore_broadcasts = 1
Already passing. The audit script returns nothing, so the value is written explicitly:
# printf '%s\n' "" "net.ipv4.icmp_echo_ignore_broadcasts = 1" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv4.icmp_echo_ignore_broadcasts = 1" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.8: Ensure net.ipv4.conf.all.accept_redirects Is Configured #
# sysctl net.ipv4.conf.all.accept_redirects
net.ipv4.conf.all.accept_redirects = 1
Fail. It should be 0. The audit script returns nothing.
# printf '%s\n' "" "net.ipv4.conf.all.accept_redirects = 0" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv4.conf.all.accept_redirects = 0" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.9: Ensure net.ipv4.conf.default.accept_redirects Is Configured #
# sysctl net.ipv4.conf.default.accept_redirects
net.ipv4.conf.default.accept_redirects = 1
Fail. The audit script returns nothing.
# printf '%s\n' "" "net.ipv4.conf.default.accept_redirects = 0" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv4.conf.default.accept_redirects = 0" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.10: Ensure net.ipv4.conf.all.secure_redirects Is Configured #
# sysctl net.ipv4.conf.all.secure_redirects
net.ipv4.conf.all.secure_redirects = 1
Fail. The audit script returns nothing.
# printf '%s\n' "" "net.ipv4.conf.all.secure_redirects = 0" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv4.conf.all.secure_redirects = 0" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.11: Ensure net.ipv4.conf.default.secure_redirects Is Configured #
# sysctl net.ipv4.conf.default.secure_redirects
net.ipv4.conf.default.secure_redirects = 1
Fail. It should be 0. The audit script returns nothing.
# printf '%s\n' "" "net.ipv4.conf.default.secure_redirects = 0" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
# sysctl net.ipv4.conf.default.secure_redirects
net.ipv4.conf.default.secure_redirects = 0
The audit script now returns:
- "net.ipv4.conf.default.secure_redirects = 0" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.12: Ensure net.ipv4.conf.all.rp_filter Is Configured #
# sysctl net.ipv4.conf.all.rp_filter
net.ipv4.conf.all.rp_filter = 0
Fail. It should be 1. The audit script returns nothing.
# printf '%s\n' "" "net.ipv4.conf.all.rp_filter = 1" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
# sysctl net.ipv4.conf.all.rp_filter
net.ipv4.conf.all.rp_filter = 1
The audit script now returns:
- "net.ipv4.conf.all.rp_filter = 1" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.13: Ensure net.ipv4.conf.default.rp_filter Is Configured #
# sysctl net.ipv4.conf.default.rp_filter
net.ipv4.conf.default.rp_filter = 2
A value of 2 is also a valid setting for this parameter; it corresponds to loose mode, which is less strict than the value of 1 expected by the benchmark. Either way, this fails the recommendation as written.
Unlike the other parameters in this subsection, running the audit script here does return a result:
- "net.ipv4.conf.default.rp_filter = 2" is set in: "/usr/lib/sysctl.d/50-default.conf"
This value is already present in a shipped configuration file, so the dedicated remediation script is needed to comment out the conflicting line before the correct value is written:
#!/usr/bin/env bash
{
l_option="net.ipv4.conf.default.rp_filter" l_value="1"
l_grep="${l_option//./(\\.|\\/)}" a_files=()
l_systemdsysctl="$(readlink -e /lib/systemd/systemd-sysctl \
|| readlink -e /usr/lib/systemd/systemd-sysctl)"
l_ufw_file="$([ -f /etc/default/ufw ] && \
awk -F= '/^\s*IPT_SYSCTL=/ {print $2}' /etc/default/ufw)"
[ -f "$(readlink -e "$l_ufw_file")" ] && \
a_files+=("$l_ufw_file"); a_files+=("/etc/sysctl.conf")
while IFS= read -r l_fname; do
l_file="$(readlink -e "${l_fname//# /}")"
[ -n "$l_file" ] && ! grep -Psiq -- '(^|\h+)'"$l_file"'\b' \
<<< "${a_files[*]}" && a_files+=("$l_file")
done < <("$l_systemdsysctl" --cat-config | tac | \
grep -Psio -- '^\h*#\h*\/[^#\n\r\h]+\.conf\b')
for l_file in "${a_files[@]}"; do
grep -Psio -- '\h*'"$l_grep"'\h*=\h*\H+\b' "$l_file" \
| grep -Psivq -- '^\h*'"$l_grep"'\h*=\h*'"$l_value"'\b' && \
sed -ri '/^\s*'"$l_grep"'\s*=\s*(0|[2-9]|1[0-9]+)/s/^/# /' "$l_file"
done
}
After running this, the audit script returns nothing, and the usual process is followed:
# printf '%s\n' "" "net.ipv4.conf.default.rp_filter = 1" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
# sysctl net.ipv4.conf.default.rp_filter
net.ipv4.conf.default.rp_filter = 1
The audit script now returns:
- "net.ipv4.conf.default.rp_filter = 1" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.14: Ensure net.ipv4.conf.all.accept_source_route Is Configured #
# sysctl net.ipv4.conf.all.accept_source_route
net.ipv4.conf.all.accept_source_route = 0
Already passing. The audit script returns nothing, so the value is written explicitly:
# printf '%s\n' "" "net.ipv4.conf.all.accept_source_route = 0" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv4.conf.all.accept_source_route = 0" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.15: Ensure net.ipv4.conf.default.accept_source_route Is Configured #
# sysctl net.ipv4.conf.default.accept_source_route
net.ipv4.conf.default.accept_source_route = 0
Already passing. Unlike most recommendations in this group, the audit script does return a result here:
- "net.ipv4.conf.default.accept_source_route = 0" is set in: "/usr/lib/sysctl.d/50-default.conf"
The value is correct, but the file is outside /etc/sysctl.d/, so it is still written explicitly there:
# printf '%s\n' "" "net.ipv4.conf.default.accept_source_route = 0" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
The audit script now returns two entries:
- "net.ipv4.conf.default.accept_source_route = 0" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
- "net.ipv4.conf.default.accept_source_route = 0" is set in: "/usr/lib/sysctl.d/50-default.conf"
Multiple files reporting the parameter is not itself a problem, provided all of them agree on the correct value.
3.3.1.16: Ensure net.ipv4.conf.all.log_martians Is Configured #
# sysctl net.ipv4.conf.all.log_martians
net.ipv4.conf.all.log_martians = 0
Fail. It should be 1. The audit script returns nothing.
# printf '%s\n' "" "net.ipv4.conf.all.log_martians = 1" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv4.conf.all.log_martians = 1" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.17: Ensure net.ipv4.conf.default.log_martians Is Configured #
# sysctl net.ipv4.conf.default.log_martians
net.ipv4.conf.default.log_martians = 0
Fail. The audit script returns nothing.
# printf '%s\n' "" "net.ipv4.conf.default.log_martians = 1" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
# sysctl net.ipv4.conf.default.log_martians
net.ipv4.conf.default.log_martians = 1
The audit script now returns:
- "net.ipv4.conf.default.log_martians = 1" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.1.18: Ensure net.ipv4.tcp_syncookies Is Configured #
# sysctl net.ipv4.tcp_syncookies
net.ipv4.tcp_syncookies = 1
Already passing. The audit script returns nothing, so the value is written explicitly:
# printf '%s\n' "" "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.d/61-ipv4_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv4.tcp_syncookies = 1" is set in: "/etc/sysctl.d/61-ipv4_sysctl.conf"
3.3.2: Configure IPv6 Parameters #
This subsection covers 3.3.2.1 through 3.3.2.8. Since the decision was made in 3.1.1 to leave IPv6 enabled rather than disable it, these recommendations apply and are addressed. A quick re-check confirms that IPv6 has in fact not been disabled:
#!/usr/bin/env bash
f_ipv6_chk()
{
a_output=()
! grep -Pqs -- '^\h*0\b' /sys/module/ipv6/parameters/disable && \
a_output+=(" - IPv6 is disabled")
if sysctl net.ipv6.conf.all.disable_ipv6 | \
grep -Pqs -- "^\h*net\.ipv6\.conf\.all\.disable_ipv6\h*=\h*1\b" && \
sysctl net.ipv6.conf.default.disable_ipv6 | \
grep -Pqs -- "^\h*net\.ipv6\.conf\.default\.disable_ipv6\h*=\h*1\b"; then
[ "${#a_output[@]}" -le 0 ] && a_output+=(" - IPv6 is disabled")
fi
[ "${#a_output[@]}" -le 0 ] && a_output+=(" - IPv6 is not disabled")
printf '%s\n' "" "${a_output[@]}" ""
}
f_ipv6_chk
- IPv6 is not disabled
3.3.2.1: Ensure net.ipv6.conf.all.forwarding Is Configured #
# sysctl net.ipv6.conf.all.forwarding
net.ipv6.conf.all.forwarding = 0
Already passing. The audit script returns nothing, so the value is written explicitly:
# printf '%s\n' "" "net.ipv6.conf.all.forwarding = 0" >> /etc/sysctl.d/61-ipv6_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv6.conf.all.forwarding = 0" is set in: "/etc/sysctl.d/61-ipv6_sysctl.conf"
3.3.2.2: Ensure net.ipv6.conf.default.forwarding Is Configured #
# sysctl net.ipv6.conf.default.forwarding
net.ipv6.conf.default.forwarding = 0
Already passing. The audit script returns nothing, so the value is written explicitly:
# printf '%s\n' "" "net.ipv6.conf.default.forwarding = 0" >> /etc/sysctl.d/61-ipv6_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv6.conf.default.forwarding = 0" is set in: "/etc/sysctl.d/61-ipv6_sysctl.conf"
3.3.2.3: Ensure net.ipv6.conf.all.accept_redirects Is Configured #
# sysctl net.ipv6.conf.all.accept_redirects
net.ipv6.conf.all.accept_redirects = 1
Fail. It should be 0. The audit script returns nothing.
# printf '%s\n' "" "net.ipv6.conf.all.accept_redirects = 0" >> /etc/sysctl.d/61-ipv6_sysctl.conf
# sysctl --system
(...)
# sysctl net.ipv6.conf.all.accept_redirects
net.ipv6.conf.all.accept_redirects = 0
The audit script now returns:
- "net.ipv6.conf.all.accept_redirects = 0" is set in: "/etc/sysctl.d/61-ipv6_sysctl.conf"
3.3.2.4: Ensure net.ipv6.conf.default.accept_redirects Is Configured #
# sysctl net.ipv6.conf.default.accept_redirects
net.ipv6.conf.default.accept_redirects = 1
Fail. The audit script returns nothing.
# printf '%s\n' "" "net.ipv6.conf.default.accept_redirects = 0" >> /etc/sysctl.d/61-ipv6_sysctl.conf
# sysctl --system
(...)
# sysctl net.ipv6.conf.default.accept_redirects
net.ipv6.conf.default.accept_redirects = 0
The audit script now returns:
- "net.ipv6.conf.default.accept_redirects = 0" is set in: "/etc/sysctl.d/61-ipv6_sysctl.conf"
3.3.2.5: Ensure net.ipv6.conf.all.accept_source_route Is Configured #
# sysctl net.ipv6.conf.all.accept_source_route
net.ipv6.conf.all.accept_source_route = 0
Already passing. The audit script returns nothing, so the value is written explicitly:
# printf '%s\n' "" "net.ipv6.conf.all.accept_source_route = 0" >> /etc/sysctl.d/61-ipv6_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv6.conf.all.accept_source_route = 0" is set in: "/etc/sysctl.d/61-ipv6_sysctl.conf"
3.3.2.6: Ensure net.ipv6.conf.default.accept_source_route Is Configured #
# sysctl net.ipv6.conf.default.accept_source_route
net.ipv6.conf.default.accept_source_route = 0
Already passing. The audit script returns nothing, so the value is written explicitly:
# printf '%s\n' "" "net.ipv6.conf.default.accept_source_route = 0" >> /etc/sysctl.d/61-ipv6_sysctl.conf
# sysctl --system
(...)
The audit script now returns:
- "net.ipv6.conf.default.accept_source_route = 0" is set in: "/etc/sysctl.d/61-ipv6_sysctl.conf"
3.3.2.7: Ensure net.ipv6.conf.all.accept_ra Is Configured #
# sysctl net.ipv6.conf.all.accept_ra
net.ipv6.conf.all.accept_ra = 1
Fail. It should be 0. The audit script returns nothing.
# printf '%s\n' "" "net.ipv6.conf.all.accept_ra = 0" >> /etc/sysctl.d/61-ipv6_sysctl.conf
# sysctl --system
(...)
# sysctl net.ipv6.conf.all.accept_ra
net.ipv6.conf.all.accept_ra = 0
The audit script now returns:
- "net.ipv6.conf.all.accept_ra = 0" is set in: "/etc/sysctl.d/61-ipv6_sysctl.conf"
3.3.2.8: Ensure net.ipv6.conf.default.accept_ra Is Configured #
# sysctl net.ipv6.conf.default.accept_ra
net.ipv6.conf.default.accept_ra = 1
Fail. The audit script returns nothing.
# printf '%s\n' "" "net.ipv6.conf.default.accept_ra = 0" >> /etc/sysctl.d/61-ipv6_sysctl.conf
# sysctl --system
(...)
# sysctl net.ipv6.conf.default.accept_ra
net.ipv6.conf.default.accept_ra = 0
The audit script now returns:
- "net.ipv6.conf.default.accept_ra = 0" is set in: "/etc/sysctl.d/61-ipv6_sysctl.conf"
Pass.
With this section complete, Lynis is run again:
================================================================================
Lynis security scan details:
Scan mode:
Normal [▆] Forensics [ ] Integration [ ] Pentest [ ]
Lynis modules:
- Compliance status [?]
- Security audit [V]
- Vulnerability scan [V]
Details:
Hardening index : 69 [############# ]
Tests performed : 274
Plugins enabled : 2
Software components:
- Firewall [V]
- Intrusion software [X]
- Malware scanner [X]
Files:
- Test and debug information : /var/log/lynis.log
- Report data : /var/log/lynis-report.dat
================================================================================
The hardening index moves from 68 to 69.