diff --git a/collections/ansible_collections/nullified/infrastructure/roles/k3s/tasks/main.yml b/collections/ansible_collections/nullified/infrastructure/roles/k3s/tasks/main.yml index 26df51e..92cc326 100644 --- a/collections/ansible_collections/nullified/infrastructure/roles/k3s/tasks/main.yml +++ b/collections/ansible_collections/nullified/infrastructure/roles/k3s/tasks/main.yml @@ -85,7 +85,7 @@ - name: reset permissions become: true - command: + ansible.builtin.command: cmd: "mv {{ backup_sudoers.backup }} /etc/sudoers" removes: "{{ backup_sudoers.backup }}" when: backup_sudoers.backup diff --git a/collections/ansible_collections/nullified/infrastructure/roles/mariadb/defaults/main.yml b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/defaults/main.yml new file mode 100644 index 0000000..97b7cd4 --- /dev/null +++ b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/defaults/main.yml @@ -0,0 +1,12 @@ +--- +mariadb_install_server: true +mariadb_install_client: false +mariadb_nft_filter_input: false +mariadb_nft_filter_output: false +mariadb_nft_allowed_ingress_list: [] +mariadb_nft_allowed_egress_list: [] +mariadb_server_port: 3306 +mariadb_server_run_init_sql: false +mariadb_server_run_custom_sql: false +mariadb_server_custom_sql: "" +mariadb_server_bind_addresses: false diff --git a/collections/ansible_collections/nullified/infrastructure/roles/mariadb/handlers/main.yml b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/handlers/main.yml new file mode 100644 index 0000000..4fdf551 --- /dev/null +++ b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: restart mariadb service + become: true + ansible.builtin.systemd_service: + name: mariadb.service + enabled: true + state: restarted diff --git a/collections/ansible_collections/nullified/infrastructure/roles/mariadb/meta/main.yml b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/meta/main.yml new file mode 100644 index 0000000..8dc660d --- /dev/null +++ b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/meta/main.yml @@ -0,0 +1,21 @@ +--- +galaxy_info: + author: Florian L. + namespace: nullified + description: Install MariaDB and configure it, along with firewall rules + license: MIT + min_ansible_version: 2.15 + + # https://galaxy.ansible.com/api/v1/platforms/ + platforms: + - name: Debian + versions: + - bookworm + + galaxy_tags: + - github + - database + - mariadb + - sql + +dependencies: [] diff --git a/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tasks/client.yml b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tasks/client.yml new file mode 100644 index 0000000..d1c8d30 --- /dev/null +++ b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tasks/client.yml @@ -0,0 +1,10 @@ +--- +- name: install client packages + become: true + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + force_apt_get: true + pkg: + - mariadb-client + - mariadb-client-core diff --git a/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tasks/main.yml b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tasks/main.yml new file mode 100644 index 0000000..54d9d5e --- /dev/null +++ b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tasks/main.yml @@ -0,0 +1,21 @@ +--- +- name: setup server + include_tasks: server.yml + when: mariadb_install_server is truthy + +- name: setup client + include_tasks: client.yml + when: mariadb_install_client is truthy + +- name: install firewall rules + become: true + template: + src: ../templates/nftables.d/mariadb.nft.j2 + dest: /etc/nftables.d/mariadb.nft + mode: '0600' + register: nft_rule + +- name: load firewall rules + become: true + ansible.builtin.command: /usr/sbin/nft -f /etc/nftables.d/mariadb.nft + when: nft_rule.changed diff --git a/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tasks/server.yml b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tasks/server.yml new file mode 100644 index 0000000..4db3493 --- /dev/null +++ b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tasks/server.yml @@ -0,0 +1,36 @@ +--- +- name: install server packages + become: true + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + force_apt_get: true + pkg: + - mariadb-common + - mariadb-server + - mariadb-server-core + +- name: initialize database + become: true + block: + - name: export initialization SQL file + ansible.builtin.template: + src: ../templates/mariadb_init.sql.j2 + dest: /tmp/mariadb_init.sql + mode: '0600' + register: sql_init + - name: run initialization file + ansible.builtin.shell: mysql < /tmp/mariadb_init.sql + when: sql_init.changed + when: mariadb_server_run_init_sql is truthy or mariadb_server_run_custom_sql is truthy + +- name: update bind addresses to allow external connections + become: true + ansible.builtin.lineinfile: + path: /etc/mysql/mariadb.conf.d/50-server.cnf + regexp: '^bind-address\b.+' + line: "bind-address = {{ mariadb_server_bind_addresses|join(',') }}" + state: present + when: mariadb_server_bind_addresses is truthy + notify: + - 'mariadb : restart mariadb service' diff --git a/collections/ansible_collections/nullified/infrastructure/roles/mariadb/templates/mariadb_init.sql.j2 b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/templates/mariadb_init.sql.j2 new file mode 100644 index 0000000..69d6af0 --- /dev/null +++ b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/templates/mariadb_init.sql.j2 @@ -0,0 +1,22 @@ +{% if mariadb_server_run_init_sql %} +# Run hardening steps from `mysql_secure_installation` +DELETE FROM mysql.global_priv WHERE User=''; +DELETE FROM mysql.global_priv WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); +DROP DATABASE IF EXISTS test; +DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'; + +UPDATE mysql.global_priv +SET priv=json_set( + priv, + '$.password_last_changed', UNIX_TIMESTAMP(), + '$.plugin', 'mysql_native_password', + '$.authentication_string', PASSWORD('{{ mariadb_server_root_password }}'), + '$.auth_or', json_array(json_object(), json_object('plugin', 'unix_socket')) + ) +WHERE User='root'; + +FLUSH PRIVILEGES; +{% endif %} +{% if mariadb_server_run_custom_sql and mariadb_server_custom_sql|length %} +{{ mariadb_server_custom_sql }} +{% endif %} diff --git a/collections/ansible_collections/nullified/infrastructure/roles/mariadb/templates/nftables.d/mariadb.nft.j2 b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/templates/nftables.d/mariadb.nft.j2 new file mode 100644 index 0000000..7bb1847 --- /dev/null +++ b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/templates/nftables.d/mariadb.nft.j2 @@ -0,0 +1,26 @@ +{%- set allowed_ingress_list4 = mariadb_nft_allowed_ingress_list | ansible.utils.ipv4 -%} +{%- set allowed_ingress_list6 = mariadb_nft_allowed_ingress_list | ansible.utils.ipv6 -%} +{%- set allowed_egress_list4 = mariadb_nft_allowed_egress_list | ansible.utils.ipv4 | default([], true) -%} +{%- set allowed_egress_list6 = mariadb_nft_allowed_egress_list | ansible.utils.ipv6 | default([], true) -%} +table inet filter { +{% if mariadb_install_server %} + chain input { +{% if mariadb_nft_filter_input %} + {%+ if allowed_ingress_list4 %}ip saddr { {{ allowed_ingress_list4 | join(', ') }} } tcp dport {{ mariadb_server_port }} accept{% endif +%} + {%+ if allowed_ingress_list6 %}ip6 saddr { {{ allowed_ingress_list6 | join(', ') }} } tcp dport {{ mariadb_server_port }} accept{% endif +%} +{% else %} + tcp dport {{ mariadb_server_port }} accept +{% endif %} + } +{% endif %} +{% if mariadb_install_client %} + chain output { +{% if mariadb_nft_filter_output %} + {%+ if allowed_egress_list4 %}ip daddr { {{ allowed_egress_list4 | join(', ') }} } tcp dport {{ mariadb_server_port }} accept{% endif +%} + {%+ if allowed_egress_list6 %}ip daddr { {{ allowed_egress_list6 | join(', ') }} } tcp dport {{ mariadb_server_port }} accept{% endif +%} +{% else %} + tcp dport {{ mariadb_server_port }} accept +{% endif %} + } +{% endif %} +} diff --git a/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tests/inventory b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/collections/ansible_collections/nullified/infrastructure/roles/mariadb/vars/main.yml b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/vars/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/collections/ansible_collections/nullified/infrastructure/roles/mariadb/vars/main.yml @@ -0,0 +1 @@ +--- diff --git a/inventory/host_vars/actinium/vars.yml b/inventory/host_vars/actinium/vars.yml index 57a5f10..36a667b 100644 --- a/inventory/host_vars/actinium/vars.yml +++ b/inventory/host_vars/actinium/vars.yml @@ -8,3 +8,7 @@ security_firewall_mangle_policy_forward: accept k3s_cluster_name: internal k3s_cluster_role: server k3s_cluster_ip: "{{ vault_cluster_ip }}" + +mariadb_server_root_password: "{{ vault_mariadb_server_root_password }}" +mariadb_server_custom_sql: "{{ vault_mariadb_server_custom_sql }}" +mariadb_server_bind_addresses: "{{ vault_mariadb_server_bind_addresses }}" diff --git a/playbooks/internal.yml b/playbooks/internal.yml index 96394ff..f98a70b 100644 --- a/playbooks/internal.yml +++ b/playbooks/internal.yml @@ -17,6 +17,13 @@ ansible.builtin.include_role: name: nullified.infrastructure.server +- name: setup mariadb servers + hosts: internal:&mariadb + tasks: + - name: include mariadb role + ansible.builtin.include_role: + name: nullified.infrastructure.mariadb + - name: setup workstations hosts: internal:&workstation tasks: