Jamyy's Weblog

sslh: 讓 TCP/443 同時提供 SSH、HTTPS、OpenVPN 服務

by Jamyy on 十月.13, 2016, under Linux

假設 Linux 主機 IP 位址為 192.168.1.1
透過防火牆 NAT (port redirection) 提供對外服務

原防火牆 NAT 設置
Public Port: TCP/2468 → Private: 192.168.1.1:22 (SSH)
Public Port: TCP/443 → Private: 192.168.1.1:443 (HTTPS)
Public Port: TCP/1194 → Private: 192.168.1.1:1194 (OpenVPN)

使用 SSLH 接應各服務之後的防火牆 NAT 設置
Public Port: TCP/443 → Private: 192.168.1.1:443 (SSH、HTTPS、OpenVPN)

環境: CentOS 6

新增 private IP address

# cd /etc/sysconfig/network-scripts/
# cp -a ifcfg-eth0 ifcfg-eth0:0
# vi ifcfg-eth0:0

#修改以下內容
DEVICE=eth0:0
IPADDR=172.16.0.1
NETMASK=255.255.255.255

# service network restart
# ip addr show eth0

確認出現 172.16.0.1/32

設定 sshd 服務

# vi /etc/ssh/sshd_config

#for SSLH
ListenAddress 172.16.0.1:22

#for Direct-Connection
ListenAddress 192.168.1.1:2468

# service sshd restart
# ss -ntulp | grep sshd

確認 sshd 聆聽指定 IP 與 port

說明:

  1. 如果區域網路內使用 TCP/22 進行 SSH 連線的話, 其實讓 sshd 聆聽於 0.0.0.0:22 無妨
  2. 最好不要讓 sshd 只聆聽於 172.16.0.1:22, 萬一 sslh 未啟動或 crash 將無法 SSH 連入主機

設定 HTTPS 服務

# vi /etc/httpd/conf.d/ssl.conf

Listen 172.16.0.1:443

# service httpd restart
# ss -ntulp | grep httpd

確認 httpd 聆聽 172.16.0.1:443

說明:

  1. 因為 sslh 使用 TCP/443 接應服務, 因此必須將 HTTPS 服務改由 172.16.0.1:443 聆聽, 或變更 HTTPS 的服務埠口, 如 0.0.0.0:444
  2. 建議於 Web Server 設置: "若直接以 IP address 連入站台則回應錯誤訊息", 避免 IP 位址遭試探時暴露網站資訊

設定 OpenVPN 服務

# vi /etc/openvpn/server.conf

local 0.0.0.0
port 1194
proto tcp

# service openvpn restart

說明: 讓 OpenVPN 以 TCP 傳輸方式進行服務

安裝並設定 sslh

安裝
# yum install epel-release
# yum install sslh

設定
# vi /etc/sslh.cfg

# This is a basic configuration file that should provide
# sensible values for "standard" setup.

verbose: false;
foreground: false;
inetd: false;
numeric: true;
transparent: false;
timeout: "2";
on-timeout: "ssl";
user: "sslh";
pidfile: "/var/run/sslh/sslh.pid";


# Change hostname with your external address name.
listen:
(
    { host: "192.168.1.1"; port: "443"; }
);

protocols:
(
     { name: "ssh"; service: "ssh"; host: "172.16.0.1"; port: "22"; },
     { name: "openvpn"; host: "172.16.0.1"; port: "1194"; },
     { name: "ssl"; host: "172.16.0.1"; port: "443"; log_level: 0; },
     { name: "anyprot"; host: "172.16.0.1"; port: "443"; }
);

# chkconfig sslh on
# service sslh start

說明:

  1. 【注意】原設置 timeout: 2; 會讓 CentOS 啟動 sslh 時發生 segfault, 改成 timeout: "2"; 才能正常運行
  2. numeric: true; 表示 sslh 的 syslog 以純數字記錄 (不解析 host name、service port)
  3. on-timeout: "ssl"; 表示: 若連線 timeout 則預設連入 ssl 服務 (HTTPS), 避免洩漏 sshd 連線資訊
  4. anyprot 指向 172.16.0.1:443 表示: 若無法判別 protocol 則預設連入 HTTPS 服務

調整安全防護機制, 避免 forwarded IP 遭到封鎖而無法提供服務

避免 DenyHosts 阻擋 forwarded IP
# echo 172.16.0.1 >> /var/lib/denyhosts/allowed-hosts
# service denyhosts restart

避免 Fail2ban 阻擋 forwarded IP
# sed -i 's/^ignoreip = /ignoreip = 172.16.0.1 /' /etc/fail2ban/jail.conf
# service fail2ban restart

避免 OSSEC 阻擋 forwarded IP
# vi /var/ossec/etc/ossec.conf

# 於 white_list 區域加入 172.16.0.1
<white_list>172.16.0.1</white_list>

# service ossec-hids restart



後記

衷心建議, 最好不要在防火牆只開這條規則
Public Port: TCP/443 → Private: 192.168.1.1:443 (SSH、HTTPS、OpenVPN)
加上直接連入 sshd 的 policy 會在 "無法以 TCP/443 連入 sshd" 的情況下, 還有一條活路可走
Public Port: TCP/2468 → Private: 192.168.1.1:2468 (SSH)



Ref:



:, ,