Replace gpg_wks_server with easywks

This commit is contained in:
s3lph 2021-10-03 03:53:34 +02:00
parent b916dd89d7
commit 6ae26d9da8
17 changed files with 111 additions and 201 deletions
README.mdgalaxy.yml
plugins/filter
roles
easywks
gpg_wks_server
postfix
defaults/main
templates/etc/postfix

View file

@ -9,7 +9,7 @@
- `s3lph.mailserver.mailman`: [Mailman 3][mailman] mailing list server, management and archive interface
- `s3lph.mailserver.dovecot`: [Dovecot][dovecot] IMAP server
- `s3lph.mailserver.schleuder`: [Schleuder][schleuder] PGP-encrypted mailing list server
- `s3lph.mailserver.gpg_wks_server`: [GnuPG WKS][wks] server
- `s3lph.mailserver.easywks`: [EasyWKS][easywks] server
## Status of This Collection
@ -239,27 +239,35 @@ Run `ansible-playbook -t role::dovecot` to deploy
TODO: Documentation/Example
### GPG WKS Server
### EasyWKS
```yaml
# Register a "gpgwks" postfix transport in master.cf, which pipes
# mail into gpg-wks-server --receive
postfix_gpg_wks_enable: yes
# mail into easywks process. LMTP should be preferred though!
#postfix_easywks_pipe_transport: yes
# Domains to enable WKS for, along with the addresses to submit keys
# to. These addresses must be configured externally, e.g. through
# PostfixAdmin, and use the `gpgwks:` transport.
gpg_wks_server_submission_address:
example.org: webkey@example.org
example.net: wks@example.net
# When the easywks package is available in your system's package
# sources, set this to no. Otherwise the package is downloaded from
# the project upstream releases at Gitlab.
#easywks_download: no
# If the created WKD directory needs to be rsynced to another
# location, add the location here (without the trailing `/hu/`)
gpg_wks_server_destination:
example.net: /var/www/example.net/html/.well-known/openpgpkeys/example.net
# Simple /etc/easywks.yml encoded as a multiline string
easywks_config: |
mailing_method: smtp
smtp:
host: localhost
port: 8025
lmtpd:
host: "::1"
port: 8024
domains:
example.org:
submission_address: webkey@example.org
example.net:
submission_address: wks@example.net
```
Run `ansible-playbook -t role::gpg_wks_server` to deploy
Run `ansible-playbook -t role::postfix:config,role::easywks` to deploy
[postfix]: http://www.postfix.org/
[postsrsd]: https://github.com/roehling/postsrsd
@ -268,4 +276,4 @@ Run `ansible-playbook -t role::gpg_wks_server` to deploy
[mailman]: http://list.org/
[dovecot]: https://dovecot.org/
[schleuder]: https://schleuder.org/
[wks]: https://wiki.gnupg.org/WKS
[easywks]: https://gitlab.com/s3lph/easywks

View file

@ -8,7 +8,7 @@ namespace: s3lph
name: mailserver
# The version of the collection. Must be compatible with semantic versioning
version: '0.1.3'
version: '0.1.4'
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
readme: README.md

View file

@ -1,46 +0,0 @@
import hashlib
def _zrtp_base32(sha1):
# https://datatracker.ietf.org/doc/html/rfc6189#section-5.1.6
alphabet = 'ybndrfg8ejkmcpqxot1uwisza345h769'
encoded = ''
bits = int.from_bytes(sha1, 'big')
shift = 155
for j in range(32):
n = (bits >> shift) & 31;
encoded += alphabet[n];
shift -= 5
return encoded
def _wkd_hash(uid):
return _zrtp_base32(hashlib.sha1(uid.encode()).digest())
def wkd_address(address):
local, host = address.rsplit('@', 1)
hu = _wkd_hash(local)
return '@'.join([hu, host])
def wkd_uid(address):
local, host = address.rsplit('@', 1)
return _wkd_hash(local)
def wkd_url(address):
# https://datatracker.ietf.org/doc/html/draft-koch-openpgp-webkey-service-06#section-6.1
local, host = address.rsplit('@', 1)
hu = _wkd_hash(local)
return 'https://' + host + '/.well-known/openpgpkey/hu/' + hu
class FilterModule:
def filters(self):
return {
'wkd_address': wkd_address,
'wkd_uid': wkd_uid,
'wkd_url': wkd_url
}

View file

@ -0,0 +1,7 @@
---
easywks_download: yes
easywks_config: ""
easywks_service_http_enabled: yes
easywks_service_lmtp_enabled: yes

View file

@ -0,0 +1,11 @@
---
- name: restart easywks-http
service:
name: easywks-http
state: restarted
- name: restart easywks-lmtp
service:
name: easywks-lmtp
state: restarted

View file

@ -0,0 +1,24 @@
---
- name: render easywks config file
template:
src: etc/easywks.yml.j2
dest: /etc/easywks.yml
owner: root
group: root
mode: 0644
notify:
- restart easywks-http
- restart easywks-lmtp
- name: start and enable easywks-http
service:
name: easywks-http
state: started
enabled: "{{ easywks_service_http_enabled }}"
- name: start and enable easywks-lmtp
service:
name: easywks-lmtp
state: started
enabled: "{{ easywks_service_lmtp_enabled }}"

View file

@ -0,0 +1,25 @@
---
- name: install easywks from system package sources
apt:
name: easywks
notify:
- restart easywks-http
- restart easywks-lmtp
when: "easywks_download"
- name: get easywks package url
uri:
# https://gitlab.com/s3lph/easywks
url: "https://gitlab.com/api/v4/projects/29907182/releases"
return_content: yes
register: "register_easywks_gitlab_releases"
changed_when: no
when: "easywks_download"
- name: install easywks from upstream release
apt:
deb: "{{ url }}"
vars:
url: "{{ (register_easywks_gitlab_releases.json[0].assets.links | selectattr('name', 'equalto', 'Debian Package'))[0].direct_asset_url }}"
when: "easywks_download"

View file

@ -0,0 +1,11 @@
---
- import_tasks: install.yml
tags:
- "role::easywks"
- "role::easywks:install"
- import_tasks: config.yml
tags:
- "role::easywks"
- "role::easywks:config"

View file

@ -0,0 +1,4 @@
---
{{ ansible_managed | comment }}
{{ easywks_config }}

View file

@ -1,7 +0,0 @@
---
gpg_wks_server_cron_cronexpr: '0 3 * * *'
gpg_wks_server_rsync_cronexpr: '*/5 * * * *'
gpg_wks_server_submission_address: {}
gpg_wks_server_destination: {}

View file

@ -1,62 +0,0 @@
---
- name: create wks domain directories
file:
name: "/var/lib/gnupg/wks/{{ item }}"
state: directory
owner: webkey
group: webkey
loop: "{{ gpg_wks_server_submission_address.keys() }}"
- name: render submission-address files
copy:
dest: "/var/lib/gnupg/wks/{{ item.key }}/submission-address"
content: |
{{ item.value }}
loop: "{{ gpg_wks_server_submission_address | dict2items }}"
- name: render policy files
copy:
dest: "/var/lib/gnupg/wks/{{ item.key }}/policy"
content: |
submission-address: {{ item.value }}
loop: "{{ gpg_wks_server_submission_address | dict2items }}"
- name: initialize gpg-wks-server
become: yes
become_user: webkey
command: /usr/bin/gpg-wks-server --list-domains
- name: check if secret keys exist
command: /usr/bin/gpg --list-secret-keys {{ gpg_wks_server_submission_address[item] }}
become: yes
become_user: webkey
changed_when: no
ignore_errors: yes
register: gpg_wks_server_register_secret_keys
loop: "{{ gpg_wks_server_submission_address.keys() }}"
- name: create gpg private key
command: /usr/bin/gpg --batch --passphrase '' --quick-gen-key {{ item.value }} default default never
become: yes
become_user: webkey
when: "(gpg_wks_server_register_secret_keys.results | selectattr('item', 'equalto', item.key))[0].rc != 0"
loop: "{{ gpg_wks_server_submission_address | dict2items }}"
- name: export gpg public key to wks
command: /usr/bin/gpg --batch --yes --output /var/lib/gnupg/wks/{{ item.key }}/hu/{{ item.value | s3lph.mailserver.wkd_uid }} --export-options export-minimal --export {{ item.value }}
become: yes
become_user: webkey
loop: "{{ gpg_wks_server_submission_address | dict2items }}"
- name: initial hu rsync
command: /usr/bin/rsync --delete --archive /var/lib/gnupg/wks/{{ item.key }}/hu/ {{ item.value }}/hu/
loop: "{{ gpg_wks_server_destination | dict2items }}"
- name: initial submission-address rsync
command: /usr/bin/rsync --delete --archive /var/lib/gnupg/wks/{{ item.key }}/submission-address {{ item.value }}/submission-address
loop: "{{ gpg_wks_server_destination | dict2items }}"
- name: initial submission-address policy
command: /usr/bin/rsync --delete --archive /var/lib/gnupg/wks/{{ item.key }}/policy {{ item.value }}/policy
loop: "{{ gpg_wks_server_destination | dict2items }}"

