cleanup: remove dead code and stale files

- Delete unreferenced roles: icinga2-container, debug, mailcow, syncthing
- Remove unused Galaxy deps from requirements.yml (docker, kubernetes)
- Delete roles/requirements.yml (graylog2.graylog, bertvv.bind, artis3n.tailscale)
- Merge netbox.netbox from collections/requirements.yml into root, delete file
- Delete 56 stale fact_cache files
- Remove unused inventory groups: home_cluster, dns_servers
- Update findings.md
This commit is contained in:
Graham McIntire 2026-06-04 14:35:28 -05:00
parent ee72c64246
commit 44c109c6c9
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59
22 changed files with 14 additions and 884 deletions

View file

@ -1,5 +0,0 @@
---
collections:
- ansible.posix
- netbox.netbox
# - devsec.hardening

View file

@ -18,6 +18,10 @@
- **Added `pipefail`** to risky shell command in `udp-gro-fix.yml`.
- **Quoted octal mode values**`mode: 0755``mode: '0755'`, etc.
- **Hardened `.ansible-lint` config** — set `profile: production`, added exclude paths, removed all skip_list entries.
- **Deleted unreferenced roles** — removed `icinga2-container/`, `debug/`, `mailcow/`, `syncthing/` (no plays applied them).
- **Removed unused Galaxy dependencies** — deleted `geerlingguy.docker`, `geerlingguy.kubernetes` from `requirements.yml`; deleted entire `roles/requirements.yml` (graylog2.graylog, bertvv.bind, artis3n.tailscale); merged `netbox.netbox` into root file.
- **Cleaned fact_cache** — removed 56 stale files.
- **Removed unused inventory groups**`home_cluster` and `dns_servers` (defined but never targeted).
---
@ -82,16 +86,7 @@ All items in this section have been fixed.
## 🟡 Dead Code & Stale Files
| # | Issue | Location |
|---|-------|----------|
| 37 | **`icinga2-container/` and `debug/` roles exist but never referenced** in any playbook. | `roles/icinga2-container/`, `roles/debug/` |
| 38 | **`mailcow` and `syncthing` roles exist but no play applies them.** | `roles/mailcow/`, `roles/syncthing/` |
| 39 | **`geerlingguy.docker` and `geerlingguy.kubernetes` never used** in any playbook. | `requirements.yml:15-19` |
| 40 | **`graylog2.graylog` and `bertvv.bind` never used** — Entire `roles/requirements.yml` appears legacy. | `roles/requirements.yml` |
| 41 | **`collections/requirements.yml` is redundant** — Lists `ansible.posix` and `netbox.netbox` without version pins. | `collections/requirements.yml` |
| 42 | **49/56 fact_cache files are stale** — 40 use old `s1_` naming convention, 9 are decommissioned hosts. | `fact_cache/` |
| 43 | **`home_cluster` and `dns_servers` groups** — Defined but never targeted by any play. | `hosts` |
| 44 | **`node_exporter_servers` is a pure alias** for `prometheus_servers` (1 host). | `hosts` |
All items in this section have been fixed.
---
@ -115,6 +110,13 @@ All items in this section have been fixed.
| 34 | `partial-become` bug in librenms | Added `become: yes` |
| 35 | `risky-shell-pipe` without pipefail | Added `set -o pipefail` |
| 36 | Minimal `.ansible-lint` config | Set `profile: production`, added exclude paths, empty skip_list |
| 37 | Unreferenced `icinga2-container/` and `debug/` roles | Deleted |
| 38 | Unreferenced `mailcow/` and `syncthing/` roles | Deleted |
| 39 | `geerlingguy.docker` and `geerlingguy.kubernetes` never used | Removed from `requirements.yml` |
| 40 | `graylog2.graylog` and `bertvv.bind` never used | Deleted `roles/requirements.yml` |
| 41 | `collections/requirements.yml` redundant | Merged into root file, deleted |
| 42 | Stale fact_cache files (56 files) | Deleted all |
| 43 | `home_cluster` and `dns_servers` groups never targeted | Removed from `hosts` |
---

