title: Some exposed Docker ports are not accessible from outside (dovecot, postfix)
body: <p>this is driving me nuts, but for some reason, I cannot access certain ports from outside. I've checked almost every possible setting, but I have no idea why this is not working. I have no idea where to fix this issue (Ubuntu firewall vs. Docker vs. Dovecot vs. Postfix) and I'm really hoping that you guys can help me.</p>
  
  <p><strong>FYI: mycooldomain.com is just a placeholder for my domain which I don't want to share at the moment.</strong></p>
  
  <p><strong>I'll buy a beer for the one who helps me fixing this! :)</strong></p>
  
  <p><strong>Short intro</strong></p>
  
  <p>On my root server, I'm running the following docker mail server container (<a href="https://github.com/tomav/docker-mailserver/" rel="noreferrer">https://github.com/tomav/docker-mailserver/</a>) which exposes several ports (143, 25, 587, 993). The container runs dovecot (IMAP) and postfix (SMTP).</p>
  
  <p><strong>tl;dr</strong></p>
  
  <p>I have the aforementioned mail server (dovecot, postfix) running in a docker container and can only connect to one port (143 - IMAP). Other ports 25, 587 and 993 are not accessible from outside - only from the host directly. Docker exposes them correctly and they are listed in the iptables correctly. The logs in the container (dovecot, postfix) don't show any reaction when requests come in (no rejected request or something like that), so I suppose they never reach the service in the container. Other docker container ports (e.g. my web server: 80, 443).</p>
  
  <p><strong>Here's the detailed information:</strong></p>
  
  <p>I can connect to every port from the host directly (let's test the IMAP secure port):</p>
  
  <pre><code>mastix@localhost:~$ telnet mail.mycooldomain.com 993
  Trying xxx.xxx.xxx.xxx…
  Connected to mail.mycooldomain.com.
  Escape character is '^]'.
  220 mail.mycooldomain.com ESMTP Postfix (Ubuntu)
  </code></pre>
  
  <p>But not from my local machine:</p>
  
  <pre><code>mastixmc$ telnet mail.mycooldomain.com 993
  Trying xxx.xxx.xxx.xxx…
  telnet:connect to address xxx.xxx.xxx.xxx: Operation timed out
  telnet: Unable to connect to remote host
  </code></pre>
  
  <p><code>docker-compose ps</code> shows me that they are <strong>exposed</strong> and <strong>bound</strong> correctly:</p>
  
  <pre><code>110/tcp,
  0.0.0.0:143-143/tcp,
  0.0.0.0:25-&gt;25/tcp, 4190/tcp,     
  0.0.0.0:587-&gt;587/tcp,             
  0.0.0.0:993-&gt;993/tcp, 995/tcp
  </code></pre>
  
  <p><code>netstat -ntlp</code> tells me the same:</p>
  
  <pre><code>Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
  tcp6       0      0 :::587                  :::*                    LISTEN      -
  tcp6       0      0 :::143                  :::*                    LISTEN      -
  tcp6       0      0 :::80                   :::*                    LISTEN      -
  tcp6       0      0 :::25                   :::*                    LISTEN      -
  tcp6       0      0 :::443                  :::*                    LISTEN      -
  tcp6       0      0 :::2332                 :::*                    LISTEN      -
  tcp6       0      0 :::993                  :::*                    LISTEN      -
  </code></pre>
  
  <p>I can access my web server (80/443) and unsecure IMAP (143) - which I will not allow in the future. But all other ports are not accessible.</p>
  
  <p>I even set up UFW (although that's not needed) to make sure that Ubuntu doesn't block anything:</p>
  
  <pre><code>Added user rules (see 'ufw status' for running firewall):
  ufw allow 80/tcp
  ufw allow 443/tcp
  ufw allow 25/tcp
  ufw allow 587/tcp
  ufw allow 143/tcp
  ufw allow 993/tcp
  </code></pre>
  
  <p>When looking at the logs (Dovecot, Postfix) I don't see any information, so it looks like the request does not reach the services.</p>
  
  <p>I <strong>DID NOT</strong> touch the following Docker/UFW settings:</p>
  
  <p>/etc/default/ufw</p>
  
  <pre><code>DEFAULT_FORWARD_POLICY="DROP"
  </code></pre>
  
  <p>And <strong>DID NOT</strong> change <code>iptables = false</code> in the docker engine.</p>
  
  <p>Here's the iptables -L call, where you can clearly see that the DOCKER chain adds the rules correctly (also my ufw rules are there):</p>
  
  <pre><code>Chain INPUT (policy ACCEPT)
  target     prot opt source               destination
  ufw-before-logging-input  all  --  anywhere             anywhere
  ufw-before-input  all  --  anywhere             anywhere
  ufw-after-input  all  --  anywhere             anywhere
  ufw-after-logging-input  all  --  anywhere             anywhere
  ufw-reject-input  all  --  anywhere             anywhere
  ufw-track-input  all  --  anywhere             anywhere
  
  Chain FORWARD (policy DROP)
  target     prot opt source               destination
  DOCKER-ISOLATION  all  --  anywhere             anywhere
  DOCKER     all  --  anywhere             anywhere
  ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
  ACCEPT     all  --  anywhere             anywhere
  ACCEPT     all  --  anywhere             anywhere
  DOCKER     all  --  anywhere             anywhere
  ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
  ACCEPT     all  --  anywhere             anywhere
  ACCEPT     all  --  anywhere             anywhere
  DOCKER     all  --  anywhere             anywhere
  ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
  ACCEPT     all  --  anywhere             anywhere
  ACCEPT     all  --  anywhere             anywhere
  ufw-before-logging-forward  all  --  anywhere             anywhere
  ufw-before-forward  all  --  anywhere             anywhere
  ufw-after-forward  all  --  anywhere             anywhere
  ufw-after-logging-forward  all  --  anywhere             anywhere
  ufw-reject-forward  all  --  anywhere             anywhere
  ufw-track-forward  all  --  anywhere             anywhere
  
  Chain OUTPUT (policy ACCEPT)
  target     prot opt source               destination
  ufw-before-logging-output  all  --  anywhere             anywhere
  ufw-before-output  all  --  anywhere             anywhere
  ufw-after-output  all  --  anywhere             anywhere
  ufw-after-logging-output  all  --  anywhere             anywhere
  ufw-reject-output  all  --  anywhere             anywhere
  ufw-track-output  all  --  anywhere             anywhere
  
  Chain DOCKER (3 references)
  target     prot opt source               destination
  ACCEPT     tcp  --  anywhere             172.19.0.3           tcp dpt:https
  ACCEPT     tcp  --  anywhere             172.19.0.3           tcp dpt:http
  ACCEPT     tcp  --  anywhere             172.19.0.7           tcp dpt:imaps
  ACCEPT     tcp  --  anywhere             172.19.0.7           tcp dpt:submission
  ACCEPT     tcp  --  anywhere             172.19.0.7           tcp dpt:imap2
  ACCEPT     tcp  --  anywhere             172.19.0.7           tcp dpt:smtp
  
  Chain DOCKER-ISOLATION (1 references)
  target     prot opt source               destination
  DROP       all  --  anywhere             anywhere
  DROP       all  --  anywhere             anywhere
  DROP       all  --  anywhere             anywhere
  DROP       all  --  anywhere             anywhere
  DROP       all  --  anywhere             anywhere
  DROP       all  --  anywhere             anywhere
  RETURN     all  --  anywhere             anywhere
  [...]
  Chain ufw-user-input (1 references)
  target     prot opt source               destination
  ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:imaps
  ACCEPT     udp  --  anywhere             anywhere             udp dpt:imaps
  ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:2332
  ACCEPT     udp  --  anywhere             anywhere             udp dpt:2332
  ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
  ACCEPT     udp  --  anywhere             anywhere             udp dpt:http
  ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:https
  ACCEPT     udp  --  anywhere             anywhere             udp dpt:https
  ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:submission
  ACCEPT     udp  --  anywhere             anywhere             udp dpt:submission
  ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
  ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:imap2
  ACCEPT     udp  --  anywhere             anywhere             udp dpt:imap2
  </code></pre>
  
  <p>So everything looks correct to me.</p>
  
  <p><strong>Update #1:</strong></p>
  
  <p>nmap from docker host (against mycooldomain.com):</p>
  
  <pre><code>PORT    STATE    SERVICE
  25/tcp  filtered smtp
  80/tcp  filtered http
  143/tcp filtered imap
  443/tcp filtered https
  587/tcp filtered submission
  993/tcp filtered imaps
  </code></pre>
  
  <p>nmap from my local machine (against mycooldomain.com):</p>
  
  <pre><code>PORT    STATE SERVICE
  80/tcp  open  http
  143/tcp open  imap
  443/tcp open  https
  </code></pre>
  
  <p>As you can see the ports are not open, therefore I can't connect from remote to the ports 25, 587 and 993.</p>
  
  <p><strong>UPDATE #2:</strong></p>
  
  <p>So I've stopped all containers and openend a simple python HTTP server:</p>
  
  <pre><code>sudo python -m SimpleHTTPServer 993
  </code></pre>
  
  <p>Also can't access this port. So I opened the same server with port 8080 => success.</p>
  
  <p><strong>It looks like either Ubuntu or my hoster is blocking port 993! I'm currently in contact with the one who provides the root server.</strong></p>
  
  <p>I already filed an issue in the project itself (<a href="https://github.com/tomav/docker-mailserver/issues/602" rel="noreferrer">https://github.com/tomav/docker-mailserver/issues/602</a>), but they couldn't help me either.</p>
  
  <p>Thank you very much in advance,</p>
  
  <p>Greetz,</p>
  
  <p>Sascha</p>