Security Best Practices for Speedify Self-Hosted Servers

This document describes security hardening recommendations for anyone running a self-hosted Speedify speed server. The recommendations are derived from the production configuration used across the Speedify server fleet.


Table of Contents


SSH Hardening

SSH is the primary remote administration channel. A misconfigured SSH daemon is one of the most common entry points for attackers.

Disable password authentication

PasswordAuthentication no
PermitEmptyPasswords no

Use SSH key pairs exclusively. Password-based authentication is susceptible to brute-force attacks.

Disable root login

PermitRootLogin no

All administrative access should go through a named user account with sudo privileges. On the host, disable the root password entirely:

usermod -p '!' root

Restrict protocol and authentication methods

Protocol 2
HostbasedAuthentication no
IgnoreRhosts yes
PermitUserEnvironment no

SSH protocol 1 has known cryptographic weaknesses. Rhosts and host-based authentication are legacy mechanisms that should never be enabled.

Limit authentication attempts and session parameters

MaxAuthTries 4
LoginGraceTime 60
ClientAliveInterval 30
ClientAliveCountMax 240
TCPKeepAlive no

LoginGraceTime 60    disconnects unauthenticated sessions after 60 seconds. ClientAliveInterval  with ClientAliveCountMax  provides application-layer keepalive detection (more reliable than TCPKeepAlive   ).

Restrict MAC algorithms

MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com

This disables weak MAC algorithms (MD5, SHA-1, and non-ETM variants where stronger alternatives exist). Prefer the etm  (encrypt-then-MAC) variants.

Disable X11 forwarding

X11Forwarding no

Speed servers have no graphical interface. X11 forwarding expands the attack surface unnecessarily.

Restrict which users can log in

AllowUsers youruser1 youruser2

Explicitly whitelist the user accounts permitted to SSH into the server. This prevents any other local account from being used as an SSH entry point.

Set a login banner

Banner /etc/issue.net

A legal banner can serve as a notice to unauthorized users and may be required for compliance in some jurisdictions.

Lock down file permissions

chmod 0600 /etc/ssh/sshd_config

The SSH daemon configuration should only be readable by root.


Firewall Configuration

Speed servers route VPN client traffic to the internet. Without strict firewall rules, clients can abuse the server for spam, attacks, or access to internal services.

Default-deny inbound policy

chain INPUT {
  policy DROP;
  mod state state INVALID DROP;
  mod state state (ESTABLISHED RELATED) ACCEPT;
  interface lo ACCEPT;
  proto icmp icmp-type echo-request ACCEPT;
  # ... explicit allow rules for needed ports ...
}

Start from a DROP-all baseline and only open the ports you need. At minimum:

  • The SSH port (from trusted IPs only -- bastion hosts or office IPs)
  • Ports used by the speed server for VPN client connections
  • Port 9100 from Docker bridge networks for Prometheus node-exporter

Restrict SSH access by source IP

Limit SSH access to known bastion hosts or management IPs rather than opening it to the world:

proto tcp saddr <bastion-ip>/32 dport <ssh-port> ACCEPT;

Block abusable egress ports

VPN clients will attempt to route arbitrary traffic through the server. Block the most commonly abused protocols in the DOCKER-USER chain (which applies to all container-originated traffic):

# Block SMTP (spam)
proto tcp dport 25 DROP;

# Block SMB (worm propagation, lateral movement)
proto (tcp udp) dport 445 DROP;

# Block DHCP (network disruption)
proto udp dport (67 68) DROP;

Block access to private networks and cloud metadata

Prevent VPN clients from reaching internal infrastructure, RFC 1918 addresses, and cloud provider metadata endpoints:

daddr 169.254.169.254/32 DROP;   # Cloud metadata (AWS, GCP, Azure, etc.)
daddr 10.0.0.0/8 DROP;
daddr 172.16.0.0/12 DROP;
daddr 192.168.0.0/16 DROP;

This is critical -- without it, a VPN client could query the instance metadata service and potentially extract credentials or other sensitive information.

Block torrent traffic

If you do not want your server used for torrenting (which generates abuse complaints and may violate hosting provider ToS):

# String matching on HTTP tracker announces
proto (tcp udp) dport 80 mod string string ("announce.php?passkey=" "info_hash" "get_peers") algo bm from 1 to 1024 jump BTSUSPECT;

# String matching on high ports for peer protocol
proto (tcp udp) dport 1024:65535 mod string string ("get_peers" "info_hash" "BitTorrent protocol") algo bm from 1 to 1024 jump BTSUSPECT;

Supplement string matching with an IP blocklist of known BitTorrent trackers (e.g., from ngosang/trackerslist).

Block known malware signatures

Use iptables string matching to detect and drop traffic containing known malware patterns:

# Drop all traffic from hosts that matched a malware signature in the past 30s
mod recent name "malware" rcheck seconds 30 DROP;

# Match malware HTTP signatures
proto tcp dport 80 mod string hex-string <patterns> algo bm to 1024 jump MALWARE;

