aboutsummaryrefslogtreecommitdiff
path: root/roles
diff options
context:
space:
mode:
Diffstat (limited to 'roles')
-rw-r--r--roles/container_base/handlers/main.yaml4
-rw-r--r--roles/container_base/tasks/main.yaml27
-rw-r--r--roles/git/handlers/main.yaml7
-rw-r--r--roles/git/tasks/main.yaml22
-rw-r--r--roles/git/templates/git_nginx.conf.j216
-rw-r--r--roles/host/files/60-machinectl-fast-user-auth.rules6
-rw-r--r--roles/host/handlers/main.yaml25
-rw-r--r--roles/host/tasks/main.yaml195
-rw-r--r--roles/host/templates/nginx-reload.sh.j23
-rw-r--r--roles/host/templates/nginx.conf.j267
-rw-r--r--roles/host/templates/nspawn.j210
-rw-r--r--roles/mail/handlers/main.yaml15
-rw-r--r--roles/mail/tasks/main.yaml61
-rw-r--r--roles/mail/templates/dovecot.conf.j222
-rw-r--r--roles/mail/templates/opendkim.conf.j215
-rw-r--r--roles/mail/templates/postfix_main.cf.j227
-rw-r--r--roles/mail/templates/postfix_master.cf.j231
17 files changed, 553 insertions, 0 deletions
diff --git a/roles/container_base/handlers/main.yaml b/roles/container_base/handlers/main.yaml
new file mode 100644
index 0000000..93df41f
--- /dev/null
+++ b/roles/container_base/handlers/main.yaml
@@ -0,0 +1,4 @@
+- name: Restart Container systemd-networkd
+ ansible.builtin.systemd:
+ name: systemd-networkd
+ state: restarted
diff --git a/roles/container_base/tasks/main.yaml b/roles/container_base/tasks/main.yaml
new file mode 100644
index 0000000..275a24a
--- /dev/null
+++ b/roles/container_base/tasks/main.yaml
@@ -0,0 +1,27 @@
+- name: Ensure systemd-networkd is running in container
+ ansible.builtin.systemd:
+ name: systemd-networkd
+ state: started
+ enabled: yes
+
+- name: Set static IP for container dynamically
+ ansible.builtin.copy:
+ dest: /etc/systemd/network/80-container-host0.network
+ content: |
+ [Match]
+ Name=host0
+ [Network]
+ Address={{ containers[inventory_hostname].ip }}/24
+ Gateway={{ bridge_ip }}
+ DNS=1.1.1.1 8.8.8.8
+ notify: Restart Container systemd-networkd
+
+- name: Apply container network changes immediately
+ ansible.builtin.meta: flush_handlers
+
+- name: Install Packages
+ ansible.builtin.dnf:
+ name:
+ - epel-release
+ - python3-passlib
+ state: present
diff --git a/roles/git/handlers/main.yaml b/roles/git/handlers/main.yaml
new file mode 100644
index 0000000..3503da0
--- /dev/null
+++ b/roles/git/handlers/main.yaml
@@ -0,0 +1,7 @@
+- name: Restart Git Services
+ ansible.builtin.systemd:
+ name: "{{ item }}"
+ state: restarted
+ loop:
+ - nginx
+ - fcgiwrap@nginx.socket
diff --git a/roles/git/tasks/main.yaml b/roles/git/tasks/main.yaml
new file mode 100644
index 0000000..b80989e
--- /dev/null
+++ b/roles/git/tasks/main.yaml
@@ -0,0 +1,22 @@
+- name: Install Git, Nginx, and Fcgiwrap
+ ansible.builtin.dnf:
+ name:
+ - cgit
+ - nginx
+ - fcgiwrap
+ state: present
+
+- name: Deploy Git Nginx configuration
+ ansible.builtin.template:
+ src: git_nginx.conf.j2
+ dest: /etc/nginx/conf.d/default.conf
+ notify: Restart Git Services
+
+- name: Ensure Git Web Services are Enabled and Running
+ ansible.builtin.systemd:
+ name: "{{ item }}"
+ state: started
+ enabled: yes
+ loop:
+ - nginx
+ - fcgiwrap@nginx.socket
diff --git a/roles/git/templates/git_nginx.conf.j2 b/roles/git/templates/git_nginx.conf.j2
new file mode 100644
index 0000000..cd37f25
--- /dev/null
+++ b/roles/git/templates/git_nginx.conf.j2
@@ -0,0 +1,16 @@
+server {
+ listen 80;
+ server_name _;
+
+ root /usr/share/cgit;
+ try_files $uri @cgit;
+
+ location @cgit {
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME /var/www/cgi-bin/cgit;
+ fastcgi_param PATH_INFO $uri;
+ fastcgi_param QUERY_STRING $args;
+ fastcgi_param HTTP_HOST $server_name;
+ fastcgi_pass unix:/run/fcgiwrap-nginx.sock;
+ }
+}
diff --git a/roles/host/files/60-machinectl-fast-user-auth.rules b/roles/host/files/60-machinectl-fast-user-auth.rules
new file mode 100644
index 0000000..eee39ea
--- /dev/null
+++ b/roles/host/files/60-machinectl-fast-user-auth.rules
@@ -0,0 +1,6 @@
+polkit.addRule(function(action, subject) {
+ if(action.id == "org.freedesktop.machine1.host-shell" &&
+ subject.isInGroup("wheel")) {
+ return polkit.Result.YES;
+ }
+});
diff --git a/roles/host/handlers/main.yaml b/roles/host/handlers/main.yaml
new file mode 100644
index 0000000..e643580
--- /dev/null
+++ b/roles/host/handlers/main.yaml
@@ -0,0 +1,25 @@
+- name: Reload Firewalld
+ ansible.builtin.systemd:
+ name: firewalld
+ state: reloaded
+
+- name: Restart Host systemd-networkd
+ ansible.builtin.systemd:
+ name: systemd-networkd
+ state: restarted
+
+- name: Restart Containers
+ ansible.builtin.systemd:
+ name: "systemd-nspawn@{{ item.key }}"
+ state: restarted
+ loop: "{{ containers | dict2items }}"
+
+- name: Restart Nginx
+ ansible.builtin.systemd:
+ name: nginx
+ state: restarted
+
+- name: Restart Polkit
+ ansible.builtin.systemd:
+ name: polkit
+ state: restarted
diff --git a/roles/host/tasks/main.yaml b/roles/host/tasks/main.yaml
new file mode 100644
index 0000000..007d44d
--- /dev/null
+++ b/roles/host/tasks/main.yaml
@@ -0,0 +1,195 @@
+- name: Install firewalld and systemd-networkd packages
+ ansible.builtin.dnf:
+ name:
+ - firewalld
+ - systemd-container
+ - systemd-networkd
+ - openssl
+ - python3-libsemanage
+ - policycoreutils
+ state: present
+
+- name: Configure Polkit to allow machinectl fast user auth
+ ansible.builtin.copy:
+ src: 60-machinectl-fast-user-auth.rules
+ dest: /etc/polkit-1/rules.d/60-machinectl-fast-user-auth.rules
+ mode: "0644"
+ notify: Restart Polkit
+
+- name: Ensure firewalld and systemd-networkd are running
+ ansible.builtin.systemd:
+ name: "{{ item }}"
+ state: started
+ enabled: yes
+ loop:
+ - firewalld
+ - systemd-networkd
+
+- name: Enable masquerading for container internet access
+ ansible.posix.firewalld:
+ masquerade: yes
+ state: enabled
+ permanent: yes
+ zone: public
+ notify: Reload Firewalld
+
+- name: Open HTTP and HTTPS (TCP) for Nginx
+ ansible.posix.firewalld:
+ service: "{{ item }}"
+ state: enabled
+ permanent: yes
+ zone: public
+ loop:
+ - http
+ - https
+ notify: Reload Firewalld
+
+- name: Open HTTPS (UDP) for HTTP/3 QUIC support
+ ansible.posix.firewalld:
+ port: 443/udp
+ state: enabled
+ permanent: yes
+ zone: public
+ notify: Reload Firewalld
+
+- name: Configure Host Firewall Port Forwarding dynamically
+ ansible.posix.firewalld:
+ port_forward:
+ - port: "{{ item.1 }}"
+ proto: tcp
+ toaddr: "{{ item.0.value.ip }}"
+ toport: "{{ item.1 }}"
+ permanent: yes
+ state: enabled
+ loop: "{{ containers | dict2items | subelements('value.forward_ports', skip_missing=True) }}"
+ notify: Reload Firewalld
+
+- name: Create bridge netdev on host
+ ansible.builtin.copy:
+ dest: /etc/systemd/network/10-nspawn-br0.netdev
+ content: |
+ [NetDev]
+ Name=nspawn-br0
+ Kind=bridge
+ notify: Restart Host systemd-networkd
+
+- name: Assign IP to the host bridge
+ ansible.builtin.copy:
+ dest: /etc/systemd/network/10-nspawn-br0.network
+ content: |
+ [Match]
+ Name=nspawn-br0
+ [Network]
+ Address={{ bridge_ip }}/24
+ notify: Restart Host systemd-networkd
+
+- name: Apply networking changes immediately
+ ansible.builtin.meta: flush_handlers
+
+- name: Ensure containers are bootstrapped (AlmaLinux 10)
+ ansible.builtin.dnf:
+ installroot: "/var/lib/machines/{{ item.key }}"
+ releasever: "10"
+ name:
+ - almalinux-release
+ - systemd
+ - dbus
+ - systemd-networkd
+ - passwd
+ - dnf
+ - iproute
+ state: present
+ loop: "{{ containers | dict2items }}"
+
+- name: Initialize machine-id for containers
+ ansible.builtin.command: systemd-machine-id-setup --root=/var/lib/machines/{{ item.key }}
+ args:
+ creates: "/var/lib/machines/{{ item.key }}/etc/machine-id"
+ loop: "{{ containers | dict2items }}"
+
+- name: Fix SELinux contexts in container rootfs
+ ansible.builtin.command: restorecon -R /var/lib/machines/{{ item.key }}
+ register: restorecon_result
+ changed_when: "'Relabeled' in restorecon_result.stdout"
+ loop: "{{ containers | dict2items }}"
+
+- name: Ensure systemd-nspawn directory exists
+ ansible.builtin.file:
+ path: /etc/systemd/nspawn
+ state: directory
+ mode: "0755"
+
+- name: Ensure Let's Encrypt mock directories exist
+ ansible.builtin.file:
+ path: "{{ item }}"
+ state: directory
+ mode: '0755'
+ loop:
+ - "/etc/letsencrypt/archive/{{ vault_public_domain }}"
+ - "/etc/letsencrypt/live/{{ vault_public_domain }}"
+
+- name: Check if Let's Encrypt certificate exists
+ ansible.builtin.stat:
+ path: "/etc/letsencrypt/live/{{ vault_public_domain }}/fullchain.pem"
+ register: le_cert
+
+- name: Generate self-signed fallback cert in Let's Encrypt paths if missing
+ ansible.builtin.command: >
+ openssl req -x509 -nodes -days 365
+ -newkey ec -pkeyopt ec_paramgen_curve:prime256v1
+ -keyout /etc/letsencrypt/live/{{ vault_public_domain }}/privkey.pem
+ -out /etc/letsencrypt/live/{{ vault_public_domain }}/fullchain.pem
+ -subj "/CN={{ vault_public_domain }}"
+ args:
+ creates: "/etc/letsencrypt/live/{{ vault_public_domain }}/fullchain.pem"
+ when: not le_cert.stat.exists
+
+- name: Create systemd-nspawn configuration
+ ansible.builtin.template:
+ src: nspawn.j2
+ dest: "/etc/systemd/nspawn/{{ item.key }}.nspawn"
+ loop: "{{ containers | dict2items }}"
+ notify: Restart Containers
+
+- name: Enable and Start Containers
+ ansible.builtin.systemd:
+ name: "systemd-nspawn@{{ item.key }}"
+ state: started
+ enabled: yes
+ loop: "{{ containers | dict2items }}"
+
+- name: Install Nginx
+ ansible.builtin.dnf:
+ name: nginx
+ state: present
+
+- name: Allow Nginx to connect to upstream servers (SELinux)
+ ansible.posix.seboolean:
+ name: httpd_can_network_connect
+ state: yes
+ persistent: yes
+
+- name: Configure Nginx dynamically
+ ansible.builtin.template:
+ src: nginx.conf.j2
+ dest: /etc/nginx/nginx.conf
+ validate: nginx -t -c %s
+ notify: Restart Nginx
+
+- name: Ensure Nginx is enabled and running
+ ansible.builtin.systemd:
+ name: nginx
+ state: started
+ enabled: yes
+
+- name: Ensure Let's Encrypt renewal hook directory exists
+ ansible.builtin.file:
+ path: /etc/letsencrypt/renewal-hooks/post
+ state: directory
+ mode: '0755'
+
+- name: Deploy Let's Encrypt post-renewal hook for Nginx
+ ansible.builtin.template:
+ src: nginx-reload.sh.j2
+ dest: /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh
+ mode: '0755'
diff --git a/roles/host/templates/nginx-reload.sh.j2 b/roles/host/templates/nginx-reload.sh.j2
new file mode 100644
index 0000000..f248776
--- /dev/null
+++ b/roles/host/templates/nginx-reload.sh.j2
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+systemctl reload nginx
diff --git a/roles/host/templates/nginx.conf.j2 b/roles/host/templates/nginx.conf.j2
new file mode 100644
index 0000000..7360cae
--- /dev/null
+++ b/roles/host/templates/nginx.conf.j2
@@ -0,0 +1,67 @@
+user nginx;
+worker_processes auto;
+worker_rlimit_nofile 8192;
+error_log /var/log/nginx/error.log notice;
+pid /run/nginx.pid;
+
+events {
+ worker_connections 4096;
+}
+
+http {
+ log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ '$status $body_bytes_sent "$http_referer" '
+ '"$http_user_agent" "$http_x_forwarded_for"';
+
+ access_log /var/log/nginx/access.log main;
+
+ sendfile on;
+ tcp_nopush on;
+ keepalive_timeout 65;
+ types_hash_max_size 4096;
+
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ # Modern SSL configuration
+ ssl_protocols TLSv1.2 TLSv1.3;
+ ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
+ ssl_prefer_server_ciphers on;
+ ssl_session_cache shared:SSL:10m;
+ ssl_session_timeout 1d;
+ ssl_session_tickets off;
+
+ # Redirect all HTTP traffic to HTTPS
+ server {
+ listen 80 default_server;
+ server_name _;
+ return 301 https://$host$request_uri;
+ }
+
+{% for name, config in containers.items() %}
+{% if config.web_subdomain is defined %}
+ server {
+ listen 443 ssl; # TCP for HTTP/1.1 & HTTP/2
+ listen 443 quic; # UDP for HTTP/3 QUIC
+ http2 on; # Enable HTTP/2 over TCP
+
+ server_name {{ config.web_subdomain }}.{{ vault_public_domain }};
+
+ # Nginx reads them natively, no combining needed
+ ssl_certificate /etc/letsencrypt/live/{{ vault_public_domain }}/fullchain.pem;
+ ssl_certificate_key /etc/letsencrypt/live/{{ vault_public_domain }}/privkey.pem;
+
+ # Advertise HTTP/3 availability to browsers
+ add_header Alt-Svc 'h3=":443"; ma=2592000' always;
+
+ location / {
+ proxy_pass http://{{ config.ip }}:80;
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto https;
+ }
+ }
+{% endif %}
+{% endfor %}
+}
diff --git a/roles/host/templates/nspawn.j2 b/roles/host/templates/nspawn.j2
new file mode 100644
index 0000000..15faf53
--- /dev/null
+++ b/roles/host/templates/nspawn.j2
@@ -0,0 +1,10 @@
+[Exec]
+Boot=yes
+Hostname={{ item.key }}.{{ vault_public_domain }}
+
+[Files]
+BindReadOnly=/etc/letsencrypt/live/{{ vault_public_domain }}:/etc/letsencrypt/live/{{ vault_public_domain }}
+BindReadOnly=/etc/letsencrypt/archive/{{ vault_public_domain }}:/etc/letsencrypt/archive/{{ vault_public_domain }}
+
+[Network]
+Bridge=nspawn-br0
diff --git a/roles/mail/handlers/main.yaml b/roles/mail/handlers/main.yaml
new file mode 100644
index 0000000..2d6ec58
--- /dev/null
+++ b/roles/mail/handlers/main.yaml
@@ -0,0 +1,15 @@
+- name: Fix DKIM permissions
+ ansible.builtin.file:
+ path: /etc/opendkim/keys/
+ owner: opendkim
+ group: opendkim
+ recurse: yes
+
+- name: Restart Mail Services
+ ansible.builtin.systemd:
+ name: "{{ item }}"
+ state: restarted
+ loop:
+ - postfix
+ - dovecot
+ - opendkim
diff --git a/roles/mail/tasks/main.yaml b/roles/mail/tasks/main.yaml
new file mode 100644
index 0000000..66b4215
--- /dev/null
+++ b/roles/mail/tasks/main.yaml
@@ -0,0 +1,61 @@
+- name: Install Mail Packages
+ ansible.builtin.dnf:
+ name:
+ - postfix
+ - dovecot
+ - opendkim
+ - opendkim-tools
+ state: present
+
+- name: Ensure OpenDKIM keys directory exists
+ ansible.builtin.file:
+ path: "/etc/opendkim/keys/{{ vault_public_domain }}"
+ state: directory
+ owner: opendkim
+ group: opendkim
+ mode: "0750"
+
+- name: Generate DKIM Key
+ ansible.builtin.command:
+ cmd: "opendkim-genkey -a ed25519 -s default -d {{ vault_public_domain }} -D /etc/opendkim/keys/{{ vault_public_domain }}/"
+ creates: "/etc/opendkim/keys/{{ vault_public_domain }}/default.private"
+ notify: Fix DKIM permissions
+
+- name: Configure OpenDKIM mappings
+ ansible.builtin.copy:
+ dest: "{{ item.path }}"
+ content: "{{ item.content }}"
+ mode: "0644"
+ loop:
+ - { path: /etc/opendkim/KeyTable, content: "default._domainkey.{{ vault_public_domain }} {{ vault_public_domain }}:default:/etc/opendkim/keys/{{ vault_public_domain }}/default.private\n" }
+ - { path: /etc/opendkim/SigningTable, content: "*@{{ vault_public_domain }} default._domainkey.{{ vault_public_domain }}\n" }
+ - { path: /etc/opendkim/TrustedHosts, content: "127.0.0.1\nlocalhost\n10.0.0.0/24\n" }
+ notify: Restart Mail Services
+
+- name: Deploy Configurations
+ ansible.builtin.template:
+ src: "{{ item.src }}"
+ dest: "{{ item.dest }}"
+ mode: "0644"
+ loop:
+ - { src: postfix_main.cf.j2, dest: /etc/postfix/main.cf }
+ - { src: postfix_master.cf.j2, dest: /etc/postfix/master.cf }
+ - { src: dovecot.conf.j2, dest: /etc/dovecot/dovecot.conf }
+ - { src: opendkim.conf.j2, dest: /etc/opendkim.conf }
+ notify: Restart Mail Services
+
+- name: Add Mail User
+ ansible.builtin.user:
+ name: me
+ shell: /sbin/nologin
+ password: "{{ vault_mail_user_password | password_hash('sha512') }}"
+
+- name: Ensure Services are Enabled and Running
+ ansible.builtin.systemd:
+ name: "{{ item }}"
+ state: started
+ enabled: yes
+ loop:
+ - postfix
+ - dovecot
+ - opendkim
diff --git a/roles/mail/templates/dovecot.conf.j2 b/roles/mail/templates/dovecot.conf.j2
new file mode 100644
index 0000000..e733bae
--- /dev/null
+++ b/roles/mail/templates/dovecot.conf.j2
@@ -0,0 +1,22 @@
+protocols = imap
+listen = *
+mail_location = maildir:~/Maildir
+auth_mechanisms = plain login
+ssl = required
+ssl_cert = </etc/letsencrypt/live/{{ vault_public_domain }}/fullchain.pem
+ssl_key = </etc/letsencrypt/live/{{ vault_public_domain }}/privkey.pem
+
+passdb {
+ driver = pam
+}
+userdb {
+ driver = passwd
+}
+
+service auth {
+ unix_listener /var/spool/postfix/private/auth {
+ group = postfix
+ mode = 0660
+ user = postfix
+ }
+}
diff --git a/roles/mail/templates/opendkim.conf.j2 b/roles/mail/templates/opendkim.conf.j2
new file mode 100644
index 0000000..b29fcb3
--- /dev/null
+++ b/roles/mail/templates/opendkim.conf.j2
@@ -0,0 +1,15 @@
+PidFile /run/opendkim/opendkim.pid
+Mode sv
+Syslog yes
+SyslogSuccess yes
+LogWhy yes
+UserID opendkim:opendkim
+Socket inet:8891@localhost
+Umask 002
+Canonicalization relaxed/relaxed
+Selector default
+MinimumKeyBits 1024
+KeyTable /etc/opendkim/KeyTable
+SigningTable refile:/etc/opendkim/SigningTable
+ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
+InternalHosts refile:/etc/opendkim/TrustedHosts
diff --git a/roles/mail/templates/postfix_main.cf.j2 b/roles/mail/templates/postfix_main.cf.j2
new file mode 100644
index 0000000..df20610
--- /dev/null
+++ b/roles/mail/templates/postfix_main.cf.j2
@@ -0,0 +1,27 @@
+myhostname = mail.{{ vault_public_domain }}
+mydomain = {{ vault_public_domain }}
+myorigin = $mydomain
+mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
+inet_interfaces = all
+inet_protocols = ipv4
+mynetworks = 127.0.0.0/8, 10.0.0.0/24
+home_mailbox = Maildir/
+message_size_limit = 26214400
+alias_maps = lmdb:/etc/aliases
+alias_database = lmdb:/etc/aliases
+
+smtpd_tls_cert_file = /etc/letsencrypt/live/{{ vault_public_domain }}/fullchain.pem
+smtpd_tls_key_file = /etc/letsencrypt/live/{{ vault_public_domain }}/privkey.pem
+smtpd_tls_security_level = may
+smtp_tls_security_level = may
+smtpd_tls_protocols = >=TLSv1.2
+smtp_tls_protocols = >=TLSv1.2
+
+smtpd_sasl_type = dovecot
+smtpd_sasl_path = private/auth
+smtpd_sasl_auth_enable = yes
+smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
+
+smtpd_milters = inet:localhost:8891
+non_smtpd_milters = inet:localhost:8891
+milter_default_action = accept
diff --git a/roles/mail/templates/postfix_master.cf.j2 b/roles/mail/templates/postfix_master.cf.j2
new file mode 100644
index 0000000..c2648ca
--- /dev/null
+++ b/roles/mail/templates/postfix_master.cf.j2
@@ -0,0 +1,31 @@
+smtp inet n - y - - smtpd
+pickup unix n - y 60 1 pickup
+cleanup unix n - y - 0 cleanup
+qmgr unix n - n 300 1 qmgr
+tlsmgr unix - - y 1000? 1 tlsmgr
+rewrite unix - - y - - trivial-rewrite
+bounce unix - - y - 0 bounce
+defer unix - - y - 0 bounce
+trace unix - - y - 0 bounce
+verify unix - - y - 1 verify
+flush unix n - y 1000? 0 flush
+proxymap unix - - n - - proxymap
+proxywrite unix - - n - 1 proxymap
+smtp unix - - y - - smtp
+relay unix - - y - - smtp
+showq unix n - y - - showq
+error unix - - y - - error
+retry unix - - y - - error
+discard unix - - y - - discard
+local unix - n n - - local
+virtual unix - n n - - virtual
+lmtp unix - - y - - lmtp
+anvil unix - - y - 1 anvil
+scache unix - - y - 1 scache
+smtps inet n - y - - smtpd
+ -o syslog_name=postfix/smtps
+ -o smtpd_tls_wrappermode=yes
+ -o smtpd_sasl_auth_enable=yes
+ -o smtpd_reject_unlisted_recipient=no
+ -o smtpd_client_restrictions=permit_sasl_authenticated,reject
+ -o milter_macro_daemon_name=ORIGINATING