<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Every port hMailServer listens on or connects to, and the firewall rules to match]]></title><description><![CDATA[<p dir="auto"><em>Written for 6.3.4. hMailServer 6.3.7 (17 October 2026) lets the IMAP and POP3 listeners take the client's address from a PROXY protocol header, as the SMTP listener does, each from the peers on a list of its own; both are off by default, and in the Control Panel the PROXY protocol and XCLIENT are a card on Incoming relays, while API &amp; monitoring is Monitoring &amp; alerts. The ACME http-01 challenge responder serves up to 64 connections at once and closes one past that, where it served one at a time. The REST listener refuses a state-changing request that carries a credential when the browser reports it as cross-site (<code>Sec-Fetch-Site</code>, or an <code>Origin</code> that is not this server's); scripts, <code>hmctl</code> and the PowerShell module send no such header and are unaffected. 6.3.7's container image is <code>registry.gitlab.com/hmailserver/hmailserver:6.3.7</code>. See <a href="/topic/28277">the 6.3.7 announcement</a>. hMailServer 6.3.8 (2 November 2026) has the web services listener close a connection, with no answer and before the TLS handshake, from an address whose IP range allows none of SMTP, POP3 and IMAP - an auto-ban's, or one of your own that allows nothing - while loopback and the addresses in <code>WebServicesTrustedProxies</code> are never refused by a range; so a range of your own that allows some addresses nothing now closes this listener to them as well, and with it ACME's http-01 validation when this listener answers it, MTA-STS, CalDAV, CardDAV, Autodiscover, autoconfiguration and the Web Key Directory: check that the certificate authority, the sending MTAs and these services' clients do not come from one. 6.3.8's container image is <code>registry.gitlab.com/hmailserver/hmailserver:6.3.8</code>, also tagged <code>6.3</code> and <code>latest</code>. See <a href="/topic/28278">the 6.3.8 announcement</a>.</em></p>
<p dir="auto">This topic lists every socket hMailServer 6.3.4 can open, inbound and outbound, and the firewall rules that follow. The one thing to know first: <strong>a new server listens on four mail ports and on nothing else.</strong> Every other listener is off until a setting gives it a port, three of them bind only to <code>127.0.0.1</code> when you do, and almost every outbound connection beyond DNS, SMTP delivery and the recipient's MTA-STS policy exists because an administrator turned a feature on. Write the firewall for what you turned on.</p>
<p dir="auto">Connection security per mail port, and what a new 6.3.4 installation sets on each, is in <a href="/topic/28255">Connecting a mail client: IMAP, POP3, SMTP submission and the ports</a>.</p>
<h3><a class="anchor-offset" name="two-kinds-of-listener-set-in-two-places"></a>Two kinds of listener, set in two places</h3>
<p dir="auto"><strong>Mail-protocol listeners</strong> (SMTP, POP3, IMAP) are rows of the table <code>hm_tcpipports</code>, edited on <strong>Connections &amp; protocols → TCP/IP ports</strong> in the Control Panel (Windows), on the Control Deck, over COM (<code>Settings.TCPIPPorts</code>, Windows) and over REST at <code>/api/v1/ports</code>, where a new row's <code>address</code> defaults to <code>0.0.0.0</code>. A port you add, change or delete takes effect at a reinitialise (<code>POST /api/v1/server/reinitialize</code>, or the Deck's button that restarts the services in place) or a service restart.</p>
<p dir="auto"><strong>Service listeners</strong> are one key each, all off by default. Set their <code>[Settings]</code> keys in the Control Panel (Windows), over REST (<code>PUT /api/v1/settings/ini/{name}</code>), with <code>hmctl ini set</code> or <code>hmailserver --set-setting NAME=VALUE</code>; the Deck has no page for them. Since 6.3.4 the database holds these keys, so a line edited in <code>hMailServer.ini</code> turns no listener on (<code>HM5804</code>); <a href="/topic/28222">Settings: what is not stock, when a save takes effect</a> explains the store. Each listener's port, bind address and certificate files are among the 28 keys that wait for a reinitialise: <strong>Apply now</strong> in the Control Panel or the Deck, <code>POST /api/v1/server/reinitialize</code>, <code>Application.Reinitialize</code> over COM, or a restart. <code>AcmeHttpPort</code> applies when it is saved. The SNMP agent's settings are <code>hm_settings</code> rows instead, set on the Deck's <strong>Settings</strong> page under <strong>Server</strong>, over REST (<code>/api/v1/settings</code>) or with <code>hmctl settings set</code>, with no Control Panel page, and read when the agent starts, at a service start or a Reinitialize.</p>
<h3><a class="anchor-offset" name="the-mail-listeners"></a>The mail listeners</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Port</th>
<th>Protocol</th>
<th>Created by</th>
<th>Default bind</th>
<th>What it says on connect</th>
</tr>
</thead>
<tbody>
<tr>
<td>25</td>
<td>SMTP</td>
<td>Seeded in every new database</td>
<td>The row's IP address (<code>0.0.0.0</code> or <code>::</code> is every address)</td>
<td><code>220 MAIL01 ESMTP</code>: the <em>Welcome banner</em> from <strong>Connections &amp; protocols → Protocols → SMTP</strong>, or the computer name, with <code> ESMTP</code> appended</td>
</tr>
<tr>
<td>587</td>
<td>SMTP submission</td>
<td>Seeded</td>
<td>The row's IP address</td>
<td>The same banner</td>
</tr>
<tr>
<td>110</td>
<td>POP3</td>
<td>Seeded</td>
<td>The row's IP address</td>
<td><code>+OK POP3</code>, or your welcome message</td>
</tr>
<tr>
<td>143</td>
<td>IMAP</td>
<td>Seeded</td>
<td>The row's IP address</td>
<td><code>* OK IMAPrev1</code>, or your welcome message</td>
</tr>
<tr>
<td>465, 993, 995</td>
<td>SMTP, IMAP, POP3 over implicit TLS</td>
<td>You, once you have a certificate</td>
<td>What you choose</td>
<td>Nothing until the TLS handshake completes</td>
</tr>
</tbody>
</table>
<p dir="auto">A listener bound to one internal address is the usual reason mail works from the LAN and not from outside. Two failures leave one port dead and the rest running: a TLS port with no certificate selected does not start (<code>HM5113</code>), and a port something else holds does not bind (<code>HM4316</code>). On Windows with WSL2 in mirrored networking mode, a socket bound inside WSL takes the port from Windows too, shows in neither <code>Get-NetTCPConnection</code> nor <code>netstat -ano</code>, and on the project's test bench only <code>wsl --shutdown</code> gave it back.</p>
<h3><a class="anchor-offset" name="the-service-listeners"></a>The service listeners</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Listener</th>
<th>Port key, default</th>
<th>Bind key, default</th>
<th>TLS</th>
<th>How to tell it is up</th>
</tr>
</thead>
<tbody>
<tr>
<td>REST API, the Control Deck at <code>/</code>, the webmail at <code>/portal</code>, SCIM at <code>/scim/v2</code> (since 6.3.4)</td>
<td><code>RestApiPort</code>, <code>0</code>; 8045 is the conventional port</td>
<td><code>RestApiBindAddress</code>, <code>127.0.0.1</code></td>
<td>Required unless bound to <code>127.0.0.1</code>, <code>localhost</code> or <code>::1</code></td>
<td><code>RestApi: Listening on &lt;endpoint&gt; (https)</code> or <code>(http, loopback only)</code> in the application log</td>
</tr>
<tr>
<td>Public web services</td>
<td><code>WebServicesHttpPort</code>, <code>WebServicesHttpsPort</code>, both <code>0</code>; 80 and 443 to enable</td>
<td><code>WebServicesBindAddress</code>, <code>0.0.0.0</code></td>
<td><code>WebServicesCertificateFile</code> and <code>WebServicesPrivateKeyFile</code> on the HTTPS port, or the ACME certificate on disk</td>
<td>A URL it serves answers</td>
</tr>
<tr>
<td>Prometheus metrics and health probes</td>
<td><code>MetricsServerPort</code>, <code>0</code></td>
<td><code>MetricsServerBindAddress</code>, <code>127.0.0.1</code>, an IP literal only</td>
<td><code>MetricsServerCertificateFile</code> + <code>MetricsServerPrivateKeyFile</code>; plain HTTP otherwise</td>
<td><code>/livez</code> answers <code>200 alive</code></td>
</tr>
<tr>
<td>ManageSieve (RFC 5804)</td>
<td><code>ManageSieveServerPort</code>, <code>0</code>; 4190 is the standard port</td>
<td><code>ManageSieveServerBindAddress</code>, <code>127.0.0.1</code></td>
<td>STARTTLS, only when an IMAP, POP3 or SMTP port has a certificate</td>
<td>Its capability response</td>
</tr>
<tr>
<td>ACME http-01 challenge</td>
<td><code>AcmeHttpPort</code>, <code>80</code></td>
<td>Every address</td>
<td>Never</td>
<td>Open only during an issuance</td>
</tr>
<tr>
<td>SNMP agent, UDP, since 6.3.4</td>
<td><code>SnmpPort</code>, <code>161</code>, with <code>SnmpEnabled</code> off</td>
<td><code>SnmpBindAddress</code>, empty = every address</td>
<td>SNMPv3 at authPriv instead of TLS</td>
<td>A stranger gets no answer at all</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>One port carries the REST API, the Deck and the webmail</strong>; there is no second port to open. It will not start without an administrator password, nor beyond loopback without a certificate, and with <code>RestApiCertificateFile</code> empty it takes the ACME certificate when one exists. For users to reach <code>/portal</code>, or an identity provider SCIM, it needs a certificate they trust, a reachable bind address and a firewall rule, or a TLS-terminating proxy in front (<a href="/topic/28240">Behind a gateway, load balancer or reverse proxy</a>). Turning it on is in <a href="/topic/28264">The REST API: turning it on, credentials, roles, one-time codes</a>.</p>
<p dir="auto"><strong>The web services listener binds every address by default.</strong> It serves the MTA-STS policy at <code>/.well-known/mta-sts.txt</code> (HTTPS only), ACME challenges, Thunderbird autoconfig, Outlook autodiscover and the Apple profile (HTTPS only), <code>security.txt</code>, CardDAV and CalDAV under <code>/dav/</code> (HTTPS only; CalDAV since 6.3.4), and, since 6.3.4, the OpenPGP Web Key Directory (HTTPS only) and an S/MIME authority's root and CRL (plain HTTP). <code>MtaStsHostingEnabled</code> and <code>AutoconfigEnabled</code> default to <code>1</code> while both ports stay <code>0</code>, which the server reports once at startup; the ports stay <code>0</code> on purpose, because port 80 may belong to IIS. The HTTPS port waits for a certificate, its own or ACME's, and says so in the log.</p>
<p dir="auto"><strong>Metrics.</strong> A host name or <code>localhost</code> as the bind address is refused (<code>MetricsServer: Invalid bind address</code>) and the probes go with the listener. Beyond loopback with no credential, <code>/metrics</code> answers 503 while the probes still answer. More, including the SNMP agent, is in <a href="/topic/28272">Monitoring and health: Prometheus metrics, health probes, Grafana, OTLP and SNMPv3</a>.</p>
<p dir="auto"><strong>ManageSieve</strong> has no certificate of its own and offers no STARTTLS, saying so in the log, until a mail port has one.</p>
<p dir="auto"><strong>The ACME challenge listener</strong> is not permanent. When <code>WebServicesHttpPort</code> equals <code>AcmeHttpPort</code>, the web services listener answers <code>/.well-known/acme-challenge/</code>; otherwise a temporary listener binds <code>AcmeHttpPort</code> for the issuance, and a failed bind logs <code>Failed to start the http-01 challenge listener. Is the port in use?</code> The client uses the <code>http-01</code> challenge only, so port 80 must be reachable from the internet (<a href="/topic/28187">Let's Encrypt certificates are automatic</a>).</p>
<p dir="auto"><strong>The SNMP agent</strong> (since 6.3.4) answers nobody until <code>SnmpAllowedAddresses</code> names a manager; a datagram from any other address is dropped before it is read. Bind it to <code>127.0.0.1</code> or a management address, and name managers one by one: UDP does not prove a source address. Error <code>7420</code> is a port it could not bind, such as one the operating system's own SNMP service holds. <a href="https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/Snmp.md" rel="nofollow ugc">Snmp.md</a> lists the Linux bind to 161 under the packaged unit as not proved by any test.</p>
<p dir="auto"><strong>A Control Panel on another machine</strong> (Windows) reaches the COM API over DCOM, which must be permitted, after probing TCP port 135 (the RPC endpoint mapper). <code>hmctl</code> and the PowerShell module use the REST listener instead.</p>
<h3><a class="anchor-offset" name="where-windows-and-linux-differ"></a>Where Windows and Linux differ</h3>
<ul>
<li><strong>Where you set a listener.</strong> On Windows, the TCP/IP ports page, <strong>Connections &amp; protocols → Web services &amp; autoconfiguration</strong>, <strong>TLS &amp; certificates → Certificates (ACME)</strong> and <strong>Monitoring &amp; troubleshooting → API &amp; monitoring</strong> (<strong>Monitoring &amp; alerts</strong> since 6.3.7). Linux has no Control Panel and no COM: the Deck for the mail listeners and the SNMP agent, and REST, <code>hmctl</code> or <code>hmailserver --set-setting</code> for every listener's <code>[Settings]</code> key. The packaged <code>RestApiPort=0</code> is stored at the first start, and a line edited afterwards turns nothing on; <a href="/topic/28190">First install on Linux</a> has the order.</li>
<li><strong>Low ports.</strong> The packaged <code>hmailserver.service</code> runs as its own user with <code>CAP_NET_BIND_SERVICE</code>, which it has for port 25 and which also lets the agent bind UDP 161.</li>
<li><strong>The database port.</strong> On Windows <code>[Database] Port</code> of <code>0</code> means the provider's own default. On Linux write it out (<code>5432</code>, <code>3306</code><img src="https://www.hmailserver.co.uk/assets/plugins/nodebb-plugin-emoji/emoji/android/1f61e.png?v=6eecd33477c" class="not-responsive emoji emoji-android emoji--disappointed" style="height:23px;width:auto;vertical-align:middle" title="):" alt="😞" /> it goes into the connection string as it stands.</li>
<li><strong>DNS.</strong> On Windows the custom servers under <strong>Connections &amp; protocols → DNS resolver</strong> are given port <code>0</code>, because the Windows DNS client supplies 53 itself and rejects an entry that names one; <code>DNSServer</code> is one IPv4 address with no port syntax.</li>
<li><strong>Containers.</strong> The image exposes 25, 110, 143, 465, 587, 993, 995, 4190 and 8045, and SNMP is published as UDP. No image of 6.3.4 is published; 6.3.8's is <code>registry.gitlab.com/hmailserver/hmailserver:6.3.8</code>, also tagged <code>6.3</code> and <code>latest</code>, and <a href="/topic/28246">In a container or on Kubernetes</a> has the rest.</li>
</ul>
<h3><a class="anchor-offset" name="proving-what-is-listening"></a>Proving what is listening</h3>
<p dir="auto">On Windows, on the server and then from outside:</p>
<pre><code class="language-powershell">Get-NetTCPConnection -State Listen -LocalPort 587 |
  Select-Object LocalAddress, LocalPort, OwningProcess
Test-NetConnection 127.0.0.1 -Port 25
Get-NetFirewallRule -Enabled True | Where-Object DisplayName -like "*hMail*"
Test-NetConnection mail.example.com -Port 25
openssl s_client -connect mail.example.com:465 -quiet
</code></pre>
<p dir="auto">On Linux, <code>ss -ltnp</code> lists listening sockets with their process, and the REST listener answers <code>curl -u Administrator http://127.0.0.1:8045/api/v1/status</code>. On Windows, <strong>Monitoring &amp; troubleshooting → Server status</strong> lists the listeners the service brought up; senders timing out with nothing in the SMTP log means nothing reached a listener.</p>
<h3><a class="anchor-offset" name="what-the-server-connects-to"></a>What the server connects to</h3>
<p dir="auto"><strong>On every server, with nothing turned on:</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Destination</th>
<th>Port</th>
<th>Setting</th>
<th>If it is blocked</th>
</tr>
</thead>
<tbody>
<tr>
<td>DNS resolvers</td>
<td>53, UDP and TCP</td>
<td>The machine's resolvers, or <code>DNSServer</code></td>
<td>Nothing is delivered externally, and DNSBL, SPF, DKIM, DMARC, MTA-STS and DANE stop at once</td>
</tr>
<tr>
<td>Every recipient domain's MX host</td>
<td>25</td>
<td>None</td>
<td>Messages stay queued and are retried, by default 4 times at 60-minute intervals, then bounced</td>
</tr>
<tr>
<td>The recipient domain's MTA-STS policy, from <code>mta-sts.&lt;domain&gt;</code></td>
<td>443</td>
<td><code>MtaStsEnabled</code>, <code>1</code></td>
<td>Delivery to a domain with an enforcing policy falls back to what DANE and your TLS settings allow</td>
</tr>
</tbody>
</table>
<p dir="auto">DANE and TLS-RPT need no port of their own: TLSA records come over DNS, and TLS-RPT reports are sent as ordinary mail. Delivery leaves from <code>SMTPDeliveryBindToIP</code>, or a rule's <em>bind to address</em> action; since 6.3.4 <code>SMTPDeliveryBindToIP</code> may name one address of each family, separated by a comma.</p>
<p dir="auto"><strong>Only when you configure it:</strong></p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Destination</th>
<th>Port</th>
<th>Setting, as shipped</th>
</tr>
</thead>
<tbody>
<tr>
<td>Smart host, or a route's host</td>
<td><code>SMTPRelayerPort</code> (25; <code>0</code> is read as 25), or the route's own</td>
<td>Empty</td>
</tr>
<tr>
<td>Database server</td>
<td>The provider's port</td>
<td><code>[Database]</code>; since 6.3.4 MySQL and MariaDB use TLS on it when offered</td>
</tr>
<tr>
<td>SpamAssassin <code>spamd</code>, ClamAV <code>clamd</code></td>
<td><code>127.0.0.1:783</code>, <code>localhost:3310</code></td>
<td>Both off; no TLS</td>
</tr>
<tr>
<td>An HTTP filter engine</td>
<td>The URL's</td>
<td><code>FilterHookUrl</code>, empty</td>
</tr>
<tr>
<td>The ACME directory</td>
<td>443</td>
<td><code>AcmeEnabled</code>, <code>0</code>; <code>AcmeDirectoryUrl</code> is Let's Encrypt</td>
</tr>
<tr>
<td>The update feed, <code>https://updates.progressiverobot.com</code>, and the installer from the project's package registry on <code>gitlab.com</code></td>
<td>443</td>
<td><code>UpdateCheckEnabled</code>, <code>0</code></td>
</tr>
<tr>
<td>The password breach check, <code>https://api.pwnedpasswords.com/range/</code></td>
<td>443</td>
<td><code>BreachCheckEnabled</code>, <code>0</code> (since 6.3.4)</td>
</tr>
<tr>
<td>An object store: <code>https://s3.&lt;region&gt;.amazonaws.com</code>, <code>https://&lt;account&gt;.blob.core.windows.net</code> or <code>MessageStoreObjectEndpoint</code></td>
<td>443, or the endpoint's</td>
<td><code>MessageStoreObjectService</code>, empty (since 6.3.4)</td>
</tr>
<tr>
<td>OAuth2: a key set, an introspection endpoint, the outbound relay's token endpoint</td>
<td>The URL's</td>
<td><code>OAuth2JwksUrl</code>, <code>OAuth2IntrospectionUrl</code>, <code>OutboundOAuth2TokenUrl</code>, empty</td>
</tr>
<tr>
<td>An OpenID Connect issuer: <code>&lt;issuer&gt;/.well-known/openid-configuration</code>, then its token endpoint</td>
<td>The issuer's</td>
<td><code>oidc_issuer</code>, empty (since 6.3.4)</td>
</tr>
<tr>
<td>Outbound webhooks, alert webhooks, a sandbox service, a route of mail in to a webhook</td>
<td>The URL's</td>
<td>No subscription, rule or route; <code>SandboxEnabled</code>, <code>0</code> (all since 6.3.4)</td>
</tr>
<tr>
<td>A syslog collector</td>
<td><code>SyslogPort</code>, 514 (UDP, TCP); 6514 is the registered TLS port</td>
<td><code>SyslogEnabled</code>, off (since 6.3.4)</td>
</tr>
<tr>
<td>An OpenTelemetry collector</td>
<td>The endpoint's</td>
<td><code>OtelEndpoint</code>, <code>OtelMetricsEndpoint</code>, <code>OtelLogsEndpoint</code>, empty</td>
</tr>
<tr>
<td>The browser vendor's push service</td>
<td>The service's</td>
<td><code>WebPushEnabled</code>, <code>0</code> (since 6.3.4)</td>
</tr>
<tr>
<td>External accounts and migrations: another server's POP3 or IMAP; <code>imap.gmail.com</code> or <code>outlook.office365.com</code> on 993; <code>graph.microsoft.com</code>; CardDAV and CalDAV over https</td>
<td>The account's; a person's own account 110, 995, 143 or 993 at public addresses unless <code>reader_fetch_accounts_private_addresses</code> is on</td>
<td>Nothing until an account or a migration is made</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>At a person's request in the webmail</strong>: since 6.3.4, a correspondent's OpenPGP key from their domain's Web Key Directory (<code>lookup_wkd</code>, on; never an address inside your network) or from <code>https://keys.openpgp.org</code> (<code>lookup_keyserver</code>, off), and a sender's BIMI logo (public addresses only, and only with <code>AuthenticationResultsEnabled</code>, which is <code>0</code>); and, since 6.3.2, a one-click unsubscribe, posted to a public address only.</p>
<p dir="auto"><strong>Where an outbound request may go.</strong> Every outbound web request is https, or plain http to this machine only; https is verified against the machine's root store, host name checked, TLS 1.2 at least, so a private CA must be in that store (or in <code>MessageStoreObjectCaFile</code> for an object store). Outbound webhooks may reach a private address, on purpose; a route of mail in to a webhook never reaches a link-local or cloud metadata address, and one not made by the server administrator reaches public addresses only.</p>
<p dir="auto"><strong>Through a proxy.</strong> <code>HttpProxy</code> (<code>host:port</code> or <code>[ipv6]:port</code>, since 6.2.28) carries the update feed and its downloads, the JWKS and introspection fetches, the breach check and the object store. It sends no proxy credentials, and a value with no port fails with <code>HttpProxy must be host:port (or [ipv6]:port).</code> rather than going direct. ACME issuance, the outbound relay's token request, a mail-in-to-webhook route and the MTA-STS policy fetch never use it; the MTA-STS fetch is on by default, so a proxy-only egress stops it. Whether the other requests above use the proxy is not documented: prove a proxy-only egress before relying on it. <a href="https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/UpdateFeed.md" rel="nofollow ugc">UpdateFeed.md</a>, written before the feed site's first deployment, says the address answers nothing usable until then.</p>
<h3><a class="anchor-offset" name="the-firewall-matrix"></a>The firewall matrix</h3>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Direction</th>
<th>Port</th>
<th>From or to</th>
<th>Only when</th>
</tr>
</thead>
<tbody>
<tr>
<td>In</td>
<td>TCP 25</td>
<td>Anywhere</td>
<td>Always</td>
</tr>
<tr>
<td>In</td>
<td>TCP 587, and 465, 993, 995</td>
<td>Anywhere, or your users' networks</td>
<td>587 always; the others once you have created them</td>
</tr>
<tr>
<td>In</td>
<td>TCP 143, 110</td>
<td>Your users</td>
<td>A client still uses them; deny them afterwards</td>
</tr>
<tr>
<td>In</td>
<td>TCP 80</td>
<td>Anywhere</td>
<td>ACME, or web services over HTTP</td>
</tr>
<tr>
<td>In</td>
<td>TCP 443</td>
<td>Anywhere</td>
<td><code>WebServicesHttpsPort</code> is 443</td>
</tr>
<tr>
<td>In</td>
<td>TCP REST port (8045)</td>
<td>Your management network; users for <code>/portal</code>; the identity provider for SCIM</td>
<td>The listener is bound beyond loopback, with TLS</td>
</tr>
<tr>
<td>In</td>
<td>TCP metrics port, ManageSieve 4190</td>
<td>Prometheus; your management network</td>
<td>Bound beyond loopback (or keep <code>127.0.0.1</code> and a tunnel)</td>
</tr>
<tr>
<td>In</td>
<td>UDP 161</td>
<td>The SNMP managers only, on the bound address</td>
<td>The agent is on</td>
</tr>
<tr>
<td>In</td>
<td>TCP 135 and DCOM</td>
<td>The administrator's machine</td>
<td>A remote Control Panel (Windows)</td>
</tr>
<tr>
<td>Out</td>
<td>TCP 25</td>
<td>Anywhere, or only the smart host on its port</td>
<td>Always</td>
</tr>
<tr>
<td>Out</td>
<td>UDP and TCP 53</td>
<td>Your resolvers</td>
<td>Always</td>
</tr>
<tr>
<td>Out</td>
<td>TCP 443</td>
<td>Anywhere, or the hosts in the tables above</td>
<td>MTA-STS is on (the default) or a feature needs it</td>
</tr>
<tr>
<td>Out</td>
<td>Database, <code>spamd</code>, <code>clamd</code>, syslog, OTLP ports</td>
<td>Those hosts</td>
<td>They are not on this machine</td>
</tr>
<tr>
<td>Out</td>
<td>TCP 110, 995, 143, 993, or the account's port</td>
<td>The servers mail is collected or migrated from</td>
<td>An external account or a migration exists</td>
</tr>
</tbody>
</table>
<p dir="auto"><strong>Windows.</strong> The installer opens no firewall port, so nothing reaches the server until you add the rules. In an elevated PowerShell:</p>
<pre><code class="language-powershell">New-NetFirewallRule -DisplayName "hMailServer SMTP"        -Direction Inbound -Protocol TCP -LocalPort 25  -Action Allow
New-NetFirewallRule -DisplayName "hMailServer Submission"  -Direction Inbound -Protocol TCP -LocalPort 587 -Action Allow
New-NetFirewallRule -DisplayName "hMailServer IMAPS"       -Direction Inbound -Protocol TCP -LocalPort 993 -Action Allow
New-NetFirewallRule -DisplayName "hMailServer POP3S"       -Direction Inbound -Protocol TCP -LocalPort 995 -Action Allow
</code></pre>
<p dir="auto"><strong>Linux.</strong> With firewalld, <code>firewall-cmd --permanent --add-port={25,587,993,995}/tcp</code> and <code>firewall-cmd --reload</code>; with ufw, <code>ufw allow 25,587,993,995/tcp</code>. The documentation page's chapter 4.4 also opens 110, 143 and 465; leave them out.</p>
<p dir="auto">On either system, add 143, 110, 465, 80 or 443 only when the matrix says so, and forward the same ports on the router or cloud firewall. The Linux package's own firewall hook (<code>AutoBanFirewall=1</code>) only blocks, and needs <code>CAP_NET_ADMIN</code>, which the unit does not grant by default; on Windows the same switch is refused under <code>NT SERVICE\hMailServer</code> (<code>HM7460</code>). Put the addresses you administer from in <code>AutoBanNeverBan</code> first; <a href="/topic/28220">Reading the logs, and fail2ban</a> has auto-ban in the firewall.</p>
<h3><a class="anchor-offset" name="what-it-does-not-do"></a>What it does not do</h3>
<ul>
<li>The SNMP agent sends no trap or inform and does not answer SNMPv1; nothing leaves it unasked.</li>
<li>Country blocking downloads no geographic database; the <code>.mmdb</code> file is yours to fetch and keep fresh.</li>
<li>No AI or machine-learning service is called by the server.</li>
</ul>
<h3><a class="anchor-offset" name="where-to-read-more"></a>Where to read more</h3>
<ul>
<li>Wiki: <a href="https://gitlab.com/hmailserver/hmailserver/-/wikis/Ports-Reference" rel="nofollow ugc">Ports Reference</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/wikis/Before-You-Install" rel="nofollow ugc">Before You Install</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/wikis/Installing-hMailServer" rel="nofollow ugc">Installing hMailServer</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/wikis/Installing-on-Linux" rel="nofollow ugc">Installing on Linux</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/wikis/Settings-Reference" rel="nofollow ugc">Settings Reference</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/wikis/Troubleshooting" rel="nofollow ugc">Troubleshooting</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/wikis/Encryption-and-Certificates" rel="nofollow ugc">Encryption and Certificates</a>.</li>
<li>Documents at v6.3.4: <a href="https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/EvidencePack.md" rel="nofollow ugc">EvidencePack.md</a> (what leaves the server), <a href="https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/SettingsApply.md" rel="nofollow ugc">SettingsApply.md</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/Snmp.md" rel="nofollow ugc">Snmp.md</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/UpdateFeed.md" rel="nofollow ugc">UpdateFeed.md</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/InboundWebhooks.md" rel="nofollow ugc">InboundWebhooks.md</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/ObjectStorage.md" rel="nofollow ugc">ObjectStorage.md</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/PasswordBreachCheck.md" rel="nofollow ugc">PasswordBreachCheck.md</a>, <a href="https://gitlab.com/hmailserver/hmailserver/-/blob/v6.3.4/hmailserver/docs/Migration.md" rel="nofollow ugc">Migration.md</a>.</li>
<li>The documentation page's <a href="https://www.progressiverobot.com/hmailserver-documentation/#22-ports-reference" rel="nofollow ugc">ports reference</a> and <a href="https://www.progressiverobot.com/hmailserver-documentation/#44-open-the-windows-firewall" rel="nofollow ugc">Open the firewall</a> chapters.</li>
<li>On the forum: <a href="/topic/28187">Let's Encrypt certificates are automatic</a>, <a href="/topic/28190">First install on Linux</a>, <a href="/topic/28192">The Control Deck</a>, <a href="/topic/28227">Installing on Windows: wizard pages, service account, profile and the first hour</a>, <a href="/topic/28229">Your first domain and mailbox, and the DNS records your domain needs</a>, <a href="/topic/28256">TLS on the listeners: your own certificate, versions, ciphers</a> and <a href="/topic/28225">Troubleshooting by symptom: no mail in, no mail out</a>.</li>
</ul>
]]></description><link>https://www.hmailserver.co.uk/topic/28226/every-port-hmailserver-listens-on-or-connects-to-and-the-firewall-rules-to-match</link><generator>RSS for Node</generator><lastBuildDate>Fri, 06 Nov 2026 09:05:53 GMT</lastBuildDate><atom:link href="https://www.hmailserver.co.uk/topic/28226.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 27 Sep 2026 19:08:13 GMT</pubDate><ttl>60</ttl></channel></rss>