View file

@ -50,9 +50,6 @@ netbox.vntx.net
ns1.as393837.net ansible_host=204.110.191.222
git.mcintire.me ansible_host=git
[dns_servers:children]
bind9_servers
[uisp_servers]
uisp.vntx.net
@ -64,7 +61,3 @@ node3 ansible_host=node3
[postgresql_servers]
db.w5isp.com
[home_cluster:children]
proxmox_servers
postgresql_servers

View file

@ -13,9 +13,5 @@ collections:
version: ">=1.0.0" # Required for Proxmox VM management
- name: community.mysql
version: ">=3.0.0" # Required for Icinga2 MySQL management
roles:
- name: geerlingguy.docker
version: "7.9.0"
- name: geerlingguy.kubernetes
version: "8.2.0"
- name: netbox.netbox
version: ">=3.0.0" # Required for NetBox automation

View file

@ -1,12 +0,0 @@
- name: create /tmp/ansible-debug
ansible.builtin.file:
path: /tmp/ansible-debug
state: directory
- name: collect vars
ansible.builtin.template:
src: templates/data.j2
dest: "/tmp/ansible-debug/{{ item.key }}.json"
vars:
data: "{{ item.value }}"
loop: "{{ {'hostvars': hostvars, 'groups': groups, 'vars': vars} | dict2items }}"

View file

@ -1 +0,0 @@
{{ data | to_nice_json }}

View file

@ -1,71 +0,0 @@
FROM ubuntu:22.04
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=UTC
# Add Icinga repository
RUN apt-get update && apt-get install -y \
wget \
gnupg \
lsb-release \
ca-certificates \
&& wget -O - https://packages.icinga.com/icinga.key | apt-key add - \
&& echo "deb [signed-by=/usr/share/keyrings/icinga-archive-keyring.gpg] https://packages.icinga.com/ubuntu icinga-$(lsb_release -cs) main" > /etc/apt/sources.list.d/icinga2.list \
&& echo "deb-src [signed-by=/usr/share/keyrings/icinga-archive-keyring.gpg] https://packages.icinga.com/ubuntu icinga-$(lsb_release -cs) main" >> /etc/apt/sources.list.d/icinga2.list \
&& wget -O /usr/share/keyrings/icinga-archive-keyring.gpg https://packages.icinga.com/icinga.key
# Install packages
RUN apt-get update && apt-get install -y \
icinga2 \
icinga2-ido-mysql \
icingaweb2 \
icingacli \
mariadb-client \
apache2 \
libapache2-mod-php \
php-bcmath \
php-curl \
php-gd \
php-intl \
php-ldap \
php-mbstring \
php-mysql \
php-pgsql \
php-soap \
php-xml \
php-zip \
php-imagick \
supervisor \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Enable Apache modules
RUN a2enmod rewrite headers env dir mime
# Configure Apache for IcingaWeb2
COPY icingaweb2.conf /etc/apache2/sites-available/
RUN a2dissite 000-default && a2ensite icingaweb2
# Create directories
RUN mkdir -p /etc/icinga2/pki \
/var/run/icinga2/cmd \
/var/log/icinga2 \
/var/lib/icinga2/api/zones \
/var/cache/icinga2 \
&& chown -R nagios:nagios /etc/icinga2 /var/run/icinga2 /var/log/icinga2 /var/lib/icinga2 /var/cache/icinga2
# Setup volumes
VOLUME ["/etc/icinga2", "/etc/icingaweb2", "/var/lib/icinga2"]
# Expose ports
EXPOSE 80 5665
# Copy supervisord config
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Copy startup script
COPY docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

View file

