SSH TUNNEL
PORT FORWARD
-L -R -D
LONG-LIVED
DetectionBlue TeamSOCOctober 12, 2026•9 min read

Detecting SSH Tunneling: Port Forwarding and Long-Lived Sessions

SSH is installed everywhere and trusted by default, which is exactly why it is such a durable tunnel. The forwarding flags are loud on the command line and the sessions are unusually long on the wire.

Scroll

SSH port forwarding turns an encrypted admin channel into a general-purpose tunnel. The three flags that matter are -L (local forward), -R (remote forward) and -D (dynamic SOCKS proxy). Because the payload is encrypted, we detect the tunnel from process arguments, session duration and byte symmetry rather than from content.

Signals at a Glance

SignalWhereATT&CK
ssh/plink process with -L, -R or -D forwarding flagsSysmon 1, 4688, auditd, EDRT1572
Outbound SSH from a workstation or non-admin server to the InternetFirewall, Zeek conn.logT1572
Session lasting hours with steady bidirectional bytesZeek conn.log, NetFlowT1090
ssh -D opens a local SOCKS listener on the clientEDR listening-port telemetryT1090.001
sshd with AllowTcpForwarding or GatewayPorts enabled on servers that do not need itConfig auditT1021.004

Command-Line Forwarding Flags

The forwarding flags are explicit and rarely appear in routine administration of a workstation. The Windows OpenSSH client ships with the OS, so ssh.exe on an endpoint with -R or -D deserves a look. Start with a process-creation rule:

title: SSH Client Port Forwarding Flags
logsource:
  category: process_creation
  product: windows
detection:
  selection_img:
    Image|endswith:
      - '\ssh.exe'
      - '\plink.exe'
  selection_flags:
    CommandLine|contains:
      - ' -R '
      - ' -L '
      - ' -D '
      - ' -N '
  condition: selection_img and selection_flags
level: medium
# tune/validate: allow-list admin jump hosts and developer workstations;
# -N with -R or -D (no remote command) is the higher-signal combination.

Linux hosts need auditd execve or EDR telemetry for the same arguments. The same logic applies there: forwarding flags combined with -N and -f (background, no command) indicate a tunnel rather than an interactive session.

Session Duration and Server Configuration

On the wire we cannot read the payload, but we can measure it. Interactive SSH is bursty and short; a tunnel carrying proxied traffic stays up for hours and moves data in both directions. Start from Zeek connection logs:

# Splunk (Zeek conn.log) - long outbound SSH to external hosts
index=zeek sourcetype=bro_conn id.resp_p=22 service=ssh
| where duration > 3600 AND NOT cidrmatch("10.0.0.0/8", 'id.resp_h')
| eval ratio=round(orig_bytes/(resp_bytes+1),2)
| stats count AS sessions, max(duration) AS longest, sum(orig_bytes) AS up, sum(resp_bytes) AS down
    BY id.orig_h, id.resp_h
| sort - longest
# tune/validate: exclude approved bastions, Git hosting and vendor support
# destinations, and consider non-22 ports where ssh is detected by app-ID.
Vetted sources

Use the SigmaHQ process-creation rules for SSH and plink tunneling, Elastic detection rules for SSH port forwarding, Splunk ESCU analytic stories for lateral movement over SSH, and Zeek connection and SSH logs. Always baseline your own environment — administrators and developers use forwarding legitimately, so scope by host role.

Build Detections That Fire

Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.

Detection EngineeringManaged Detection & ResponseThreat HuntingIncident ResponsePurple Teaming
  • Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
  • Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
  • 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Written by: Mjolnir Threat Research (MTAC)  |  Published: October 12, 2026  |  Last reviewed: October 12, 2026