Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete the CIS requirement to prevent rsyslog from receiving logs from remote clients #10619

3 changes: 1 addition & 2 deletions controls/cis_rhel8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1752,10 +1752,9 @@ controls:
levels:
- l1_server
- l1_workstation
status: partial
status: automated
rules:
- rsyslog_nolisten
# This rule should be extended to consider rainerscript syntax

- id: 4.2.2.1.1
title: Ensure systemd-journal-remote is installed (Manual)
Expand Down
3 changes: 1 addition & 2 deletions controls/cis_rhel9.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1598,10 +1598,9 @@ controls:
levels:
- l1_server
- l1_workstation
status: partial
status: automated
rules:
- rsyslog_nolisten
# This rule should be extended to consider rainerscript syntax

- id: 4.2.2.1.1
title: Ensure systemd-journal-remote is installed (Manual)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# platform = multi_platform_all
# reboot = false
# strategy = configure
# complexity = low
# disruption = low

- name: "{{{ rule_title }}} - Define Rsyslog Config Lines Regex in Legacy Syntax"
ansible.builtin.set_fact:
rsyslog_listen_legacy_regex:
'^\s*\$(((Input(TCP|RELP)|UDP)ServerRun)|ModLoad\s+(imtcp|imudp|imrelp))'

- name: "{{{ rule_title }}} - Search for Legacy Config Lines in Rsyslog Main Config File"
ansible.builtin.find:
paths: "/etc"
pattern: "rsyslog.conf"
contains: "{{ rsyslog_listen_legacy_regex }}"
register: rsyslog_listen_legacy_main_file

- name: "{{{ rule_title }}} - Search for Legacy Config Lines in Rsyslog Include Files"
ansible.builtin.find:
paths: "/etc/rsyslog.d/"
pattern: "*.conf"
contains: "{{ rsyslog_listen_legacy_regex }}"
register: rsyslog_listen_legacy_include_files

- name: "{{{ rule_title }}} - Assemble List of Config Files With Listen Lines in Legacy Syntax"
ansible.builtin.set_fact:
rsyslog_legacy_remote_listen_files: >-
{{ rsyslog_listen_legacy_main_file.files | map(attribute='path') | list
+ rsyslog_listen_legacy_include_files.files | map(attribute='path') | list }}

- name: "{{{ rule_title }}} - Comment Listen Config Lines Wherever Defined Using Legacy Syntax"
ansible.builtin.replace:
path: "{{ item }}"
regexp: "{{ rsyslog_listen_legacy_regex }}"
replace: '# \1'
loop: "{{ rsyslog_legacy_remote_listen_files }}"
register: rsyslog_listen_legacy_comment
when:
- rsyslog_legacy_remote_listen_files | length > 0

- name: "{{{ rule_title }}} - Define Rsyslog Config Lines Regex in RainerScript Syntax"
ansible.builtin.set_fact:
rsyslog_listen_rainer_regex: '^\s*(module|input)\((load|type)="(imtcp|imudp)".*$'

- name: "{{{ rule_title }}} - Search for RainerScript Config Lines in Rsyslog Main Config File"
ansible.builtin.find:
paths: "/etc"
pattern: "rsyslog.conf"
contains: "{{ rsyslog_listen_rainer_regex }}"
register: rsyslog_rainer_remote_main_file

- name: "{{{ rule_title }}} - Search for RainerScript Config Lines in Rsyslog Include Files"
ansible.builtin.find:
paths: "/etc/rsyslog.d/"
pattern: "*.conf"
contains: "{{ rsyslog_listen_rainer_regex }}"
register: rsyslog_rainer_remote_include_files

- name: "{{{ rule_title }}} - Assemble List of Config Files With Listen Lines in RainerScript"
ansible.builtin.set_fact:
rsyslog_rainer_remote_listen_files: >-
{{ rsyslog_rainer_remote_main_file.files | map(attribute='path') | list
+ rsyslog_rainer_remote_include_files.files | map(attribute='path') | list }}

- name: "{{{ rule_title }}} - Comment Listen Config Lines Wherever Defined Using RainerScript"
ansible.builtin.replace:
path: "{{ item }}"
regexp: "{{ rsyslog_listen_rainer_regex }}"
replace: '# \1'
loop: "{{ rsyslog_rainer_remote_listen_files }}"
register: rsyslog_listen_rainer_comment
when:
- rsyslog_rainer_remote_listen_files | length > 0

- name: "{{{ rule_title }}} - Restart Rsyslog if Any Line Were Commented Out"
ansible.builtin.service:
name: rsyslog
state: restarted
when:
- rsyslog_listen_legacy_comment is changed or rsyslog_listen_rainer_comment is changed
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# platform = multi_platform_all
# reboot = false
# strategy = configure
# complexity = low
# disruption = low

legacy_regex='^\s*\$(((Input(TCP|RELP)|UDP)ServerRun)|ModLoad\s+(imtcp|imudp|imrelp))'
rainer_regex='^\s*(module|input)\((load|type)="(imtcp|imudp)".*$'

