sslh
Overview
Section titled “Overview”sslh is a protocol multiplexer that accepts incoming connections on a single port and routes them to appropriate backends based on protocol detection. This allows running multiple services (HTTPS, SSH, OpenVPN, etc.) on the same port 443.
Key Features
Section titled “Key Features”- Multiplex multiple protocols on single port
- Transparent protocol detection
- Load balancing capabilities
- IPv4 and IPv6 support
- TLS/SSL certificate forwarding
- HTTPS, SSH, OpenVPN, Xmpp support
- Lightweight and efficient
- Systemd integration
- ACL-based routing
Use Cases
Section titled “Use Cases”- Unified port access for multiple services
- Firewall policy compliance (single port)
- Network security with limited open ports
- Accessing services through restrictive firewalls
- Server consolidation
- Penetration testing from restricted networks
Installation
Section titled “Installation”Linux/Debian-based
Section titled “Linux/Debian-based”sudo apt-get update
sudo apt-get install sslh
brew install sslh
CentOS/RHEL
Section titled “CentOS/RHEL”sudo yum install sslh
Build from Source
Section titled “Build from Source”git clone https://github.com/yob/sslh.git
cd sslh
make
sudo make install
Configuration
Section titled “Configuration”Basic Configuration File
Section titled “Basic Configuration File”Default location: /etc/sslh/sslh.cfg
# sslh configuration file
verbose: false;
foreground: false;
inetd: false;
numeric: true;
# Listen on port 443 for all incoming connections
listen:
(
{ host: "0.0.0.0"; port: "443"; }
);
# Protocol-specific backends
protocols:
(
# HTTPS traffic to Apache
{ name: "https"; host: "localhost"; port: "8443"; },
# SSH traffic to SSH server
{ name: "ssh"; host: "localhost"; port: "22"; },
# OpenVPN
{ name: "openvpn"; host: "localhost"; port: "1194"; },
# XMPP
{ name: "xmpp"; host: "localhost"; port: "5222"; }
);
# Logging
logfile: "/var/log/sslh/sslh.log";
pidfile: "/var/run/sslh.pid";
Listen on Multiple Ports
Section titled “Listen on Multiple Ports”listen:
(
{ host: "0.0.0.0"; port: "443"; },
{ host: "0.0.0.0"; port: "8443"; },
{ host: "::"; port: "443"; } # IPv6
);
SSL/TLS Pass-through Configuration
Section titled “SSL/TLS Pass-through Configuration”protocols:
(
{
name: "https";
host: "localhost";
port: "8443";
sni_hostnames: [ "example.com", "www.example.com" ];
},
{ name: "ssh"; host: "localhost"; port: "22"; }
);
Basic Usage
Section titled “Basic Usage”Start sslh Service
Section titled “Start sslh Service”sudo systemctl start sslh
Enable on Boot
Section titled “Enable on Boot”sudo systemctl enable sslh
Check Service Status
Section titled “Check Service Status”sudo systemctl status sslh
View Service Logs
Section titled “View Service Logs”sudo journalctl -u sslh -f
Running sslh Manually
Section titled “Running sslh Manually”Foreground Mode (Debugging)
Section titled “Foreground Mode (Debugging)”sudo sslh -f -v -c /etc/sslh/sslh.cfg
Flags:
-f: Foreground (don’t daemonize)-v: Verbose output-c: Configuration file path
Background Mode
Section titled “Background Mode”sudo sslh -c /etc/sslh/sslh.cfg
Test Configuration
Section titled “Test Configuration”sudo sslh -t -c /etc/sslh/sslh.cfg
Validates configuration without starting service.
Routing Configurations
Section titled “Routing Configurations”HTTPS + SSH on Port 443
Section titled “HTTPS + SSH on Port 443”protocols:
(
{ name: "https"; host: "localhost"; port: "8443"; },
{ name: "ssh"; host: "localhost"; port: "22"; }
);
Upstream services needed:
- HTTPS web server on port 8443
- SSH server on port 22
HTTPS + SSH + OpenVPN + XMPP
Section titled “HTTPS + SSH + OpenVPN + XMPP”protocols:
(
{ name: "https"; host: "localhost"; port: "8443"; },
{ name: "ssh"; host: "localhost"; port: "22"; },
{ name: "openvpn"; host: "localhost"; port: "1194"; },
{ name: "xmpp"; host: "localhost"; port: "5222"; }
);
Remote Server Routing
Section titled “Remote Server Routing”protocols:
(
{
name: "https";
host: "10.0.0.5";
port: "8443";
},
{
name: "ssh";
host: "10.0.0.6";
port: "22";
}
);
Route to different backend servers by protocol.
Load Balanced HTTPS
Section titled “Load Balanced HTTPS”protocols:
(
{
name: "https";
host: "localhost";
port: "8443";
},
{
name: "https";
host: "localhost";
port: "8444";
}
);
Round-robin between multiple web servers.
Client Connection Methods
Section titled “Client Connection Methods”Connect via SSH Through sslh
Section titled “Connect via SSH Through sslh”# Server running sslh on port 443
ssh -p 443 user@example.com
# Or with specific config
ssh -p 443 -o "StrictHostKeyChecking=no" user@example.com
Connect via HTTPS
Section titled “Connect via HTTPS”curl https://example.com:443/
# Web browser: https://example.com:443
OpenVPN Through sslh
Section titled “OpenVPN Through sslh”Configure OpenVPN client to connect to:
remote example.com 443
proto tcp
Stunnel Integration (for non-TLS Protocols)
Section titled “Stunnel Integration (for non-TLS Protocols)”Some protocols need encapsulation in TLS:
# stunnel wrapper for SSH through HTTPS port
[ssh-over-https]
client = yes
accept = localhost:2222
connect = example.com:443
Advanced Configurations
Section titled “Advanced Configurations”SNI-Based Routing
Section titled “SNI-Based Routing”protocols:
(
{
name: "https";
host: "localhost";
port: "8443";
sni_hostnames: [ "api.example.com" ];
},
{
name: "https";
host: "localhost";
port: "8445";
sni_hostnames: [ "www.example.com" ];
}
);
Routes based on SNI hostname in TLS ClientHello.
Alpha Protocol (Fallback)
Section titled “Alpha Protocol (Fallback)”protocols:
(
{ name: "https"; host: "localhost"; port: "8443"; },
{ name: "ssh"; host: "localhost"; port: "22"; },
{ name: "tls"; host: "localhost"; port: "443"; } # Catch-all
);
User-Based ACLs
Section titled “User-Based ACLs”protocols:
(
{
name: "https";
host: "localhost";
port: "8443";
user_filter: [ "user1", "user2" ];
},
{ name: "ssh"; host: "localhost"; port: "22"; }
);
Inetd Mode (xinetd Integration)
Section titled “Inetd Mode (xinetd Integration)”inetd: true;
protocols:
(
{ name: "https"; host: "localhost"; port: "8443"; },
{ name: "ssh"; host: "localhost"; port: "22"; }
);
Setting Up Backend Services
Section titled “Setting Up Backend Services”Configure HTTPS Listener
Section titled “Configure HTTPS Listener”# Apache HTTPS on 8443
sudo a2enmod ssl
sudo a2enmod rewrite
# Create SSL config pointing to port 8443
# in /etc/apache2/sites-available/ssl.conf
<VirtualHost *:8443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/ssl/certs/server.crt
SSLCertificateKeyFile /etc/ssl/private/server.key
</VirtualHost>
sudo systemctl restart apache2
SSH Server Setup
Section titled “SSH Server Setup”# Ensure SSH runs on default port 22
sudo nano /etc/ssh/sshd_config
# Port 22
sudo systemctl restart ssh
OpenVPN Backend Configuration
Section titled “OpenVPN Backend Configuration”# /etc/openvpn/server.conf
port 1194
proto tcp
ca ca.crt
cert server.crt
key server.key
dh dh.pem
# Point clients to port 443
Certificate Management
Section titled “Certificate Management”# Self-signed certificate for sslh
sudo openssl req -x509 -newkey rsa:2048 \
-keyout /etc/ssl/private/sslh.key \
-out /etc/ssl/certs/sslh.crt \
-days 365 -nodes
Network Configuration
Section titled “Network Configuration”Firewall Rules (iptables)
Section titled “Firewall Rules (iptables)”# Allow incoming on port 443
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow SSH and HTTPS backends
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8443 -j ACCEPT
# Save rules
sudo iptables-save > /etc/iptables/rules.v4
UFW Rules
Section titled “UFW Rules”sudo ufw allow 443/tcp
sudo ufw allow 22/tcp
sudo ufw allow 8443/tcp
sudo ufw enable
IPv6 Support
Section titled “IPv6 Support”listen:
(
{ host: "0.0.0.0"; port: "443"; }, # IPv4
{ host: "::"; port: "443"; } # IPv6
);
Monitoring and Logging
Section titled “Monitoring and Logging”View Real-time Logs
Section titled “View Real-time Logs”sudo journalctl -u sslh -f
Check Process Status
Section titled “Check Process Status”ps aux | grep sslh
Monitor Connections
Section titled “Monitor Connections”sudo netstat -antp | grep 443
# or
sudo ss -antp | grep 443
Enable Verbose Logging
Section titled “Enable Verbose Logging”# In /etc/sslh/sslh.cfg
verbose: true;
logfile: "/var/log/sslh/sslh.log";
Log Analysis
Section titled “Log Analysis”# Count connections by protocol
sudo grep "Accepted" /var/log/sslh/sslh.log | \
awk '{print $NF}' | sort | uniq -c
# Monitor in real-time
sudo tail -f /var/log/sslh/sslh.log
Troubleshooting
Section titled “Troubleshooting”Connection Refused
Section titled “Connection Refused”Issue: Clients can’t connect to multiplexed port.
Solution:
# 1. Check sslh is running
sudo systemctl status sslh
# 2. Verify configuration
sudo sslh -t -c /etc/sslh/sslh.cfg
# 3. Check backend services
sudo netstat -antp | grep 8443
sudo netstat -antp | grep 22
# 4. Verify port binding
sudo netstat -antp | grep 443
Protocol Detection Fails
Section titled “Protocol Detection Fails”Issue: Traffic routing to wrong backend.
Solution:
# Test with verbose logging
sudo systemctl stop sslh
sudo sslh -f -v -c /etc/sslh/sslh.cfg
# Attempt connection and watch output
# Modify protocol detection if needed
Backend Service Not Responding
Section titled “Backend Service Not Responding”Issue: Service exists but sslh can’t route to it.
Solution:
# Test backend connectivity
nc -zv localhost 8443 # HTTPS backend
ssh -p 22 localhost # SSH backend
# Verify firewall allows traffic
sudo iptables -L -n | grep 8443
# Check backend service configuration
sudo lsof -i :8443
High CPU Usage
Section titled “High CPU Usage”Issue: sslh consuming excessive CPU.
Solution:
# Check for connection storms
sudo netstat -antp | grep 443 | wc -l
# Implement rate limiting
sudo iptables -A INPUT -p tcp --dport 443 \
-m limit --limit 100/second --limit-burst 200 -j ACCEPT
# Monitor process
top -p $(pidof sslh)
Performance Optimization
Section titled “Performance Optimization”Connection Limits
Section titled “Connection Limits”# Increase file descriptor limit
sudo ulimit -n 65536
# Make permanent in /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536
TCP Tuning
Section titled “TCP Tuning”# Optimize for connection multiplexing
sudo sysctl -w net.core.somaxconn=4096
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=4096
Multiple sslh Instances
Section titled “Multiple sslh Instances”# Run multiple multiplexers for load distribution
sudo sslh -l localhost:1443 &
sudo sslh -l localhost:1444 &
# Load balance with nginx upstream
upstream sslh {
server localhost:1443;
server localhost:1444;
}
Security Best Practices
Section titled “Security Best Practices”| Practice | Reason |
|---|---|
| Use firewall rules | Restrict access to multiplexer |
| Monitor logs | Detect suspicious patterns |
| Validate certificates | Ensure backend authenticity |
| Rate limit connections | Prevent DoS attacks |
| Keep updated | Security patches and bug fixes |
Restrict Backend Access
Section titled “Restrict Backend Access”# Only allow sslh to connect to backends
sudo iptables -A INPUT -p tcp --dport 8443 \
-s localhost -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8443 -j DROP
Integration Examples
Section titled “Integration Examples”With nginx
Section titled “With nginx”upstream http_backend {
server localhost:8443;
}
server {
listen 8443 ssl;
ssl_certificate /etc/ssl/certs/server.crt;
ssl_certificate_key /etc/ssl/private/server.key;
location / {
proxy_pass https://http_backend;
}
}
With Docker
Section titled “With Docker”FROM ubuntu:22.04
RUN apt-get update && apt-get install -y sslh
COPY sslh.cfg /etc/sslh/sslh.cfg
EXPOSE 443
CMD ["sslh", "-f", "-c", "/etc/sslh/sslh.cfg"]
Docker Compose
Section titled “Docker Compose”version: '3'
services:
sslh:
image: sslh:latest
ports:
- "443:443"
volumes:
- ./sslh.cfg:/etc/sslh/sslh.cfg
depends_on:
- web
- ssh
web:
image: nginx:latest
expose:
- "8443"
ssh:
image: linux:ssh
expose:
- "22"
References
Section titled “References”- GitHub: yob/sslh
- Documentation: sslh README
- Man Page:
man sslh - Protocol Detection: SSLH Protocols
Quick Reference
Section titled “Quick Reference”# Start service
sudo systemctl start sslh
# Test configuration
sudo sslh -t -c /etc/sslh/sslh.cfg
# Run in foreground with verbose output
sudo sslh -f -v -c /etc/sslh/sslh.cfg
# Connect via SSH (multiplexed)
ssh -p 443 user@server
# Connect via HTTPS
curl https://server:443/
# View logs
sudo journalctl -u sslh -f
# Monitor connections
sudo ss -antp | grep 443