# Match SIP scanners
proto udp dport 5060 mod string string ("User-Agent: VaxSIPUserAgent" "User-Agent: friendly-scanner") algo bm to 65535 jump MALWARE;

Also block known malware C&C IP addresses (Phorpiex, Lethic, sinkholes).

Block the Docker API from containers

Prevent containers from reaching the Docker daemon on the bridge network:

proto (tcp udp) daddr 172.17.0.0/16 dport 2375 DROP;

If a container is compromised, access to the Docker socket/API would give the attacker full control of the host.

Rate-limit ICMP

proto icmp icmp-type echo-request mod hashlimit hashlimit-above 10/second hashlimit-burst 1 hashlimit-mode "srcip" hashlimit-name pingratelimit jump LOGDROP;

Port scan detection

For sensitive ports (SSH, RDP), use hashlimit rules to detect and block scanning activity:

chain BLOCKSCANBYPORT {
  # Allow repeated connections to the same destination IP
  mod hashlimit hashlimit-above 5/minute hashlimit-mode "srcip,dstport,dstip" hashlimit-name blockScanPortSingleIPaccept RETURN;

  # Detect slow scanners
  mod hashlimit hashlimit-above 30/hour hashlimit-mode "srcip,dstport" hashlimit-name blockScanPortSlowSuspect jump SUSPECTSLOWSCANNING;

  # Allow up to 10 connection attempts per minute across all IPs for a given port
  mod hashlimit hashlimit-upto 10/minute hashlimit-mode "srcip,dstport" hashlimit-name blockScanPortAllowed RETURN;

  # Drop everything else
  DROP;
}

Reload firewall rules on a schedule

Firewall rules that reference external blocklists (emerging threats, torrent trackers) should be refreshed daily via cron.


Kernel & Network Hardening

Base security sysctl settings

These should be applied on every speed server:

# Disable ICMP redirects (prevent MITM routing attacks)
sysctl -w net.ipv4.conf.all.accept_redirects=0
sysctl -w net.ipv4.conf.default.accept_redirects=0
sysctl -w net.ipv4.conf.all.secure_redirects=0
sysctl -w net.ipv4.conf.default.secure_redirects=0


# Ignore ICMP broadcast requests (prevent smurf attacks)
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1


# Ignore bogus ICMP error responses
sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1


# Disable core dumps for SUID binaries
sysctl -w fs.suid_dumpable=0

Speed server-specific TCP/network tuning

These settings optimize the network stack for high-throughput VPN workloads:

# BBR congestion control (requires kernel >= 4.9)
sysctl -w net.core.default_qdisc=fq
sysctl -w net.ipv4.tcp_congestion_control=bbr


# Connection tracking limits (tune based on expected concurrent connections)
sysctl -w net.ipv4.tcp_max_orphans=131072
sysctl -w net.ipv4.tcp_max_syn_backlog=2048
sysctl -w net.ipv4.tcp_max_tw_buckets=131072


# TCP/UDP memory limits (in pages; tune to your server's RAM)
sysctl -w net.ipv4.tcp_mem="285594 380793 571188"
sysctl -w net.ipv4.udp_mem="571188 761587 1142376"


# Loose-mode reverse path filtering
# Value 2 (loose) is needed because VPN traffic arrives on interfaces
# that may not match the kernel's routing table for the source address.
sysctl -w net.ipv4.conf.default.rp_filter=2
sysctl -w net.ipv4.conf.all.rp_filter=2


# Ephemeral port range
sysctl -w net.ipv4.ip_local_port_range="49152 65535"


# Disable IPv6 Router Advertisement acceptance
sysctl -w net.ipv6.conf.all.accept_ra=0
sysctl -w net.ipv6.conf.docker0.accept_ra=0

inotify limits

If running many VPN containers with dnsmasq (as simple-ss does):

sysctl -w fs.inotify.max_user_instances=16384
sysctl -w fs.inotify.max_user_watches=16384

Persist settings

Add all sysctl settings to /etc/sysctl.d/99-speedify.conf so they survive reboots.


Docker Security

The ss-manager runs as a Docker container and dynamically spawns VPN session containers. Docker security is therefore critical.

Disable the userland proxy

In /etc/docker/daemon.json   :

{
  "userland-proxy": false
}

The userland proxy (docker-proxy) is a user-space TCP/UDP forwarder that Docker uses by default for port publishing. Disabling it forces Docker to use native iptables NAT rules instead, which is more performant and avoids an extra process per published port.

Restrict log sizes

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "500m"
  }
}

Without log size limits, a misbehaving container can fill the disk and cause a denial of service.

Limit ss-manager container core dumps

Run the ss-manager container with:

ulimits:
  - core:0:0

This prevents core dumps inside the container, which could contain sensitive data (encryption keys, session tokens).

Mount the Docker socket carefully

