Skip to content

Instantly share code, notes, and snippets.

@michele-tn
Last active January 28, 2026 18:23
Show Gist options
  • Select an option

  • Save michele-tn/55ae202742d52d7616f521c22be24d55 to your computer and use it in GitHub Desktop.

Select an option

Save michele-tn/55ae202742d52d7616f521c22be24d55 to your computer and use it in GitHub Desktop.
kill_hbbs_hbbr_connections.sh is a Bash script designed to terminate active network connections on specific RustDesk server ports without stopping or killing the RustDesk server processes (hbbs and hbbr).

kill_hbbs_hbbr_connections.sh — Description

image

Overview

kill_hbbs_hbbr_connections.sh is a Bash script designed to terminate active network connections on specific RustDesk server ports without stopping or killing the RustDesk server processes (hbbs and hbbr).

The script is intended for system administrators running a self-hosted RustDesk server who need to:

  • Reset active or stuck connections
  • Force clients to reconnect
  • Perform maintenance or debugging
  • Clear established sessions without restarting services

The script relies on the Linux ss utility and uses the ss -K command to drop TCP connections at the socket level.


How RustDesk Works (Architecture Overview)

RustDesk is a remote desktop solution that attempts to establish direct client-to-client (P2P) connections when network conditions allow it (e.g. via NAT traversal / hole punching).
When a direct connection cannot be established, traffic falls back to a relay path.

This behavior is documented in the official RustDesk documentation:

In a self-hosted setup, the server-side infrastructure typically includes:

  • hbbs — Rendezvous / ID / Signaling server
    (handles client discovery, ID registration, NAT detection, and connection setup)
  • hbbr — Relay server
    (relays traffic only when direct P2P connectivity is not possible)

A detailed explanation of the architecture and connection flow is available in the official documentation:

🔗 https://github.com/rustdesk/rustdesk/wiki/How-does-RustDesk-work%3F

Connection Flow Summary

  1. A RustDesk client connects to hbbs
  2. hbbs performs:
    • Client ID registration
    • NAT type detection
    • Signaling and hole punching
  3. If a direct P2P connection is possible, traffic flows directly between peers
  4. If NAT traversal fails, traffic is relayed through hbbr
  5. Optional web clients connect via WebSocket endpoints

RustDesk Server Components and Ports

hbbs — Rendezvous & Signaling Server

Port Protocol Description
21115 TCP NAT type test and rendezvous handshake
21116 UDP Client ID registration and heartbeat
21116 TCP TCP hole punching and signaling
21118 TCP Web client support (WebSocket, optional)

hbbr — Relay Server

Port Protocol Description
21117 TCP Relay service for indirect connections
21119 TCP Web client support (WebSocket, optional)

Note
Ports 21118 and 21119 are only required if the RustDesk web client is used.
If the web client is not needed, these ports can be safely closed.


What the Script Does

The script operates only at the network connection level.

Key Characteristics

  • ✅ Drops active TCP connections
  • ❌ Does not stop or restart hbbs or hbbr
  • ❌ Does not kill processes
  • 🔒 Requires sudo privileges
  • 🎯 Targets only RustDesk-related ports

Default Target Ports

21115 21116 21117 21118 21119


Operating Modes

The script supports two execution modes:

1. established mode (recommended)

Drops only established TCP connections, leaving handshake or transient states untouched.

Command used internally:

ss -K state established sport = :PORT

This mode is safer and minimizes unintended disruption.

2. all mode

Drops all TCP connection states on the target ports. Command used internally:

ss -K sport = :PORT

This mode is more aggressive and should be used with caution.

Port Targeting

The script can operate in two ways:

  • All default RustDesk ports
  • A single specified port (e.g. 21115)

This allows precise control when troubleshooting specific components such as: Rendezvous* issues (21115)

  • Relay congestion (21117)
  • Web client sessions (21118, 21119)

Typical Use Cases

  • Resetting stuck RustDesk client sessions
  • Forcing reconnects after network changes
  • Clearing stale relay connections
  • Performing live maintenance without downtime
  • Debugging NAT traversal or relay behavior

Why This Script Is Useful

In a RustDesk self-hosted environment, restarting hbbs or hbbr:

  • Disconnects all clients
  • Interrupts active sessions
  • May impact service availability

This script provides a non-disruptive alternative, allowing administrators to control connectivity without service restarts.

Reference