View file

@ -1,43 +0,0 @@
---
- name: install gpg-wks-server
apt:
name:
- gpg-wks-server
- acl
- name: render gpg-wks-server wrapper script
template:
src: usr/local/bin/gpg-wks-server-wrapper.j2
dest: /usr/local/bin/gpg-wks-server-wrapper
owner: root
group: root
mode: "0755"
- name: create webkey group
group:
name: webkey
system: yes
- name: create webkey user
user:
name: webkey
group: webkey
home: /var/lib/gnupg/wks
system: yes
shell: /usr/sbin/nologin
- name: chmod gpg-wks-server home
file:
path: /var/lib/gnupg/wks
state: directory
owner: webkey
group: webkey
mode: "2750"
- name: render gpg-wks-server crontab
template:
src: etc/cron.d/gpg-wks-server.j2
dest: /etc/cron.d/gpg-wks-server
owner: root
group: root

View file

@ -1,11 +0,0 @@
---
- import_tasks: install.yml
tags:
- "role::gpg_wks_server"
- "role::gpg_wks_server:install"
- import_tasks: config.yml
tags:
- "role::gpg_wks_server"
- "role::gpg_wks_server:config"

View file

@ -1,6 +0,0 @@
{{ ansible_managed | comment }}
{{ gpg_wks_server_cron_cronexpr }} webkey /usr/bin/gpg-wks-server --cron
{% for domain, destination in gpg_wks_server_destination.items() %}
{{ gpg_wks_server_rsync_cronexpr }} root /usr/bin/rsync -r -p --delete --chmod=Fa+r /var/lib/gnupg/wks/{{ domain }}/hu/ {{ destination }}/hu/
{% endfor %}

View file

@ -1,5 +0,0 @@
#!/bin/bash
{{ ansible_managed | comment }}
export PATH=/usr/bin:/usr/sbin
gpg-wks-server -v --receive --gpg=/usr/bin/gpg | sendmail -t

View file

@ -21,7 +21,7 @@ postfix_mailman_enable: no
postfix_schleuder_enable: no
postfix_srsd_enable: no
postfix_spamassassin_enable: no
postfix_gpg_wks_enable: no
postfix_easywks_pipe_transport: no
postfix_srsd_forward_lookup: "tcp:localhost:10001"
postfix_srsd_reverse_lookup: "tcp:localhost:10002"

View file

@ -22,7 +22,7 @@ schleuder unix y n n - - pipe
flags=DRhu user=schleuder argv=/usr/bin/schleuder work ${recipient}
{% endif %}
{% if postfix_gpg_wks_enable %}
{% if postfix_easywks_pipe_transport %}
gpgwks unix y n n - - pipe
flags=DRhu user=webkey argv=/usr/local/bin/gpg-wks-server-wrapper
{% endif %}
flags=DRhu user=easywks argv=/usr/bin/easywks process
{% endif %}