diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md index 8f58e1a36..7e75973d1 100644 --- a/docs/_Sidebar.md +++ b/docs/_Sidebar.md @@ -55,6 +55,7 @@ - [Jitsi](/roles/debian/jitsi) - [LDAP Server](/roles/debian/ldap_server) - [LHCI](/roles/debian/lhci) + - [Mailpit](/roles/debian/mailpit) - [Mount sync](/roles/debian/mount_sync) - [MariaDB Client](/roles/debian/mysql_client) - [MySQL Server - Oracle Community Edition](/roles/debian/mysql_server_oracle_ce) diff --git a/docs/roles/debian/firewall_config.md b/docs/roles/debian/firewall_config.md index 5f8f34ee2..1577b0c12 100644 --- a/docs/roles/debian/firewall_config.md +++ b/docs/roles/debian/firewall_config.md @@ -77,6 +77,9 @@ firewall_config: firewall_allowed_tcp_ports: - "80" - "443" + mailpit_open: + firewall_allowed_tcp_ports: + - "8025" ftp_open: firewall_allowed_tcp_ports: - "20" diff --git a/docs/roles/debian/mailpit.md b/docs/roles/debian/mailpit.md new file mode 100644 index 000000000..5431d0cf2 --- /dev/null +++ b/docs/roles/debian/mailpit.md @@ -0,0 +1,63 @@ +# Mailpit +[Mailpit](https://mailpit.axllent.org) provides a dummy SMTP mail server and a HTTP interface for checking email so you can verify email is functional in an application without actually sending it out. This is particularly handy in dev and testing environments, as well as on local development environments. + +The defaults will install Mailpit as a service and start it with SMTP on port 1025 and the web UI on port 8025. Don't forget, for access to the web UI you will need to open the firewall port. By default the web UI is on port 8025. + +The role will also attempt to create a self-signed SSL certificate for Mailpit unless you set `mailpit.create_cert` to `false`. If you already have an SSL certificate you may do this and provide the paths to cert and key and, as long as `mailpit.https` is set to `true` the service will try to start with the specified cert and key. There are also ready defaults for LetsEncrypt commented out. + +If you set `mailpit.service` to `false` then the role will simply install Mailpit and stop, leaving it to you to start and stop the application. + +This role works fine in Docker, however [for `ce-dev` you might consider using the Mailpit container instead](https://mailpit.axllent.org/docs/install/docker/). + + + + + +## Default variables +```yaml +--- +mailpit: + script_install_path: "/home/{{ user_provision.username }}" + https: true + create_cert: true + service: true + database_directory: "/home/{{ user_provision.username }}/mailpit" # must be readable and writeable by the executing user + database_filename: mailpit.db + smtp_listen: 0.0.0.0:1025 + web_ui_listen: 0.0.0.0:8025 + web_ui_webroot: / + web_ui_authfile_src: "" # path to your base auth passwords file on the Ansible controller - see https://mailpit.axllent.org/docs/configuration/http-authentication/ + web_ui_authfile_dest: "" # path where you want to place your passwords file on the target - leave empty for no basic auth + web_ui_ssl_cert: "/etc/ssl/selfsigned/{{ _domain_name }}.cert" + web_ui_ssl_key: "/etc/ssl/selfsigned/{{ _domain_name }}.key" + # LetsEncrypt example paths + #web_ui_ssl_cert: "/etc/letsencrypt/live/{{ _domain_name }}/fullchain.pem" + #web_ui_ssl_key: "/etc/letsencrypt/live/{{ _domain_name }}/privkey.pem" + additional_options: "" # runtime custom options - see https://mailpit.axllent.org/docs/configuration/runtime-options/ + # only used if https: false, otherwise must run as root + user: "{{ user_provision.username }}" + group: "{{ user_provision.username }}" + # @see the 'ssl' role - defaults to using LetsEncrypt + ssl: + replace_existing: false + domains: + - "{{ _domain_name }}" + handling: selfsigned + # example LetsEncrypt config + #handling: letsencrypt + #http_01_port: 80 + #autorenew: true + #email: sysadm@codeenigma.com + #services: + # - nginx + #web_server: standalone + #certbot_register_command: "/usr/bin/certbot certonly --agree-tos --preferred-challenges http -n" + #certbot_renew_command: "/usr/bin/certbot certonly --agree-tos --force-renew" + #reload_command: restart + #reload: + # - mailpit + #on_calendar: "Mon *-*-* 04:00:00" + +``` + + diff --git a/roles/debian/firewall_config/README.md b/roles/debian/firewall_config/README.md index 5f8f34ee2..1577b0c12 100644 --- a/roles/debian/firewall_config/README.md +++ b/roles/debian/firewall_config/README.md @@ -77,6 +77,9 @@ firewall_config: firewall_allowed_tcp_ports: - "80" - "443" + mailpit_open: + firewall_allowed_tcp_ports: + - "8025" ftp_open: firewall_allowed_tcp_ports: - "20" diff --git a/roles/debian/firewall_config/defaults/main.yml b/roles/debian/firewall_config/defaults/main.yml index 422c6cf7f..7c9193af6 100644 --- a/roles/debian/firewall_config/defaults/main.yml +++ b/roles/debian/firewall_config/defaults/main.yml @@ -29,6 +29,9 @@ firewall_config: firewall_allowed_tcp_ports: - "80" - "443" + mailpit_open: + firewall_allowed_tcp_ports: + - "8025" ftp_open: firewall_allowed_tcp_ports: - "20" diff --git a/roles/debian/mailpit/README.md b/roles/debian/mailpit/README.md new file mode 100644 index 000000000..5431d0cf2 --- /dev/null +++ b/roles/debian/mailpit/README.md @@ -0,0 +1,63 @@ +# Mailpit +[Mailpit](https://mailpit.axllent.org) provides a dummy SMTP mail server and a HTTP interface for checking email so you can verify email is functional in an application without actually sending it out. This is particularly handy in dev and testing environments, as well as on local development environments. + +The defaults will install Mailpit as a service and start it with SMTP on port 1025 and the web UI on port 8025. Don't forget, for access to the web UI you will need to open the firewall port. By default the web UI is on port 8025. + +The role will also attempt to create a self-signed SSL certificate for Mailpit unless you set `mailpit.create_cert` to `false`. If you already have an SSL certificate you may do this and provide the paths to cert and key and, as long as `mailpit.https` is set to `true` the service will try to start with the specified cert and key. There are also ready defaults for LetsEncrypt commented out. + +If you set `mailpit.service` to `false` then the role will simply install Mailpit and stop, leaving it to you to start and stop the application. + +This role works fine in Docker, however [for `ce-dev` you might consider using the Mailpit container instead](https://mailpit.axllent.org/docs/install/docker/). + + + + + +## Default variables +```yaml +--- +mailpit: + script_install_path: "/home/{{ user_provision.username }}" + https: true + create_cert: true + service: true + database_directory: "/home/{{ user_provision.username }}/mailpit" # must be readable and writeable by the executing user + database_filename: mailpit.db + smtp_listen: 0.0.0.0:1025 + web_ui_listen: 0.0.0.0:8025 + web_ui_webroot: / + web_ui_authfile_src: "" # path to your base auth passwords file on the Ansible controller - see https://mailpit.axllent.org/docs/configuration/http-authentication/ + web_ui_authfile_dest: "" # path where you want to place your passwords file on the target - leave empty for no basic auth + web_ui_ssl_cert: "/etc/ssl/selfsigned/{{ _domain_name }}.cert" + web_ui_ssl_key: "/etc/ssl/selfsigned/{{ _domain_name }}.key" + # LetsEncrypt example paths + #web_ui_ssl_cert: "/etc/letsencrypt/live/{{ _domain_name }}/fullchain.pem" + #web_ui_ssl_key: "/etc/letsencrypt/live/{{ _domain_name }}/privkey.pem" + additional_options: "" # runtime custom options - see https://mailpit.axllent.org/docs/configuration/runtime-options/ + # only used if https: false, otherwise must run as root + user: "{{ user_provision.username }}" + group: "{{ user_provision.username }}" + # @see the 'ssl' role - defaults to using LetsEncrypt + ssl: + replace_existing: false + domains: + - "{{ _domain_name }}" + handling: selfsigned + # example LetsEncrypt config + #handling: letsencrypt + #http_01_port: 80 + #autorenew: true + #email: sysadm@codeenigma.com + #services: + # - nginx + #web_server: standalone + #certbot_register_command: "/usr/bin/certbot certonly --agree-tos --preferred-challenges http -n" + #certbot_renew_command: "/usr/bin/certbot certonly --agree-tos --force-renew" + #reload_command: restart + #reload: + # - mailpit + #on_calendar: "Mon *-*-* 04:00:00" + +``` + + diff --git a/roles/debian/mailpit/defaults/main.yml b/roles/debian/mailpit/defaults/main.yml new file mode 100644 index 000000000..5a0666593 --- /dev/null +++ b/roles/debian/mailpit/defaults/main.yml @@ -0,0 +1,42 @@ +--- +mailpit: + script_install_path: "/home/{{ user_provision.username }}" + https: true + create_cert: true + service: true + database_directory: "/home/{{ user_provision.username }}/mailpit" # must be readable and writeable by the executing user + database_filename: mailpit.db + smtp_listen: 0.0.0.0:1025 + web_ui_listen: 0.0.0.0:8025 + web_ui_webroot: / + web_ui_authfile_src: "" # path to your base auth passwords file on the Ansible controller - see https://mailpit.axllent.org/docs/configuration/http-authentication/ + web_ui_authfile_dest: "" # path where you want to place your passwords file on the target - leave empty for no basic auth + web_ui_ssl_cert: "/etc/ssl/selfsigned/{{ _domain_name }}.cert" + web_ui_ssl_key: "/etc/ssl/selfsigned/{{ _domain_name }}.key" + # LetsEncrypt example paths + #web_ui_ssl_cert: "/etc/letsencrypt/live/{{ _domain_name }}/fullchain.pem" + #web_ui_ssl_key: "/etc/letsencrypt/live/{{ _domain_name }}/privkey.pem" + additional_options: "" # runtime custom options - see https://mailpit.axllent.org/docs/configuration/runtime-options/ + # only used if https: false, otherwise must run as root + user: "{{ user_provision.username }}" + group: "{{ user_provision.username }}" + # @see the 'ssl' role - defaults to using LetsEncrypt + ssl: + replace_existing: false + domains: + - "{{ _domain_name }}" + handling: selfsigned + # example LetsEncrypt config + #handling: letsencrypt + #http_01_port: 80 + #autorenew: true + #email: sysadm@codeenigma.com + #services: + # - nginx + #web_server: standalone + #certbot_register_command: "/usr/bin/certbot certonly --agree-tos --preferred-challenges http -n" + #certbot_renew_command: "/usr/bin/certbot certonly --agree-tos --force-renew" + #reload_command: restart + #reload: + # - mailpit + #on_calendar: "Mon *-*-* 04:00:00" diff --git a/roles/debian/mailpit/tasks/main.yml b/roles/debian/mailpit/tasks/main.yml new file mode 100644 index 000000000..aa376cfe4 --- /dev/null +++ b/roles/debian/mailpit/tasks/main.yml @@ -0,0 +1,87 @@ +--- +- name: Download latest Mailpit install script. + ansible.builtin.get_url: + url: https://raw.githubusercontent.com/axllent/mailpit/develop/install.sh + dest: "{{ mailpit.script_install_path }}/mailpit-install.sh" + mode: '0750' + owner: "{{ mailpit.user }}" + group: "{{ mailpit.group }}" + force: true + +- name: Attempt to install Mailpit. + ansible.builtin.command: + cmd: "{{ mailpit.script_install_path }}/mailpit-install.sh" + +- name: Generate SSL keys if requested. + ansible.builtin.include_role: + name: debian/ssl + vars: + ssl: "{{ mailpit.ssl }}" + when: mailpit.create_cert + +- name: Copy basic htauth file to server. + ansible.builtin.copy: + src: "{{ mailpit.web_ui_authfile_src }}" + dest: "{{ mailpit.web_ui_authfile_dest }}" + owner: root + group: root + mode: 0644 + when: mailpit.web_ui_authfile_dest | length > 0 + +- name: Start the launch string for the Mailpit service with the database location. + ansible.builtin.set_fact: + _mailpit_service_command: "-d {{ mailpit.database_directory }}/{{ mailpit.database_filename }}" + when: mailpit.service + +- name: Add web UI settings to launch string for Mailpit. + ansible.builtin.set_fact: + _mailpit_service_command: "{{ _mailpit_service_command }} --listen {{ mailpit.web_ui_listen }} --webroot {{ mailpit.web_ui_webroot }}" + when: mailpit.service + +- name: Add SMTP settings to launch string for Mailpit. + ansible.builtin.set_fact: + _mailpit_service_command: "{{ _mailpit_service_command }} --smtp {{ mailpit.smtp_listen }}" + when: mailpit.service + +- name: Add auth file to the launch string for Mailpit. + ansible.builtin.set_fact: + _mailpit_service_command: "{{ _mailpit_service_command }} --ui-auth-file {{ mailpit.web_ui_authfile_dest }}" + when: + - mailpit.service + - mailpit.web_ui_authfile_dest | length > 0 + +- name: Add SSL options to the launch string for Mailpit. + ansible.builtin.set_fact: + _mailpit_service_command: "{{ _mailpit_service_command }} --ui-tls-cert {{ mailpit.web_ui_ssl_cert }} --ui-tls-key {{ mailpit.web_ui_ssl_key }}" + when: + - mailpit.service + - mailpit.https + +- name: Add any additionally provided options to the launch string for Mailpit. + ansible.builtin.set_fact: + _mailpit_service_command: "{{ _mailpit_service_command }} {{ mailpit.additional_options }}" + when: + - mailpit.service + - mailpit.additional_options | length > 0 + +- name: Copy systemd service file to server. + ansible.builtin.template: + src: mailpit.service.j2 + dest: "/etc/systemd/system/mailpit.service" + owner: root + group: root + mode: 0755 + when: mailpit.service + +- name: Ensure the database directory exists and is writeable. + ansible.builtin.file: + path: "{{ mailpit.database_directory }}" + state: directory + +- name: Start Mailpit. + ansible.builtin.systemd_service: + name: mailpit + state: started + daemon_reload: true + enabled: true + when: mailpit.service diff --git a/roles/debian/mailpit/templates/mailpit.service.j2 b/roles/debian/mailpit/templates/mailpit.service.j2 new file mode 100644 index 000000000..b3cc0c12a --- /dev/null +++ b/roles/debian/mailpit/templates/mailpit.service.j2 @@ -0,0 +1,16 @@ +[Unit] +Description=Mailpit server + +[Service] +ExecStart=/usr/local/bin/mailpit {{ _mailpit_service_command }} +Restart=always +# Restart service after 10 seconds if node service crashes +RestartSec=10 +SyslogIdentifier=mailpit +{% if not mailpit.https %} +User={{ mailpit.user }} +Group={{ mailpit.group }} +{% endif %} + +[Install] +WantedBy=multi-user.target diff --git a/roles/debian/nginx/tasks/domain.yml b/roles/debian/nginx/tasks/domain.yml index 2c15440ea..57c7d7b9e 100644 --- a/roles/debian/nginx/tasks/domain.yml +++ b/roles/debian/nginx/tasks/domain.yml @@ -9,6 +9,7 @@ when: - domain.ssl is defined - domain.ssl.handling == 'letsencrypt' + - domain.ssl.services | length > 0 # if services[] is defined we can assume we are running certbot on port 80 or 443 - name: Enable vhost. ansible.builtin.file: @@ -18,6 +19,7 @@ when: - domain.ssl is defined - domain.ssl.handling == 'letsencrypt' + - domain.ssl.services | length > 0 - name: Reload the nginx service. ansible.builtin.service: @@ -26,6 +28,7 @@ when: - domain.ssl is defined - domain.ssl.handling == 'letsencrypt' + - domain.ssl.services | length > 0 - name: Generates SSL keys. ansible.builtin.include_role: @@ -42,6 +45,7 @@ when: - domain.ssl is defined - domain.ssl.handling == 'letsencrypt' + - domain.ssl.services | length > 0 - name: Delete the temporary vhost for LetsEncrypt. ansible.builtin.file: @@ -50,6 +54,7 @@ when: - domain.ssl is defined - domain.ssl.handling == 'letsencrypt' + - domain.ssl.services | length > 0 # If auth_enabled is defined and yes, and auth_pass is not defined or is defined but empty, generate a random password. - name: Generate random htauth password.