I’ve seen a lot of questions asked on some places, how to send SMTP traffic over proxies. Noone – as usual has given a proper answer on this really specific problem. Let me explain.
- I do have a mailserver, but it is blocked to use SMTP ports. This mailserver is postfix.
- I also do have access to a squid-proxy.
- Now, I want to send e-mail over this squid proxy. Can this be done.
- Now, all questions are just returned with the answer ”Nope, squid is a http/https proxy. No can do!”
I beg to differ. You can send SMTP traffic over a SQUID proxy. You just have to tweak the sending and ports. First of all; we know that squid proxies requires a handshake that very much looks like this:
CONNECT remote.http.server:80 HTTP/1.0
With this done, the SQUID proxy replies like this:
HTTP/1.1 200 Connection established
While playing with the postfix settings, it turns out that postfix ignores that response. So instead, you could just connect to a SMTP-server instead. If the squid proxy is not controlled by you, however, this connectivity will fail on SMTP ports. So this solution is based on the fact that your real SMTP relay server should answer at port 80 or 443, as it was a web service itself.
For several years ago, I configured a postfix to answer on those ports, since port 25 and 587 locally was usually blocked. To make sure I have a relay that can handle the mail service, I therefore configured a VPS specifically to use the default webports to receive e-mail. When received, this postfix service will then make sure that the mail are delivered properly.
So, where does the squid service come in?
Well, I’ve seen a lot of recommendations that includes installations of complex crappy application that needs to be configured to death. I was thinking if this could be handled easier, by for example netcat. A little experimenting I figured out, that the only thing required for this to work was to put up a simple script that handles the proxy link and a inetd-kind-of service. But for systemd. It very much looks like this:
#!/bin/bash cat <(echo "CONNECT SMTP.SERVER.IP:443 HTTP/1.0"; echo "") -|nc squid.server.host 3128
This little nifty script makes sure we connect to the squid proxy. When connected, it sends the command to the SQUID proxy, necessary to make squid reconnect to the real server. As it probably blocks the regular ports, but allows http/https-traffic, squid will now open a connection to the real server.
With this knowledge, I now need a local service that handles postfix relay connections as it was a real SMTP relay that it connects to, since postfix does not handle proxies. For this example, I’ve been using port 1588 (instead 587). With help from https://mgdm.net/weblog/systemd-socket-activation/ i managed to do the following:
[Unit] Description=ProxySMTP Socket [Socket] ListenStream=1588 Accept=yes [Install] WantedBy=sockets.target
[Unit] Description=SMTP Requires=proxysmtp.socket [Service] ExecStart=-/usr/local/sbin/smtp.sh StandardInput=socket DynamicUser=yes ProtectHome=true PrivateUsers=true [Install] WantedBy=multi-user.target
Some things that has been pointed out at the site I got inspired from is to take not one the @ in the filename. This is significant as it indicates the service is a template and that a new instance of the service will be run on every connection.
With all this in place, it is time to enable the service and test it. This is done in following steps:
- systemctl daemon-reload
- systemctl enable proxysmtp
- systemctl start proxysmtp.socket
- systemctl enable proxysmtp.socket
When testing this solution, I will now get the following response when trying to connect to port 1588 as configured above:
my-server:~$ telnet localhost 1588 Trying localhost... Connected to localhost. Escape character is '^]'. HTTP/1.1 200 Connection established 220 my-smtp-server ESMTP Postfix
This is something that is apparently perfectly supported by postfix, so now we’ve configured SMTP-Over-Proxy with very low effort and very high efficiency.