Initial commit

This commit is contained in:
2023-11-30 15:19:54 +13:00
commit 3c0ab7279f
25 changed files with 1205 additions and 0 deletions

17
tasks/config.yml Normal file
View File

@@ -0,0 +1,17 @@
---
- name: Ensure custom scripts directory exists
file:
path: /usr/local/directadmin/scripts/custom
state: directory
- name: Include user configuration
include_tasks: config/users.yml
- name: Include mail configuration
include_tasks: config/mail.yml
- name: Include DirectAdmin configuration
include_tasks: config/directadmin.yml
- name: Flush handlers
meta: flush_handlers

View File

@@ -0,0 +1,42 @@
---
- name: Setup One-Click logon
ini_file:
path: /usr/local/directadmin/conf/directadmin.conf
section: null
option: "{{ item.option }}"
value: "{{ item.value }}"
backup: false
state: present
no_extra_spaces: true
create: true
loop:
- name: Allow one-click logon Roundcube
option: one_click_webmail_login
value: 1
- name: Allow on-click logon phpMyAdmin
option: one_click_pma_login
value: 1
loop_control:
label: "{{ item.name }}"
notify:
- "directadmin : Restart DirectAdmin"
- "directadmin : Build phpMyAdmin"
- "directadmin : Build Roundcube"
- "directadmin : Rewrite confs"
- name: Ensure custom configs are present
ini_file:
path: /usr/local/directadmin/conf/directadmin.conf
section: null
option: "{{ item.option }}"
value: "{{ item.value }}"
backup: false
state: present
no_extra_spaces: true
create: true
loop: "{{ directadmin_custom_conf }}"
loop_control:
label: "{{ item.name }}"
notify:
- "directadmin : Restart DirectAdmin"
- "directadmin : Rewrite confs"

17
tasks/config/mail.yml Normal file
View File

@@ -0,0 +1,17 @@
---
- name: Include Spamassasin configuration
import_tasks: mail/spamassassin.yml
- name: Import Dovecot configuration
import_tasks: mail/dovecot.yml
- name: Import Exim configuration
import_tasks: mail/exim.yml
- name: Ensure DirectAdmin Custom Templates exists
file:
path: /usr/local/directadmin/data/templates/custom
state: directory
- name: Import Apache configuration
import_tasks: mail/apache.yml

View File

@@ -0,0 +1,47 @@
- name: Create Webmail V-Host
copy:
dest: /usr/local/directadmin/data/templates/custom/virtual_host2.conf.CUSTOM.4.post
content: |
</VirtualHost>
<VirtualHost |IP|:|PORT_80| |MULTI_IP|>
ServerName webmail.|DOMAIN|
ServerAdmin |ADMIN|
DocumentRoot /var/www/html/roundcube/
CustomLog /var/log/httpd/domains/|DOMAIN|.bytes bytes
CustomLog /var/log/httpd/domains/|DOMAIN|.log combined
ErrorLog /var/log/httpd/domains/|DOMAIN|.error.log
<IfModule !mod_ruid2.c>
SuexecUserGroup webapps webapps
</IfModule>
notify:
- "directadmin : Rewrite confs"
- name: Create Webmail V-Host (Secure)
copy:
dest: /usr/local/directadmin/data/templates/custom/virtual_host2_secure.conf.CUSTOM.4.post
content: |
</VirtualHost>
<VirtualHost |IP|:|PORT_443| |MULTI_IP|>
ServerName webmail.|DOMAIN|
ServerAdmin |ADMIN|
DocumentRoot /var/www/html/roundcube/
SSLEngine on
SSLCertificateFile |CERT|
SSLCertificateKeyFile |KEY|
|CAROOT|
CustomLog /var/log/httpd/domains/|DOMAIN|.bytes bytes
CustomLog /var/log/httpd/domains/|DOMAIN|.log combined
ErrorLog /var/log/httpd/domains/|DOMAIN|.error.log
<IfModule !mod_ruid2.c>
SuexecUserGroup webapps webapps
</IfModule>
notify:
- "directadmin : Rewrite confs"
- name: Include NGINX if running as proxy
include_tasks: nginx.yml

View File

