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 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.
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.
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.
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
/procand/etc/hostsas 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.
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.
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.
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 |