diff --git a/playbooks/02-xmpp-server.yaml b/playbooks/02-xmpp-server.yaml index ddc45b2..8ed79b0 100644 --- a/playbooks/02-xmpp-server.yaml +++ b/playbooks/02-xmpp-server.yaml @@ -60,13 +60,19 @@ - name: "Ensure movim database is present and accessible" ansible.builtin.include_tasks: file: tasks/chat/database.yml + - name: "Ensure movim version is installed - v{{ movim.version }}" ansible.builtin.include_tasks: file: tasks/chat/movim.yml - - name: "Ensure ejabberd is configured" + + - name: "Ensure X509 certificates are properly installed" ansible.builtin.include_tasks: - file: tasks/chat/ejabberd.yml + file: tasks/chat/x509.yml - name: "Ensure nginx is configured" ansible.builtin.include_tasks: file: tasks/chat/nginx.yml + + - name: "Ensure ejabberd is configured" + ansible.builtin.include_tasks: + file: tasks/chat/ejabberd.yml diff --git a/playbooks/tasks/chat/database.yml b/playbooks/tasks/chat/database.yml index 8ee7471..bfb8610 100644 --- a/playbooks/tasks/chat/database.yml +++ b/playbooks/tasks/chat/database.yml @@ -1,16 +1,22 @@ --- -- name: Ensure database user Exists +- name: Ensure databases user exist community.postgresql.postgresql_user: - user: movim - password: movim + user: "{{ item }}" + password: "{{ item }}" state: present become_user: "{{ postgres.user }}" become: true + with_items: + - movim + - ejabberd -- name: Ensure database exists +- name: Ensure databases exist community.postgresql.postgresql_db: - name: movim - owner: movim + name: "{{ item }}" + owner: "{{ item }}" state: present become_user: "{{ postgres.user }}" become: true + with_items: + - movim + - ejabberd diff --git a/playbooks/tasks/chat/ejabberd.yml b/playbooks/tasks/chat/ejabberd.yml index eed46eb..95555cc 100644 --- a/playbooks/tasks/chat/ejabberd.yml +++ b/playbooks/tasks/chat/ejabberd.yml @@ -1,3 +1,22 @@ --- -- name: Use variables - ansible.builtin.include_vars: vars.yml +- name: Create ejabberd configuration file + ansible.builtin.copy: + src: tasks/chat/files/ejabberd.yml + dest: /opt/ejabberd/conf/ejabberd.yml + owner: "{{ ejabberd.user }}" + group: "{{ ejabberd.group }}" + mode: "644" + +- name: Create ejabberd upload directory + ansible.builtin.file: + path: /opt/ejabberd/upload + state: directory + owner: "{{ ejabberd.user }}" + group: "{{ ejabberd.group }}" + mode: "755" + +- name: Restart ejabberd service + ansible.builtin.service: + name: ejabberd + state: restarted + diff --git a/playbooks/tasks/chat/files/ejabberd.yml b/playbooks/tasks/chat/files/ejabberd.yml new file mode 100644 index 0000000..0085df2 --- /dev/null +++ b/playbooks/tasks/chat/files/ejabberd.yml @@ -0,0 +1,303 @@ +loglevel: warning + +log_rotate_count: 0 + +hosts: + - trans13nrv.eu.org + +fqdn: xmpp.trans13nrv.eu.org + +certfiles: + - "/etc/letsencrypt/live/trans13nrv.eu.org/privkey.pem" + - "/etc/letsencrypt/live/trans13nrv.eu.org/fullchain.pem" + +update_sql_schema: true +new_sql_schema: true +sql_type: pgsql +sql_server: localhost +sql_database: ejabberd +sql_username: ejabberd +sql_password: ejabberd +auth_method: [sql] + +default_db: sql + +acme: + auto: false + +language: fr + +define_macro: + 'TLS_CIPHERS': "HIGH:!aNULL:!eNULL:!3DES:@STRENGTH" + 'TLS_OPTIONS': + - "no_sslv3" + - "no_tlsv1" + - "no_tlsv1_1" + - "cipher_server_preference" + - "no_compression" + # 'DH_FILE': "/path/to/dhparams.pem" + # generated with: openssl dhparam -out dhparams.pem 2048 + +c2s_ciphers: 'TLS_CIPHERS' +s2s_ciphers: 'TLS_CIPHERS' +c2s_protocol_options: 'TLS_OPTIONS' +s2s_protocol_options: 'TLS_OPTIONS' +# c2s_dhfile: 'DH_FILE' +# s2s_dhfile: 'DH_FILE' + +listen: + - + port: 5222 + ip: "137.74.82.131" + module: ejabberd_c2s + max_stanza_size: 262144 + shaper: c2s_shaper + access: c2s + starttls: true + - + port: 5223 + ip: "137.74.82.131" + module: ejabberd_c2s + max_stanza_size: 262144 + shaper: c2s_shaper + access: c2s + tls: true + - + port: 5269 + ip: "137.74.82.131" + module: ejabberd_s2s_in + max_stanza_size: 524288 + - + port: 5443 + ip: "137.74.82.131" + module: ejabberd_http + tls: true + protocol_options: 'TLS_OPTIONS' + request_handlers: + /api: mod_http_api + /bosh: mod_bosh + ## /captcha: ejabberd_captcha + /upload: mod_http_upload + /ws: ejabberd_http_ws + custom_headers: + "Access-Control-Allow-Origin": "*" + "Access-Control-Allow-Methods": "OPTIONS, HEAD, GET, PUT" + "Access-Control-Allow-Headers": "Authorization" + "Access-Control-Allow-Credentials": "true" +# - +# port: 5280 +# module: ejabberd_http +# tls: false +# protocol_options: 'TLS_OPTIONS' +# request_handlers: {} +# /.well-known/acme-challenge: ejabberd_acme +# /admin: ejabberd_web_admin + - + port: 3478 + ip: "137.74.82.131" + transport: udp + module: ejabberd_stun + use_turn: true + turn_ipv4_address: "137.74.82.131" + - + port: 1883 + ip: "137.74.82.131" + module: mod_mqtt + backlog: 1000 + + +## Disabling digest-md5 SASL authentication. digest-md5 requires plain-text +## password storage (see auth_password_format option). +disable_sasl_mechanisms: + - "digest-md5" + - "X-OAUTH2" + +s2s_use_starttls: required + +## Store the plain passwords or hashed for SCRAM: +auth_password_format: scram + +## Full path to a script that generates the image. +## captcha_cmd: "/usr/share/ejabberd/captcha.sh" + +acl: + admin: + user: + - "stupeflo@trans13nrv.eu.org" + - "llowin@trans13nrv.eu.org" + + local: + user_regexp: "" + loopback: + ip: + - 127.0.0.0/8 + - ::1/128 + +access_rules: + local: + allow: local + c2s: + deny: blocked + allow: all + announce: + allow: admin + configure: + allow: admin + muc_create: + allow: local + pubsub_createnode: + allow: local + trusted_network: + allow: loopback + +api_permissions: + "console commands": + from: + - ejabberd_ctl + who: all + what: "*" + "admin access": + who: + access: + allow: + - acl: loopback + - acl: admin + oauth: + scope: "ejabberd:admin" + access: + allow: + - acl: loopback + - acl: admin + what: + - "*" + - "!stop" + - "!start" + "public commands": + who: + ip: 127.0.0.1/8 + what: + - status + - connected_users_number + +shaper: + normal: + rate: 3000 + burst_size: 20000 + fast: 200000 + +shaper_rules: + max_user_sessions: 10 + max_user_offline_messages: + 5000: admin + 100: all + c2s_shaper: + none: admin + normal: all + s2s_shaper: fast + +modules: + mod_admin_update_sql: {} + mod_adhoc: {} + mod_admin_extra: {} + mod_announce: + access: announce + mod_avatar: {} + mod_blocking: {} + mod_bosh: {} + mod_caps: {} + mod_carboncopy: {} + mod_client_state: {} + mod_configure: {} + ## mod_delegation: {} # for xep0356 + mod_disco: {} + mod_fail2ban: {} + mod_http_api: {} + mod_http_upload: + name: "HTTP File Upload" + access: local + max_size: 104857600 # 100 MiB. + file_mode: "0640" + dir_mode: "2750" + docroot: "/opt/ejabberd/upload/@HOST@" + put_url: "https://@HOST@:8443/upload" + thumbnail: false + hosts: + - upload.trans13nrv.eu.org + mod_last: {} + mod_mam: + ## Mnesia is limited to 2GB, better to use an SQL backend + ## For small servers SQLite is a good fit and is very easy + ## to configure. Uncomment this when you have SQL configured: + db_type: sql + assume_mam_usage: true + default: always + mod_mqtt: {} + mod_muc: + access: + - allow + access_admin: + - allow: admin + access_create: muc_create + access_persistent: muc_create + access_mam: + - allow + default_room_options: + mam: true + host: muc.trans13nrv.eu.org + mod_muc_admin: {} + mod_offline: + access_max_user_messages: max_user_offline_messages + mod_ping: {} + mod_pres_counter: + count: 5 + interval: 60 + mod_privacy: {} + mod_private: {} + ## mod_proxy65: + ## access: local + ## max_connections: 5 + mod_pubsub: + access_createnode: pubsub_createnode + ignore_pep_from_offline: false + last_item_cache: false + max_items_node: 1000 + default_node_config: + max_items: 1000 + plugins: + - "flat" + - "pep" + host: pubsub.trans13nrv.eu.org + force_node_config: + "eu.siacs.conversations.axolotl.*": + access_model: open + ## Avoid buggy clients to make their bookmarks public + storage:bookmarks: + access_model: whitelist + mod_push: {} + mod_push_keepalive: {} + ## mod_register: + ## ## Only accept registration requests from the "trusted" + ## ## network (see access_rules section above). + ## ## Think twice before enabling registration from any + ## ## address. See the Jabber SPAM Manifesto for details: + ## ## https://github.com/ge0rg/jabber-spam-fighting-manifesto + ## ip_access: trusted_network + mod_register: + ip_access: trusted_network + mod_roster: + versioning: true + mod_s2s_dialback: {} + mod_shared_roster: {} + mod_sic: {} + mod_stream_mgmt: + resend_on_timeout: if_offline + mod_stun_disco: {} + mod_vcard: + search: false + mod_vcard_xupdate: {} + mod_version: {} + +### Local Variables: +### mode: yaml +### End: +### vim: set filetype=yaml tabstop=8 \ No newline at end of file diff --git a/playbooks/tasks/chat/movim.yml b/playbooks/tasks/chat/movim.yml index e3978a9..571ce0f 100644 --- a/playbooks/tasks/chat/movim.yml +++ b/playbooks/tasks/chat/movim.yml @@ -132,7 +132,7 @@ mode: "644" create: true -- name: Ensure demon caches directory exists +- name: Ensure demon cache directories exists ansible.builtin.file: path: "{{ item }}" owner: "{{ www.user }}" @@ -149,12 +149,12 @@ - systemctl - daemon-reload -- name: Enable and start Movim Damon Service +- name: Enable and restarted Movim Damon Service when: not movim_is_installed ansible.builtin.systemd_service: service: movim.service enabled: true - state: started + state: restarted - name: Enable and start Movim Damon Service ansible.builtin.systemd_service: diff --git a/playbooks/tasks/chat/nginx.yml b/playbooks/tasks/chat/nginx.yml index 94ca5c2..4e3e9f6 100644 --- a/playbooks/tasks/chat/nginx.yml +++ b/playbooks/tasks/chat/nginx.yml @@ -1,12 +1,5 @@ --- -- name: disable access logs - ansible.builtin.blockinfile: - path: "{{ nginx.paths.conf_d }}/10-access_log-disabled.conf" - block: | - access_log off; - create: true - -- name: Create auto redirect to TLS +- name: Create auto redirect to TLS for movim ansible.builtin.blockinfile: path: "{{ nginx.paths.sites_available }}/redirect_to_https" block: | @@ -17,39 +10,6 @@ } create: true -- name: Disable movim website - ansible.builtin.file: - path: "{{ nginx.paths.sites_enabled }}/{{ movim.domain }}" - state: absent - -- name: Disable auto redirect to TLS - ansible.builtin.file: - path: "{{ nginx.paths.sites_enabled }}/redirect_to_https" - state: absent - -- name: Enable default website - ansible.builtin.file: - dest: "{{ nginx.paths.sites_enabled }}/default" - src: "{{ nginx.paths.sites_available }}/default" - state: link - -- name: Install X509 certificates - ansible.builtin.command: - argv: - - certbot - - certonly - - --agree-tos - - -m psotmaster@trans13nrv.eu.org - - --nginx - - -d - - "{{ movim.domain }}" - creates: "/etc/letsencrypt/live/{{ movim.domain }}/privkey.pem" - -- name: Disable default website - ansible.builtin.file: - path: "{{ nginx.paths.sites_enabled }}/default" - state: absent - - name: Create movim website ansible.builtin.template: dest: "{{ nginx.paths.sites_available }}/{{ movim.domain }}" @@ -70,7 +30,14 @@ dest: "{{ nginx.paths.sites_enabled }}/redirect_to_https" src: "{{ nginx.paths.sites_available }}/redirect_to_https" +- name: Set access logs to off + ansible.builtin.blockinfile: + path: "{{ nginx.paths.conf_d }}/10-access_log-disabled.conf" + block: | + access_log off; + create: true + - name: Reload nginx service ansible.builtin.systemd_service: name: nginx - state: reloaded \ No newline at end of file + state: restarted diff --git a/playbooks/tasks/chat/templates/ejabberd.yaml.j2 b/playbooks/tasks/chat/templates/ejabberd.yaml.j2 index 6c1e931..635d205 100644 --- a/playbooks/tasks/chat/templates/ejabberd.yaml.j2 +++ b/playbooks/tasks/chat/templates/ejabberd.yaml.j2 @@ -209,7 +209,7 @@ modules: ## ## Mnesia is limited to 2GB, better to use an SQL backend ## ## For small servers SQLite is a good fit and is very easy ## ## to configure. Uncomment this when you have SQL configured: - ## ## db_type: sql + ## ## db_type: sql ## assume_mam_usage: true ## default: always mod_mqtt: {} diff --git a/playbooks/tasks/chat/templates/movim.j2 b/playbooks/tasks/chat/templates/movim.j2 index 110a782..2c4cd8b 100644 --- a/playbooks/tasks/chat/templates/movim.j2 +++ b/playbooks/tasks/chat/templates/movim.j2 @@ -5,7 +5,7 @@ server { server_name {{ movim.domain }}; ssl_certificate /etc/letsencrypt/live/{{ movim.domain }}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/{{ movim.domain }}/privkey.pem; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; # Where Movim public directory is setup diff --git a/playbooks/tasks/chat/x509.yml b/playbooks/tasks/chat/x509.yml new file mode 100644 index 0000000..ff8be84 --- /dev/null +++ b/playbooks/tasks/chat/x509.yml @@ -0,0 +1,55 @@ +--- +- name: Disable movim website + ansible.builtin.file: + path: "{{ nginx.paths.sites_enabled }}/{{ movim.domain }}" + state: absent + +- name: Disable auto redirect to TLS + ansible.builtin.file: + path: "{{ nginx.paths.sites_enabled }}/redirect_to_https" + state: absent + +- name: Enable default website + ansible.builtin.file: + dest: "{{ nginx.paths.sites_enabled }}/default" + src: "{{ nginx.paths.sites_available }}/default" + state: link + +- name: Install X509 certificates for movim + ansible.builtin.command: + argv: + - certbot + - certonly + - --agree-tos + - -m + - psotmaster@trans13nrv.eu.org + - --nginx + - -d + - "{{ movim.domain }}" + creates: "/etc/letsencrypt/live/{{ movim.domain }}*/privkey.pem" + +- name: Install X509 certificates for ejabberd hosts + ansible.builtin.command: + argv: + - certbot + - certonly + - --agree-tos + - -m + - psotmaster@trans13nrv.eu.org + - --nginx + - -d + - trans13nrv.eu.org + - -d + - xmpp.trans13nrv.eu.org + - -d + - muc.trans13nrv.eu.org + - -d + - "pubsub.trans13nrv.eu.org" + - -d + - upload.trans13nrv.eu.org + creates: "/etc/letsencrypt/live/trans13nrv.eu.org/privkey.pem" + +- name: Disable default website + ansible.builtin.file: + path: "{{ nginx.paths.sites_enabled }}/default" + state: absent diff --git a/playbooks/tasks/ns/files/db.trans13nrv.eu.org.zone b/playbooks/tasks/ns/files/db.trans13nrv.eu.org.zone index 7e7a350..d7fad54 100644 --- a/playbooks/tasks/ns/files/db.trans13nrv.eu.org.zone +++ b/playbooks/tasks/ns/files/db.trans13nrv.eu.org.zone @@ -1,7 +1,7 @@ $ORIGIN trans13nrv.eu.org. $TTL 300s @ SOA ns1 postmaster ( - 2024052300 ; Serial + 2024052340 ; Serial 8h ; Refresh 30m ; Retry 1w ; Expire @@ -18,6 +18,7 @@ ns1 A 137.74.82.130 ;;; XMPP ;;; ; server IP jabber A 137.74.82.131 +@ A 137.74.82.131 ; ports _xmpp-server._tcp IN SRV 5 0 5269 xmpp @@ -37,6 +38,6 @@ xmpp CNAME jabber ; XMPP Service turn CNAME jabber ; VOIP service chat CNAME jabber ; Web Frontend muc CNAME jabber ; Multi-User chat -upload CNAME jabbbr ; Upload over XMPP +upload CNAME jabber ; Upload over XMPP pubsub CNAME jabber ; Pub-Sub over XMPP proxy CNAME jabber ; Proxy for file transfer over XMPP diff --git a/playbooks/vars.yml b/playbooks/vars.yml index cc54b8d..f8c7687 100644 --- a/playbooks/vars.yml +++ b/playbooks/vars.yml @@ -24,4 +24,7 @@ nginx: paths: sites_enabled: /etc/nginx/sites-enabled sites_available: /etc/nginx/sites-available - conf_d: /etc/nginx/conf.d \ No newline at end of file + conf_d: /etc/nginx/conf.d +ejabberd: + user: ejabberd + group: ejabberd \ No newline at end of file