@ -1,77 +0,0 @@
#!/bin/bash
set -e
# Wait for database to be ready
if [ ! -z "${MYSQL_HOST}" ]; then
echo "Waiting for database connection..."
for i in {1..30}; do
if mysql -h${MYSQL_HOST} -u${MYSQL_USER} -p${MYSQL_PASSWORD} -e "SELECT 1" >/dev/null 2>&1; then
echo "Database is ready!"
break
fi
echo "Waiting for database... ($i/30)"
sleep 2
done
fi
# Initialize Icinga2 database if needed
if [ ! -z "${MYSQL_HOST}" ] && [ ! -z "${INIT_MYSQL}" ]; then
echo "Checking if Icinga2 database needs initialization..."
if ! mysql -h${MYSQL_HOST} -u${MYSQL_USER} -p${MYSQL_PASSWORD} ${MYSQL_DATABASE} -e "SELECT * FROM icinga_dbversion" >/dev/null 2>&1; then
echo "Initializing Icinga2 database..."
mysql -h${MYSQL_HOST} -u${MYSQL_USER} -p${MYSQL_PASSWORD} ${MYSQL_DATABASE} < /usr/share/icinga2-ido-mysql/schema/mysql.sql
fi
fi
# Configure IDO-MySQL if environment variables are set
if [ ! -z "${MYSQL_HOST}" ]; then
cat > /etc/icinga2/features-available/ido-mysql.conf <<EOF
library "db_ido_mysql"
object IdoMysqlConnection "ido-mysql" {
user = "${MYSQL_USER}"
password = "${MYSQL_PASSWORD}"
host = "${MYSQL_HOST}"
database = "${MYSQL_DATABASE}"
}
EOF
icinga2 feature enable ido-mysql
fi
# Setup API if certificates don't exist
if [ ! -f /var/lib/icinga2/certs/ca.crt ]; then
echo "Setting up Icinga2 API..."
icinga2 api setup
fi
# Enable required features
icinga2 feature enable api command checker mainlog notification
# Configure IcingaWeb2 database settings if provided
if [ ! -z "${ICINGAWEB_MYSQL_HOST}" ]; then
mkdir -p /etc/icingaweb2
cat > /etc/icingaweb2/resources.ini <<EOF
[icingaweb_db]
type = "db"
db = "mysql"
host = "${ICINGAWEB_MYSQL_HOST}"
dbname = "${ICINGAWEB_MYSQL_DATABASE}"
username = "${ICINGAWEB_MYSQL_USER}"
password = "${ICINGAWEB_MYSQL_PASSWORD}"
[icinga_ido]
type = "db"
db = "mysql"
host = "${MYSQL_HOST}"
dbname = "${MYSQL_DATABASE}"
username = "${MYSQL_USER}"
password = "${MYSQL_PASSWORD}"
EOF
fi
# Fix permissions
chown -R nagios:nagios /etc/icinga2 /var/run/icinga2 /var/log/icinga2 /var/lib/icinga2 /var/cache/icinga2
chown -R www-data:icingaweb2 /etc/icingaweb2
# Execute CMD
exec "$@"

View file

@ -1,20 +0,0 @@
<VirtualHost *:80>
DocumentRoot /usr/share/icingaweb2/public
<Directory /usr/share/icingaweb2/public>
Options SymLinksIfOwnerMatch
AllowOverride None
Require all granted
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
</Directory>
ErrorLog ${APACHE_LOG_DIR}/icingaweb2-error.log
CustomLog ${APACHE_LOG_DIR}/icingaweb2-access.log combined
</VirtualHost>

View file

@ -1,18 +0,0 @@
[supervisord]
nodaemon=true
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:apache2]
command=/usr/sbin/apache2ctl -D FOREGROUND
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/apache2.log
stderr_logfile=/var/log/supervisor/apache2_err.log
[program:icinga2]
command=/usr/sbin/icinga2 daemon
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/icinga2.log
stderr_logfile=/var/log/supervisor/icinga2_err.log

View file

