README ¶
pwch (/piːwɪtʃ/)
pwch
Renovate
pwch (short for password change) is a simple Go service for small mail server setups with a PostgreSQL user store and dovecot IMAP server. It will enable your users to change their password on their own via a pure html selfservice portal and encrypt dovecot mailboxes with per user keys. It's suppposed to be run on the same host as your dovecot IMAP server installation.
WARNING
Try this software with great care only. DO NOT simply deploy it on your production mail server without this consideration:
- pwch will encrypt your user mailboxes. If anything fails these mails are gone forever.
What it does
- checks whether an email address exists in the user database
- sends one time links to change the password to existing email addresses
- enforces configurable password policy
- implements naive rate limiting when sending one time links
- encrypts mailboxes with per user keys derived from their password
What it does not
- give an attacker hints whether an email address exists in the database
- there is no 'Forgot password' option. It's not possible by design. If you forget your password you will need to reset it manually in the database. All stored emails will be lost then.
How it works
When a user enters an email address in the selfservice portal, pwch checks whether the address is present in the database. If it is, the given address will receive an email containing a one time link which is valid for a configurable amount of time.
You still need your current password to set a new one. If all checks are passed pwch will directly change the password in the database, run a wrapper script to reencrypt your mailbox and terminate all existing IMAP sessions for your user. If any of the above steps fail, pwch will rollback the changes. The wrapper script executes doveadm commands. That is why dovecot/doveadm has to be installed on the same host.
Attention: The wrapper script needs the setuid bit set.
What it looks like
The html and css files are fully customizable. This is what the default looks like.
Requirements
- Local dovecot installation with doveadm
- PostgreSQL database containing user store
- SMTP server with STARTTLS enabled
- Optional: AppArmor
Database schema requirements
Take a look at postgres.sql for the minimal requirements to set up your database.
Dovecot requirements
See dovecot-sql.conf to configure dovecot SQL queries.
You will have to configure dovecot as well to encrypt mailboxes:
mail_plugins = mail_crypt
plugin {
mail_crypt_curve = secp521r1
mail_crypt_require_encrypted_user_key = yes
mail_crypt_save_version = 2
}
Please take a look at the official Documentation
How to deploy
You can use this ansible role to take care of the deployment if you like.
- Create a system group
# groupadd --system pwch
- Create a system user
# useradd --gid pwch --no-create-home --shell /sbin/nologin --system pwch
- Create the config directory
# mkdir /etc/pwch
-
Create the config file at
/etc/pwch/config.yml
. Set owner and group topwch
and remove all permissions to others. -
Create the html assets directory and copy the html assets to this directory.
# mkdir /usr/local/src/pwch
-
Copy the pwch binary to
/usr/local/bin/
and runchmod +x
to make it executable. -
Copy the doveadm_wrapper binary to
/usr/local/bin/
and first runchown root:pwch
, then runchmod 4750
to set the setuid bit. -
Copy the systemd unit file to
/etc/systemd/system/
and runsystemctl daemon-reload
-
Enable and start the service
# systemctl enable pwch.service
# systemctl start pwch.service
AppArmor (Optional)
The pwch policy allows PostgreSQL unix socket connections only.
-
Copy the AppArmor policies to
/etc/apparmor.d/usr.local.bin.pwch
and/etc/apparmor.d/usr.local.bin.doveadm_wrapper
-
Load the policies with
apparmor_parser -r /etc/apparmor.d/usr.local.bin.pwch /etc/apparmor.d/usr.local.bin.doveadm_wrapper
Create new mail user
pwch takes care of password changes of existing users. To create new users you have to execute these steps manually.
- Create initial user password
# doveadm pw -s BLF-CRYPT -r 14 // or whatever cost you have set
ATTENTION: Remove the {BLF-CRYPT}
prefix before inserting the password into the database.
- When the user accounts is present in the database, run:
# doveadm -o plugin/mail_crypt_private_password=<sha3-512-hashed password> mailbox cryptokey generate -u <user@example.org> -U
INFO: To calculate the sha3-512 hash of the password run this command inside postgres cli (pgcrypto must be activated)
select encode(digest('<plain_text_password>', 'sha3-512'), 'hex');
- When the mailbox is encrypted tell your new user to change the password.
Integration testing
Integration testing has to be done locally with vagrant and ansible. After installing these dependencies on your machine you have to build the pwch binaries and move them to the correct directories in order to deploy them with ansible on your vagrant box.
A simple go build
in the cmd/
directories should yield a pwch
and a
doveadm_wrapper
binary. Place these binaries in vagrant/roles/pwch/files/
.
Then simply run vagrant up
inside the vagrant/
directory. If the ansible
playbook does not start automatically, run vagrant provision
.