Tutorial for publishing Mailcow behind Traefik V3 using full TCP passthrough.
Overview Link to heading
In this setup, Traefik only acts as a TCP forwarder. It does not terminate TLS or alter the traffic of the mail services. This is important to keep compatibility with SMTP, SMTPS, IMAP, IMAPS, and Sieve.
Mailcow remains responsible for certificates, internal services, and authentication logic. Traefik only exposes the ports and forwards the connections to the correct backend.
When to use full passthrough Link to heading
Use this model when:
-
you want Mailcow to keep control of the TLS certificates;
-
you need to expose mail services without application-layer inspection;
-
you want to avoid TLS negotiation issues in protocols such as SMTP and IMAP;
-
you want a simple TCP routing layer at the edge.
Prerequisites Link to heading
Before you begin, make sure you already have:
-
Traefik V3 running;
-
Mailcow installed and reachable on the internal network;
-
DNS pointing to the correct public IP;
-
The required ports open in the firewall;
-
An alternate port plan if Traefik is running in LXC.
Edge router port forwarding Link to heading
On the edge router, forward the required external ports to the Traefik host as follows:
80->80443->443110->110143->143465->465587->587993->993995->99525->2525
Keep the SMTP inbound exception on 2525 if port 25 is not available directly on the Traefik host, especially in LXC or other constrained environments.
If you run Traefik in Docker, you can publish the SMTP port like this:
1ports:
2 - "2525:25"
This keeps the external SMTP entry on 2525 while forwarding it to container port 25.
Certificate generation with DNS-01 Link to heading
Because ports 80 and 443 are reserved for Traefik on the edge, Mailcow cannot complete the usual HTTP-01 validation path directly on its own host. In this setup, Mailcow must request certificates with DNS-01 instead of HTTP-01.
Follow the Mailcow DNS-01 documentation here: mailcow DNS-01 SSL guide.
The usual flow is:
- Enable DNS-01 in
mailcow.conf. - Configure the DNS provider credentials in
data/conf/acme/dns-01.conf. - Restart the
acme-mailcowcontainer. - Verify the certificate request in the logs.
With DNS-01, Mailcow validates ownership through DNS TXT records, so it does not need direct public access to port 80 for certificate issuance.
Traefik static configuration Link to heading
Below is the static configuration with the TCP ports needed for Mailcow:
1entryPoints:
2 smtp-in:
3 address: "[::]:2525"
4 http:
5 address: "[::]:80"
6 pop3:
7 address: "[::]:110"
8 imap:
9 address: "[::]:143"
10 https:
11 address: "[::]:443"
12 smtps:
13 address: "[::]:465"
14 smtp:
15 address: "[::]:587"
16 imaps:
17 address: "[::]:993"
18 pop3s:
19 address: "[::]:995"
20 sieve:
21 address: "[::]:4190"
Traefik dynamic configuration Link to heading
The dynamic configuration below defines the TCP routers and services for Mailcow. For HTTPS certificate passthrough, the mailcow-https router must be a TCP router. A normal HTTP router would terminate TLS at the application layer, which breaks passthrough.
The https entryPoint is used for the Mailcow web interface and certificate passthrough. The http entryPoint can be kept for plain HTTP handling or redirects if you want to add them later.
1tcp:
2 routers:
3 smtp-in:
4 entryPoints:
5 - smtp-in
6 rule: "HostSNI(`*`)"
7 service: smtp-in
8 tls:
9 passthrough: true
10 domains:
11 - main: mail.domain.com
12 sans: []
13
14 pop3:
15 entryPoints:
16 - pop3
17 rule: "HostSNI(`*`)"
18 service: pop3
19 tls:
20 passthrough: true
21 domains:
22 - main: mail.domain.com
23 sans: []
24
25 imap:
26 entryPoints:
27 - imap
28 rule: "HostSNI(`*`)"
29 service: imap
30 tls:
31 passthrough: true
32 domains:
33 - main: mail.domain.com
34 sans: []
35
36 mailcow-https:
37 entryPoints:
38 - https
39 rule: "HostSNI(`mail.domain.com`) || HostSNI(`autoconfig.domain.com`) || HostSNI(`autodiscover.domain.com`)"
40 service: mailcow-https
41 tls:
42 passthrough: true
43
44 smtps:
45 entryPoints:
46 - smtps
47 rule: "HostSNI(`*`)"
48 service: smtps
49 tls:
50 passthrough: true
51 domains:
52 - main: mail.domain.com
53 sans: []
54
55 smtp:
56 entryPoints:
57 - smtp
58 rule: "HostSNI(`*`)"
59 service: smtp
60 tls:
61 passthrough: true
62 domains:
63 - main: mail.domain.com
64 sans: []
65
66 imaps:
67 entryPoints:
68 - imaps
69 rule: "HostSNI(`*`)"
70 service: imaps
71 tls:
72 passthrough: true
73 domains:
74 - main: mail.domain.com
75 sans: []
76
77 pop3s:
78 entryPoints:
79 - pop3s
80 rule: "HostSNI(`*`)"
81 service: pop3s
82 tls:
83 passthrough: true
84 domains:
85 - main: mail.domain.com
86 sans: []
87
88 sieve:
89 entryPoints:
90 - sieve
91 rule: "HostSNI(`*`)"
92 service: sieve
93 tls:
94 passthrough: true
95 domains:
96 - main: mail.domain.com
97 sans: []
98
99services:
100 smtp-in:
101 loadBalancer:
102 servers:
103 - address: "mailcow-ip:25"
104
105 pop3:
106 loadBalancer:
107 servers:
108 - address: "mailcow-ip:110"
109
110 imap:
111 loadBalancer:
112 servers:
113 - address: "mailcow-ip:143"
114
115 mailcow-https:
116 loadBalancer:
117 servers:
118 - address: "mailcow-ip:443"
119
120 smtps:
121 loadBalancer:
122 servers:
123 - address: "mailcow-ip:465"
124
125 smtp:
126 loadBalancer:
127 servers:
128 - address: "mailcow-ip:587"
129
130 imaps:
131 loadBalancer:
132 servers:
133 - address: "mailcow-ip:993"
134
135 pop3s:
136 loadBalancer:
137 servers:
138 - address: "mailcow-ip:995"
139
140 sieve:
141 loadBalancer:
142 servers:
143 - address: "mailcow-ip:4190"
What each port does Link to heading
25: SMTP inbound on Mailcow, reached through the Traefiksmtp-inentryPoint.2525: alternative for inbound SMTP traffic when you do not want to use port 25.80: HTTP entryPoint on Traefik.443: HTTPS entryPoint on Traefik.110: POP3.995: POP3S.587: authenticated mail submission.465: SMTPS.143: IMAP over plaintext or STARTTLS.993: IMAPS.4190: Sieve.
Important note about port 25 Link to heading
If you run Traefik in LXC, it is common to replace port 25 with another port, such as 2525, because of network limitations, NAT, permissions, or a conflict with the host.
In that case, expose inbound SMTP on another port in Traefik and adjust the external forwarding if needed.
Best practices Link to heading
- Do not terminate TLS in Traefik for these services if the goal is full passthrough.
- Make sure Mailcow is listening on the correct internal ports.
- Test each protocol separately: SMTP, SMTPS, IMAP, IMAPS, and Sieve.
- Verify that the firewall allows the ports exposed by Traefik.
- In LXC environments, validate port publishing before going to production.
Summary Link to heading
With full passthrough, Traefik V3 works as a TCP transport layer for Mailcow without interfering with the TLS used by the mail services. This simplifies routing and reduces compatibility issues, especially in LXC environments or setups with port restrictions.