@ -1,47 +0,0 @@
---
# Default variables for Mailcow
mailcow_hostname: "{{ inventory_hostname }}"
mailcow_base_path: /opt/mailcow-dockerized
# API configuration
mailcow_api_key: "{{ vault_mailcow_api_key | default('') }}"
mailcow_api_allow_ips: "127.0.0.1,::1"
# HTTP/HTTPS bindings
mailcow_http_bind: "127.0.0.1"
mailcow_http_port: 8080
mailcow_https_bind: "127.0.0.1"
mailcow_https_port: 8443
# Mail ports - bind to all interfaces
mailcow_smtp_port: 25
mailcow_submission_port: 587
mailcow_smtps_port: 465
mailcow_imap_port: 143
mailcow_imaps_port: 993
mailcow_pop3_port: 110
mailcow_pop3s_port: 995
# Database configuration
mailcow_dbname: mailcow
mailcow_dbuser: mailcow
mailcow_dbpass: "{{ vault_mailcow_dbpass | default('') }}"
mailcow_dbroot: "{{ vault_mailcow_dbroot | default('') }}"
# Skip various checks
mailcow_skip_lets_encrypt: "y"
mailcow_skip_sogo: "n"
mailcow_skip_clamd: "n"
mailcow_skip_solr: "n"
mailcow_additional_san: ""
# Compose project name
mailcow_compose_project_name: mailcowdockerized
# Git repository
mailcow_git_repo: https://github.com/mailcow/mailcow-dockerized.git
mailcow_git_branch: master
# External mail storage path (outside Docker)
mailcow_vmail_path: /opt/mailcow-mail

View file

@ -1,15 +0,0 @@
---
# Handlers for Mailcow
- name: restart mailcow
ansible.builtin.systemd:
name: mailcow
state: restarted
daemon_reload: true
become: true
- name: reload mailcow
ansible.builtin.command: docker compose restart
args:
chdir: "{{ mailcow_base_path }}"

View file

