Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Breaking Changes

* **role:apache_httpd, role:apache_tomcat, role:mastodon, role:postgresql_server**: Rename tags to the project-wide naming scheme. `apache_httpd:config` becomes `apache_httpd:configure`, and `apache_tomcat:users`, `mastodon:users`, `postgresql_server:users` and `postgresql_server:databases` lose their trailing `s` (`...:user`, `...:database`). Adjust any `--tags` / `--skip-tags` invocations and automation that reference the old tag names.
* **role:sshd**: Ship hardened SSH defaults that change the behaviour of existing installations on the next run: X11 forwarding, agent forwarding and TCP keepalives are now off, `MaxAuthTries` is lowered to `3`, `ClientAliveCountMax` to `2`, and `LogLevel` is raised to `VERBOSE`. Sessions relying on X11 or agent forwarding stop working, and a client offering more than three keys from its SSH agent can be locked out. Restore the previous behaviour where needed via the new variables: `sshd__x11_forwarding: true`, `sshd__allow_agent_forwarding: true`, `sshd__tcp_keep_alive: true`, `sshd__max_auth_tries: 6`, `sshd__client_alive_count_max: 3`, `sshd__log_level: 'INFO'`. Additionally configurable are `sshd__allow_tcp_forwarding` and `sshd__max_sessions`.
* **role:apache_httpd, role:apache_solr, role:freeipa_server, role:grav, role:icingaweb2, role:influxdb, role:mariadb_server, role:mongodb, role:nextcloud, role:opensearch**: Align section tags to the controlled vocabulary, which uses plural names for sections that manage multiple objects. The `:user` tags become `:users`, the `:database` tags become `:databases`, and `apache_httpd:config` becomes `apache_httpd:configure`. Adjust any `--tags` / `--skip-tags` invocations and automation that reference the old tag names.
* **role:minio_client, role:objectstore_backup**: Both roles and their playbooks (`playbooks/minio_client.yml`, `playbooks/objectstore_backup.yml`) have been removed, along with the corresponding role blocks in `playbooks/setup_nextcloud.yml` and the `setup_nextcloud__skip_minio_client` / `setup_nextcloud__skip_objectstore_backup` variables. MinIO Server has been archived as no-longer-maintained since February 2026, and we are moving away from using object storage for critical data. Users relying on these roles must replace the MinIO-based object-store backup with their own solution (e.g. `rclone`); the `mc` binary, its config under `/etc/mc/`, the `objectstore-backup` systemd timer/service, and `/usr/local/bin/mc-mirror.sh` are no longer managed by lfops and will remain on existing hosts until removed manually ([#241](https://github.com/Linuxfabrik/lfops/issues/241)).
* **role:infomaniak_vm**: Always create a managed port for every entry in `infomaniak_vm__networks`, even when no `fixed_ip` is set. Previously only networks with a `fixed_ip` got a managed port; networks without one relied on OpenStack's auto-created port. To avoid creating unused (but billed) managed ports on VMs provisioned under the old behavior, make sure to manually rename the existing port in OpenStack to match the `port_name`. Note that this port will not survive VM deletion / detachment, since it was automatically created and therefore is owned by OpenStack, not the user.

Expand Down Expand Up @@ -72,7 +73,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* **role:icinga2_master, role:icingadb**: Validate the Icinga 2 configuration before restarting the service. A faulty config now fails the playbook run loudly instead of bouncing the daemon into a broken state and leaving Icinga 2 down.
* **role:nextcloud**: Automatic app updates are now enabled by default (`nextcloud__timer_app_update_enabled`). The scheduled app update only switches Nextcloud into maintenance mode when an app update is actually pending, so an instance that is already up to date keeps serving requests without interruption. After updating, the recommended database migrations are applied automatically. A failed run no longer leaves the instance stuck in maintenance mode.
* **role:clamav**: Now runs on Debian and Ubuntu in addition to Red Hat-family systems, and works on RHEL 10. The role seeds the signature database on first install so the scanner starts reliably, and runs an EICAR self-test (also available on its own via the `clamav:test` tag) that confirms detection actually works.
* **role:sshd**: Ship hardened SSH defaults: X11 forwarding, agent forwarding and TCP keepalives are now off, `MaxAuthTries` is `3`, `ClientAliveCountMax` is `2`, and the log level is `VERBOSE`. All are overridable via the new `sshd__allow_agent_forwarding`, `sshd__allow_tcp_forwarding`, `sshd__client_alive_count_max`, `sshd__max_auth_tries`, `sshd__max_sessions`, `sshd__tcp_keep_alive` and `sshd__x11_forwarding` variables. Note: a client offering more than three keys from its SSH agent can be rejected by `MaxAuthTries 3`; use an explicit identity on the client or raise `sshd__max_auth_tries`.
* **role:acme_sh**: Issue ECDSA P-256 certificates by default instead of RSA-4096, for faster TLS handshakes at equivalent security. Certificates previously issued as RSA are reissued as ECDSA on the next run, and the superseded RSA certificate is dropped from renewal. Set `acme_sh__key_length` to an RSA value such as `4096` to keep RSA.
* **playbooks**: Enable the CRB repository on Rocky 10 too, not just Rocky 9. Previously Rocky 10 hosts silently skipped this step, which could leave dependencies such as `python3-virtualenv` uninstallable.
* **role:grafana**: Apply the systemd/chkconfig workaround on RHEL 10 as well, not just RHEL 9.
Expand Down
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ LFOps overrides the project-agnostic "Changelog" rule above (alphabetical sortin
#### Tags

* Naming scheme: `role_name` and `role_name:section`. For example `apache_httpd` and `apache_httpd:vhosts`.
* The role should only do what one expects from the tag name. For example, the `mariadb:user` tag only manages MariaDB users.
* The role should only do what one expects from the tag name. For example, the `mariadb:users` tag only manages MariaDB users.
* The README of a role should provide a list of the available tags and what they do.
* The tags should be set in the role itself. Do not set them in the playbook.
* Blocks/tasks that install base packages do not require tags such as `apache:pkgs`, `apache:setup` or `apache:install`. There is no real world scenario where it makes sense to only run the installation via Ansible, some configuration is always required.
Expand All @@ -414,7 +414,7 @@ Controlled vocabulary of standard `role_name:section` tags (alphabetical):
* `role_name:configure`: Renders and deploys the role's configuration files and applies settings. The most common section; everything that is neither install, state, nor one of the more specific sections below belongs here.
* `role_name:containers`: Manages the role's containers and their systemd container units.
* `role_name:cron`: Deploys the role's scheduled jobs (cron entries or systemd timers).
* `role_name:database`: Creates, updates and deletes the databases managed by the role.
* `role_name:databases`: Creates, updates and deletes the databases managed by the role.
* `role_name:dump`: Sets up scheduled dumps / backups of the role's data.
* `role_name:enroll`: Registers (enrolls) the node with a remote service or controller.
* `role_name:firewalls`: Manages the cloud provider firewall / security-group rules (VM provisioning roles).
Expand All @@ -426,7 +426,7 @@ Controlled vocabulary of standard `role_name:section` tags (alphabetical):
* `role_name:state`: Manages the runtime state of the role's services, timers and sockets (start / stop / enable / disable).
* `role_name:update`: Updates the managed application to a newer version.
* `role_name:upgrade`: Runs the post-update migration / upgrade steps after the package itself was updated.
* `role_name:user`: Creates, updates and deletes the application or service user accounts managed by the role.
* `role_name:users`: Creates, updates and deletes the application or service user accounts managed by the role.

The Ansible built-in tags `always` and `never` are reserved for their built-in meaning: tag the platform-variable loading and `assert` validation tasks with `always` so the variables and checks are present even when the role runs with a specific `--tags` selection.

Expand Down
2 changes: 2 additions & 0 deletions playbooks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ Calls the following roles (in order):

Calls the following roles (in order):

* [kernel_settings](https://github.com/Linuxfabrik/lfops/tree/main/roles/kernel_settings): `core_dumps__skip_kernel_settings`
* [core_dumps](https://github.com/Linuxfabrik/lfops/tree/main/roles/core_dumps)


Expand Down Expand Up @@ -1008,6 +1009,7 @@ Calls the following roles (in order):
* [policycoreutils](https://github.com/Linuxfabrik/lfops/tree/main/roles/policycoreutils): `setup_basic__skip_policycoreutils`
* [selinux](https://github.com/Linuxfabrik/lfops/tree/main/roles/selinux): `setup_basic__skip_selinux`
* [kernel_modules](https://github.com/Linuxfabrik/lfops/tree/main/roles/kernel_modules): `setup_basic__skip_kernel_modules`
* [kernel_settings](https://github.com/Linuxfabrik/lfops/tree/main/roles/kernel_settings): `setup_basic__skip_kernel_settings`
* [core_dumps](https://github.com/Linuxfabrik/lfops/tree/main/roles/core_dumps): `setup_basic__skip_core_dumps`
* [systemd_journald](https://github.com/Linuxfabrik/lfops/tree/main/roles/systemd_journald): `setup_basic__skip_systemd_journald`
* [hostname](https://github.com/Linuxfabrik/lfops/tree/main/roles/hostname): `setup_basic__skip_hostname`
Expand Down
5 changes: 5 additions & 0 deletions playbooks/core_dumps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@

roles:

- role: 'linuxfabrik.lfops.kernel_settings'
kernel_settings__sysctl__dependent_var: '{{ core_dumps__kernel_settings__sysctl__dependent_var | d([]) }}'
when:
- 'not core_dumps__skip_kernel_settings | d(false)'

- role: 'linuxfabrik.lfops.core_dumps'


Expand Down
7 changes: 7 additions & 0 deletions playbooks/setup_basic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@
when:
- 'not setup_basic__skip_kernel_modules | d(false)'

- role: 'linuxfabrik.lfops.kernel_settings'
kernel_settings__sysctl__dependent_var: '{{
(not setup_basic__skip_core_dumps | d(false)) | ternary(core_dumps__kernel_settings__sysctl__dependent_var, []) | d([])
}}'
when:
- 'not setup_basic__skip_kernel_settings | d(false)'

- role: 'linuxfabrik.lfops.core_dumps'
when:
- 'not setup_basic__skip_core_dumps | d(false)'
Expand Down
2 changes: 1 addition & 1 deletion roles/apache_solr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Any [LFOps playbook](https://github.com/Linuxfabrik/lfops/blob/main/playbooks/RE
* Manages the state of `solr.service`.
* Triggers: none.

`apache_solr:user`
`apache_solr:users`

* Generates hashed passwords and deploys `security.json`.
* Triggers: solr.service restart.
Expand Down
2 changes: 1 addition & 1 deletion roles/apache_solr/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,4 @@

tags:
- 'apache_solr'
- 'apache_solr:user'
- 'apache_solr:users'
2 changes: 1 addition & 1 deletion roles/apache_tomcat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ ansible-playbook --inventory=myinv linuxfabrik.lfops.shell
* Configure access to optional web apps.
* Triggers: tomcat.service restart.

`apache_tomcat:user`
`apache_tomcat:users`

* Create users and roles.
* Triggers: tomcat.service restart.
Expand Down
4 changes: 2 additions & 2 deletions roles/apache_tomcat/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
tags:
- 'apache_tomcat'
- 'apache_tomcat:configure'
- 'apache_tomcat:user'
- 'apache_tomcat:users'
- 'apache_tomcat:state'


Expand Down Expand Up @@ -178,7 +178,7 @@

tags:
- 'apache_tomcat'
- 'apache_tomcat:user'
- 'apache_tomcat:users'


- block:
Expand Down
20 changes: 10 additions & 10 deletions roles/core_dumps/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,25 @@ This role hardens a system by disabling core dumps. Core dumps can leak sensitiv
The role disables core dumps through the three mechanisms a modern Linux system uses, following the CIS Benchmark recommendations:

* `* hard core 0` in `/etc/security/limits.d/` stops the shell / PAM from writing core dumps.
* `fs.suid_dumpable = 0` (sysctl) prevents core dumps of setuid / setgid processes.
* `fs.suid_dumpable = 0` (sysctl) prevents core dumps of setuid / setgid processes. This value is not written by this role directly; it is handed to the `kernel_settings` role, which owns sysctl management.
* `Storage=none` and `ProcessSizeMax=0` in `/etc/systemd/coredump.conf.d/` keep `systemd-coredump` from storing core dumps.

The `hard core` limit applies to login sessions started after the change. The sysctl value is applied immediately via `sysctl --system`.
The `hard core` limit applies to login sessions started after the change.


## Dependent Roles

Any LFOps playbook that installs this role runs these for you. Optional ones can be disabled via the playbook's skip variables.

* The `fs.suid_dumpable` sysctl is applied through the `kernel_settings` role (role: [kernel_settings](https://github.com/Linuxfabrik/lfops/tree/main/roles/kernel_settings)).


## Tags

`core_dumps`

* Deploys the core dump configuration.
* Triggers: `sysctl --system`.
* Triggers: none.


## Optional Role Variables
Expand All @@ -33,12 +40,6 @@ The `hard core` limit applies to login sessions started after the change. The sy
* Type: Number.
* Default: `0`

`core_dumps__sysctl_suid_dumpable`

* The `fs.suid_dumpable` sysctl value. `0` prevents core dumps of setuid / setgid processes.
* Type: Number.
* Default: `0`

`core_dumps__systemd_process_size_max`

* The `ProcessSizeMax` value in `/etc/systemd/coredump.conf.d/`. `0` disables processing of core dumps by `systemd-coredump`.
Expand All @@ -55,7 +56,6 @@ Example:
```yaml
# optional
core_dumps__limits_hard_core: 0
core_dumps__sysctl_suid_dumpable: 0
core_dumps__systemd_process_size_max: 0
core_dumps__systemd_storage: 'none'
```
Expand Down
8 changes: 7 additions & 1 deletion roles/core_dumps/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
core_dumps__limits_hard_core: 0
core_dumps__sysctl_suid_dumpable: 0
core_dumps__systemd_process_size_max: 0
core_dumps__systemd_storage: 'none'

# Injected into the kernel_settings role by the playbook, so that fs.suid_dumpable
# is managed through the single sysctl path provided by kernel_settings. Override via
# kernel_settings__sysctl__host_var / __group_var if a non-zero value is ever needed.
core_dumps__kernel_settings__sysctl__dependent_var:
- name: 'fs.suid_dumpable'
value: 0
2 changes: 0 additions & 2 deletions roles/core_dumps/handlers/main.yml

This file was deleted.

12 changes: 0 additions & 12 deletions roles/core_dumps/meta/argument_specs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,6 @@ argument_specs:
`hard core` limit in `/etc/security/limits.d/`. `0` disables
core dumps for all users.

core_dumps__sysctl_suid_dumpable:
type: 'int'
required: false
default: 0
choices:
- 0
- 1
- 2
description: >-
`fs.suid_dumpable` sysctl. `0` prevents core dumps of setuid /
setgid processes.

core_dumps__systemd_process_size_max:
type: 'int'
required: false
Expand Down
11 changes: 2 additions & 9 deletions roles/core_dumps/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,8 @@
group: 'root'
mode: 0o644

- name: 'Deploy /etc/sysctl.d/linuxfabrik-core-dumps.conf'
ansible.builtin.template:
backup: true
src: 'etc/sysctl.d/linuxfabrik-core-dumps.conf.j2'
dest: '/etc/sysctl.d/linuxfabrik-core-dumps.conf'
owner: 'root'
group: 'root'
mode: 0o644
notify: 'core_dumps: sysctl --system'
# fs.suid_dumpable is set via the kernel_settings role (see the playbook),
# not here, so sysctl management stays in a single place.

- name: 'mkdir -p /etc/systemd/coredump.conf.d'
ansible.builtin.file:
Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion roles/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ The example role is a single standalone service, so it has no walkthrough.
* Manages optional example plugins (install/remove).
* Triggers: none.

`example:user`
`example:users`

* Manages application users via the REST API.
* Triggers: none.
Expand Down
3 changes: 0 additions & 3 deletions roles/example/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ example__maintenance_cron_minute: '{{ 59 | random(seed=inventory_hostname) }}'
example__service_enabled: true
example__service_state: 'started'

# recommended-but-optional: gates the backup cron. empty default = no backups taken.
example__backup_target: ''

# simple config directive, used to demonstrate the variable-subgroup README section.
example__conf_tls_protocols: 'TLSv1.2 TLSv1.3'


Expand Down
4 changes: 2 additions & 2 deletions roles/example/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@

tags:
- 'example'
- 'example:user'
- 'example:users'


- block:
Expand All @@ -473,4 +473,4 @@
- 'example:configure'
- 'example:plugins'
- 'example:state'
- 'example:user'
- 'example:users'
2 changes: 1 addition & 1 deletion roles/freeipa_server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Manual steps:
* Deploys `/etc/systemd/system/pki-tomcatd@.service.d/override.conf`.
* Triggers: none.

`freeipa_server:user`
`freeipa_server:users`

* Manages FreeIPA users and their group memberships.
* Triggers: none.
Expand Down
2 changes: 1 addition & 1 deletion roles/freeipa_server/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@
tags:
- 'freeipa_server'
- 'freeipa_server:configure'
- 'freeipa_server:user'
- 'freeipa_server:users'


# HBAC rule management
Expand Down
2 changes: 1 addition & 1 deletion roles/grav/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Any [LFOps playbook](https://github.com/Linuxfabrik/lfops/blob/main/playbooks/RE
* `systemctl enable/disable grav-update.timer --now`.
* Triggers: none.

`grav:user`
`grav:users`

* Install the Administration Panel plugin for Grav.
* Create Grav User Accounts.
Expand Down
2 changes: 1 addition & 1 deletion roles/grav/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
- 'not grav__skip_admin'
tags:
- 'grav'
- 'grav:user'
- 'grav:users'


- block:
Expand Down
2 changes: 1 addition & 1 deletion roles/icingaweb2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Manual steps:
* Deploys `/etc/icingaweb2/resources.ini`.
* Triggers: none.

`icingaweb2:user`
`icingaweb2:users`

* Creates user accounts and deploys the role config.
* Triggers: none.
Expand Down
4 changes: 2 additions & 2 deletions roles/icingaweb2/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- 'icingaweb2'
- 'icingaweb2:configure'
- 'icingaweb2:resources'
- 'icingaweb2:user'
- 'icingaweb2:users'

- block:

Expand Down Expand Up @@ -239,4 +239,4 @@

tags:
- 'icingaweb2'
- 'icingaweb2:user'
- 'icingaweb2:users'
4 changes: 2 additions & 2 deletions roles/influxdb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Any [LFOps playbook](https://github.com/Linuxfabrik/lfops/blob/main/playbooks/RE
* Deploys the /etc/influxdb/influxdb.conf config file.
* Triggers: influxdb.service restart.

`influxdb:database`
`influxdb:databases`

* Creates or deletes InfluxDB databases.
* Triggers: none.
Expand All @@ -42,7 +42,7 @@ Any [LFOps playbook](https://github.com/Linuxfabrik/lfops/blob/main/playbooks/RE
* Manages the state of the InfluxDB service.
* Triggers: none.

`influxdb:user`
`influxdb:users`

* Creates, updates or deletes InfluxDB users.
* Triggers: none.
Expand Down
4 changes: 2 additions & 2 deletions roles/influxdb/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@

tags:
- 'influxdb'
- 'influxdb:database'
- 'influxdb:databases'


- name: 'Create, update or delete influxdb users'
Expand All @@ -200,4 +200,4 @@
ansible_python_interpreter: '/opt/python-venv/influxdb/bin/python3'
tags:
- 'influxdb'
- 'influxdb:user'
- 'influxdb:users'
4 changes: 2 additions & 2 deletions roles/mariadb_server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Manual steps:
* Deploys the keyfile for the [File Key Management Encryption Plugin](https://mariadb.com/kb/en/file-key-management-encryption-plugin/) and restarts MariaDB if necessary.
* Triggers: mariadb.service restart.

`mariadb_server:database`
`mariadb_server:databases`

* Create or delete mariadb databases.
* Triggers: none.
Expand Down Expand Up @@ -121,7 +121,7 @@ Manual steps:
* Must be explicitly called.
* Triggers: mariadb.service restart.

`mariadb_server:user`
`mariadb_server:users`

* Create DBA.
* Create, update or delete MariaDB users.
Expand Down
Loading