DuckCorp Infrastructure

This is the root of the DuckCorp Admin Team materials used to install, configure and manage services.

DuckCorp is commited to Free Software, thus all materials are published under the GPL v3 License (see details of the license in the COPYING file).


All sensitive materials are encrypted, read the Dealing with Secrets chapter to know more about this.

Configuration Management & Deployment

We use Ansible to help us automate as much as possible; you'll find more about it in the ansible directory.

Still, many things are handled manually, this is WIP.


Our TLS certificates are managed using mkcert. The mkcert.conf file holds the DuckCorp-specific configuration, and services contains the specific service names not in /etc/services. The keys configuration and resulting certificates are stored in the pki directory.

With this layout, mkcert can be run in-place (at the top-level of this repository), automagically finding its configuration and work directories.


In the scripts directory are the following scripts:

  • adm_check_*: this series of scripts check various resources hosted by DuckCorp against the outside world to see if there is any misconfiguration or if the hosting became obsolete (without the user telling us, which happen very often…)
  • adm_publish_tlsa: compute TLSA DNS RR for DNSSEC-enabled DNS zones based on the available TLS certificates
  • check_certs_expiration: warn when certificates are nearly expired (or already expired)

They are meant to be run in-place from the top of this repository. The lib subdirectory contains code factorized between the scripts.


The admin-oriented documentation can be found alongside the other materials, but for some topics we might write a dedicated explanation and store it in the doc directory.

For Admin Team Members

Sensitive Data

You need to set the ANSIBLE_VAULT_PASSWORD_FILE environment variable with the path to the password file.