Official RustDesk architecture documentation:
🔗 How does RustDesk work

👽 SCRIPT: kill_hbbs_hbbr_connections.sh

#!/bin/bash
# kill_hbbs_hbbr_connections.sh
# Kill ONLY network connections (NOT processes) for RustDesk hbbs/hbbr ports.

DEFAULT_PORTS=(21115 21116 21117 21118 21119)
DOC_LINK="https://github.com/rustdesk/rustdesk/wiki/How-does-RustDesk-work%3F"

print_intro() {
  cat <<EOF
RustDesk connection killer (connections only, processes are NOT stopped)

How RustDesk works (diagram / protocol overview):
  $DOC_LINK

Port reference (RustDesk self-hosting docs):
  hbbs (ID / rendezvous server):
    - 21115/TCP : NAT type test
    - 21116/UDP : ID registration + heartbeat
    - 21116/TCP : TCP hole punching + connection service
    - 21118/TCP : Web client support (WebSocket endpoint)

  hbbr (relay server):
    - 21117/TCP : Relay service
    - 21119/TCP : Web client support (WebSocket endpoint)

Notes:
  - If you don't need the web client, ports 21118 and 21119 can be closed.
  - This script uses 'ss -K' to drop existing TCP connections without killing hbbs/hbbr processes.

EOF
}

usage() {
  cat <<'EOF'
Usage:
  sudo ./kill_hbbs_hbbr_connections.sh [options]

Options:
  -m, --mode MODE     MODE: all | established
                      all         -> ss -K sport = :PORT
                      established -> ss -K state established sport = :PORT (recommended)

  -p, --port PORT     Kill connections only on a specific port (e.g. 21115).
                      If omitted, default ports are used:
                      21115 21116 21117 21118 21119

  -l, --list          List current TCP connections on target ports and exit.
  -h, --help          Show this help message.

Examples:
  # Recommended mode on all default ports
  sudo ./kill_hbbs_hbbr_connections.sh -m established

  # Standard mode on all default ports
  sudo ./kill_hbbs_hbbr_connections.sh -m all

  # Target a single port (recommended)
  sudo ./kill_hbbs_hbbr_connections.sh -m established -p 21115

  # List connections only
  sudo ./kill_hbbs_hbbr_connections.sh --list
EOF
}

MODE="established"
TARGET_PORT=""
DO_LIST="0"

# Print description + doc link at script start
print_intro

# Parse arguments
while [[ $# -gt 0 ]]; do
  case "$1" in
    -m|--mode)
      MODE="$2"
      shift 2
      ;;
    -p|--port)
      TARGET_PORT="$2"
      shift 2
      ;;
    -l|--list)
      DO_LIST="1"
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "Unknown argument: $1"
      echo
      usage
      exit 1
      ;;
  esac
done

# Validate mode
if [[ "$MODE" != "all" && "$MODE" != "established" ]]; then
  echo "Invalid mode: $MODE (use: all | established)"
  exit 1
fi

# Build port list
PORTS=()
if [[ -n "$TARGET_PORT" ]]; then
  if ! [[ "$TARGET_PORT" =~ ^[0-9]+$ ]] || (( TARGET_PORT < 1 || TARGET_PORT > 65535 )); then
    echo "Invalid port: $TARGET_PORT"
    exit 1
  fi
  PORTS=("$TARGET_PORT")
else
  PORTS=("${DEFAULT_PORTS[@]}")
fi

list_connections() {
  echo "Current TCP connections on ports: ${PORTS[*]}"
  for p in "${PORTS[@]}"; do
    echo "---- PORT $p ----"
    if [[ "$MODE" == "established" ]]; then
      ss -Htn state established "( sport = :$p )" || true
    else
      ss -Htan "( sport = :$p )" || true
    fi
  done
}

kill_connections() {
  for p in "${PORTS[@]}"; do
    if [[ "$MODE" == "established" ]]; then
      echo "Killing ESTABLISHED connections on port $p ..."
      ss -K state established sport = :$p >/dev/null 2>&1 || true
    else
      echo "Killing ALL connections on port $p ..."
      ss -K sport = :$p >/dev/null 2>&1 || true
    fi
  done
}

if [[ "$DO_LIST" == "1" ]]; then
  list_connections
  exit 0
fi

echo "Mode: $MODE"
echo "Ports: ${PORTS[*]}"
kill_connections
echo "Done."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment