Accept mail arriving through the relay tunnel - #5
Open
cyberb wants to merge 8 commits into
Open
Conversation
redirect terminates port 25 and forwards each message down the frp tunnel, which arrives at the device on loopback. Postfix needs somewhere to put it that is not the port it already offers the internet, so this adds a smtpd on 127.0.0.1:10025, the port the platform's frpc proxy forwards to. Two things had to be turned off for that service rather than left at their defaults. mynetworks trusts loopback, and everything through the tunnel arrives from loopback, so without emptying it this port would relay to any destination for anyone who reached it. There is a test that it refuses. The milters had to go as well, and this is the one that would have been quiet. opendkim runs in sign and verify mode with 127.0.0.1 in TrustedHosts, so it classifies tunnel traffic as internal: it would have signed mail from the whole internet with this device's key instead of verifying it, and forged mail would have arrived looking DKIM authenticated as the user's own domain. rspamd does its own verification when it lands, so nothing is lost by dropping them here. Tests cover delivery to a local mailbox, the port staying on loopback, the relay refusal, and that a delivered message carries no signature of ours.
run_ssh wraps the command in double quotes, so the double quotes inside the python sent over the heredoc were stripped before python ever saw it and the first tunnel test died on a syntax error. The run stops at the first failure, so the other two had never run.
Buster has no python3, so driving the tunnel with smtplib only ever worked on bookworm. Bash opens the socket itself, which is available on both.
Platform held the port the mail app listens on, so it knew an internal detail of another snap and opened an smtp proxy on every relayed device whether or not mail was installed. The app registers its socket on install and refresh, and platform forwards there and only adds the proxy once something has registered. Postfix takes the tunnel on a unix socket rather than a loopback port, so the listener is reachable through the filesystem instead of by anything local that can open a connection.
The tunnel listens on a unix socket now, which the shell cannot open on its own and buster has no python for, so the tests were reaching for socat and an apt install. The mail snap ships php, which speaks unix sockets and is there on both distros by definition. run_ssh wraps the command in double quotes, so the script is escaped once and passed through a heredoc rather than fighting nested quoting.
The app registers its socket on install, but the platform it installs onto is whatever is released, so a 404 means that platform predates the endpoint rather than that anything is wrong. The snap installs and simply has no tunnel. The cli build runs its tests now, which is where the three cases live.
Postfix refuses commands that arrive before it has answered unless it has advertised pipelining and the client is authorised to use it, so firing the whole conversation at once got 554 protocol synchronization. The exchange is lock step now, with the message body the one part written without a read in between.
It read the ini straight out of the snap, where date.timezone is still
{{ .Timezone }}, so every cli run warned and fell back to utc. The rendered one
lives beside the php-fpm config the service already uses; the path is derived
so the wrapper works outside a snap environment too, which is how the tests
reach it.
Arguments are quoted now so ones with spaces survive.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Mail app side of inbound mail. Completes the chain with syncloud/redirect#63
(terminates port 25, forwards down the tunnel) and syncloud/platform#762
(asks frps for the proxy that carries it).
redirect forwards each message down the frp tunnel, which arrives at the
device on loopback. Postfix needs somewhere to put it that is not the port it
already offers the internet, so this adds an smtpd on
127.0.0.1:10025— theport the platform's frpc proxy forwards to.
Two defaults that had to be turned off
mynetworks trusts loopback, and everything through the tunnel arrives from
loopback. Left alone, this port would relay to any destination for anyone who
reached it. Emptied for this service, with a test that it refuses.
The milters had to go too, and this is the one that would have been quiet.
opendkim runs
Mode svwith127.0.0.1inTrustedHosts, so it classifiestunnel traffic as internal. It would have signed mail from the whole
internet with this device's key instead of verifying it, and forged mail would
have landed in the user's mailbox looking DKIM-authenticated as their own
domain. rspamd does its own verification when it lands, so nothing is lost by
dropping them here.
Tests
Delivery to a local mailbox through the tunnel port, the port staying on
loopback rather than facing the internet, the relay refusal, and that a
delivered message carries no signature of ours.
Not covered here
rspamd and redis are not packaged yet, so inbound mail is unfiltered: nothing
scans it, and there is no Junk folder to file it into. dovecot sieve is not
enabled either. That is the larger piece of work and wants its own branch —
this one is the part that makes the tunnel deliver at all.
Port 10025 is the contract with the platform side; it appears there as
config.MailInboundPort.