First, clone [the repository](ssh:// You should probably have a look at the Requirements in the underlying directories too.

Git configuration

  • Always create a merge commit : $ git config --local merge.ff false
  • Allow fast-forward merges when using pull : $ git config --local pull.ff only
  • All commits must be GPG signed : $ git config --local commit.gpgSign true

Dealing with Secrets

We use Ansible Vault to hide some parameters like service credentials, user personal information or emails to avoid SPAM.

To make it easy git attributes are defined to make diff-ing and merging easy.

Your configuration needs to be enhanced to tel git how to handle these files. This is very easy, look at this URL for more info:


Git usage

When merging a branch, use --verify-signatures switch. If this fails, then DO NOT MERGE!!!

When adding submodule, please use the HTTPs URL to allow contributors to clone. Also use --name to set the submodule name or the path is taken by default. Then, you can ask git to automatically rewrite the URL to the right form with this command:

git config --global url.ssh://

For External Contributor

You're welcome to contribute ideas, report problems, send patches… using our Ticket Tracker (in the Contribution tracker).

You can clone this repository or browse it.

| Branch: | Revision:

duckcorp-infra @ master

# Date Author Comment
913f599c 2019-03-01 14:42 Marc Dequènes

add 'freds' user

ad6dfb77 2019-02-28 08:42 Marc Dequènes

dc-dovecot: adapt for Dovecot 2.3

929e449f 2019-02-28 08:42 Marc Dequènes

mail: ensure to fetch facts for mda replication partner

fd27c961 2019-02-24 18:11 Marc Dequènes

update 'bind9' module to avoid vars conflicts

a66cf6ea 2019-02-24 12:29 Marc Dequènes

dc-postfix: use vars instead of static set_fact

5f93387b 2019-02-24 12:29 Marc Dequènes

dc-dovecot: use vars instead of static set_fact

c1594edc 2019-02-24 11:17 Marc Dequènes

mail: ensure facts for Redis master are fetched

fccc455f 2019-02-24 11:01 Marc Dequènes

dc-ldap: use vars instead of static set_fact

14a2f554 2019-02-24 10:25 Marc Dequènes needs 'expires' apache plugin

6ca99d81 2019-02-24 00:21 Marc Dequènes install config

initial install fails without it

a7e9483c 2019-01-17 14:34 Marc Dequènes

disable all monitoring until Nicecity-NG is ready

the current machine is not able to hold the load and crash

2dbd6575 2019-01-11 19:28 Marc Dequènes

force lists in intermediate variables to be resolved #2

65d9ed5c 2019-01-11 19:23 Marc Dequènes

dc-web: rsync needed for 'synchronize' module

d25cc3cc 2019-01-11 17:02 Marc Dequènes

update submodules

1562056d 2019-01-11 17:01 Marc Dequènes

force lists in intermediate variables to be resolved

35a67e9f 2019-01-10 04:58 Marc Dequènes fix index permissions

802177b7 2018-12-30 14:44 Marc Dequènes

Orfeo: needs accounts resolution

It was removed in e8b3717 because Orfeo does not have historical VIP
shell accounts anymore, but certain services needs it (like

aad53888 2018-12-30 13:41 Marc Dequènes

dns: adjust rate limiting

f498ead5 2018-12-30 10:33 Marc Dequènes

Pond: experimenting with Bind DNSSEC support

55ee712d 2018-12-30 10:32 Marc Dequènes

Pond: update list of reverse zones

a7da91d8 2018-12-29 10:18 Marc Dequènes

dns: add rate limiting

6e731173 2018-12-29 08:31 Marc Dequènes

added duckcorp/

9ab70ad9 2018-12-29 07:59 Marc Dequènes

dc-postfix: rework TLS security

  • enforce server cipher order
  • be more restrictive with mandatory secured connections
  • smtpd?_tls_session_cache_database is not needed anymore, RFC 5077 TLS
    session tickets is recommended instead
  • share TLS settings among server types
7dcda2d6 2018-12-28 16:35 Marc Dequènes (Duck) webstats are no more

Removed Piwik/Matomo from the CSP.

0cf9ae03 2018-12-28 16:27 Marc Dequènes (Duck) forgot alias to TLD

e8b37173 2018-12-28 07:35 Marc Dequènes (Duck)

Orfeo: not a shell server anymore

f968f7df 2018-12-27 07:04 Marc Dequènes

unlock_host_encryption: failed when facts caching is expired

`system.boot.options` could not be defined because `_ip` depends on
facts, which prevented using any of the `system.boot.*` variables. So
moved initramfs SSH IP option in a separate top-level variable.

112ade40 2018-12-27 07:03 Marc Dequènes

unlock_host_encryption: do not log passphrases

84711404 2018-12-19 08:17 Marc Dequènes ensure 'proxy_wstunnel' Apache module is loaded

df6e330d 2018-12-19 08:08 Marc Dequènes no need for TLS to reach weechat on localhost

A recent update changed the behavior and the weechat certificate was not
accepted anymore. Weechat can bind on localhost only, and the port is
not opened anyway, so we do not need TLS between the proxy and Weechat.

75a83248 2018-12-19 08:00 Marc Dequènes weechat port was hardcoded

f7f0da45 2018-12-14 02:47 Marc Dequènes

dc-web: remove manually managed vhost confdir

b18c4706 2018-12-14 02:47 Marc Dequènes

added duckcorp/ (web only)

c1c28bf2 2018-12-14 02:33 Marc Dequènes

added duckland/ (web only)

3c210693 2018-12-14 02:13 Marc Dequènes fix DN for 'dc-duckland' group

cbeb6a63 2018-12-14 02:09 Marc Dequènes

added duckcorp/ (web only)

c8355c25 2018-12-13 14:03 Marc Dequènes

added duckcorp/ (web only)

cd87ba9a 2018-12-13 12:50 Marc Dequènes prune useless files

77ff0dab 2018-12-13 12:11 Marc Dequènes

dc-web: install indexoverride data and config

50d2c386 2018-12-13 11:51 Marc Dequènes

dc-web: install shared data

04054cfc 2018-12-13 11:12 Marc Dequènes

pki: remove useless certs

3ea6b94f 2018-12-13 11:04 Marc Dequènes

added DL/

c6d062d6 2018-12-13 10:42 Marc Dequènes

added DL/

5b710d38 2018-12-13 10:10 Marc Dequènes fix ProxyPassReverse

01e5f906 2018-12-13 09:57 Marc Dequènes

dc-icecast: add ansible_managed tags

eea73e50 2018-12-13 09:53 Marc Dequènes

dc-ftp: fix mode

0fae6ebe 2018-12-13 09:52 Marc Dequènes

Merge branch 'radio'

4f25165c 2018-12-13 09:52 Marc Dequènes

added radio

41dda944 2018-12-13 09:03 Marc Dequènes

dc-ftp: add ansible_managed tags

09433a02 2018-12-13 08:59 Marc Dequènes

Merge branch 'ftp'

af35a124 2018-12-13 08:58 Marc Dequènes

added FTP installation

d6f87283 2018-12-11 15:48 Marc Dequènes

Merge branch 'dovecot_antispam_imapsieve'

70ea0c6c 2018-12-11 15:12 Marc Dequènes

dc-dovecot: replace obsolete 'antispam' plugin with 'imapsieve'

- update dc-spoolinger config as 'imapsieve' does not normalize line
endings like 'antispam' did
- also fix global SIEVE scripts not properly recompiled

fixes #630

520b44df 2018-12-07 02:49 Marc Dequènes

add playbook to unlock encrypted filesystems

2194c5f6 2018-12-06 19:11 Marc Dequènes

Elwing: enable initramfs_ssh and enable decrypting Elwing_data volume

134fa877 2018-12-06 18:53 Marc Dequènes

ignore '__pycache__' directories

cdcd99e0 2018-12-06 18:52 Marc Dequènes

dc-base: move 'initramfs_ssh' parameter in the tree

Also fix the default value btw.

d4a206f1 2018-12-06 18:46 Marc Dequènes

dc-base: take care of encrypted filesystems

66944da3 2018-12-06 18:19 Marc Dequènes

dc-base: update initramfs after generating dropbear's host keys

4e8a4d1c 2018-12-06 18:10 Marc Dequènes

Merge branch 'Toushirou-NG'

daf34d8f 2018-12-06 18:10 Marc Dequènes

add special vars to prepare Toushirou-NG

b51060f1 2018-12-06 18:10 Marc Dequènes

dc-base: reuse OpenSSH keys for dropbear-initramfs

394eced5 2018-12-06 16:32 Marc Dequènes

web: vhosts cleanup in accounts

171152bb 2018-12-06 16:12 Marc Dequènes

lib/ansible_inventory: find_host_by_fqdn() is now case insensitive

2dad7ea1 2018-12-06 16:12 Marc Dequènes

adm_check_web: clarify when CNAME differs

e3e4bb8e 2018-12-06 16:11 Marc Dequènes

adm_check_web: adapt to new scheme from the 'httpd' role

2d2eafd0 2018-12-06 14:44 Marc Dequènes

adm_check_mx: clarify the partially missing MX2

67766a22 2018-12-06 14:44 Marc Dequènes

adm_check_mx: handle multiple MX1 and clarify the partially missing

60ca37cf 2018-12-06 14:43 Marc Dequènes

adm_check_mx: fix MX2 check

- use the computed list of provided MX2
- fix result when provided MX2 list is empty

9726d378 2018-12-06 09:58 Marc Dequènes

dc-dovecot: enable vacation-seconds SIEVE rules

5ee863e9 2018-12-06 09:57 Marc Dequènes

dc-dovecot: enable spamtest SIEVE rules

76c95ab8 2018-12-06 09:07 Marc Dequènes replace unmaintained Roundcube 'sieverules' plugin by 'managesieve'

7badb0ca 2018-12-06 06:10 Marc Dequènes

dc-dovecot: workaround for Debian#915687

b14d3d60 2018-12-06 05:29 Marc Dequènes

dc-dovecot: enable IMAP METADATA

66f1a4bc 2018-12-06 04:41 Marc Dequènes not need for document root

5bded476 2018-12-05 16:22 Marc Dequènes

update submodules

67d85a02 2018-12-05 14:33 Marc Dequènes avoid duplicate headers

a67bcabf 2018-12-05 09:43 Marc Dequènes

update submodules

18ef5eab 2018-12-05 09:22 Marc Dequènes

update submodules

30980af1 2018-12-05 09:22 Marc Dequènes

dc-web: lowercase status page vhost name to avoid duplicates

218e55fb 2018-12-05 07:56 Marc Dequènes

dc-accounts: fix hosts resolution order, broke FQDN resolution with Python/Ansible

9c8196bf 2018-12-05 07:14 Marc Dequènes

switch the controller to Python 3

4de9bb8d 2018-12-05 07:13 Marc Dequènes

fix E502

e622a1c6 2018-12-04 19:13 Marc Dequènes

ignore more pedantic flake8 tests

64ca35b6 2018-12-04 19:12 Marc Dequènes

added duckcorp/

c44433bb 2018-12-04 13:02 Marc Dequènes

fix E122

948b37ed 2018-12-04 13:01 Marc Dequènes

fix E265

10db18a8 2018-12-04 13:00 Marc Dequènes

vcs: prepare partition and directories

9b1801d6 2018-12-04 12:59 Marc Dequènes

fix ANSIBLE0011

5ad2d234 2018-12-04 12:58 Marc Dequènes


16c6bf14 2018-12-04 12:45 Marc Dequènes

mail: create mail storage partition

9499819b 2018-12-04 12:28 Marc Dequènes

added duckcorp/

06993aa2 2018-12-04 05:01 Marc Dequènes

add DICT server and client and duckcorp/ web client

068e7350 2018-12-03 10:48 Marc Dequènes

dc-postfix: fix IPv6 quoting

52672286 2018-12-03 10:28 Marc Dequènes

dl/l2tp: fix tunnel auth

a58b7f15 2018-12-03 10:21 Marc Dequènes

dl/l2tp: remove 'noccp' option

1b91365b 2018-12-03 04:19 Marc Dequènes

redmine: move vaulted variables in a specific file, easier to maintain

18fece2a 2018-12-03 04:09 Marc Dequènes setup local repositories

a712a5d1 2018-12-01 09:29 Marc Dequènes

added duckcorp/

134acfc1 2018-11-26 18:53 Marc Dequènes

mail: more quota for gorou