Hegemon is an Ansible based Debian server configuration tool. This started as a fork of the absolutely wonderful Soverign playbooks for a personal cloud.
These playbooks strive to be reasonably secure, full featured, and low on maintenance.
- Email Services
- IMAP over SSL via Dovecot, complete with full text search provided by Solr.
- POP3 over SSL, also via Dovecot.
- SMTP over SSL via Postfix
- DNSBLs to discard spam before it ever hits mail filters.
- Webmail via Roundcube, with Carddav, ManageSieve, and 2-factor authentication plugins.
- Mobile push notifications via Z-Push.
- Email client automatic configuration.
- Mail server verification via OpenDKIM and OpenDMARC so the Internet knows the mailserver is legit.
- Spam fighting via Rspamd and Postgrey.
- Virtual domains for email, backed by PostgreSQL.
- Email virus alerts using ClamSMTP.
- Personal Cloud
- Chat Services
- Internet Services
- User Setup
- User configuration with a remote git dotfiles directory, Stow linking, and Vim, Vundle, and Vim plugins.
- RFC6238 two-factor authentication compatible with Google Authenticator and various hardware tokens.
- SSH configuration preventing root login and insecure password authentication with improved defaults.
- VPN server via OpenVPN.
- Security
- SSL certificates obtained from Let's Encrypt automatically refreshed monthly. Used by Apache2, Dovecot, Postfix, and Prosody.
- Secure on-disk storage for email and more via EncFS.
- Firewall management via Uncomplicated Firewall (ufw).
- Validating, recursive, and caching DNS resolver provided by unbound.
- Intrusion prevention via fail2ban.
- GeoIP blocking using Xtables-addons.
- Malware detection via rkhunter, ClamAV, and LMD.
- File integrity monitoring with Samhain.
- Improved security with weekly lynis checks, and apparmor security.
- Maintenance
- Common package installation with useful programs, including nice-to-have tools like mosh, htop, and ranger.
- NTP, Apticron, and unattended-upgrades for server maintenance.
- Nightly backups to Tarsnap.
- Monit to keep everything running smoothly (and alert you when it’s not).
- collectd to collect system statistics, with optional integration to librato, an hosted monitoring solution.
- Locally hosted Carbon metric processing daemon and Whisper time-series database library funneling collectd data into a Grafana metrics dashboard.
- A VPS (or bare-metal server). Linode, Scaleway, and DigitalOcean are fantastic options. Make sure to have at least 512 MB of RAM for the system.
- 64-bit Debian 9.1 or an equivalent Linux distribution. (Deviating from Debian will require more tweaks to the playbooks. See Ansible’s different packaging modules.)
- A Tarsnap account with credit. Tarsnap is an optional backup service; consider paying the hosting provider for backups or using an additional backup service for redundancy.
- Just about any computer will do. Consider an older desktop, a laptop with a broken screen, an Intel NUC, or a Qotom thin client. Media and general purpose local servers need few resources to be effective.
If using Scaleway, create the instance and allow it to boot fully. Once booted, change the kernel to the Apparmor kernel and reboot using SSH or the console. This will allow the kernel modules to be fetched. Do not switch over to Apparmor during the first boot cycle as it will break the process.
Log in through the remote console, or as part of the local install process.
Install Required Packages:
apt install sudo
Change the root password:
passwd
Create a deploy user account for Ansible:
adduser deploy
Authorize an ssh key for the deploy account:
mkdir /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
cp /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
chmod 400 /home/deploy/.ssh/authorized_keys
chown deploy:deploy /home/deploy -R
adduser deploy sudo
If the host provider doesn't copy ssh keys into the root user's account, keys can be added to the deploy user's authorized_keys file with this command, instead of the cp
command above:
nano /home/deploy/.ssh/authorized_keys
Make sure Ansible 2.2+ is installed.
Choose a vault password option by uncommenting the setting in the 'ansible.cfg' file.
Modify the settings in the group_vars
folder. All passwords and sensitive data is contained in ansible-vault encrypted files, ending with _vault.yml. The hosts
file is also encrypted. This allows for forking this repo and keeping sensitive passwords in a personal git account, available to multiple computers. All '_vault'.yml' files are referenced by their counterparts without '_vault' for ease of searching. Vault files can be edited, encrypted, and decrypted with this command:
ansible-vault [create|decrypt|edit|encrypt|encrypt_string|rekey|view] all_vault.yml
Python 3.3 or higher on Linux will generate the appropriate mail password hash:
python3 -c 'import crypt; print(crypt.crypt("password", salt=crypt.METHOD_SHA512))'
On OS X and other platforms the passlib package may be used to generate the required string:
python -c 'import passlib.hash; print(passlib.hash.sha512_crypt.encrypt("password", rounds=5000))'
To create an IRC password hash:
python3 -c 'import crypt; print("irc_password_salt: {}\nirc_password_hash: {}".format(*crypt.crypt("password", salt=crypt.METHOD_SHA256).split("$")[2:]))'
Insert the values for irc_password_salt
and irc_password_hash
into ircbouncer_vault.yml.
On OS X and other platforms the passlib package may be used to generate the required string:
python -c 'import passlib.hash; print("irc_password_salt: {}\nirc_password_hash: {}".format(*passlib.hash.sha256_crypt.encrypt("password", rounds=5000).split("$")[2:]))'
For Git hosting, create a key and copy the public key into place:
ssh-keygen -t rsa -b 4096 -C "$(whoami)@$(hostname)-$(date -I)" -f gitolite
cp ~/.ssh/gitolite.pub ~/hegemon/roles/git/files/
If the SSH daemon listens on a non-standard port, add a colon and the port number after the IP address. In that case you also need to add the custom port to the task Set firewall rules for S
in the file roles/remote/tasks/ufw.yml
.
If using Tarsnap, download and install from www.tarsnap.com/download.html, or use brew install tarsnap
if using Homebrew.
Create a new machine key for the server (while in the hegemon/ directory):
tarsnap-keygen --keyfile roles/tarsnap/files/decrypted_tarsnap.key --user me@example.com --machine example.com
Create A
or CNAME
records which point to the server's IP address:
example.com
mail.example.com
(for IMAP/POP/SMTP)www.example.com
(for Web hosting)autoconfig.example.com
(for email client automatic configuration)autodiscover.example.com
(for active-sync autodiscovery)sync.example.com
(for z-push syncronization)read.example.com
(for Wallabag)news.example.com
(for Selfoss)cloud.example.com
(for nextCloud)git.example.com
(for cgit)
Create an MX
record for example.com
which assigns mail.example.com
as the domain’s mail server.
To run the remote playbook:
ansible-playbook remote.yml
To run one or more tasks, use tags:
ansible-playbook remote.yml -t ufw,ntp,swap
The dependencies
tag just installs dependencies, performing no other operations. The tasks associated with the dependencies
tag do not rely on the user-provided settings that live in group_vars
. Running the playbook with the dependencies
tag is particularly convenient for working with Docker images.
To ensure emails pass DKIM checks, add a txt
record. The name field will be default._domainkey.example.com.
The p=
field contains the public key used by OpenDKIM. The exact value can be found in the file /etc/opendkim/keys/example.com/default.txt
, which is also copied locally when the DKIM task runs. The v=
and p=
keys are required. The h=
key is optional, and defaults to all hash algorithms. The k=
key is optional, and defaults to 'rsa'. The s=
key is optional, and defaults to '*', for all services. See the DKIM reference here for any questions.
Example:
v=DKIM1; h=sha256; k=rsa; s=*; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDKKAQfMwKVx+oJripQI+Ag4uTwYnsXKjgBGtl7Tk6UMTUwhMqnitqbR/ZQEZjcNolTkNDtyKZY2Z6LqvM4KsrITpiMbkV1eX6GKczT8Lws5KXn+6BHCKULGdireTAUr3Id7mtjLrbi/E3248Pq0Zs39hkDxsDcve12WccjafJVwIDAQAB
For DMARC, add a txt
record. The name field should be _dmarc.example.com
and the value should be v=DMARC1; p=reject; adkim=s; aspf=s
. More info on DMARC can be found here.
Add an SPF txt
record. The name should be v=spf1 mx -all
.
Set the reverse DNS with the server provider to mail.example.com
.
For reference, see this post.
Make sure to validate functionality by sending an email to check-auth@verifier.port25.com and review the report that will be emailed back.
Also, visit DKIMValidator.com for another test.
Check certificate issuance at crt.sh.
Check SSL setup with SSLlabs.com/ssltest.
Be careful with Let's Encrypt SSL issuance, as there is a rate limit of 5 duplicate certificates / week. Please see letsencrypt.org/docs/rate-limits.
Make sure to allow SMTP outbound mail with the server provider. Most providers will have this turned off by default. Scaleway requires a hard boot of the server through their console to change firewall rules and allow SMTP traffic.
Sign into the ZNC web interface, which isn’t exposed through the firewall, and requires an SSH tunnel:
ssh deploy@example.com -L 6643:localhost:6643
Then proceed to localhost:6643.
Similarly, to access the monit server monitoring page, use another SSH tunnel:
ssh deploy@example.com -L 2812:localhost:2812
Again, proceed to localhost:2812.
Please create an issue.
To reboot the machine, the reboot.yml playbook needs run. This will restart the machine, decrypt the encfs, and restart all services that use the encrypted system. Optionally, the task can be used to just re-mount and restart services without a reboot, which is useful if encfs has a hiccup:
ansible-playbook reboot.yml
The other option is to enter the encfs password manually. This requires SSH into the machine after reboot, or accessing via a console interface:
encfs /encrypted /decrypted --public
After this, services dependent on the decrypted folder will need restarted:
sudo systemctl restart postgresql dovecot tomcat8 apache2 prosody
These programs and references have been invaluable in this project:
- The inspiration and original fork for this project.
- An endless wealth of Debian server knowledge. This project doesn't come close to the vastness of DebOps and doens't try to.
- A fantastic single service setup for personally hosted e-mail.