Make a DNS record like the following (replacing your domain and .onion):
_onion-mx._tcp.example.com. 3600 IN SRV 0 5 25 fofofmumububu.onion.
Test that it is working by doing a DNS query of your domain, it should return the record:
$ host -t srv _onion-mx._tcp.example.net
_onion-mx._tcp.example.net has SRV record 0 5 25 fofofmumububu.onion.
You need to install a script which replies to TCP table lookup queries.
This will detail how to get the python script working, but there is also a go implementation, which is probably more performant.
Download the script and put it in /usr/local/bin and make it executable.
Install the needed dependency:
# apt install python-dnspython
Create a copy of the postdns.ini file and rename it postdns.local.ini to avoid tampering with the reference config (if no postdns.local.ini exists, the reference config will be used)
Edit the config file and change
- under the
DOMAIN
section thehostname
field with your local domain - under the
RESOLVER
section theresolver_ip
field with your resolver (default is 127.0.0.1)- to use multiple resolvers, seperate them with comma
,
- to use multiple resolvers, seperate them with comma
- under the
RESOLVER
section theresolver_port
field with the port your resolver listens (default is 53)
Discussion:
The script queries the destination domain for a specific SRV record, '_onion-mx._tcp.' and if it finds a '.onion' address in the reply it gives it back to postfix to be used by the 'smtptor' service defined in master.cf. If no valid SRV record is found the mail is passed to 'smtp' service. This gives us dynamic SRV lookups that lead to SMTP over onion addresses!
- To change the SRV record the scripts looks for, edit the config file mentioned above and change under the
DNS
section thesrv_record
field with the SRV record you have setup (default is_onion-mx._tcp.
) - To change the service that will be used when a '.onion' address is found, edit the config file mentioned above and change under the
REROUTE
section theonion_transport
field with the service you want to be used (default issmtptor
)
In main.cf:
transport_maps = tcp:127.0.0.1:23000
Discussion:
If you want to "pin" some onion transports with a static map, because you've confirmed addresses out-of-band and don't want to leak metadata through DNS requests, you can do that by setting the generated transport map before the tcp map, like this:
transport_maps = hash:/etc/postfix/tor_transport, tcp:127.0.0.1:23000
This will lookup the entries in the static map and resolve them, but if they aren't there, it will try a DNS SRV lookup.
Now set the following in master.cf:
127.0.0.1:23000 inet n n n - 0 spawn user=nobody argv=/usr/local/bin/postdns.py
and restart postfix.
Send some mail and look at your headers to see if it worked.