@ -1,212 +0,0 @@
---
# Install and configure Mailcow
- name: Install required packages
ansible.builtin.apt:
name:
- git
- curl
- docker.io
- docker-compose
- python3-pip
- python3-docker
- jq
state: present
update_cache: true
- name: Ensure docker service is running
ansible.builtin.systemd:
name: docker
state: started
enabled: true
- name: Create mailcow user
ansible.builtin.user:
name: mailcow
groups: docker
shell: /bin/bash
home: /home/mailcow
create_home: true
state: present
- name: Ensure mailcow base directory exists
ansible.builtin.file:
path: "{{ mailcow_base_path }}"
state: directory
owner: mailcow
group: mailcow
mode: '0755'
- name: Check if Mailcow repository exists
ansible.builtin.stat:
path: "{{ mailcow_base_path }}/.git"
register: mailcow_repo
- name: Remove non-git Mailcow directory
ansible.builtin.file:
path: "{{ mailcow_base_path }}"
state: absent
when:
- mailcow_base_path is defined
- not mailcow_repo.stat.exists
- name: Clone Mailcow repository
ansible.builtin.git:
repo: "{{ mailcow_git_repo }}"
dest: "{{ mailcow_base_path }}"
version: "{{ mailcow_git_branch }}"
force: true
when: not mailcow_repo.stat.exists
- name: Add Mailcow directory to git safe directories
ansible.builtin.shell: |
if git config --global --get safe.directory {{ mailcow_base_path }} >/dev/null 2>&1; then
echo "already_present"
else
git config --global --add safe.directory {{ mailcow_base_path }}
echo "added"
fi
register: git_safe_dir
changed_when: "'added' in git_safe_dir.stdout"
when: mailcow_repo.stat.exists
- name: Update Mailcow repository
ansible.builtin.git:
repo: "{{ mailcow_git_repo }}"
dest: "{{ mailcow_base_path }}"
version: "{{ mailcow_git_branch }}"
update: true
when: mailcow_repo.stat.exists
register: git_update_result
failed_when:
- git_update_result.failed
- "'Local modifications exist' not in git_update_result.msg | default('')"
- name: Change ownership of Mailcow directory
ansible.builtin.file:
path: "{{ mailcow_base_path }}"
owner: mailcow
group: mailcow
recurse: true
# Let generate_config.sh create the default configuration
- name: Create docker-compose override file
ansible.builtin.template:
src: docker-compose.override.yml.j2
dest: "{{ mailcow_base_path }}/docker-compose.override.yml"
owner: mailcow
group: mailcow
mode: '0640'
backup: true
notify: restart mailcow
- name: Make generate_config.sh executable
ansible.builtin.file:
path: "{{ mailcow_base_path }}/generate_config.sh"
mode: '0755'
owner: mailcow
group: mailcow
- name: Check if mailcow is already configured
ansible.builtin.stat:
path: "{{ mailcow_base_path }}/mailcow.conf"
register: mailcow_configured
- name: Remove incomplete mailcow.conf
ansible.builtin.file:
path: "{{ mailcow_base_path }}/mailcow.conf"
state: absent
when:
- mailcow_configured.stat.exists
- mailcow_configured.stat.size < 1000 # If config is too small, it's incomplete
- name: Run generate_config.sh script
ansible.builtin.shell: |
cd {{ mailcow_base_path }}
./generate_config.sh << EOF
{{ mailcow_hostname }}
{{ timezone }}
EOF
args:
creates: "{{ mailcow_base_path }}/mailcow.conf"
- name: Update mailcow.conf with secure passwords
ansible.builtin.lineinfile:
path: "{{ mailcow_base_path }}/mailcow.conf"
regexp: "^{{ item.key }}="
line: "{{ item.key }}={{ item.value }}"
state: present
loop:
- { key: "DBPASS", value: "{{ vault_mailcow_dbpass }}" }
- { key: "DBROOT", value: "{{ vault_mailcow_dbroot }}" }
- { key: "REDISPASS", value: "{{ vault_mailcow_redispass }}" }
- { key: "API_KEY", value: "{{ vault_mailcow_api_key }}" }
no_log: true
- name: Stop any running Mailcow containers
ansible.builtin.command: docker compose down
args:
chdir: "{{ mailcow_base_path }}"
failed_when: false
changed_when: false
- name: Prune unused Docker networks
ansible.builtin.command: docker network prune -f
changed_when: true
- name: Pull docker images
ansible.builtin.command: docker compose pull
args:
chdir: "{{ mailcow_base_path }}"
register: mailcow_pull_result
changed_when: "'Pulling' in mailcow_pull_result.stdout or 'Downloaded' in mailcow_pull_result.stderr"
- name: Start Mailcow services
ansible.builtin.command: docker compose up -d
args:
chdir: "{{ mailcow_base_path }}"
register: mailcow_up_result
changed_when: "'Created' in mailcow_up_result.stdout or 'Starting' in mailcow_up_result.stdout"
- name: Check if ufw is installed
ansible.builtin.command: which ufw
register: ufw_check
changed_when: false
failed_when: false
- name: Configure firewall for mail services
community.general.ufw:
rule: allow
port: "{{ item.port }}"
proto: "{{ item.proto }}"
comment: "{{ item.comment }}"
loop:
- { port: "25", proto: "tcp", comment: "SMTP" }
- { port: "587", proto: "tcp", comment: "SMTP Submission" }
- { port: "465", proto: "tcp", comment: "SMTPS" }
# - { port: "143", proto: "tcp", comment: "IMAP" } # Disabled non-TLS
- { port: "993", proto: "tcp", comment: "IMAPS" }
# - { port: "110", proto: "tcp", comment: "POP3" } # Disabled non-TLS
- { port: "995", proto: "tcp", comment: "POP3S" }
- { port: "4190", proto: "tcp", comment: "Sieve" }
when:
- ansible_facts['os_family'] == "Debian"
- ufw_check.rc == 0
- name: Create systemd service for Mailcow
ansible.builtin.template:
src: mailcow.service.j2
dest: /etc/systemd/system/mailcow.service
owner: root
group: root
mode: '0644'
notify: restart mailcow
- name: Enable Mailcow service
ansible.builtin.systemd:
name: mailcow
enabled: true
daemon_reload: true
# Caddy not needed - Mailcow includes nginx for SSL termination

View file

