Recently I had a monologue on the Gnus development list, where I lamented the munging of the From: header in my emails to the Emacs development mailing list when sent through Gmane using nntp, and proceeded to solve the problem.
Since then I've discovered, and fixed, a line-ending problem, so I thought I would document the entire solution in a little more detail here.
There are three steps to perform on the machine running Gnus (in this case, my laptop):
- Install and configure opendkim, generate key
- Update DNS of your domain
- Integrate signing of news articles in Gnus
Install and configure opendkim, generate key
Installing is just
sudo apt install opendkim.
/etc/opendkim/ I have three files:
internalhosts containing the IP-addresses of my laptop (where Gnus
127.0.0.1 tullinup.koldfront.dk 192.168.0.102
keytable defining where to find the key corresponding to a domain:
signingtable, saying what addresses to sign with what
/etc/opendkim.conf I have changed these lines:
Selector news SignatureAlgorithm rsa-sha256 InternalHosts /etc/opendkim/internalhosts KeyTable /etc/opendkim/keytable SigningTable refile:/etc/opendkim/signingtable
To generate the key, I went to the directory
/etc/dkimkeys, and ran
opendkim-genkey -b 2048 -d koldfront.dk -s koldfront.dk.news
Notice that I am using the selector
news, separate from the selector
my mail server uses to sign outgoing email (
Make sure the generated private key,
opendkim.opendkim and has permissions
Also generated by the command is a file called
this contains the information that goes in DNS.
I run my own DNS servers, so I copied the content of the .txt file to my
/etc/bind/db.koldfront.dk, with a slight adjustment to
the "hostname". I think that is necessary because of the
-s argumen I
opendkim-genkey - I had to change
koldfront.dk.news._domainkey IN TXT to
news._domainkey.koldfront.dk. IN TXT.
After remembering to bump the serial field in the zonefile, it's just a
matter of telling bind to reload the zone, so it can be resigned for
DNSSEC and distributed to the two other DNS servers, i.e.
rndc reload koldfront.dk IN internet.
Integration in Gnus
The final step is to make Gnus sign outgoing news articles - to do that
I added a function to the
message-send-news-hook, which runs
opendkim, as the opendkim user, on the article, and adds the header
generated to it.
(add-hook 'message-send-news-hook 'asjo-add-dkim-signature) (defun asjo-add-dkim-signature () "Add a DKIM-signature: header" (save-excursion (message-goto-eoh) (insert (asjo-generate-dkim-signature)))) (defun asjo-generate-dkim-signature () "Genedate DKIM signature from current buffer by calling opendkim." (save-excursion (shell-command-on-region (point-min) (point-max) "sudo -u opendkim /usr/sbin/opendkim -bs -t - | awk 'NR > 1' | sed 's/\r//'" " *asjo-generate-dkim-output") (with-current-buffer " *asjo-generate-dkim-output" (buffer-string))))
The thing I missed in the first iteration was that
lines ending with \r\n, and Gnus expects just \n in the article buffer,
so I had to strip them.
I found this when I posted to an nntp-based blog-engine I am developing, which balked at the line endings!
When I write to the Emacs development list via Gmane/nntp, the From:-lines are no longer munged, as that is only necessary if SPF fails (it does almost by definition for a mailing list forwarding emails) and there were no DKIM-signature - and I've now added the latter.
Unfortunately it's not really feasible for this to work "out-of-the-box" in a news reader, because the public key needs to be added to DNS, which - while simple - is not something the news reader can do automatically.
I guess the installation could be made "less systemwide" by having the key in my home directory and using a configuration referring to that, but since I'm the primary user of my laptop, it's fine.