@@ -0,0 +1,113 @@
---
- name: Add imap_sieve to mail_plugins for dovecot
lineinfile:
path: /etc/dovecot/conf/imap_mail_plugins.conf
regex: "^mail_plugins = (?!.*imap_sieve)(.*)$"
line: "mail_plugins = \\1 imap_sieve"
backrefs: true
notify:
- "directadmin : Ensure Dovecot custom for custombuild is present"
- "directadmin : Persist mail plugins"
- "directadmin : Restart Dovecot"
- name: Configure plusaddressing for Dovecot
copy:
dest: /etc/dovecot/conf.d/subaddressing.conf
content: |
recipient_delimiter = +
lmtp_save_to_detail_mailbox = no
lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes
notify:
- "directadmin : Restart Dovecot"
- name: Configure imap_sieve for Dovecot
copy:
dest: /etc/dovecot/conf.d/99-imap-sieve.conf
content: |
plugin {
sieve_plugins = sieve_imapsieve sieve_extprograms
# From elsewhere to Spam folder
imapsieve_mailbox1_name = Spam
imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_before = file:/usr/local/bin/dovecot-sieve/report-spam.sieve
# From Spam folder to elsewhere
imapsieve_mailbox2_name = *
imapsieve_mailbox2_from = Spam
imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_before = file:/usr/local/bin/dovecot-sieve/report-ham.sieve
sieve_pipe_bin_dir = /usr/local/bin/dovecot-sieve
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
}
notify:
- "directadmin : Restart Dovecot"
- name: Ensure dovecot-sieve script directory is present
file:
path: /usr/local/bin/dovecot-sieve
state: directory
owner: mail
- name: Create report-spam script
copy:
dest: /usr/local/bin/dovecot-sieve/report-spam.sieve
content: |
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "sa-learn-spam.sh" [ "${username}" ];
notify:
- "directadmin : Compile and fix permissions report-spam script"
- name: Create report-ham script
copy:
dest: /usr/local/bin/dovecot-sieve/report-ham.sieve
content: |
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.mailbox" "*" {
set "mailbox" "${1}";
}
if string "${mailbox}" "Trash" {
stop;
}
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "sa-learn-ham.sh" [ "${username}" ];
notify:
- "directadmin : Compile and fix permissions report-ham script"
- name: Create spam learning script
copy:
dest: /usr/local/bin/dovecot-sieve/sa-learn-spam.sh
content: |
#!/bin/bash
# you can also use tcp/ip here, consult spamc(1)
inputmail=`/usr/bin/cat`
ddomain=`/usr/bin/echo "${1}"| /usr/bin/cut -d'@' -f2`
dusername=`/usr/bin/egrep "^${ddomain}:" /etc/virtual/domainowners| /usr/bin/cut -d' ' -f2`
exec /usr/bin/spamc -u ${dusername} -L spam <<< "${inputmail}"
mode: "0755"
- name: Create ham learning script
copy:
dest: /usr/local/bin/dovecot-sieve/sa-learn-ham.sh
content: |
#!/bin/bash
# you can also use tcp/ip here, consult spamc(1)
inputmail=`/usr/bin/cat`
ddomain=`/usr/bin/echo "${1}"| /usr/bin/cut -d'@' -f2`
dusername=`/usr/bin/egrep "^${ddomain}:" /etc/virtual/domainowners| /usr/bin/cut -d' ' -f2`
exec /usr/bin/spamc -u ${dusername} -L ham <<< "${inputmail}"
mode: "0755"

View File

@@ -0,0 +1,21 @@
---
- name: Ensure /etc/exim is present
file:
path: /etc/exim
state: directory
- name: Add plusaddressing to Exim
copy:
dest: /etc/exim/local_part_suffix.conf
content: |
local_part_suffix = +*
local_part_suffix_optional
notify:
- "directadmin : Restart Exim"
- name: Ensure Exim custom strings configured
template:
src: templates/exim/strings.conf.custom.j2
dest: /etc/exim.strings.conf.custom
notify:
- "directadmin : Restart Exim"

276
tasks/config/mail/nginx.yml Normal file
View File

