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 & monitoring is Monitoring & 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 (Sec-Fetch-Site, or an Origin that is not this server's); scripts, hmctl and the PowerShell module send no such header and are unaffected. 6.3.7's container image is registry.gitlab.com/hmailserver/hmailserver:6.3.7. See the 6.3.7 announcement. 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 WebServicesTrustedProxies 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 registry.gitlab.com/hmailserver/hmailserver:6.3.8, also tagged 6.3 and latest. See the 6.3.8 announcement.
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: a new server listens on four mail ports and on nothing else. Every other listener is off until a setting gives it a port, three of them bind only to 127.0.0.1 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.
Connection security per mail port, and what a new 6.3.4 installation sets on each, is in Connecting a mail client: IMAP, POP3, SMTP submission and the ports.
Two kinds of listener, set in two places
Mail-protocol listeners (SMTP, POP3, IMAP) are rows of the table hm_tcpipports, edited on Connections & protocols → TCP/IP ports in the Control Panel (Windows), on the Control Deck, over COM (Settings.TCPIPPorts, Windows) and over REST at /api/v1/ports, where a new row's address defaults to 0.0.0.0. A port you add, change or delete takes effect at a reinitialise (POST /api/v1/server/reinitialize, or the Deck's button that restarts the services in place) or a service restart.
Service listeners are one key each, all off by default. Set their [Settings] keys in the Control Panel (Windows), over REST (PUT /api/v1/settings/ini/{name}), with hmctl ini set or hmailserver --set-setting NAME=VALUE; the Deck has no page for them. Since 6.3.4 the database holds these keys, so a line edited in hMailServer.ini turns no listener on (HM5804); Settings: what is not stock, when a save takes effect explains the store. Each listener's port, bind address and certificate files are among the 28 keys that wait for a reinitialise: Apply now in the Control Panel or the Deck, POST /api/v1/server/reinitialize, Application.Reinitialize over COM, or a restart. AcmeHttpPort applies when it is saved. The SNMP agent's settings are hm_settings rows instead, set on the Deck's Settings page under Server, over REST (/api/v1/settings) or with hmctl settings set, with no Control Panel page, and read when the agent starts, at a service start or a Reinitialize.
The mail listeners
Port
Protocol
Created by
Default bind
What it says on connect
25
SMTP
Seeded in every new database
The row's IP address (0.0.0.0 or :: is every address)
220 MAIL01 ESMTP: the Welcome banner from Connections & protocols → Protocols → SMTP, or the computer name, with ESMTP appended
587
SMTP submission
Seeded
The row's IP address
The same banner
110
POP3
Seeded
The row's IP address
+OK POP3, or your welcome message
143
IMAP
Seeded
The row's IP address
* OK IMAPrev1, or your welcome message
465, 993, 995
SMTP, IMAP, POP3 over implicit TLS
You, once you have a certificate
What you choose
Nothing until the TLS handshake completes
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 (HM5113), and a port something else holds does not bind (HM4316). On Windows with WSL2 in mirrored networking mode, a socket bound inside WSL takes the port from Windows too, shows in neither Get-NetTCPConnection nor netstat -ano, and on the project's test bench only wsl --shutdown gave it back.
The service listeners
Listener
Port key, default
Bind key, default
TLS
How to tell it is up
REST API, the Control Deck at /, the webmail at /portal, SCIM at /scim/v2 (since 6.3.4)
RestApiPort, 0; 8045 is the conventional port
RestApiBindAddress, 127.0.0.1
Required unless bound to 127.0.0.1, localhost or ::1
RestApi: Listening on <endpoint> (https) or (http, loopback only) in the application log
Public web services
WebServicesHttpPort, WebServicesHttpsPort, both 0; 80 and 443 to enable
WebServicesBindAddress, 0.0.0.0
WebServicesCertificateFile and WebServicesPrivateKeyFile on the HTTPS port, or the ACME certificate on disk
A URL it serves answers
Prometheus metrics and health probes
MetricsServerPort, 0
MetricsServerBindAddress, 127.0.0.1, an IP literal only
MetricsServerCertificateFile + MetricsServerPrivateKeyFile; plain HTTP otherwise
/livez answers 200 alive
ManageSieve (RFC 5804)
ManageSieveServerPort, 0; 4190 is the standard port
ManageSieveServerBindAddress, 127.0.0.1
STARTTLS, only when an IMAP, POP3 or SMTP port has a certificate
Its capability response
ACME http-01 challenge
AcmeHttpPort, 80
Every address
Never
Open only during an issuance
SNMP agent, UDP, since 6.3.4
SnmpPort, 161, with SnmpEnabled off
SnmpBindAddress, empty = every address
SNMPv3 at authPriv instead of TLS
A stranger gets no answer at all
One port carries the REST API, the Deck and the webmail; there is no second port to open. It will not start without an administrator password, nor beyond loopback without a certificate, and with RestApiCertificateFile empty it takes the ACME certificate when one exists. For users to reach /portal, 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 (Behind a gateway, load balancer or reverse proxy). Turning it on is in The REST API: turning it on, credentials, roles, one-time codes.
The web services listener binds every address by default. It serves the MTA-STS policy at /.well-known/mta-sts.txt (HTTPS only), ACME challenges, Thunderbird autoconfig, Outlook autodiscover and the Apple profile (HTTPS only), security.txt, CardDAV and CalDAV under /dav/ (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). MtaStsHostingEnabled and AutoconfigEnabled default to 1 while both ports stay 0, which the server reports once at startup; the ports stay 0 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.
Metrics. A host name or localhost as the bind address is refused (MetricsServer: Invalid bind address) and the probes go with the listener. Beyond loopback with no credential, /metrics answers 503 while the probes still answer. More, including the SNMP agent, is in Monitoring and health: Prometheus metrics, health probes, Grafana, OTLP and SNMPv3.
ManageSieve has no certificate of its own and offers no STARTTLS, saying so in the log, until a mail port has one.
The ACME challenge listener is not permanent. When WebServicesHttpPort equals AcmeHttpPort, the web services listener answers /.well-known/acme-challenge/; otherwise a temporary listener binds AcmeHttpPort for the issuance, and a failed bind logs Failed to start the http-01 challenge listener. Is the port in use? The client uses the http-01 challenge only, so port 80 must be reachable from the internet (Let's Encrypt certificates are automatic).
The SNMP agent (since 6.3.4) answers nobody until SnmpAllowedAddresses names a manager; a datagram from any other address is dropped before it is read. Bind it to 127.0.0.1 or a management address, and name managers one by one: UDP does not prove a source address. Error 7420 is a port it could not bind, such as one the operating system's own SNMP service holds. Snmp.md lists the Linux bind to 161 under the packaged unit as not proved by any test.
A Control Panel on another machine (Windows) reaches the COM API over DCOM, which must be permitted, after probing TCP port 135 (the RPC endpoint mapper). hmctl and the PowerShell module use the REST listener instead.
Where Windows and Linux differ
Where you set a listener. On Windows, the TCP/IP ports page, Connections & protocols → Web services & autoconfiguration, TLS & certificates → Certificates (ACME) and Monitoring & troubleshooting → API & monitoring (Monitoring & alerts since 6.3.7). Linux has no Control Panel and no COM: the Deck for the mail listeners and the SNMP agent, and REST, hmctl or hmailserver --set-setting for every listener's [Settings] key. The packaged RestApiPort=0 is stored at the first start, and a line edited afterwards turns nothing on; First install on Linux has the order.
Low ports. The packaged hmailserver.service runs as its own user with CAP_NET_BIND_SERVICE, which it has for port 25 and which also lets the agent bind UDP 161.
The database port. On Windows [Database] Port of 0 means the provider's own default. On Linux write it out (5432, 3306 it goes into the connection string as it stands.
DNS. On Windows the custom servers under Connections & protocols → DNS resolver are given port 0, because the Windows DNS client supplies 53 itself and rejects an entry that names one; DNSServer is one IPv4 address with no port syntax.
Containers. 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 registry.gitlab.com/hmailserver/hmailserver:6.3.8, also tagged 6.3 and latest, and In a container or on Kubernetes has the rest.
Proving what is listening
On Windows, on the server and then from outside:
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
On Linux, ss -ltnp lists listening sockets with their process, and the REST listener answers curl -u Administrator http://127.0.0.1:8045/api/v1/status. On Windows, Monitoring & troubleshooting → Server status lists the listeners the service brought up; senders timing out with nothing in the SMTP log means nothing reached a listener.
What the server connects to
On every server, with nothing turned on:
Destination
Port
Setting
If it is blocked
DNS resolvers
53, UDP and TCP
The machine's resolvers, or DNSServer
Nothing is delivered externally, and DNSBL, SPF, DKIM, DMARC, MTA-STS and DANE stop at once
Every recipient domain's MX host
25
None
Messages stay queued and are retried, by default 4 times at 60-minute intervals, then bounced
The recipient domain's MTA-STS policy, from mta-sts.<domain>
443
MtaStsEnabled, 1
Delivery to a domain with an enforcing policy falls back to what DANE and your TLS settings allow
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 SMTPDeliveryBindToIP, or a rule's bind to address action; since 6.3.4 SMTPDeliveryBindToIP may name one address of each family, separated by a comma.
Only when you configure it:
Destination
Port
Setting, as shipped
Smart host, or a route's host
SMTPRelayerPort (25; 0 is read as 25), or the route's own
Empty
Database server
The provider's port
[Database]; since 6.3.4 MySQL and MariaDB use TLS on it when offered
SpamAssassin spamd, ClamAV clamd
127.0.0.1:783, localhost:3310
Both off; no TLS
An HTTP filter engine
The URL's
FilterHookUrl, empty
The ACME directory
443
AcmeEnabled, 0; AcmeDirectoryUrl is Let's Encrypt
The update feed, https://updates.progressiverobot.com, and the installer from the project's package registry on gitlab.com
443
UpdateCheckEnabled, 0
The password breach check, https://api.pwnedpasswords.com/range/
443
BreachCheckEnabled, 0 (since 6.3.4)
An object store: https://s3.<region>.amazonaws.com, https://<account>.blob.core.windows.net or MessageStoreObjectEndpoint
443, or the endpoint's
MessageStoreObjectService, empty (since 6.3.4)
OAuth2: a key set, an introspection endpoint, the outbound relay's token endpoint
The URL's
OAuth2JwksUrl, OAuth2IntrospectionUrl, OutboundOAuth2TokenUrl, empty
An OpenID Connect issuer: <issuer>/.well-known/openid-configuration, then its token endpoint
The issuer's
oidc_issuer, empty (since 6.3.4)
Outbound webhooks, alert webhooks, a sandbox service, a route of mail in to a webhook
The URL's
No subscription, rule or route; SandboxEnabled, 0 (all since 6.3.4)
A syslog collector
SyslogPort, 514 (UDP, TCP); 6514 is the registered TLS port
SyslogEnabled, off (since 6.3.4)
An OpenTelemetry collector
The endpoint's
OtelEndpoint, OtelMetricsEndpoint, OtelLogsEndpoint, empty
The browser vendor's push service
The service's
WebPushEnabled, 0 (since 6.3.4)
External accounts and migrations: another server's POP3 or IMAP; imap.gmail.com or outlook.office365.com on 993; graph.microsoft.com; CardDAV and CalDAV over https
The account's; a person's own account 110, 995, 143 or 993 at public addresses unless reader_fetch_accounts_private_addresses is on
Nothing until an account or a migration is made
At a person's request in the webmail: since 6.3.4, a correspondent's OpenPGP key from their domain's Web Key Directory (lookup_wkd, on; never an address inside your network) or from https://keys.openpgp.org (lookup_keyserver, off), and a sender's BIMI logo (public addresses only, and only with AuthenticationResultsEnabled, which is 0); and, since 6.3.2, a one-click unsubscribe, posted to a public address only.
Where an outbound request may go. 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 MessageStoreObjectCaFile 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.
Through a proxy. HttpProxy (host:port or [ipv6]:port, 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 HttpProxy must be host:port (or [ipv6]:port). 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. UpdateFeed.md, written before the feed site's first deployment, says the address answers nothing usable until then.
The firewall matrix
Direction
Port
From or to
Only when
In
TCP 25
Anywhere
Always
In
TCP 587, and 465, 993, 995
Anywhere, or your users' networks
587 always; the others once you have created them
In
TCP 143, 110
Your users
A client still uses them; deny them afterwards
In
TCP 80
Anywhere
ACME, or web services over HTTP
In
TCP 443
Anywhere
WebServicesHttpsPort is 443
In
TCP REST port (8045)
Your management network; users for /portal; the identity provider for SCIM
The listener is bound beyond loopback, with TLS
In
TCP metrics port, ManageSieve 4190
Prometheus; your management network
Bound beyond loopback (or keep 127.0.0.1 and a tunnel)
In
UDP 161
The SNMP managers only, on the bound address
The agent is on
In
TCP 135 and DCOM
The administrator's machine
A remote Control Panel (Windows)
Out
TCP 25
Anywhere, or only the smart host on its port
Always
Out
UDP and TCP 53
Your resolvers
Always
Out
TCP 443
Anywhere, or the hosts in the tables above
MTA-STS is on (the default) or a feature needs it
Out
Database, spamd, clamd, syslog, OTLP ports
Those hosts
They are not on this machine
Out
TCP 110, 995, 143, 993, or the account's port
The servers mail is collected or migrated from
An external account or a migration exists
Windows. The installer opens no firewall port, so nothing reaches the server until you add the rules. In an elevated 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
Linux. With firewalld, firewall-cmd --permanent --add-port={25,587,993,995}/tcp and firewall-cmd --reload; with ufw, ufw allow 25,587,993,995/tcp. The documentation page's chapter 4.4 also opens 110, 143 and 465; leave them out.
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 (AutoBanFirewall=1) only blocks, and needs CAP_NET_ADMIN, which the unit does not grant by default; on Windows the same switch is refused under NT SERVICE\hMailServer (HM7460). Put the addresses you administer from in AutoBanNeverBan first; Reading the logs, and fail2ban has auto-ban in the firewall.
What it does not do
The SNMP agent sends no trap or inform and does not answer SNMPv1; nothing leaves it unasked.
Country blocking downloads no geographic database; the .mmdb file is yours to fetch and keep fresh.
No AI or machine-learning service is called by the server.
Where to read more
Wiki: Ports Reference, Before You Install, Installing hMailServer, Installing on Linux, Settings Reference, Troubleshooting, Encryption and Certificates.
Documents at v6.3.4: EvidencePack.md (what leaves the server), SettingsApply.md, Snmp.md, UpdateFeed.md, InboundWebhooks.md, ObjectStorage.md, PasswordBreachCheck.md, Migration.md.
The documentation page's ports reference and Open the firewall chapters.
On the forum: Let's Encrypt certificates are automatic, First install on Linux, The Control Deck, Installing on Windows: wizard pages, service account, profile and the first hour, Your first domain and mailbox, and the DNS records your domain needs, TLS on the listeners: your own certificate, versions, ciphers and Troubleshooting by symptom: no mail in, no mail out.