@ -1,43 +0,0 @@
{
# Global options
admin off
persist_config off
}
# Mailcow web interface
mail.w5isp.com {
reverse_proxy http://127.0.0.1:{{ mailcow_http_port }} {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Proto {scheme}
}
}
# Autodiscover/Autoconfig for w5isp.com
autodiscover.w5isp.com {
reverse_proxy http://127.0.0.1:{{ mailcow_http_port }}
}
autoconfig.w5isp.com {
reverse_proxy http://127.0.0.1:{{ mailcow_http_port }}
}
# Mailcow web interface for mcintire.me
mail.mcintire.me {
reverse_proxy http://127.0.0.1:{{ mailcow_http_port }} {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Proto {scheme}
}
}
# Autodiscover/Autoconfig for mcintire.me
autodiscover.mcintire.me {
reverse_proxy http://127.0.0.1:{{ mailcow_http_port }}
}
autoconfig.mcintire.me {
reverse_proxy http://127.0.0.1:{{ mailcow_http_port }}
}

View file

@ -1,37 +0,0 @@
# Mailcow reverse proxy configuration for Caddy
mail.w5isp.com {
reverse_proxy localhost:{{ mailcow_http_port }} {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Proto {scheme}
}
}
# Redirect for autodiscover
autodiscover.w5isp.com {
reverse_proxy localhost:{{ mailcow_http_port }}
}
# Redirect for autoconfig
autoconfig.w5isp.com {
reverse_proxy localhost:{{ mailcow_http_port }}
}
# For mcintire.me domain
mail.mcintire.me {
reverse_proxy localhost:{{ mailcow_http_port }} {
header_up Host {host}
header_up X-Real-IP {remote}
header_up X-Forwarded-For {remote}
header_up X-Forwarded-Proto {scheme}
}
}
autodiscover.mcintire.me {
reverse_proxy localhost:{{ mailcow_http_port }}
}
autoconfig.mcintire.me {
reverse_proxy localhost:{{ mailcow_http_port }}
}

View file

@ -1,18 +0,0 @@
services:
nginx-mailcow:
labels:
- "traefik.enable=false"
postfix-mailcow:
ports:
- "0.0.0.0:{{ mailcow_smtp_port }}:25"
- "0.0.0.0:{{ mailcow_submission_port }}:587"
- "0.0.0.0:{{ mailcow_smtps_port }}:465"
dovecot-mailcow:
ports:
# - "0.0.0.0:{{ mailcow_imap_port }}:143" # Disabled non-TLS IMAP
- "0.0.0.0:{{ mailcow_imaps_port }}:993"
# - "0.0.0.0:{{ mailcow_pop3_port }}:110" # Disabled non-TLS POP3
- "0.0.0.0:{{ mailcow_pop3s_port }}:995"
- "0.0.0.0:4190:4190"

View file

@ -1,64 +0,0 @@
# ------------------------------
# Mailcow configuration
# ------------------------------
# Your mail server hostname
MAILCOW_HOSTNAME={{ mailcow_hostname }}
# Your timezone
TZ={{ timezone }}
# Fixed project name
COMPOSE_PROJECT_NAME={{ mailcow_compose_project_name }}
# Database configuration
DBNAME={{ mailcow_dbname }}
DBUSER={{ mailcow_dbuser }}
DBPASS={{ mailcow_dbpass }}
DBROOT={{ mailcow_dbroot }}
# Redis configuration
REDISPASS={{ mailcow_redispass | default(vault_mailcow_redispass) }}
# HTTP/HTTPS bindings
HTTP_BIND={{ mailcow_http_bind }}
HTTP_PORT={{ mailcow_http_port }}
HTTPS_BIND={{ mailcow_https_bind }}
HTTPS_PORT={{ mailcow_https_port }}
# Mail port bindings
SMTP_PORT={{ mailcow_smtp_port }}
SMTPS_PORT={{ mailcow_smtps_port }}
SUBMISSION_PORT={{ mailcow_submission_port }}
IMAP_PORT={{ mailcow_imap_port }}
IMAPS_PORT={{ mailcow_imaps_port }}
POP_PORT={{ mailcow_pop3_port }}
POPS_PORT={{ mailcow_pop3s_port }}
SIEVE_PORT=4190
# API configuration
API_KEY={{ mailcow_api_key }}
API_ALLOW_FROM={{ mailcow_api_allow_ips }}
# Skip various components
SKIP_LETS_ENCRYPT={{ mailcow_skip_lets_encrypt }}
SKIP_SOGO={{ mailcow_skip_sogo }}
SKIP_CLAMD={{ mailcow_skip_clamd }}
SKIP_SOLR={{ mailcow_skip_solr }}
# Additional SAN for certificate
ADDITIONAL_SAN={{ mailcow_additional_san }}
# Watchdog configuration
WATCHDOG_NOTIFY_EMAIL=
WATCHDOG_NOTIFY_BAN=n
WATCHDOG_SUBJECT="Watchdog ALERT"
# Other settings
MAILDIR_GC_TIME=7200
ADDITIONAL_SERVER_NAMES=
ACME_CONTACT=
# Docker settings
DOCKER_COMPOSE_VERSION=native