@@ -0,0 +1,276 @@
- name: Ensure Custom SSL config for NGINX is created
copy:
dest: /etc/nginx/webapps.ssl.conf.custom
content: |
location ~ /(\.htaccess|\.htpasswd|\.user\.ini|\.env|\.git) {
deny all;
}
location ^~ /.well-known/acme-challenge {
root /var/www/html/;
index index.php index.html index.htm;
location ~ ^/.well-known/acme-challenge/ {
access_log off;
set $my_server_addr $server_addr;
if ($server_addr ~ ^[0-9a-fA-F:]+$) { set $my_server_addr [$server_addr]; }
proxy_pass https://$my_server_addr:8081;
proxy_set_header X-Client-IP $remote_addr;
proxy_set_header X-Accel-Internal /.well-known/acme-challenge/nginx_static_files;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header Upgrade;
}
location ~ ^/.well-known/acme-challenge/nginx_static_files/ {
access_log /var/log/nginx/access_log_proxy;
alias /var/www/html/;
internal;
}
}
location ^~ /roundcube {
root /var/www/html/;
index index.php index.html index.htm;
location ~ ^/roundcube/ {
access_log off;
set $my_server_addr $server_addr;
if ($server_addr ~ ^[0-9a-fA-F:]+$) { set $my_server_addr [$server_addr]; }
proxy_pass https://$my_server_addr:8081;
proxy_set_header X-Client-IP $remote_addr;
proxy_set_header X-Accel-Internal /roundcube/nginx_static_files;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header Upgrade;
}
location ~ ^/roundcube/nginx_static_files/ {
access_log /var/log/nginx/access_log_proxy;
alias /var/www/html/;
internal;
}
}
location ^~ /phpMyAdmin {
root /var/www/html/;
index index.php index.html index.htm;
location ~ ^/phpMyAdmin/ {
access_log off;
set $my_server_addr $server_addr;
if ($server_addr ~ ^[0-9a-fA-F:]+$) { set $my_server_addr [$server_addr]; }
proxy_pass https://$my_server_addr:8081;
proxy_set_header X-Client-IP $remote_addr;
proxy_set_header X-Accel-Internal /phpMyAdmin/nginx_static_files;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header Upgrade;
}
location ~ ^/phpMyAdmin/nginx_static_files/ {
access_log /var/log/nginx/access_log_proxy;
alias /var/www/html/;
internal;
}
}
location ~ ^/phpmyadmin {
rewrite ^/* /phpMyAdmin last;
}
location ~ ^/pma {
rewrite ^/* /phpMyAdmin last;
}
location ~ ^/webmail {
rewrite ^/* /roundcube last;
}
- name: Create Webmail V-Host (Nginx)
copy:
dest: /usr/local/directadmin/data/templates/custom/nginx_server.conf
content: |
server
{
listen |IP|:|PORT_80|;
|MULTI_IP|
server_name webmail.|DOMAIN|;
root /var/www/html/roundcube;
index index.php index.html index.htm;
access_log /var/log/nginx/domains/|DOMAIN|.log;
access_log /var/log/nginx/domains/|DOMAIN|.bytes bytes;
error_log /var/log/nginx/domains/|DOMAIN|.error.log;
|*if HAVE_PHP1_FPM="1"|
# use fastcgi for all php files
location ~ \.php$
{
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include /etc/nginx/fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/nginx_limits.conf;
if (-f $request_filename)
{
fastcgi_pass unix:/usr/local/php|PHP1_RELEASE|/sockets/webapps.sock;
}
}
|*endif|
|*if HAVE_NGINX_PROXY="1"|
location /
{
# access_log off;
proxy_pass http://127.0.0.1:|PORT_8080|;
proxy_set_header X-Client-IP $remote_addr;
proxy_set_header X-Accel-Internal /nginx_static_files;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /nginx_static_files/
{
# access_log /var/log/nginx/access_log_proxy;
alias /var/www/html/roundcube/;
internal;
}
|*endif|
# deny access to apache .htaccess files
location ~ /\.ht
{
deny all;
}
}
notify:
- "directadmin : Rewrite confs"
when: >
directadmin_webserver == 'nginx' or
directadmin_webserver == 'nginx_apache'
- name: Create Webmail V-Host (Secure - Nginx)
copy:
dest: /usr/local/directadmin/data/templates/custom/nginx_server_secure.conf
content: |
|CUSTOM1|
|?DOCROOT=`HOME`/domains/`DOMAIN`/private_html|
|?REALDOCROOT=`HOME`/domains/`DOMAIN`/private_html|
|?OPEN_BASEDIR_PATH=`HOME`/:/tmp:/opt/alt/php`PHP1_RELEASE`/usr/share/pear/:/dev/urandom:/var/tmp:/usr/local/lib/php/|
|?HOST_DOMAIN=`DOMAIN`|
|*if HOST_POINTER|
|?HOST_DOMAIN=`HOST_POINTER`|
|*endif|
server
{
|CUSTOM|
listen |IP|:|PORT_443| ssl|SPACE_HTTP2|;
|MULTI_IP|
server_name |HOST_DOMAIN| www.|HOST_DOMAIN| |SERVER_ALIASES|;
access_log /var/log/nginx/domains/|DOMAIN|.log;
access_log /var/log/nginx/domains/|DOMAIN|.bytes bytes;
error_log /var/log/nginx/domains/|DOMAIN|.error.log;
root |DOCROOT|;
index index.php index.html index.htm;
ssl_certificate |CERT|;
ssl_certificate_key |KEY|;
|FORCE_SSL_REDIRECT|
|NGINX_PHP_CONF|
|*if HAVE_NGINX_PROXY="1"|
location /
{
|CUSTOM2|
|LOCATION_INSERT|
# access_log off;
proxy_buffering |PROXY_BUFFERING|;
proxy_pass https://|PROXY_IP|:|PORT_8081|;
proxy_set_header X-Client-IP $remote_addr;
proxy_set_header X-Accel-Internal /nginx_static_files;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_hide_header Upgrade;
}
location /nginx_static_files/
{
# access_log /var/log/nginx/access_log_proxy;
alias |DOCROOT|/;
internal;
}
|*else|
|NGINX_REDIRECTS|
|PROTECTED_DIRECTORIES|
|HOTLINK_PROTECTION|
|EXTRA_LOCATIONS|
|*endif|
|CUSTOM3|
include /etc/nginx/webapps.ssl.conf.custom;
|CUSTOM4|
}
server
{
listen |IP|:|PORT_443| ssl|SPACE_HTTP2|;
|MULTI_IP|
server_name webmail.|DOMAIN|;
root /var/www/html/roundcube;
index index.php index.html index.htm;
access_log /var/log/nginx/domains/|DOMAIN|.log;
access_log /var/log/nginx/domains/|DOMAIN|.bytes bytes;
error_log /var/log/nginx/domains/|DOMAIN|.error.log;
ssl_certificate |CERT|;
ssl_certificate_key |KEY|;
|*if HAVE_PHP1_FPM="1"|
# use fastcgi for all php files
location ~ \.php$
{
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include /etc/nginx/fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/nginx_limits.conf;
if (-f $request_filename)
{
fastcgi_pass unix:/usr/local/php|PHP1_RELEASE|/sockets/webapps.sock;
}
}
|*endif|
|*if HAVE_NGINX_PROXY="1"|
location /
{
# access_log off;
proxy_pass http://127.0.0.1:|PORT_8080|;
proxy_set_header X-Client-IP $remote_addr;
proxy_set_header X-Accel-Internal /nginx_static_files;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /nginx_static_files/
{
# access_log /var/log/nginx/access_log_proxy;
alias /var/www/html/roundcube/;
internal;
}
|*endif|
# deny access to apache .htaccess files
location ~ /\.ht
{
deny all;
}
}
notify:
- "directadmin : Rewrite confs"
when: >
directadmin_webserver == 'nginx' or
directadmin_webserver == 'nginx_apache'

View File

@@ -0,0 +1,16 @@
---
- name: Enable Spamassassin learning
blockinfile:
path: /etc/systemd/system/spamassassin.service.d/override.conf
state: present
marker: "# {mark} ANSIBLE MANAGED BLOCK"
block: |
[Service]
ExecStart=
# Add "-l" flag to spamd
ExecStart=/usr/bin/spamd --pidfile /var/run/spamd.pid -d -c -m 15 --ipv4 -l
create: true
backup: false
notify:
- "directadmin : Reload Systemd"
- "directadmin : Restart Spamassassin"

19
tasks/config/users.yml Normal file
View File

@@ -0,0 +1,19 @@
---
# This file contains configuration actions related to Users
- name: Enable spamassassin on user create
copy:
src: directadmin/scripts/custom/user_create_post.sh
dest: /usr/local/directadmin/scripts/custom/user_create_post.sh
mode: "0755"
- name: Set Spam defaults on domain create
copy:
dest: /usr/local/directadmin/scripts/custom/domain_create_post.sh
content: |
#!/bin/sh
F=/etc/virtual/$domain/filter.conf
if [ -e $F ]; then
echo "where=userspamfolder" >> $F
echo "action=rewrite&value=filter&user=$username" >> /usr/local/directadmin/data/task.queue
fi
mode: "0755"

33
tasks/letsencrypt.yml Normal file
View File

@@ -0,0 +1,33 @@
---
- name: execute LetsEncrypt setup script
command: /usr/local/directadmin/scripts/letsencrypt.sh request_single {{ directadmin_hostname }} 4096
register: directadmin_letsencrypt_output
- debug:
var: directadmin_letsencrypt_output.stdout_lines
- name: enable SSL with LetsEncrypt for DirectAdmin
lineinfile:
path: "{{ directadmin_config_path }}"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
loop:
- name: Turn SSL on
regexp: '^SSL\=0'
line: 'SSL=1'
- name: Configure CA Root Cert
regexp: '^carootcert='
line: 'carootcert=/usr/local/directadmin/conf/carootcert.pem'
- name: Force hostname
regexp: '^force_hostname='
line: "force_hostname={{ directadmin_hostname }}"
- name: SSL Redirect Setup
regexp: '^ssl_redirect_host='
line: "ssl_redirect_host={{ directadmin_hostname }}"
- name: Enable LetsEncrypt
regexp: '^letsencrypt='
line: "letsencrypt=1"
loop_control:
label: "{{ item.name }}"
notify:
- Restart DirectAdmin

109
tasks/main.yml Normal file
View File

@@ -0,0 +1,109 @@
---
- name: Check if DirectAdmin exists
stat:
path: /usr/local/directadmin/directadmin
register: da
- name: Configure pre-install options
when: not da.stat.exists
block:
- name: Ensure custombuild directory exists
file:
path: "{{ directadmin_custombuild_path }}"
state: directory
- name: Setup options for base install
template:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
loop:
- name: options.conf
src: custombuild/options.conf.j2
dest: "{{ directadmin_custombuild_path }}/options.conf"
- name: php_extensions.conf
src: custombuild/php_extensions.conf.j2
dest: "{{ directadmin_custombuild_path }}/php_extensions.conf"
loop_control:
label: "{{ item.name }}"
# vars:
# directadmin_webserver: apache # Ensure is apache install for server name SSL
- name: Download DirectAdmin installer
get_url:
url: https://download.directadmin.com/setup.sh
dest: /tmp/directadmin-setup.sh
mode: "0700"
- name: 'Coffee Time!'
debug:
msg: "Have a nice break, I'll be busy a while..."
- name: Send ntfy ping
uri:
url: https://ntfy.cybercinch.nz/
method: POST
body_format: json
body:
topic: ansiballz
title: DirectAdmin provisioning
tags:
- robot
- warning
- cd
message: DirectAdmin install is beginning on {{ inventory_hostname }}
- name: Run installer
shell: "{{ lookup('ansible.builtin.template', 'templates/cli/directadmin-setup.j2') }}"
- name: Send ntfy ping
uri:
url: https://ntfy.cybercinch.nz/
method: POST
body_format: json
body:
topic: ansiballz
title: DirectAdmin provisioning
tags:
- robot
- heavy_check_mark
message: DirectAdmin install is completed on {{ inventory_hostname }}
- name: Add new IPv6 to DA
template:
src: da-ip.j2
dest: /usr/local/directadmin/data/admin/ips/{{ hostvars[inventory_hostname]['ansible_default_ipv6']['address'] }}
owner: diradmin
group: diradmin
mode: "0600"
notify:
- Restart DirectAdmin
- Rewrite confs
- name: Reciprocal Link from Main IPv4
lineinfile:
path: /usr/local/directadmin/data/admin/ips/{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address']}}
line: "linked_ips={{ hostvars[inventory_hostname]['ansible_default_ipv6']['address'] | encode_ip }}=apache%3Dyes%26dns%3Dyes"
create: true
notify:
- Restart DirectAdmin
- Rewrite confs
- name: Add IP to admin ip.list
ansible.builtin.lineinfile:
path: /usr/local/directadmin/data/admin/ip.list
line: "{{ hostvars[inventory_hostname]['ansible_default_ipv6']['address'] }}"
create: true
notify:
- Restart DirectAdmin
- Rewrite confs
- name: Flushing handlers
meta: flush_handlers
- name: Get Server Hostname SSL Certificate
import_tasks: letsencrypt.yml
# Tasks which can run whether new install or just config
- name: Include configuration tasks
include_tasks: config.yml