User Tools

Site Tools

Trace: Simple POP3 Proxy

Simple POP3 Proxy

Let's set up a POP3 -> POP3S proxy as simple and efficient as it can get!

The Challenge

Time goes on, some internet protocols come and go. One such going protocol is Post Office Protocol version 3 (POP3) over a plain text connection. It's replacement is doing the same over a TLS-encrypted connection, known as POP3S.

No problem for modern, regularly updated systems. Not so simple for this vintage computing email client, which was born long before TLS v1.3 even existed.

Vintage client in this case is Apple Mail v2.1.3 on Mac OS X 10.4.10 “Tiger”.

Solution Strategy

Good news is, POP3S is unchanged, regular POP3, tunneled over a TLS-encrypted connection. And nothing demands doing this tunneling right in the email client, or even on the same computer. Tunneling can happen elsewhere, e.g. on the next gateway. Then the email client gets instructed to not connect to the POP server directly, but to that gateway. Voilá, the email client sees a POP3 server, while the email server out there sees a POP3S connection incoming. Everybody happy.

Before
  email client <--(unencrypted)--> email server
After
  email client <--(unencrypted)--> gateway <--(TLS v1.3)--> email server

As the gateway (hopefully) runs up to date software, it happily deals with the most recent encryption protocol, while the vintage email client barely notices a change.

Test Run

Before hacking away, it's always a good idea to prove the concept.

In case the following gives something like 'command not found', see Installing Required Packages below.

Unencrypted

As with most traditional internet protocols, one can connect to a POP3 server manually by using telnet. Like this, with “mail.example.com” replaced by the actual server name, of course:

$ telnet mail.example.com 110
Trying xxx.xxx.xxx.xxx...
Connected to mail.example.com.
Escape character is '^]'.
+OK Greetings from your mailserver.

That's it, already connected. Let's try to log in and receive mail (type the first line with your actual account, hit Enter):

USER <account>
-ERR [AUTH] Plaintext authentication disallowed on non-secure (SSL/TLS) connections.

D'oh! Before encryption was mandatory, one could send commands here to log in, to list, download and delete emails. These days, a server requests encryption before sending anything meaningful (which leads to POP3 with STARTTLS, an alternative to POP3S). Accordingly, we simply say bye bye:

QUIT
+OK Logging out
Connection closed by foreign host.
$

Encrypted

Doing this in an encrypted fashion is almost the same, just a different command:

$ openssl s_client -connect mail.example.com:995 -quiet -verify_quiet
+OK Greetings from your mailserver.

This time we can log in and access emails:

USER <account>
+OK
PASS <password>
+OK Logged in.
LIST
+OK 20 messages:
1 24601
2 3390
3 640891
[...]
.
QUIT 
+OK Logging out.
$

For more details, see Testing a POP3 server via telnet or OpenSSL by yiming. Thank you very much, yiming, this blog post was helpful.

Implementation

One implementation would be to run this command all the time, listening on port 110. This would require writing a startup script.

Another solution is to use xinetd, which starts a server on demand. This way is actually a bit more straightforward.

Installing Required Packages

On Debian/Ubuntu, installation of xinetd and openssl goes like this:

sudo apt-get install --no-install-recommends xinetd openssl

On OpenWRT, it's similar, with CA certificates being in a separate package:

opkg install xinetd openssl-util ca-certificates

Using the graphical package manager (Menu -> System -> Software) works as well.

Versions at the time of this writing:

Ubuntu OpenWRT OpenWRT
System 18.10 18.06.1 18.06.4
xinetd 2.3.15.3 2.3.15 2.3.15-5
openssl 1.1.1b 1.0.2q 1.0.2s-1
ca-certificate - - 20180409-2 20190110-1

xinetd Instructions

xinetd needs instructions on what to run, of course. This is achieved by creating a file /etc/xinetd.d/pop2pops with the following content:

#
# Description:
# A service tunneling POP3 requests to mail.example.com via TLS, making
# it a POP3S connection. Purpose is to allow old email clients not supporting
# modern TLS to mail servers requiring it.
#
service pop2pops
{
  type            = UNLISTED
  flags           = NORETRY
  socket_type     = stream
  protocol        = tcp
  wait            = no
  user            = nobody
  instances       = 10
  server          = /usr/bin/openssl
  server_args     = s_client -connect mail.example.com:995 -quiet -verify_quiet
  port            = 110
#  log_type        = FILE /var/log/pop2pops.log
#  log_on_success  = PID HOST USERID DURATION
#  log_on_failure  = HOST USERID
}

These three commented out lines would create a log file, logging how long each connection lasted. It's probably a good idea to do this for verifying the setup or debugging, after that it isn't needed and just wastes disk space.

The file needs no execute permissions. It's the same file in the same location on Debian/Ubuntu and on OpenWRT.

Starting the Service

Last step on the gateway is to start the new service by restarting xinetd. On Debian/Ubuntu as well as on OpenWRT, that's:

sudo service xinetd restart

sudo only if needed, of course. Alternatively, one can use OpenWRT's GUI (Menu -> System -> Startup).

Changes to the Email Client

Configure the mail client as usual, but enter the proxy's address as the email server address. Configure the port used in line port in the Xinetd script (which isn't necessarily port 110). Turn SSL off. Username and password as if connected to the mail server directly.

That's it, enjoy!

Debugging

In case the client still reports connection errors, one can try to connect manually. Using telnet (without TLS), to the gateway (not the actual mail server). Command see point Unencrypted in section Test Run above, while results should match these in point Encrypted in the same section:

$ telnet gate.jump-ing.de 110
Trying 10.0.0.1...
Connected to gate.jump-ing.de.
Escape character is '^]'.
+OK Greetings from your mailserver.
USER <account>
+OK
[...]

Email clients like Apple Mail report failure as soon an there's the word error in one of the server messages.

Multiple Servers

Connecting to multiple mail servers requires setting up one xinetd service for each server. As a matter of luck, it doesn't really matter on which port this service is listening, as long as it doesn't conflict with another service in the same network. Conveniently, ports 89..109 are unused by popular services, so using these is just fine.

To duplicate a service,

  • duplicate the file and give it a distinct name,
  • change the line with port to listen on a unique port,
  • change the line with server_args to connect to the other server and
  • restart xinetd service.

That's it, just don't forget to configure your email client to use this unusual port.

If this still isn't sufficient, it's time to watch out for a more universal solution, like Perdition.

simple_pop3_proxy.txt · Last modified: 2022/04/27 01:03 by Traumflug