readarray -t legacy_targets < <(grep -l -E -r "${legacy_regex[@]}" /etc/rsyslog.conf /etc/rsyslog.d/)
readarray -t rainer_targets < <(grep -l -E -r "${rainer_regex[@]}" /etc/rsyslog.conf /etc/rsyslog.d/)

config_changed=false
if [ ${#legacy_targets[@]} -gt 0 ]; then
for target in "${legacy_targets[@]}"; do
sed -E -i "/$legacy_regex/ s/^/# /" "$target"
done
config_changed=true
fi

if [ ${#rainer_targets[@]} -gt 0 ]; then
for target in "${rainer_targets[@]}"; do
sed -E -i "/$rainer_regex/ s/^/# /" "$target"
done
config_changed=true
fi

if $config_changed; then
systemctl restart rsyslog.service
fi
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
<def-group>
<definition class="compliance" id="rsyslog_nolisten" version="2">
{{{ oval_metadata("rsyslogd should reject remote messages") }}}
<criteria>
<criterion comment="Conditions are satisfied"
test_ref="test_rsyslog_nolisten" />
</criteria>
</definition>
<ind:textfilecontent54_test check="all" check_existence="none_exist"
comment="Ensure that the /etc/rsyslog.conf does not contain $InputTCPServerRun | $UDPServerRun | $InputRELPServerRun | $ModLoad imtcp | $ModLoad imudp | $ModLoad imrelp"
id="test_rsyslog_nolisten" version="1">
<ind:object object_ref="object_rsyslog_nolisten" />
</ind:textfilecontent54_test>
<ind:textfilecontent54_object id="object_rsyslog_nolisten" version="2">
<ind:filepath>/etc/rsyslog.conf</ind:filepath>
<ind:pattern operation="pattern match">^[\s]*\$((?:Input(?:TCP|RELP)|UDP)ServerRun|ModLoad[\s]+(imtcp|imudp|imrelp))</ind:pattern>
<ind:instance datatype="int">1</ind:instance>
</ind:textfilecontent54_object>
<definition class="compliance" id="{{{ rule_id }}}" version="2">
{{{ oval_metadata("rsyslogd should reject remote messages") }}}
<criteria operator="AND">
<criterion test_ref="test_rsyslog_nolisten_legacy"
comment="rsyslog legacy syntax is not configured to accept remote messages"/>
<criterion test_ref="test_rsyslog_nolisten_rainerscript"
comment="rsyslog RainerScript is not configured to accept remote messages"/>
</criteria>
</definition>

<ind:textfilecontent54_test id="test_rsyslog_nolisten_legacy" version="1"
check="all" check_existence="none_exist"
comment="rsyslog configuration files don't contain $InputTCPServerRun | $UDPServerRun |
$InputRELPServerRun | $ModLoad imtcp | $ModLoad imudp | $ModLoad imrelp">
<ind:object object_ref="object_rsyslog_nolisten_legacy"/>
</ind:textfilecontent54_test>

<ind:textfilecontent54_object id="object_rsyslog_nolisten_legacy" version="2">
<ind:filepath operation="pattern match">^\/etc\/rsyslog(\.conf|\.d\/.*\.conf)$</ind:filepath>
<ind:pattern operation="pattern match">^[\s]*\$((?:Input(?:TCP|RELP)|UDP)ServerRun|ModLoad[\s]+(imtcp|imudp|imrelp))</ind:pattern>
<ind:instance datatype="int">1</ind:instance>
</ind:textfilecontent54_object>

<ind:textfilecontent54_test id="test_rsyslog_nolisten_rainerscript" version="1"
check="all" check_existence="none_exist"
comment="rsyslog configuration files don't use imtcp or imudp modules">
<ind:object object_ref="object_rsyslog_nolisten_rainerscript"/>
</ind:textfilecontent54_test>

<ind:textfilecontent54_object id="object_rsyslog_nolisten_rainerscript" version="2">
<ind:filepath operation="pattern match">^\/etc\/rsyslog(\.conf|\.d\/.*\.conf)$</ind:filepath>
<ind:pattern operation="pattern match">^\s*(?:module|input)\((?:load|type)="(imtcp|imudp)".*$</ind:pattern>
<ind:instance datatype="int">1</ind:instance>
</ind:textfilecontent54_object>
</def-group>
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,29 @@ prodtype: alinux3,fedora,ol7,ol8,ol9,rhel7,rhel8,rhel9,rhv4,sle12,sle15,ubuntu22
title: 'Ensure rsyslog Does Not Accept Remote Messages Unless Acting As Log Server'

description: |-
The <tt>rsyslog</tt> daemon should not accept remote messages
unless the system acts as a log server.
To ensure that it is not listening on the network, ensure the following lines are
<i>not</i> found in <tt>/etc/rsyslog.conf</tt>:
The <tt>rsyslog</tt> daemon should not accept remote messages unless the system acts as a log
server. To ensure that it is not listening on the network, ensure any of the following lines
are <i>not</i> found in <tt>rsyslog</tt> configuration files.

If using legacy syntax:
<pre>$ModLoad imtcp
$InputTCPServerRun <i>port</i>
$ModLoad imudp
$UDPServerRun <i>port</i>
$ModLoad imrelp
$InputRELPServerRun <i>port</i></pre>

If using RainerScript syntax:
<pre>module(load="imtcp")
module(load="imudp")
input(type="imtcp" port="514")
input(type="imudp" port="514")
</pre>

rationale: |-
Any process which receives messages from the network incurs some risk
of receiving malicious messages. This risk can be eliminated for
rsyslog by configuring it not to listen on the network.
Any process which receives messages from the network incurs some risk of receiving malicious
messages. This risk can be eliminated for rsyslog by configuring it not to listen on the
network.

severity: medium

Expand Down Expand Up @@ -54,19 +62,29 @@ references:
ocil_clause: "rsyslog accepts remote messages and is not documented as a log aggregation system"

ocil: |-
Verify that the system is not accepting "rsyslog" messages from other systems unless it is documented as a log aggregation server.
Display the contents of the configuration file:
<pre>cat /etc/rsyslog.conf</pre>
Verify that the system is not accepting "rsyslog" messages from other systems unless it is
documented as a log aggregation server.
Display the contents of the rsyslog configuration files:
<pre>find /etc -maxdepth 2 -regex '/etc/rsyslog\(\.conf\|\.d\/.*\.conf\)' -exec cat '{}' \;</pre>

If any of the below lines are found, ask to see the documentation for the system being used
for log aggregation:

If using legacy syntax:
<pre>$ModLoad imtcp
$InputTCPServerRun <i>port</i>
$ModLoad imudp
$UDPServerRun <i>port</i>
$ModLoad imrelp
$InputRELPServerRun <i>port</i></pre>

If any of the above modules are being loaded in the "/etc/rsyslog.conf" file, ask to see the documentation for the system being used for log aggregation.

fixtext: 'The {{{ full_name }}} must be configured so that the rsyslog daemon does not accept log messages from other servers unless the server is being used for log aggregation.'
If using RainerScript syntax:
<pre>module(load="imtcp")
module(load="imudp")
input(type="imtcp" port="514")
input(type="imudp" port="514")
</pre>

srg_requirement: |-
{{{ full_name }}} must be configured so that the rsyslog daemon does not accept log messages from other servers unless the server is being used for log aggregation.
fixtext: |-
The {{{ full_name }}} must be configured so that the rsyslog daemon does not accept log
messages from other servers unless the server is being used for log aggregation.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash
# platform = multi_platform_all

# Declare variables used for the tests and define the create_rsyslog_test_logs function
source $SHARED/rsyslog_log_utils.sh

# create one test log file
create_rsyslog_test_logs 1

# setup test log file property
chmod 0640 ${RSYSLOG_TEST_LOGS[0]}
chown root.root ${RSYSLOG_TEST_LOGS[0]}

# add commented modules lines to main configuration file
cat << EOF > $RSYSLOG_CONF
# rsyslog configuration file

#### MODULES ####
# \$ModLoad imtcp
# \$InputTCPServerRun 5000
# \$ModLoad imudp
# \$UDPServerRun 5000
# \$ModLoad imrelp
# \$InputRELPServerRun 5000

#### RULES ####
*.* ${RSYSLOG_TEST_LOGS[0]}

EOF
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
# platform = multi_platform_all

# Declare variables used for the tests and define the create_rsyslog_test_logs function
source $SHARED/rsyslog_log_utils.sh

# create one test log file
create_rsyslog_test_logs 1

# setup test log file property
chmod 0640 ${RSYSLOG_TEST_LOGS[0]}
chown root.root ${RSYSLOG_TEST_LOGS[0]}

# create test configuration file with commented modules lines
test_conf=${RSYSLOG_CONF_DIR}/test1.conf
cat << EOF > ${test_conf}
# rsyslog test configuration file

#### MODULES ####
# \$ModLoad imtcp
# \$InputTCPServerRun 5000
# \$ModLoad imudp
# \$UDPServerRun 5000
# \$ModLoad imrelp
# \$InputRELPServerRun 5000

EOF

# add generic rule plus an include statement
cat << EOF > $RSYSLOG_CONF
# rsyslog configuration file

#### RULES ####
*.* ${RSYSLOG_TEST_LOGS[0]}

#### MODULES ####
\$IncludeConfig ${test_conf}

EOF
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash
# platform = multi_platform_all

# Declare variables used for the tests and define the create_rsyslog_test_logs function
source $SHARED/rsyslog_log_utils.sh

# create one test log file
create_rsyslog_test_logs 1

# setup test log file property
chmod 0640 ${RSYSLOG_TEST_LOGS[0]}
chown root.root ${RSYSLOG_TEST_LOGS[0]}

# add modules lines to main configuration file
cat << EOF > $RSYSLOG_CONF
# rsyslog configuration file

#### MODULES ####
\$ModLoad imtcp
\$InputTCPServerRun 5000
\$ModLoad imudp
\$UDPServerRun 5000
\$ModLoad imrelp
\$InputRELPServerRun 5000

#### RULES ####
*.* ${RSYSLOG_TEST_LOGS[0]}

EOF
Loading