An open TCP port 8009 is a clue, not an answer. It is commonly used by Apache Tomcat’s AJP connector, but the port number alone cannot tell you what service is running—or whether it is exposed in a risky way.
A useful investigation has three steps: identify the process, check where it listens, then confirm which systems can reach it.
Why port 8009 needs context
AJP, or Apache JServ Protocol, lets a front-end web server such as Apache HTTP Server pass requests to an application server such as Tomcat. In some deployments, Tomcat’s AJP connector uses TCP port 8009. The front-end might handle public HTTP or HTTPS traffic while AJP carries requests between trusted components.
But that convention is not a guarantee. The connector might be disabled, configured to use another port, or bound only to a local or private interface. Another application can also use port 8009.
There is a registry wrinkle, too: IANA lists TCP 8009 for the NVMe over Fabrics Discovery Service. That registered assignment and AJP’s common use in Tomcat describe different contexts. Neither tells you what a particular machine is running. UDP 8009 is reserved; a TCP result does not establish anything about UDP.
Treat a scan result as a starting point. Don’t label a host “Tomcat” or “vulnerable” based on the port number alone.
Find the listener on the host
On Linux, inspect TCP listeners on port 8009:
sudo ss -ltnp 'sport = :8009'
The output can show the local address, port, and—when permissions allow—the owning process. If you need a refresher on interpreting listener output and other socket checks, see how to check open ports on Linux.
Pay attention to the local address:
-
127.0.0.1:8009accepts connections on IPv4 loopback only. -
0.0.0.0:8009may accept connections on all IPv4 interfaces, subject to network and firewall controls. -
[::]:8009indicates an IPv6 wildcard listener; check the host’s actual IPv6 and network configuration to understand reachability.
A wildcard bind is not proof that the service is reachable from the internet. Firewalls, routing, and cloud network rules still affect access. Conversely, a service that is not publicly reachable can still be accessible from other machines on a private network.
On Windows, PowerShell can show the listener and its process ID:
Get-NetTCPConnection -LocalPort 8009 -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess
Then use the OwningProcess value in:
Get-Process -Id <PID>
Replace <PID> with the process ID from the first command.
Test from another machine
A local listener check answers “is something listening here?” A remote test answers “can I connect from this network location?” Those are different questions.
From a machine you’re authorized to test, Netcat can attempt a TCP connection:
nc -vz server.example.com 8009
A successful connection means a TCP service answered at that address and port. It does not identify the service as AJP or show that the service is safe. A failed attempt could mean there is no listener, a firewall is filtering traffic, or routing does not reach the host.
If the process appears to be Tomcat, inspect the Tomcat connector configuration and relevant service logs to confirm whether AJP is enabled and how it is configured. A generic port scan is not enough to confirm the protocol. If you’re tracing a reachability problem, keep the distinction between a host listener and a network rule in mind; this guide to opening ports across servers and firewalls explains why allowing a port in one place may not make it reachable end to end.
Reduce exposure if the listener is AJP
AJP is intended for communication between trusted web and application-server components, not as a public-facing service. Don’t expose an AJP connector to the public internet unless there is a specific, reviewed requirement. Historical Tomcat vulnerabilities, including Ghostcat, are a reminder that version, configuration, and network exposure matter. An open port by itself does not prove that a system is vulnerable.
If the deployment does not need AJP, disable the connector. If it does, restrict it to the required front-end hosts or trusted network, and bind it to an appropriate private or loopback interface. Use supported Tomcat versions and follow the current connector security guidance, including configuring a secret where appropriate.
Also review host firewalls, cloud security groups, and network routing. A service intended only for an internal web server can become reachable from a much wider network if one layer is configured too broadly.
A practical checklist
When you find TCP 8009 open, work through these checks before changing anything:
-
Identify the local process. Use
sson Linux orGet-NetTCPConnectionandGet-Processon Windows. - Check the bind address. Determine whether the listener is loopback-only, private, or wildcard-bound.
- Test from the relevant network. A local check cannot tell you what a remote client can reach.
- Confirm the protocol in configuration. Don’t infer AJP from the port number alone.
- Limit access or disable the connector. Keep AJP reachable only by systems that actually need it.
The key distinction is between a port number, a process listening on that port, and a service reachable from a particular network. Checking all three gives you a much more reliable basis for deciding what to secure.
I originally published a more detailed version of this guide on the SSHFlow blog.
I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.
Top comments (0)