Open mikecardwell opened 7 years ago
So our reason for the external script was, that as long as the system is not transparently routing traffic through Tor (which probably most mailservers don't do, as Tor exit nodes are widely rejected on port 25), exim still tries to lookup route_data
that is not an IP (e.g. foobfakf.onion) through standard DNS means. So either you have a local DNS cache, that transparently lookups .onion to Tor DNS or you use our perl-script version.
The question is whether we'd like to add this option for transparently routed systems, somehow in the documention, though we haven't yet such a chapter.
Btw, we would love comments and suggestions on our current router setups https://git-ipuppet.immerda.ch/ibox-modules/tree/ib_exim/files/conf.d/relay/routers#n192
Haven't tested actually using it with manualroute
as route_data
, but I wrote something up that does sorted by priority, then randomized by weighted for the SRV records, on the off chance that anyone ever has more than one.
Example complicated records:
# dig +short _onion-mx._tcp.onionmx.r53.ryanc.org SRV
10 0 2525 zero555555555555.onion.
10 20 25 smallbox5a555555.onion.
10 20 25 smallbox5b555555.onion.
10 60 25 bigbox5555555555.onion.
20 0 25 backupbox5555555.onion.
Perl code:
#!/usr/bin/env perl
use warnings;
use strict;
use Net::DNS::Resolver;
sub weighted_rr_shuffle {
# sort by ascending priority, then do a weighted shuffle within each priority
return map {$_->[0]} sort {
$a->[0]->priority <=> $b->[0]->priority || $b->[1] <=> $a->[1]
} map {
# https://softwareengineering.stackexchange.com/a/344274
# Weighted Random Sampling (2005; Efraimidis, Spirakis)
# http://utopia.duth.gr/~pefraimi/research/data/2007EncOfAlg.pdf
# tweaked to randomize order of equal weights
[$_, ($_->weight ? (rand() ** (1 / $_->weight)) : -1) + rand() * 1e-9]
} @_;
}
sub onionmx {
my $domain = shift;
my $res = Net::DNS::Resolver->new();
my $query = $res->search('_onion-mx._tcp.'.$domain, 'SRV');
if ($query) {
# load all valid resource records with a .onion address
my @rrlist = grep {
$_->type eq 'SRV' && $_->target =~ /\A(?:[a-z2-7]{16}|[a-z2-7]{56})\.onion\z/
} $query->answer;
# build result for route_data
return join(' : ', map {
# exim uses : as a seperator, so it needs to be doubled to escape it
$_->target . ($_->port == 25 ? '' : '::'.$_->port)
} weighted_rr_shuffle(@rrlist));
}
return '';
}
1;
Calling interactively via exim4 -be
:
# exim4 -be
> ${perl{onionmx}{grepular.com}}
grepularmmmiatj7.onion
> ${perl{onionmx}{onionmx.r53.ryanc.org}}
bigbox5555555555.onion : smallbox5b555555.onion : smallbox5a555555.onion : zero555555555555.onion::2525 : backupbox5555555.onion
> ${perl{onionmx}{onionmx.r53.ryanc.org}}
smallbox5b555555.onion : bigbox5555555555.onion : smallbox5a555555.onion : zero555555555555.onion::2525 : backupbox5555555.onion
> ${perl{onionmx}{onionmx.r53.ryanc.org}}
bigbox5555555555.onion : smallbox5a555555.onion : smallbox5b555555.onion : zero555555555555.onion::2525 : backupbox5555555.onion
Thought you might be interested. The following Exim macro+router allows me to route to systems with _onion-mx srv records without having to use an external script:
Of course, it relies on the system that it is running on to be set up with transparent Tor routing.