TCP Port Monitoring - Watch Mail, Database and SSH Ports
TCP port monitoring checks whether a server accepts a TCP connection on a specific port, such as 587 for mail submission or 22 for SSH. It is the right tool for services that do not speak HTTP. For mail servers, monitor the submission ports 587 or 465 rather than port 25, because many cloud platforms block outbound connections to port 25.
TCP port monitoring checks whether a host accepts a TCP connection on a given port within a timeout. If the connection is refused or times out, the monitor alerts you. Use it for services that are not websites: mail servers, SSH, FTP, game servers, VPN endpoints, message brokers and database proxies. One important exception: for mail servers, monitor the submission ports 587 or 465, not port 25, because many cloud platforms block outbound traffic to port 25 and a cloud-based checker may not be able to reach it at all.
What a TCP check does and does not tell you
A TCP check performs the start of a connection: the client sends SYN, the server answers SYN-ACK, and the client completes the handshake. If that works, the port is open and something is listening.
| Result | Typical meaning |
|---|---|
| Connected | A process is listening and the path through firewalls is open |
| Connection refused | The host is reachable but nothing is listening, often a crashed or stopped service |
| Timeout | A firewall drops the traffic, the host is down, or the network path is broken |
| DNS failure | The hostname does not resolve |
It does not tell you that the service behind the port is healthy. A mail server can accept connections and still reject every message because the disk is full. Where the service speaks HTTP, an HTTP or keyword check is a stronger signal. For everything else, a TCP check is a good first layer.
Common ports to monitor
| Port | Service | Notes |
|---|---|---|
| 22 | SSH | Useful for detecting a server that is completely unreachable |
| 21 | FTP | Control channel only; passive data ports are separate |
| 53 | DNS over TCP | DNS also uses UDP, which a TCP check does not test |
| 465 | SMTP submission, implicit TLS | Preferred check for mail servers |
| 587 | SMTP submission, STARTTLS | Preferred check for mail servers |
| 993 | IMAP over TLS | Mail retrieval for clients |
| 995 | POP3 over TLS | Mail retrieval for clients |
| 1194 | OpenVPN (when configured for TCP) | OpenVPN defaults to UDP |
| 3389 | Remote Desktop | Avoid exposing publicly if you can |
| 5672 | AMQP (RabbitMQ) | Usually internal only |
| 25565 | Minecraft Java server | Default port, often changed |
Port numbers above are defaults. Always monitor the port your service is actually configured to use.
Why not port 25?
Port 25 is used for server-to-server mail transfer. Because compromised machines have historically used it to send spam, many cloud and hosting platforms block or restrict outbound connections to port 25 by default, sometimes unless you request an exception. Monitoring services often run on exactly those platforms, so a port 25 check can fail permanently even though your mail server is fine.
Mail submission ports avoid the problem:
- 587 is the standard message submission port (RFC 6409). The client connects in plain text and upgrades with STARTTLS.
- 465 is submission over implicit TLS (RFC 8314). TLS starts immediately on connect.
Your mail server software, such as Postfix or Exim, typically serves 25, 587 and 465 from the same process. If 587 accepts connections, the mail service itself is running. You still rely on your mail provider and DNS records for inbound delivery on port 25, which you can test separately from a machine that is allowed to use it.
Test a port manually
Before creating a monitor, confirm the port is reachable from a machine outside your network.
netcat
nc -zv mail.example.com 587
-z only checks the connection without sending data, and -v prints the result. Add -w 5 to set a 5-second timeout.
bash only, no extra tools
timeout 5 bash -c '</dev/tcp/mail.example.com/587' && echo open || echo closed
Check the TLS handshake on 465
openssl s_client -connect mail.example.com:465 -servername mail.example.com </dev/null
Check STARTTLS on 587
openssl s_client -starttls smtp -connect mail.example.com:587 -servername mail.example.com </dev/null
The openssl commands show the certificate chain and confirm the mail server speaks TLS correctly, which a bare TCP check does not.
From the server itself: is the service listening?
sudo ss -tlnp | grep -E ':(587|465)\b'
If the service is listening locally but the remote test times out, the problem is a firewall or security group, not the service.
Firewalls and security groups
A port monitor fails if any layer blocks it:
- The host firewall (
ufw,firewalld,nftables) - Cloud security groups or network ACLs
- An upstream provider firewall
- Rate limiting or intrusion prevention tools such as fail2ban, which can ban an address that connects often
If you restrict who can connect, allow your monitoring service's source addresses, or monitor a port that is meant to be public anyway.
Do not expose private services to monitor them
Databases (3306, 5432), caches such as Redis (6379) and admin panels should not be reachable from the internet. Instead:
- Expose an HTTP health endpoint in your application that queries the database and cache, and monitor that.
- Or run checks from inside your private network and send the result to a heartbeat URL. See cron job monitoring with heartbeats.
For example, a cron job on a private host can check the database port and ping a heartbeat only when it succeeds:
*/5 * * * * nc -z -w 5 10.0.0.12 5432 && curl -fsS --retry 3 https://pingrobot.io/hb/<token> > /dev/null
Setting up a TCP monitor
- Pick the hostname and port. For mail, choose 587 or 465.
- Confirm reachability with
nc -zvfrom outside your network. - Set a timeout of around 10 seconds. A port that takes longer to accept a connection is effectively down for most clients.
- Name the monitor clearly, for example
mail.example.com:587 (SMTP submission). - Route alerts to whoever manages that service, which may not be the web team.
- Test by stopping the service briefly in a maintenance window, or by pointing a temporary monitor at a closed port, and confirm the alert arrives.
Checklist
- Monitor the port clients actually use
- Use 587 or 465 for mail, not 25
- Add HTTP or keyword checks where the service speaks HTTP
- Keep databases and caches private and monitor them indirectly
- Allow monitoring traffic through firewalls and fail2ban if you restrict access
- Remember that a TCP check does not test UDP services
PingRobot supports TCP port monitors alongside HTTP(S), keyword and heartbeat checks, and re-checks failures from a second region before alerting. Its checks run on Cloudflare's network, so host names proxied by Cloudflare (orange cloud) can't be checked over TCP; point the port monitor at the origin server, or use an HTTP(S) monitor for proxied sites. For an overview of monitor types, read what is uptime monitoring.
Start monitoring free — 10 monitors, no credit card.
Frequently asked questions
What does a TCP port check actually prove?
That something on the server completed a TCP handshake on that port within the timeout. It does not prove the application behind the port is healthy or answering correctly.
Why does my port 25 monitor fail when the mail server works?
Many cloud providers block or restrict outbound connections to port 25 to limit spam, so a checker running in the cloud may never reach your server on that port. Monitor 587 or 465 instead.
Should I open my database port to the internet so I can monitor it?
No. Databases should not be publicly reachable. Monitor an application health endpoint that queries the database, or run checks from inside your private network.
What is the difference between port 587 and port 465?
Both are for mail submission by clients. Port 587 starts in plain text and upgrades with STARTTLS, while port 465 uses TLS from the first byte, often called implicit TLS.