Husk is written in Rust, so you need a recent rust toolchain to compile the source. If your distribution doesn't provide such a toolchain (or it is to old), you can get an up-to-date version from here.
To compile Husk from source, clone its repository and compile:
$ git clone https://gitlab.com/husk-project/husk-milter
$ cd husk-milter
$ cargo install --locked --path .
The configuration file of Hust uses the toml format.
Husk is a milter, which means it's a background process (daemon) which
listens on a TCP port for incomming requests. This port is configured
under the name connection.
connection = "localhost:3000"
This example tells Husk to listen on 127.0.0.1 (localhost), port 3000.
There is a corresponding configuration for the MTA, so that the MTA
knows where to find Husk (see below).
Husk uses OpenPGP certificates for encryption. It needs a storage location
for these certificates. As Husk uses Sequoia PGP,
the name for this parameter is sequoia_home.
sequoia_home = "/var/lib/husk/"
Husk queries online sources for missing certificates. For WKD and DANE
the URL of the online source is derived from the email. Keyservers
have to be configured separately.
keyservers = [ "hkps://keys.openpgp.org/", "hkps://mail-api.proton.me" ]
Husk uses log4rs for logging. The configuration of log4rs is merged
into the main configuration file under the node named logging. That
means that you take a log4rs configuration and prepend logging to
each section:
[logging.appenders.console]
kind = "console"
[logging.appenders.console.encoder]
pattern = "{d(%Y-%m-%d %H:%M:%S)(local)} {h({l})} [{t}] {m}{n}"
[logging.appenders.file]
kind = "file"
path = "/tmp/husk.log"
[logging.appenders.file.encoder]
pattern = "{d(%Y-%m-%d %H:%M:%S)(local)} {h({l})} [{t}] {m}{n}"
[logging.root]
level = "debug"
appenders = ["file"]
[logging.loggers."husk"]
level = "debug"
so that [appenders.console] becomes [logging.appenders.console]
and so on.
If you do not specify any logging, Husk will default to log to the console.
You can put the configuration file at any place and start Husk with
$ husk ... --config <LOCATION> ...
or use the default location /etc/husk/config.toml. In this case you
can skip --config.
This is a description on how to add Husk to the postfix MTA. If you want to
use Husk with a different MTA, please refer to its documentation on how to add
a milter.
For postfix you have to tell the MTA where it can find the milter port.
The configuration entries are smtpd_milters and non_smtpd_milters.
smtpd_milters = inet:localhost:3000
non_smtpd_milters = $smtpd_milters
inet:localhost:3000 corresponds to the connection configuration parameter
in the Husk configuration.
The example above configures non_smtpd_milters by using the setting of
smtpd_milters (via the $ operator).
Please keep in mind that in case you configured multiple milters, the sequence is important, as Husk will change the content of the mail.
Husk has two aspects:
The CLI syntax follows the scheme NOUN (more NOUNs), VERB and then
parameters. Like
$ husk introducer add --cert-file FILE --domains DOMAIN
or
$ husk daemon start --config config.toml
Husk includes a help system, which can be used by passing --help.
$ husk --help
or
$ husk introducer add --help
and so on. It shows you the available subcommands and parameters.
The daemon is the background process which processes mails and encrypts them if possible. It has to be started separately, the MTA expects it to be reachable and doesn't start it on it's own.
$ husk daemon start &
or use
$ husk daemon start --config /path/to/the/configuration/file.toml &
Currently you have to use '&' to move the process into the background.
Husk can (and should) run as an unprivileged process (keep in mind to use a port number above 1024 as ports below require a privileged process).
TBD
For Husk to use a certificate for encryption, it has to be authenticated - meaning, that the user id of the certificate (usually an email address) is indeed the user id of the key holder of said certificate.
This authentication can only be done by humans, but once it's done, its result can be shared.
This is what an introducer does - it authenticates certificates and publishes the result in form of a certification which becomes part of the certificate.
Husk allows to use introducers to benefit from their work. At the same time, introducers are limited to a list of domains for which certifications are accepted. This is a restriction Husk imposes. The list of domains is specified by the administrator, not the introducer.
To add an introducer you need its certificate and specify which domains certifications done with this certificate should be accepted.
$ husk introducer add --cert-file FILE --domains example.com
You can specify a list of domains by
... ---domains domain1 domains2 domain3
FILE must contain a valid certificate, not expired and not revoked.
In case you already added the certificate to Husk, you can promote it by using its fingerprint.
$ husk introducer add --cert FINGERPRINT --domains example.com
$ husk introducer list
$ husk introducer remove --cert FINGERPRINT
If you remove an introducer, the certificate will stay in the certificate
store - only it's special powers will be removed. You can reactivate an
introducer by using husk introducer add --cert FINGERPRINT ..., if you
accidentially removed one.
Locals are certificates which are added to Husk by the administrator
and do not require to be introduced.
If you want to test Husk or want to use it only with a few dedicated
certificates, you can skip creating an introducer and use locals.
$ husk locals add --cert-file FILE
FILE must contain a valid certificate, not expired and not revoked.
Locals can be promoted to introducers by using
husk introducer add --cert FINGERPRINT ....
$ husk locals list
$ husk locals remove --cert FINGERPRINT
If you remove a local, its certificate will stay in the certificate store, but will be dormant.