View file

@ -1,17 +0,0 @@
[Unit]
Description=Mailcow dockerized mail server
After=docker.service
Requires=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory={{ mailcow_base_path }}
ExecStart=/usr/bin/docker-compose up -d
ExecStop=/usr/bin/docker-compose down
ExecReload=/usr/bin/docker-compose restart
User=mailcow
Group=docker
[Install]
WantedBy=multi-user.target

View file

@ -1,5 +0,0 @@
- src: graylog2.graylog
- src: bertvv.bind
- src: https://github.com/artis3n/tailscale.git
version: v5.0.1
name: artis3n.tailscale

View file

@ -1,6 +0,0 @@
---
- name: restart syncthing
ansible.builtin.systemd:
name: syncthing@graham
state: restarted
daemon_reload: true

View file

@ -1,136 +0,0 @@
---
# Install and configure Syncthing
- name: Install required packages
ansible.builtin.apt:
name:
- apt-transport-https
- curl
- gnupg2
state: present
update_cache: true
- name: Add Syncthing GPG key
ansible.builtin.get_url:
url: "https://syncthing.net/release-key.gpg"
dest: /usr/share/keyrings/syncthing-archive-keyring.gpg
mode: '0644'
- name: Add Syncthing repository
ansible.builtin.deb822_repository:
name: syncthing
types: deb
uris: https://apt.syncthing.net/
suites: syncthing
components: stable
signed_by: /usr/share/keyrings/syncthing-archive-keyring.gpg
state: present
- name: Install Syncthing
ansible.builtin.apt:
name: syncthing
state: present
update_cache: true
- name: Ensure graham user exists
ansible.builtin.user:
name: graham
state: present
- name: Create Syncthing configuration directory
ansible.builtin.file:
path: /home/graham/.config/syncthing
state: directory
owner: graham
group: graham
mode: '0755'
- name: Deploy Syncthing configuration
ansible.builtin.template:
src: config.xml.j2
dest: /home/graham/.config/syncthing/config.xml
owner: graham
group: graham
mode: '0600'
backup: true
notify: restart syncthing
- name: Create Syncthing systemd service
ansible.builtin.copy:
content: |
[Unit]
Description=Syncthing - Open Source Continuous File Synchronization
Documentation=man:syncthing(1)
After=network.target
[Service]
Type=simple
User=graham
ExecStart=/usr/bin/syncthing serve --no-browser --no-restart --logflags=0
Restart=on-failure
RestartSec=5
SuccessExitStatus=3 4
RestartForceExitStatus=3 4
# Hardening
SystemCallArchitectures=native
MemoryDenyWriteExecute=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
dest: /etc/systemd/system/syncthing@graham.service
owner: root
group: root
mode: '0644'
notify: restart syncthing
- name: Stop old syncthing service if exists
ansible.builtin.systemd:
name: syncthing@syncthing
state: stopped
enabled: false
failed_when: false
- name: Enable and start Syncthing service
ansible.builtin.systemd:
name: syncthing@graham
enabled: true
state: started
daemon_reload: true
- name: Check if ufw is installed
ansible.builtin.command: which ufw
register: ufw_check
changed_when: false
failed_when: false
- name: Configure firewall for Syncthing web UI
community.general.ufw:
rule: allow
port: '8384'
proto: tcp
comment: 'Syncthing Web UI'
when:
- ansible_facts['os_family'] == "Debian"
- ufw_check.rc == 0
- name: Configure firewall for Syncthing sync protocol
community.general.ufw:
rule: allow
port: '22000'
proto: tcp
comment: 'Syncthing Sync Protocol'
when:
- ansible_facts['os_family'] == "Debian"
- ufw_check.rc == 0
- name: Configure firewall for Syncthing discovery
community.general.ufw:
rule: allow
port: '21027'
proto: udp
comment: 'Syncthing Local Discovery'
when:
- ansible_facts['os_family'] == "Debian"
- ufw_check.rc == 0

