Why a Blacklisted IP Still Appears in ss After an Imunify360 Block

An address was added to the Imunify360 blacklist after repeated web probes, yet the same address remained visible in ss and netstat. That can look like a failed block. It may instead mean that the firewall is rejecting new traffic while Linux is still tracking a connection that already existed.

The distinction matters on a LiteSpeed hosting server. The web application firewall, LiteSpeed request limits, Imunify360’s network rules, and the kernel’s connection table operate at different layers. A useful investigation proves what each layer did instead of treating one socket listing as the final verdict.

A socket entry is not proof that new traffic is accepted

ss reports sockets known to the kernel. Its output can include listening sockets, active sessions, closing sessions, and connections retained briefly in states such as TIME-WAIT. A line containing a remote address proves that a connection exists or recently existed; it does not prove that the remote client can establish another connection after the blacklist was applied.

Start by including the TCP state, local endpoint, remote endpoint, and owning process:

ss -Htanp

Then filter for a documentation address used in the investigation:

ss -Htanp | grep -F '198.51.100.27'

Interpret the state before changing the firewall:

  • ESTAB means a TCP session completed its handshake and has not closed.
  • TIME-WAIT is a normal cleanup state after a connection closes.
  • SYN-RECV means the server has seen a connection attempt that has not completed.
  • a LISTEN entry describes the local service, not a remote client session.

Record the timestamp and rerun the check. A stale connection that disappears without being replaced is different from a stream of new sessions.

Why conntrack changes the result

Stateful firewall rules classify packets by connection-tracking state. A typical policy may allow packets belonging to an established flow and apply a blacklist only when a packet begins a new flow. In the incident behind this article, inspection of the generated firewall chain showed an early return for traffic that was not in the NEW state:

-m conntrack ! --ctstate NEW -j RETURN

With that order, adding an address to the set does not retroactively terminate an established TCP session. The existing flow can remain visible and may continue until either endpoint closes it or its state expires. New handshakes from the address should match the later blacklist rule.

Do not assume every Imunify360 installation uses this exact rule. Backends, integration modes, and product releases differ. Inspect the rules actually loaded on the server and their counters. On an nftables-based system, useful read-only checks include:

nft list ruleset
ipset list

On a legacy iptables system, inspect the active rules without flushing or replacing them:

iptables-save

Look for the named set containing the address, the chain that references the set, and any state-based return placed before the drop. Packet counters that increase during a controlled test are stronger evidence than the mere presence of a rule.

Confirm the blacklist through Imunify360 itself

Current Imunify360 documentation defines the local IP-list interface for firewall entries. A drop entry can be queried without guessing an older command syntax:

imunify360-agent ip-list local list --purpose drop --by-ip 198.51.100.27

The documented add form is:

imunify360-agent ip-list local add --purpose drop 198.51.100.27 --comment "validated scanner"

According to the official Imunify360 command-line reference, the drop purpose denies access at the network level and returns HTTP 403 on web ports when traffic arrives through a proxy. The same reference also shows older blacklist syntax in a few compatibility examples, which is a good reason to consult the installed command’s help instead of copying a command written for another release:

imunify360-agent ip-list local --help

A successful CLI response proves that the entry was accepted by Imunify360. It does not by itself prove where the packet was dropped. Correlate the entry with the generated firewall set and rule counters.

Test a new connection, not the old one

The most direct verification is a fresh connection from the blocked source after the rule is active. Test only infrastructure you control. Do not reuse the existing browser tab or keep-alive connection because it can remain on the old TCP session.

A controlled test should answer four questions:

  1. Was the blacklist entry present before the test began?
  2. Did a brand-new TCP handshake succeed?
  3. Did the firewall or web-server counter increase?
  4. Did the access, error, or security audit log record the request?

If the new connection fails while an older ESTAB line remains, the blacklist is doing exactly what a new-connection policy is designed to do. If new sessions continue to succeed, inspect rule ordering, the actual ingress interface, proxy handling, trusted-address lists, and whether another firewall backend is active.

Avoid deleting conntrack state as a routine test. Doing so can interrupt legitimate sessions and obscures the more important question: whether the deployed policy handles the next connection correctly.

Place LiteSpeed logs in the correct integration layer

The original troubleshooting also exposed a separate logging error: LiteSpeed WebAdmin was pointed at an Apache-oriented path that the process could not read. On a native LiteSpeed virtual host, the current LiteSpeed security configuration uses:

$SERVER_ROOT/logs/security_audit.log

That advice does not transfer unchanged to a cPanel virtual host generated from Apache configuration. LiteSpeed’s cPanel ModSecurity documentation says not to configure those rules in WebAdmin because WebAdmin rules apply to native LSWS virtual hosts. For cPanel-managed sites, configure the rules through the control-panel/Apache integration. The same documentation states that LSWS supports serial ModSecurity audit logging, not concurrent logging.

This prevents a common diagnostic trap: a missing audit entry may indicate the wrong log mode or configuration layer, not the absence of malicious traffic.

Throttling, WAF rules, and blacklists solve different problems

A scanner requesting .env, phpinfo paths, and other common exposures can be handled at several layers:

  • a WAF rule matches the request pattern and can return a denial;
  • per-client throttling limits request or connection rates;
  • LiteSpeed anti-DDoS controls react to abusive web behavior;
  • an Imunify360 drop entry applies a network-level decision;
  • application controls protect login and API endpoints with their own context.

These controls complement each other. Five requests per second is not automatically malicious, and one user-agent string is trivial to change. Base a block on observed behavior, affected endpoints, response codes, and sustained rate rather than a single label such as python-httpx.

LiteSpeed’s cPanel anti-DDoS guide recommends reviewing the relevant ModSecurity rule and audit log when a web request causes a block. That evidence can explain why the server acted and whether a threshold is too aggressive.

Treat shared egress addresses carefully

The observed address belonged to a range associated with a large network provider even though the site was not behind that provider’s reverse proxy. That is not contradictory. A visitor can use a consumer VPN, privacy relay, corporate gateway, or other shared egress service, making the transport peer an address owned by the service.

Do not blacklist an entire provider range simply because one address scanned the site. A broad block can affect unrelated visitors who share the same egress pool. Begin with the smallest justified scope, set an expiration where appropriate, and retain enough log context to review the decision later.

If the server does use a reverse proxy, only trust forwarded client-IP headers from explicitly trusted proxy addresses. Otherwise an attacker can forge the header and shift blocking or logging to an innocent address.

A defensible verification sequence

When a blacklisted IP still appears connected, use this sequence:

  1. Capture ss output with TCP states and process ownership.
  2. Confirm the Imunify360 drop entry using the syntax supported by the installed release.
  3. Inspect the active nftables, ipset, or iptables path and its rule order.
  4. Identify whether the visible socket predates the blacklist.
  5. Attempt a new connection from a controlled source, without connection reuse.
  6. Correlate firewall counters with LiteSpeed access, error, and ModSecurity audit logs.
  7. Verify that LiteSpeed logging is configured in the correct native or cPanel integration layer.
  8. Narrow the block to the smallest justified address or network and document its expiration.

The decisive evidence is not that an address disappeared instantly from ss. It is that new prohibited traffic cannot reach the service, the responsible control records the decision, and legitimate traffic continues normally.

Related Guides