(c) Jiri Svitak, 2026 All rights reserved.
Created for learning purposes.
Start the local Dovecot IMAP server (since v 2.4 listening on port 31143):
docker compose upUse NetCat, if available:
printf "a login user pass\na select inbox\na fetch 1 body[]\n" | nc localhost 31143Or use telnet, if available. (On Windows: Control Panel > Programs > Turn Windows features on or off > Check Telnet Client > Ok)
telnet localhost 31143In the cmd it worked.
Example IMAP commands:
a login test@example.com password
a list "" "*"
a select inbox
a fetch 1 body[]
a logout
To create an email using filesystem, create the folder mail/test@example.com/new and there a file msg1 with content:
From: spam@test.com
To: test@example.com
Subject: Cheap pills
Buy cheap pills now!
For example (using Telnet):
a fetch 1 body[]
* 1 FETCH (FLAGS (\Seen \Recent) BODY[] {87}
From: spam@test.com
To: test@example.com
Subject: Cheap pills
Buy cheap pills now!)
a OK Fetch completed (0.053 + 6.062 + 0.052 secs).
Or use Netcat:
ncat localhost 1143Use Wireshark to analyze the IMAP traffic (additional installation of the npcap library may be required on Windows):
tcp.port == 31143
The proxy loads spam sender addresses from config.yaml in the project root:
spam_senders:
- spam@test.com
- scam@test.comIf the From header matches any configured address, the proxy injects X-Spam-Flag: Yes into rewritten IMAP FETCH responses.
The proxy defaults to listening on :1143 and forwarding to localhost:31143.
You can override that with command line flags:
go run ./cmd/proxy --server 0.0.0.0 --port 1143 --proxy-host localhost --proxy-port 31143 --config config.yamlTo connect to a public IMAP server that only supports implicit TLS on port 993:
go run ./cmd/proxy --proxy-host imap.example.com --proxy-port 993 --proxy-tls --config config.yamlAdditional TLS-related flags for the upstream server:
--proxy-tls
Use implicit TLS when connecting to the upstream IMAP server
--proxy-tls-skip-verify
Skip upstream certificate verification, useful only for local debugging
--proxy-tls-server-name
Override the TLS server name used for SNI and certificate validation
@startuml
!theme plain
node "Client Machine" {
artifact "Mail Client" as Client
}
node "Proxy Server" {
artifact "IMAP Proxy\n(Spam Filter)" as Proxy
}
node "Mail Server" {
artifact "IMAP Server" as Server
}
Client - Proxy : IMAP (TCP 1143)
Proxy - Server : IMAP (TCP 31143)
@enduml