The ss-manager needs /var/run/docker.sock to spawn VPN containers. This grants full Docker API access -- effectively root on the host. Mitigations:

  • Run the ss-manager with restart_policy: always, so it recovers from crashes rather than leaving the socket exposed to a replacement container.
  • Mount /proc    and /etc/hosts    as read-only (:ro   ).
  • Mount binary directories as read-only (:ro   ).
  • Do not expose the Docker TCP API (port 2375) -- only use the Unix socket.
  • Block container access to port 2375 on the bridge network via firewall rules (see Section 2).

Network isolation

Create a dedicated Docker bridge network for VPN client containers:

docker network create \
  --driver bridge \
  --opt com.docker.network.bridge.enable_icc=true \
  --opt com.docker.network.bridge.enable_ip_masquerade=true \
  --opt com.docker.network.driver.mtu=1500 \
  --subnet 172.30.0.0/16 \
  --gateway 172.30.0.1 \
  vpnclients

This isolates VPN client containers from the default bridge network where management containers (Traefik, ss-manager) run.


User & Access Management

Minimal user accounts

Create only the accounts needed for administration. Each person should have a named account -- no shared accounts.

Dedicated operations group with sudo

groupadd operations

echo '%operations ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/operations
visudo -c  # validate syntax

Add administrative users to both operations and docker groups. This provides full sudo access while maintaining individual accountability via audit logs.

SSH key management

For each user, deploy their public key with restrictive permissions:

mkdir -p /home/<user>/.ssh
chmod 0700 /home/<user>/.ssh

# Deploy authorized_keys
chmod 0600 /home/<user>/.ssh/authorized_keys

Remove any users no longer needing access promptly.

Remove unnecessary packages

apt-get remove --purge telnet

Telnet transmits credentials in plaintext. It should never be installed on a production server.


System Hardening

Disable unused filesystem kernel modules

Prevent loading of filesystem types that are never needed on a speed server. This reduces the kernel attack surface:

for fs in cramfs freevxfs jffs2 hfs hfsplus squashfs udf; do
  echo "install ${fs} /bin/true" > /etc/modprobe.d/${fs}.conf
  modprobe -r ${fs} 2>/dev/null || true
done

Restrict cron directory permissions

chmod og-rwx /etc/crontab
chmod -R og-rwx /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly /etc/cron.d

Prevents unprivileged users from reading or modifying scheduled tasks.

Restrict core dumps In /etc/security/limits.conf:

* hard core 0

Combined with fs.suid_dumpable=0 (Section 3), this prevents core dumps that could leak sensitive data from memory.

Set timezone to UTC

timedatectl set-timezone Etc/UTC

Consistent timestamps across all servers simplify log correlation and incident response.

Install an entropy daemon

apt-get install haveged
systemctl enable --now haveged

Speed servers perform extensive cryptographic operations. haveged ensures the entropy pool stays adequately filled, preventing blocking on /dev/random and ensuring strong key generation.


Logging & Monitoring

Log rotation and cleanup

Set up cron jobs to clean up old VPN session logs:

# Delete speed server session logs older than N days
find /var/log/speedify/servers -regextype posix-egrep -regex ".*/20[0-9][0-9]/.*" -mtime +<days> -delete


# Delete analytics JSON files older than 2 days
find /var/log/speedify/analytics -name "*.json" -mtime +2 -delete

Without log rotation, a busy speed server will fill its disk.

Container log limits

The ss-manager container should have its own log size cap:

log_driver: json-file
log_options:
  max-size: "100m"

Export metrics with Prometheus node-exporter

Run node-exporter to provide system-level metrics (CPU, memory, disk, network).

Restrict access to the Docker bridge network:

# In firewall rules:
proto tcp saddr 172.16.0.0/12 dport 9100 ACCEPT;

Do not expose port 9100 to the public internet.

IP reputation monitoring

Periodically check your server's public IP addresses against reputation blocklists. Being listed on a DNSBL or having a poor IP quality score means your server may be blocked by destination services, degrading the experience for all users.

Vulnerability scanning

Run a vulnerability scanner (e.g., Vuls) on a regular schedule (e.g., twice per month) to identify unpatched packages. Speed servers are internet-facing and process untrusted traffic, making timely patching especially important.


Summary Checklist

Category Key Action Priority
SSH Disable password auth, disable root login Critical
SSH Restrict AllowUsers, set MACs High
Firewall Default-deny INPUT Critical
Firewall Block SMTP, SMB, DHCP egress High
Firewall Block cloud metadata (169.254.169.254) Critical
Firewall Block private subnets from VPN clients Critical
Firewall Block Docker API (2375) from containers Critical
Firewall Torrent/malware blocking Medium
Kernel Disable ICMP redirects High
Kernel BBR congestion control Medium
Kernel Loose-mode reverse path filtering High
Docker Disable userland proxy Medium
Docker Log size limits High
Docker Mount filesystems read-only where possible High
Users Key-only auth, named accounts Critical
System Disable unused filesystem modules Medium
System Restrict cron permissions Medium
System Install entropy daemon (haveged) Medium
Logging Log rotation/cleanup cron jobs High
Logging Prometheus metrics export (restricted) Medium