View file

@ -1,57 +0,0 @@
<configuration version="37">
<gui enabled="true" tls="false" debugging="false">
<address>0.0.0.0:8384</address>
<apikey></apikey>
<theme>default</theme>
</gui>
<options>
<listenAddress>default</listenAddress>
<globalAnnounceServer>default</globalAnnounceServer>
<globalAnnounceEnabled>true</globalAnnounceEnabled>
<localAnnounceEnabled>true</localAnnounceEnabled>
<localAnnouncePort>21027</localAnnouncePort>
<localAnnounceMCAddr>[ff12::8384]:21027</localAnnounceMCAddr>
<maxSendKbps>0</maxSendKbps>
<maxRecvKbps>0</maxRecvKbps>
<reconnectionIntervalS>60</reconnectionIntervalS>
<relaysEnabled>true</relaysEnabled>
<relayReconnectIntervalM>10</relayReconnectIntervalM>
<startBrowser>false</startBrowser>
<natEnabled>true</natEnabled>
<natLeaseMinutes>60</natLeaseMinutes>
<natRenewalMinutes>30</natRenewalMinutes>
<natTimeoutSeconds>10</natTimeoutSeconds>
<urAccepted>-1</urAccepted>
<urSeen>3</urSeen>
<urURL>https://data.syncthing.net/newdata</urURL>
<urPostInsecurely>false</urPostInsecurely>
<urInitialDelayS>1800</urInitialDelayS>
<restartOnWakeup>true</restartOnWakeup>
<autoUpgradeIntervalH>12</autoUpgradeIntervalH>
<upgradeToPreReleases>false</upgradeToPreReleases>
<keepTemporariesH>24</keepTemporariesH>
<cacheIgnoredFiles>false</cacheIgnoredFiles>
<progressUpdateIntervalS>5</progressUpdateIntervalS>
<limitBandwidthInLan>false</limitBandwidthInLan>
<minHomeDiskFree unit="%">1</minHomeDiskFree>
<releasesURL>https://upgrades.syncthing.net/meta.json</releasesURL>
<overwriteRemoteDeviceNamesOnConnect>false</overwriteRemoteDeviceNamesOnConnect>
<tempIndexMinBlocks>10</tempIndexMinBlocks>
<unackedNotificationIDs></unackedNotificationIDs>
<trafficClass>0</trafficClass>
<setLowPriority>true</setLowPriority>
<maxFolderConcurrency>0</maxFolderConcurrency>
<crashReportingURL>https://crash.syncthing.net/newcrash</crashReportingURL>
<crashReportingEnabled>true</crashReportingEnabled>
<stunKeepaliveStartS>180</stunKeepaliveStartS>
<stunKeepaliveMinS>20</stunKeepaliveMinS>
<stunServers>default</stunServers>
<databaseTuning>auto</databaseTuning>
<maxConcurrentIncomingRequestKiB>0</maxConcurrentIncomingRequestKiB>
<announceLANAddresses>true</announceLANAddresses>
<sendFullIndexOnUpgrade>false</sendFullIndexOnUpgrade>
<connectionLimitEnough>0</connectionLimitEnough>
<connectionLimitMax>0</connectionLimitMax>
<insecureAllowOldTLSVersions>false</insecureAllowOldTLSVersions>
</options>
</configuration>