From 86867fc7b914ce2726dd7ce9f2ede0ca663bd67d Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Fri, 28 Aug 2026 14:07:57 +0200 Subject: [PATCH 1/5] yamllint and ansible-lint --- .yamllint.yaml | 7 +- roles/rsyslog/defaults/main.yml | 132 ++++++++++-------- roles/rsyslog/handlers/main.yml | 19 +-- roles/rsyslog/tasks/main.yml | 95 ++++++------- .../process_auth_log_for_environment.yml | 83 +++++------ roles/rsyslog/tasks/process_auth_logs.yml | 32 ++--- roles/rsyslog/tasks/rsyslog_central.yml | 78 ++++++----- roles/rsyslog/templates/clean_loglogins.j2 | 2 +- roles/rsyslog/templates/sc_ruleset.conf.j2 | 2 +- 9 files changed, 224 insertions(+), 226 deletions(-) diff --git a/.yamllint.yaml b/.yamllint.yaml index 8824391dc..916644d96 100644 --- a/.yamllint.yaml +++ b/.yamllint.yaml @@ -13,7 +13,7 @@ rules: allow-quoted-quotes: false check-keys: false -# ansible-lint compatibility: + # ansible-lint compatibility: comments: min-spaces-from-content: 1 @@ -25,3 +25,8 @@ rules: octal-values: forbid-implicit-octal: true forbid-explicit-octal: true + + commas: + ignore: | + # uses spaces for outlining + /roles/rsyslog/defaults/main.yml diff --git a/roles/rsyslog/defaults/main.yml b/roles/rsyslog/defaults/main.yml index fd21b0cd2..8f4859b2b 100644 --- a/roles/rsyslog/defaults/main.yml +++ b/roles/rsyslog/defaults/main.yml @@ -1,17 +1,17 @@ --- -rsyslog_ca: /etc/pki/rsyslog/rsyslog_ca.pem -rsyslog_dir: /opt/openconext/logs -rsyslog_read_group: adm -loglogins_max_age: 6 -stepupapps: - - gateway - - selfservice - - ra - - middleware - - webauthn - - tiqr - - azure-mfa - - azuremfa +rsyslog_ca: "/etc/pki/rsyslog/rsyslog_ca.pem" +rsyslog_dir: "/opt/openconext/logs" +rsyslog_read_group: "adm" +rsyslog_loglogins_max_age: 6 +rsyslog_stepupapps: + - "gateway" + - "selfservice" + - "ra" + - "middleware" + - "webauthn" + - "tiqr" + - "azure-mfa" + - "azuremfa" rsyslog_dir_file_modes: > dirCreateMode="0755" @@ -40,7 +40,7 @@ rsyslog_imjournal_ratelimitinterval: 60 # Empty log check script, optional rsyslog_enable_warn_empty_script: false -rsyslog_warn_empty_log_recipient: admin@example.com +rsyslog_warn_empty_log_recipient: "admin@example.com" rsyslog_monitor_for_emptylogs_path: "{{ rsyslog_dir }}/apps/prod_sc" rsyslog_checkemptylogs_cron_minute: "0" rsyslog_checkemptylogs_cron_hour: "9" @@ -50,67 +50,75 @@ rsyslog_checkemptylogs_dir: "/usr/local/bin" # messages can become quote large; e.g., Engineblock sometimes dumps large SAMLResponses rsyslog_maxmessagesize: "32k" + +# matching rules for distributing logs on central loghost +# order is important! First matching rule wins. +# # "program" matches the syslog identifier # "contains" and "startswith" match the syslog message -# order is important! First matching rule wins. +# "dir" defaults to `apps` +# +# final path of the log file is `{{ rsyslog_dir }}/{{ dir }}/{{ env_name }}/{{ target }}` rsyslog_central_apps: # infra - - { program: "haproxy", target: "haproxy/haproxy.log" } - - { program: "acme.sh", target: "haproxy/acme.log" } - - { program: "mariadb", target: "galera/galera.log" } - - { program: "mongod", target: "mongo/mongo.log" } - - { program: "garb-systemd", target: "galera/galera_garb.log" } - - { program: "Keepalived_vrrp", target: "keepalived/keepalived.log" } - - { program: "loadbalancer", target: "traefik/traefik.log" } + - { program: "haproxy", target: "haproxy/haproxy.log" } + - { program: "acme.sh", target: "haproxy/acme.log" } + - { program: "mariadb", target: "galera/galera.log" } + - { program: "mongod", target: "mongo/mongo.log" } + - { program: "garb-systemd", target: "galera/galera_garb.log" } + - { program: "Keepalived_vrrp", target: "keepalived/keepalived.log" } + - { program: "loadbalancer", target: "traefik/traefik.log" } # core - - { program: "engineblock", contains: '"channel":"authentication"', dir: "log_logins", target: "eb-authentication.log" } - - { program: "stepup-authentication", dir: "log_logins", target: "stepup-authentication.log" } - - - { program: "engineblock", startswith: "engine", target: "eb/apache.log" } - - { program: "Apache-EB", target: "eb/apache.log" } # probably ununsed - - - { program: "engineblock", target: "eb/eb.log" } - - { program: "EBLOG", target: "eb/eb.log" } - - { program: "Apache-EBAPI", target: "eb-api/apache.log" } # probably ununsed - - { program: "oidcngserver", target: "oidcng/oidcng.log" } - - { program: "oicdngjson", target: "oidcng/oidcngjson.log" } - - { program: "oidcplaygroundserver", target: "oidc-playground/oidc-playground.log" } - - { program: "oidcplaygroundgui", target: "oidc-playground/oidc-playground-apache.log" } - - { program: "manageserver", target: "manage/manage.log" } - - { program: "managegui", target: "manage/apache.log" } + - { program: "engineblock", contains: '"channel":"authentication"', dir: "log_logins", target: "eb-authentication.log" } + - { program: "stepup-authentication", dir: "log_logins", target: "stepup-authentication.log" } + + - { program: "engineblock", startswith: "engine", target: "eb/apache.log" } + - { program: "Apache-EB", target: "eb/apache.log" } # probably ununsed + + - { program: "engineblock", target: "eb/eb.log" } + - { program: "EBLOG", target: "eb/eb.log" } + - { program: "Apache-EBAPI", target: "eb-api/apache.log" } # probably ununsed + - { program: "oidcngserver", target: "oidcng/oidcng.log" } + - { program: "oicdngjson", target: "oidcng/oidcngjson.log" } + - { program: "oidcplaygroundserver", target: "oidc-playground/oidc-playground.log" } + - { program: "oidcplaygroundgui", target: "oidc-playground/oidc-playground-apache.log" } + - { program: "manageserver", target: "manage/manage.log" } + - { program: "managegui", target: "manage/apache.log" } # core-supporting - - { program: "aaserver", target: "aa/aa.log" } - - { program: "aagui", target: "aa/apache.log" } - - { program: "aalink", target: "aa/apache.log" } - - { program: "vootserver", target: "voot/voot.log" } - - { program: "pdp", target: "pdp/pdp.log" } + - { program: "aaserver", target: "aa/aa.log" } + - { program: "aagui", target: "aa/apache.log" } + - { program: "aalink", target: "aa/apache.log" } + - { program: "vootserver", target: "voot/voot.log" } + - { program: "pdp", target: "pdp/pdp.log" } # Invite - - { program: "inviteclient", target: "invite/inviteclient.log" } - - { program: "invitewelcome", target: "invite/invitewelcome.log" } - - { program: "inviteserver", target: "invite/inviteserver.log" } - - { program: "invitejson", target: "invite/invitejson.log" } - - { program: "inviteprovisioningmock", target: "invite/inviteprovisioningmock.log" } + - { program: "inviteclient", target: "invite/inviteclient.log" } + - { program: "invitewelcome", target: "invite/invitewelcome.log" } + - { program: "inviteserver", target: "invite/inviteserver.log" } + - { program: "invitejson", target: "invite/invitejson.log" } + - { program: "inviteprovisioningmock", target: "invite/inviteprovisioningmock.log" } # dashboards - - { program: "dashboardgui", target: "dashboard/apache.log" } - - { program: "dashboardserver", target: "dashboard/dashboard.log" } - - { program: "profile", startswith: "{", target: "profile/profile.log" } - - { program: "profile", target: "profile/apache.log" } + - { program: "dashboardgui", target: "dashboard/apache.log" } + - { program: "dashboardserver", target: "dashboard/dashboard.log" } + - { program: "spdashboard", startswith: "spdashboard", target: "spdashboard/spdashboard.log" } + - { program: "spdashboard", target: "spdashboard/apache.log" } + - { program: "profile", startswith: "{", target: "profile/profile.log" } + - { program: "profile", target: "profile/apache.log" } # static - - { program: "Apache-STATIC", target: "static/apache.log" } - - { program: "Apache-METADATA", target: "metadata/apache.log" } + - { program: "Apache-STATIC", target: "static/apache.log" } + - { program: "Apache-METADATA", target: "metadata/apache.log" } # MyConext - - { program: "myconextserver", target: "eduid/myconext.log" } - - { program: "myconextjson", target: "eduid/myconextjson.log" } - - { program: "myconextgui", target: "eduid/myconext-apache.log" } - - { program: "accountgui", target: "eduid/account-apache.log" } - - { program: "servicedeskgui", target: "eduid/servicedesk-apache.log" } - - { program: "gateway", contains: '"message":"Second Factor Authenticated"', dir: "log_logins", target: "stepup-authentication.log" } - - { program: "gateway", contains: '"message":"Intrinsic Loa Requested"', dir: "log_logins", target: "stepup-authentication.log" } - - { program: "spdashboard", startswith: "spdashboard", target: "spdashboard/spdashboard.log" } - - { program: "spdashboard", target: "spdashboard/apache.log" } + - { program: "myconextserver", target: "eduid/myconext.log" } + - { program: "myconextjson", target: "eduid/myconextjson.log" } + - { program: "myconextgui", target: "eduid/myconext-apache.log" } + - { program: "accountgui", target: "eduid/account-apache.log" } + - { program: "servicedeskgui", target: "eduid/servicedesk-apache.log" } + + # SSID log_logins + - { program: "gateway", contains: '"message":"Second Factor Authenticated"', dir: "log_logins", target: "stepup-authentication.log" } + - { program: "gateway", contains: '"message":"Intrinsic Loa Requested"', dir: "log_logins", target: "stepup-authentication.log" } diff --git a/roles/rsyslog/handlers/main.yml b/roles/rsyslog/handlers/main.yml index 532abdffe..24d7e48c4 100644 --- a/roles/rsyslog/handlers/main.yml +++ b/roles/rsyslog/handlers/main.yml @@ -1,13 +1,14 @@ --- -- name: restart rsyslog - service: - name: rsyslog - state: restarted +- name: "Restart rsyslog" + ansible.builtin.systemd_service: + name: "rsyslog" + state: "restarted" -- name: Restart journald +- name: "Restart journald" ansible.builtin.systemd_service: - name: systemd-journald - state: restarted + name: "systemd-journald" + state: "restarted" -- name: Reload systemd - ansible.builtin.command: "systemctl daemon-reload" # noqa command-instead-of-module +- name: "Reload systemd" + ansible.builtin.systemd_service: + daemon_reload: true diff --git a/roles/rsyslog/tasks/main.yml b/roles/rsyslog/tasks/main.yml index 6d3fd8ce5..e57a22c85 100644 --- a/roles/rsyslog/tasks/main.yml +++ b/roles/rsyslog/tasks/main.yml @@ -1,6 +1,6 @@ --- -- name: remove old files +- name: "Remove old files" ansible.builtin.file: path: "/etc/pki/rsyslog/{{ item }}" state: "absent" @@ -9,15 +9,15 @@ - "rsyslogclientcaprd.crt" - "rsyslogclientprd.crt" -- name: Install rsyslog and python modules +- name: "Install rsyslog and python modules" ansible.builtin.package: name: - - rsyslog - - rsyslog-gnutls - - rsyslog-relp - state: present + - "rsyslog" + - "rsyslog-gnutls" + - "rsyslog-relp" + state: "present" notify: - - "restart rsyslog" + - "Restart rsyslog" - name: Install rsyslog and python modules ansible.builtin.package: @@ -28,113 +28,106 @@ notify: - "restart rsyslog" -- name: Create the group that is allowed to read the logs +- name: "Create the group that is allowed to read the logs" ansible.builtin.group: name: "{{ rsyslog_read_group }}" - state: present + state: "present" # note: this config file supports both local-log-only and central syslog hosts -- name: Put rsyslog config file +- name: "Put rsyslog config file" ansible.builtin.template: src: "rsyslog.conf.j2" dest: "/etc/rsyslog.conf" - owner: root - group: root mode: "0644" notify: - - "restart rsyslog" + - "Restart rsyslog" # journald forwards logs to rsyslog -- name: When using imjournal no forwarding necessary +- name: "When using imjournal no forwarding necessary" ansible.builtin.lineinfile: - path: /etc/systemd/journald.conf - search_string: 'ForwardToSyslog=' - line: 'ForwardToSyslog=no' + path: "/etc/systemd/journald.conf" + search_string: "ForwardToSyslog=" + line: "ForwardToSyslog=no" notify: - "Restart journald" -- name: Remove logging dropin +- name: "Remove logging dropin" ansible.builtin.file: path: "{{ rsyslog_service_dropindir }}/logging.conf" - state: absent + state: "absent" notify: - "Reload systemd" - - "restart rsyslog" + - "Restart rsyslog" # Since we specify queue.spoolDirectory, lets make sure it exists -- name: Create queue dir +- name: "Create queue dir" ansible.builtin.file: path: "{{ rsyslog_queue_dir }}" - state: directory - owner: root - group: root + state: "directory" mode: "0700" # rsyslog certificates for relp -- name: Create the pki directory if it does not exist +- name: "Create the pki directory if it does not exist" ansible.builtin.file: path: "{{ rsyslog_certifcate_dir }}" - state: directory - owner: root - group: root + state: "directory" mode: "0755" # We need a key and client certificate to when using RELP -- name: Put rsyslog client key +- name: "Put rsyslog client key" ansible.builtin.copy: content: "{{ rsyslogclientkey }}" dest: "{{ rsyslog_certifcate_dir }}/rsyslogclient.key" mode: "0400" - owner: root no_log: true notify: - - "restart rsyslog" + - "Restart rsyslog" -- name: Put rsyslog client certificate +- name: "Put rsyslog client certificate" ansible.builtin.copy: src: "{{ inventory_dir }}/files/certs/rsyslog/rsyslogclient.crt" dest: "{{ rsyslog_certifcate_dir }}/rsyslogclient.crt" mode: "0644" - owner: root - group: adm + owner: "root" + group: "adm" notify: - - "restart rsyslog" + - "Restart rsyslog" -- name: Put rsyslog CA file +- name: "Put rsyslog CA file" ansible.builtin.copy: src: "{{ inventory_dir }}/files/certs/rsyslog/rsyslog_ca.crt" dest: "{{ rsyslog_ca }}" mode: "0644" - owner: root - group: root notify: - - "restart rsyslog" + - "Restart rsyslog" # Not sure why this is necessary on the forwarding server # but seems to work -- name: Allow extra port rsyslog_tls_port_t +- name: "Allow extra port rsyslog_tls_port_t" community.general.seport: ports: "{{ rsyslog_remote_relp_port }}" - proto: tcp - setype: syslog_tls_port_t - state: present - when: ansible_selinux.mode is defined and ansible_selinux.mode == "enforcing" + proto: "tcp" + setype: "syslog_tls_port_t" + state: "present" + when: "ansible_selinux.mode is defined and ansible_selinux.mode == 'enforcing'" #### central logserver -- name: Include tasks for configuring the central log server +- name: "Include tasks for configuring the central log server" when: "'centrallog_servers' in group_names" block: - - name: Include tasks for central syslog server - ansible.builtin.include_tasks: rsyslog_central.yml + - name: "Include tasks for central syslog server" + ansible.builtin.include_tasks: + file: "rsyslog_central.yml" - - name: Include tasks for authentication log processing - ansible.builtin.include_tasks: process_auth_logs.yml + - name: "Include tasks for authentication log processing" + ansible.builtin.include_tasks: + file: "process_auth_logs.yml" when: "'auth_processor' in group_names" ### and enable -- name: Enable rsyslog +- name: "Enable rsyslog" ansible.builtin.service: - name: rsyslog + name: "rsyslog" enabled: true diff --git a/roles/rsyslog/tasks/process_auth_log_for_environment.yml b/roles/rsyslog/tasks/process_auth_log_for_environment.yml index de97e1af5..ce0705f61 100644 --- a/roles/rsyslog/tasks/process_auth_log_for_environment.yml +++ b/roles/rsyslog/tasks/process_auth_log_for_environment.yml @@ -1,78 +1,67 @@ --- - -- name: Create log_logins table for each log_login environment +- name: "Create log_logins table for each log_login environment" community.mysql.mysql_db: name: "{{ rsyslog_environment.db_loglogins_name }}" login_user: "{{ rsyslog_environment.db_loglogins_user }}" login_password: "{{ rsyslog_environment.db_loglogins_password }}" login_host: "{{ rsyslog_environment.db_loglogins_host }}" - state: import - target: /var/tmp/log_logins.sql - changed_when: false + state: "import" + target: "/var/tmp/log_logins.sql" + changed_when: false # TODO -- name: Create lastseen table for each log_login environment +- name: "Create lastseen table for each log_login environment" community.mysql.mysql_db: name: "{{ rsyslog_environment.db_lastseen_name }}" login_user: "{{ rsyslog_environment.db_lastseen_user }}" login_password: "{{ rsyslog_environment.db_lastseen_password }}" login_host: "{{ rsyslog_environment.db_lastseen_host }}" - state: import - target: /var/tmp/lastseen.sql - changed_when: false + state: "import" + target: "/var/tmp/lastseen.sql" + changed_when: false # TODO -- name: Create a python script that parses eb log_logins per environment +- name: "Create a python script that parses eb log_logins per environment" ansible.builtin.template: - src: parse_ebauth_to_mysql.py.j2 - dest: /usr/local/sbin/parse_ebauth_to_mysql_{{ rsyslog_environment.name }}.py - mode: 0740 - owner: root - group: root + src: "parse_ebauth_to_mysql.py.j2" + dest: "/usr/local/sbin/parse_ebauth_to_mysql_{{ rsyslog_environment.name }}.py" + mode: "0740" -- name: Create a python script that parses stepup log_logins per environment +- name: "Create a python script that parses stepup log_logins per environment" ansible.builtin.template: - src: parse_stepupauth_to_mysql.py.j2 - dest: /usr/local/sbin/parse_stepupauth_to_mysql_{{ rsyslog_environment.name }}.py - mode: 0740 - owner: root - group: root + src: "parse_stepupauth_to_mysql.py.j2" + dest: "/usr/local/sbin/parse_stepupauth_to_mysql_{{ rsyslog_environment.name }}.py" + mode: "0740" -- name: Put log_logins logrotate scripts for eb +- name: "Put log_logins logrotate scripts for eb" ansible.builtin.template: - src: logrotate_ebauth.j2 - dest: /etc/logrotate.d/logrotate_ebauth_{{ rsyslog_environment.name }} - mode: 0644 - owner: root - group: root + src: "logrotate_ebauth.j2" + dest: "/etc/logrotate.d/logrotate_ebauth_{{ rsyslog_environment.name }}" + mode: "0644" -- name: Put log_logins logrotate scripts for stepup +- name: "Put log_logins logrotate scripts for stepup" ansible.builtin.template: - src: logrotate_stepupauth.j2 - dest: /etc/logrotate.d/logrotate_stepupauth_{{ rsyslog_environment.name }} - mode: 0644 - owner: root - group: root + src: "logrotate_stepupauth.j2" + dest: "/etc/logrotate.d/logrotate_stepupauth_{{ rsyslog_environment.name }}" + mode: "0644" -- name: Create logdirectory for log_logins cleanup script +- name: "Create logdirectory for log_logins cleanup script" ansible.builtin.file: path: "{{ rsyslog_dir }}/apps/{{ rsyslog_environment.name }}/loglogins_cleanup/" - state: directory - owner: root + state: "directory" + mode: "0750" + owner: "root" group: "{{ rsyslog_read_group }}" - mode: 0750 -- name: Put log_logins cleanup script +- name: "Put log_logins cleanup script" ansible.builtin.template: - src: clean_loglogins.j2 - dest: /usr/local/sbin/clean_loglogins_{{ rsyslog_environment.name }} - owner: root - group: root - mode: 0700 + src: "clean_loglogins.j2" + dest: "/usr/local/sbin/clean_loglogins_{{ rsyslog_environment.name }}" + mode: "0700" -- name: Create cronjobs to run the log_logins script +- name: "Create cronjobs to run the log_logins script" ansible.builtin.cron: - name: Delete old {{ rsyslog_environment.name }} log_login data - user: root + name: "Delete old {{ rsyslog_environment.name }} log_login data" + cron_file: "loglogins_cleanup_{{ rsyslog_environment.name }}" + user: "root" minute: "20" hour: "02" job: "/usr/local/sbin/clean_loglogins_{{ rsyslog_environment.name }}" - cron_file: loglogins_cleanup_{{ rsyslog_environment.name }} diff --git a/roles/rsyslog/tasks/process_auth_logs.yml b/roles/rsyslog/tasks/process_auth_logs.yml index e1cb22365..d428bf390 100644 --- a/roles/rsyslog/tasks/process_auth_logs.yml +++ b/roles/rsyslog/tasks/process_auth_logs.yml @@ -1,24 +1,24 @@ --- -- name: Copy the log_logins and lastseen database table definitions - copy: +- name: "Copy the log_logins and lastseen database table definitions" + ansible.builtin.copy: src: "{{ item }}" - dest: /var/tmp/{{ item }} - owner: root - mode: 0744 + dest: "/var/tmp/{{ item }}" + mode: "0744" with_items: - - log_logins.sql - - lastseen.sql + - "log_logins.sql" + - "lastseen.sql" -- name: add python mysql module for parse_ebauth_to_mysql script - apt: - name: python3-mysqldb - state: present - when: ansible_os_family == "Debian" +- name: "Add python mysql module for parse_ebauth_to_mysql script" + ansible.builtin.apt: + name: "python3-mysqldb" + state: "present" + when: "ansible_os_family == 'Debian'" -- name: Process auth logs for each rsyslog environment - ansible.builtin.include_tasks: process_auth_log_for_environment.yml +- name: "Process auth logs for each rsyslog environment" + ansible.builtin.include_tasks: + file: "process_auth_log_for_environment.yml" loop: "{{ rsyslog_environments }}" loop_control: - loop_var: rsyslog_environment + loop_var: "rsyslog_environment" label: "{{ rsyslog_environment.name }}" - when: rsyslog_environment.db_loglogins_name is defined + when: "rsyslog_environment.db_loglogins_name is defined" diff --git a/roles/rsyslog/tasks/rsyslog_central.yml b/roles/rsyslog/tasks/rsyslog_central.yml index 1ad8c37ce..91829597f 100644 --- a/roles/rsyslog/tasks/rsyslog_central.yml +++ b/roles/rsyslog/tasks/rsyslog_central.yml @@ -1,72 +1,72 @@ --- -# The server uses a different set of keys as the client -- name: Put rsyslog server key +# The server uses a different set of keys than the client +- name: "Put rsyslog server key" ansible.builtin.copy: content: "{{ rsyslogserverkey }}" dest: "/etc/pki/rsyslog/rsyslogserver.key" mode: "0400" - owner: root -- name: Create directory to save the logs +- name: "Create directory to save the logs" ansible.builtin.file: path: "{{ rsyslog_dir }}" - owner: root + owner: "root" group: "{{ rsyslog_read_group }}" mode: "0750" - # recurse: true # this makes everything very slow and not sure if it is necessary -- name: Put rsyslog server certificate +- name: "Put rsyslog server certificate" ansible.builtin.copy: src: "{{ inventory_dir }}/files/certs/rsyslog/rsyslogserver.crt" dest: "/etc/pki/rsyslog/rsyslogserver.crt" mode: "0644" - owner: root - group: adm + owner: "root" + group: "adm" notify: - - "restart rsyslog" + - "Restart rsyslog" -- name: Create directories to keep configuration file +- name: "Create directories to keep configuration file" ansible.builtin.file: path: "/etc/rsyslog.d/{{ item }}" - owner: root mode: "0755" - state: directory + state: "directory" with_items: - - listeners - - rulesets - - templates + - "listeners" + - "rulesets" + - "templates" -- name: Create template configurations +- name: "Create template configurations" ansible.builtin.template: - src: sc_template.conf.j2 - dest: /etc/rsyslog.d/templates/{{ item.name }}.conf + src: "sc_template.conf.j2" + dest: "/etc/rsyslog.d/templates/{{ item.name }}.conf" backup: true + mode: "0644" vars: # use a semantic name in the template env_name: "{{ item.name }}" loop: "{{ rsyslog_environments }}" loop_control: label: "{{ item.name }}" notify: - - "restart rsyslog" + - "Restart rsyslog" -- name: Create ruleset configurations +- name: "Create ruleset configurations" ansible.builtin.template: - src: sc_ruleset.conf.j2 - dest: /etc/rsyslog.d/rulesets/{{ item.name }}.conf + src: "sc_ruleset.conf.j2" + dest: "/etc/rsyslog.d/rulesets/{{ item.name }}.conf" backup: true + mode: "0644" vars: # use a semantic name in the template env_name: "{{ item.name }}" loop: "{{ rsyslog_environments }}" loop_control: label: "{{ item.name }}" notify: - - "restart rsyslog" + - "Restart rsyslog" -- name: Create sc listener configurations +- name: "Create sc listener configurations" ansible.builtin.template: - src: listener.conf.j2 - dest: /etc/rsyslog.d/listeners/{{ item.name }}.conf + src: "listener.conf.j2" + dest: "/etc/rsyslog.d/listeners/{{ item.name }}.conf" backup: true + mode: "0644" vars: # use a semantic name in the template env_name: "{{ item.name }}" port: "{{ item.port }}" @@ -75,26 +75,28 @@ loop_control: label: "{{ item.name }}" notify: - - "restart rsyslog" + - "Restart rsyslog" -- name: Create logrotate file for apps and host logs +- name: "Create logrotate file for apps and host logs" ansible.builtin.template: - src: centralsyslog.j2 - dest: /etc/logrotate.d/centralsyslog + src: "centralsyslog.j2" + dest: "/etc/logrotate.d/centralsyslog" + mode: "0644" -- name: Put log empty warn script and cronjob - when: rsyslog_enable_warn_empty_script +- name: "Put log empty warn script and cronjob" + when: "rsyslog_enable_warn_empty_script" block: - - name: Put log empty script + - name: "Put log empty script" ansible.builtin.template: - src: warn-empty-log.sh.j2 + src: "warn-empty-log.sh.j2" dest: "{{ rsyslog_checkemptylogs_dir }}/warn-empty-log.sh" - backup: True + backup: true + mode: "0644" - - name: Create cronjob + - name: "Create cronjob" ansible.builtin.cron: name: "check empty logs" minute: "{{ rsyslog_checkemptylogs_cron_minute | str }}" - hour: "{{ rsyslog_checkemptylogs_cron_hour| str }}" + hour: "{{ rsyslog_checkemptylogs_cron_hour | str }}" weekday: "{{ rsyslog_checkemptylogs_cron_weekdays }}" job: "{{ rsyslog_checkemptylogs_dir }}/warn-empty-log.sh -m" diff --git a/roles/rsyslog/templates/clean_loglogins.j2 b/roles/rsyslog/templates/clean_loglogins.j2 index 7296b01ff..112025094 100644 --- a/roles/rsyslog/templates/clean_loglogins.j2 +++ b/roles/rsyslog/templates/clean_loglogins.j2 @@ -6,7 +6,7 @@ # The script is intended to be run daily from a cron job. MAX_DELETE_DAYS=5 -LOG_LOGINS_MAX_AGE="{{ loglogins_max_age }}" # Number of MONTHS of logins to keep +LOG_LOGINS_MAX_AGE="{{ rsyslog_loglogins_max_age }}" # Number of MONTHS of logins to keep RSYSLOG_DIR="{{ rsyslog_dir }}" RSYSLOG_ENVIRONMENT_NAME="{{ rsyslog_environment.name }}" DB_LOG_LOGINS_NAME="{{ rsyslog_environment.db_loglogins_name }}" diff --git a/roles/rsyslog/templates/sc_ruleset.conf.j2 b/roles/rsyslog/templates/sc_ruleset.conf.j2 index f8e12c0b5..357f76700 100644 --- a/roles/rsyslog/templates/sc_ruleset.conf.j2 +++ b/roles/rsyslog/templates/sc_ruleset.conf.j2 @@ -11,7 +11,7 @@ ruleset(name="{{ env_name }}") { {% endfor %} ## stepup - {%- for stepupapp in stepupapps -%} + {%- for stepupapp in rsyslog_stepupapps -%} # {{ stepupapp }} if $programname == "stepup-{{ stepupapp }}" {# -#} then { action(type="omfile" File="{{ rsyslog_dir }}/apps/{{ env_name }}/{{ stepupapp }}/{{ stepupapp }}.log") stop } From 1e01698261ce4e19f39b0dcd9aa5dbada342312b Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Fri, 28 Aug 2026 14:08:22 +0200 Subject: [PATCH 2/5] Fix weird defaults handling --- roles/rsyslog/defaults/main.yml | 4 ++-- roles/rsyslog/templates/rsyslog.conf.j2 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/rsyslog/defaults/main.yml b/roles/rsyslog/defaults/main.yml index 8f4859b2b..ed669da64 100644 --- a/roles/rsyslog/defaults/main.yml +++ b/roles/rsyslog/defaults/main.yml @@ -35,8 +35,8 @@ rsyslog_queue_dir: "/var/spool/rsyslog" rsyslog_imjournal_ratelimitburst: 20000 rsyslog_imjournal_ratelimitinterval: 60 -# rsyslog_imjournal_statefile # default is imjournal.state which means imjournal.state relative to the rsyslog workdir -# rsyslog_workdirectory # default /var/spool/rsyslog +rsyslog_imjournal_statefile: "imjournal.state" +rsyslog_workdirectory: "/var/spool/rsyslog" # Empty log check script, optional rsyslog_enable_warn_empty_script: false diff --git a/roles/rsyslog/templates/rsyslog.conf.j2 b/roles/rsyslog/templates/rsyslog.conf.j2 index e83a5af35..ae050d586 100644 --- a/roles/rsyslog/templates/rsyslog.conf.j2 +++ b/roles/rsyslog/templates/rsyslog.conf.j2 @@ -11,7 +11,7 @@ input(type="imptcp" port="514") # Provides the ability to import structured log messages from systemd journal to syslog. module(load="imjournal" UsePid="system" # PID number is retrieved as the ID of the process the journal entry originates from - StateFile="{{ rsyslog_imjournal_statefile | default('imjournal.state') }}" + StateFile="{{ rsyslog_imjournal_statefile }}" ratelimit.interval="{{ rsyslog_imjournal_ratelimitinterval }}" ratelimit.burst="{{ rsyslog_imjournal_ratelimitburst }}" ) @@ -38,7 +38,7 @@ module(load="builtin:omfile" #### GLOBAL DIRECTIVES #### # where to place aux file (spool, etc) -global(workDirectory="/var/lib/rsyslog") +global(workDirectory="{{ rsyslog_workdirectory }}") # Support large messages global(maxMessageSize="{{ rsyslog_maxmessagesize }}") From 2828314b9a634d6455567ac2633107836f328151 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Fri, 28 Aug 2026 14:08:42 +0200 Subject: [PATCH 3/5] Install python module in correct task --- roles/rsyslog/tasks/main.yml | 9 --------- roles/rsyslog/tasks/rsyslog_central.yml | 8 ++++++++ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/roles/rsyslog/tasks/main.yml b/roles/rsyslog/tasks/main.yml index e57a22c85..e0367e33e 100644 --- a/roles/rsyslog/tasks/main.yml +++ b/roles/rsyslog/tasks/main.yml @@ -19,15 +19,6 @@ notify: - "Restart rsyslog" -- name: Install rsyslog and python modules - ansible.builtin.package: - name: - - python3-dateutil - state: present - when: "'centrallog_servers' in group_names and ansible_distribution_major_version > '7'" - notify: - - "restart rsyslog" - - name: "Create the group that is allowed to read the logs" ansible.builtin.group: name: "{{ rsyslog_read_group }}" diff --git a/roles/rsyslog/tasks/rsyslog_central.yml b/roles/rsyslog/tasks/rsyslog_central.yml index 91829597f..8838ff786 100644 --- a/roles/rsyslog/tasks/rsyslog_central.yml +++ b/roles/rsyslog/tasks/rsyslog_central.yml @@ -1,4 +1,12 @@ --- +- name: "Install python modules" + ansible.builtin.package: + name: + - "python3-dateutil" + state: "present" + notify: + - "Restart rsyslog" + # The server uses a different set of keys than the client - name: "Put rsyslog server key" ansible.builtin.copy: From f9ffb9ad98852b005afb44b5ed1af17bc1df4081 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Fri, 28 Aug 2026 14:09:06 +0200 Subject: [PATCH 4/5] fix vars --- roles/rsyslog/tasks/rsyslog_central.yml | 4 ++-- roles/rsyslog/templates/listener.conf.j2 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/roles/rsyslog/tasks/rsyslog_central.yml b/roles/rsyslog/tasks/rsyslog_central.yml index 8838ff786..6ac7fdceb 100644 --- a/roles/rsyslog/tasks/rsyslog_central.yml +++ b/roles/rsyslog/tasks/rsyslog_central.yml @@ -77,8 +77,8 @@ mode: "0644" vars: # use a semantic name in the template env_name: "{{ item.name }}" - port: "{{ item.port }}" - peer: "{{ item.permittedpeer }}" + listener_port: "{{ item.port }}" + listener_peer: "{{ item.permittedpeer }}" loop: "{{ rsyslog_environments }}" loop_control: label: "{{ item.name }}" diff --git a/roles/rsyslog/templates/listener.conf.j2 b/roles/rsyslog/templates/listener.conf.j2 index ff8e188b0..29e9e76f0 100644 --- a/roles/rsyslog/templates/listener.conf.j2 +++ b/roles/rsyslog/templates/listener.conf.j2 @@ -1,10 +1,10 @@ # define rsyslog listener for environment {{ env_name }} -input(type="imrelp" port="{{ port }}" +input(type="imrelp" port="{{ listener_port }}" ruleset="{{ env_name }}" tls="on" tls.mycert="/etc/pki/rsyslog/rsyslogserver.crt" tls.myprivkey="/etc/pki/rsyslog/rsyslogserver.key" tls.caCert="{{ rsyslog_ca }}" tls.authmode="name" - tls.permittedpeer="{{ peer }}" + tls.permittedpeer="{{ listener_peer }}" ) From 2dbf3937fbb457b4a40d39df5b4092d8c540ea99 Mon Sep 17 00:00:00 2001 From: Bas Zoetekouw Date: Fri, 28 Aug 2026 14:09:16 +0200 Subject: [PATCH 5/5] use semantic variable name --- roles/rsyslog/tasks/rsyslog_central.yml | 5 +++++ roles/rsyslog/templates/rsyslog.conf.j2 | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/roles/rsyslog/tasks/rsyslog_central.yml b/roles/rsyslog/tasks/rsyslog_central.yml index 6ac7fdceb..5012cbb62 100644 --- a/roles/rsyslog/tasks/rsyslog_central.yml +++ b/roles/rsyslog/tasks/rsyslog_central.yml @@ -1,4 +1,9 @@ --- + +- name: "Set variable to note centrallog server" + ansible.builtin.set_fact: + rsyslog_is_centrallog_server: true + - name: "Install python modules" ansible.builtin.package: name: diff --git a/roles/rsyslog/templates/rsyslog.conf.j2 b/roles/rsyslog/templates/rsyslog.conf.j2 index ae050d586..227ca8f00 100644 --- a/roles/rsyslog/templates/rsyslog.conf.j2 +++ b/roles/rsyslog/templates/rsyslog.conf.j2 @@ -93,7 +93,7 @@ action(type="omfile" file="/var/log/syslog") stop -{% if 'centrallog_servers' in group_names %} +{% if rsyslog_is_centrallog_server %} #### TEMPLATE, RULES AND LISTENERS FOR REMOTE MESSAGES # Each listener (on a specific port) binds to a specific ruleset for a specific environment. # Only the rules from that specific ruleset are applied. The default ruleset defined above