保护您的 sh0 服务器
无论服务器托管在哪里,建议都相同:没有任何特定于服务商的步骤,只有在机器本身上运行的内容。
概述
sh0 保护它所提供的服务(HTTPS、加密的密钥、角色),但承载它的服务器由您负责。大多数被入侵的服务器并不是通过应用程序被攻破的:攻击者通过猜中的密码登录 SSH,或者通过没有人打算公开的端口进入。本指南按照永远不会把您锁在门外的顺序关闭这些入口。sh0 会在控制面板的“服务器安全”页面以及 sudo sh0 doctor 中实时为您检查同样的项目。
开始之前
在整个过程中保持当前的 SSH 会话打开,并从一个新的会话测试每一项更改。在您的电脑上,确认您的密钥可以在不输入密码的情况下打开会话:
ssh -o PasswordAuthentication=no root@SERVER_IP如果该会话要求输入密码,说明服务器上还没有您的密钥。先安装一个,然后再次测试:
ssh-copy-id root@SERVER_IPSSH:仅限密钥
接受 SSH 密码的服务器可能被猜中,而 root 是第一个被尝试的账户。确认密钥可用后,禁止密码登录:
cat > /etc/ssh/sshd_config.d/00-sh0-hardening.conf <<'EOF'
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
EOF先验证,再重新加载。切勿在 sshd -t 拒绝的配置上重启 sshd;重新加载会保留已打开的会话。该服务在 Debian 和 Ubuntu 上名为 ssh,在其他系统上名为 sshd。
sshd -t && systemctl reload ssh检查 root 从外部地址登录时的实际配置值,然后在关闭当前会话之前用您的密钥打开一个新会话:
sshd -T -C user=root,host=check.invalid,addr=203.0.113.1 | grep -Ei '^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin) '防火墙与 Docker 陷阱
允许 SSH、HTTP、HTTPS 和面板端口,然后启用 ufw。如果 SSH 监听的不是 22 端口,请先允许该端口。
ufw allow 22/tcp
ufw allow 80/tcp
ufw allow 443
ufw allow 9000/tcp
ufw --force enable只要 *.sh0.app 地址直接访问您的服务器,9000 端口就保持开放。只有当面板通过自己的域名以 HTTPS 提供服务后,才关闭它(sh0 serve --bind 127.0.0.1)。
cat > /usr/local/sbin/sh0-docker-user <<'EOF'
#!/bin/sh
# Docker-published ports: from the public interface, only replies get through.
IF=$(ip -o route get 1.1.1.1 | sed -n 's/.* dev \([^ ]*\).*/\1/p')
[ -n "$IF" ] || exit 1
iptables -C DOCKER-USER -i "$IF" -m conntrack --ctstate RELATED,ESTABLISHED -j RETURN 2>/dev/null ||
iptables -I DOCKER-USER 1 -i "$IF" -m conntrack --ctstate RELATED,ESTABLISHED -j RETURN
iptables -C DOCKER-USER -i "$IF" -j DROP 2>/dev/null ||
iptables -I DOCKER-USER 2 -i "$IF" -j DROP
EOF
chmod 755 /usr/local/sbin/sh0-docker-user
cat > /etc/systemd/system/sh0-docker-user.service <<'EOF'
[Unit]
Description=sh0: filter Docker-published ports (DOCKER-USER)
After=docker.service
Requires=docker.service
PartOf=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/sh0-docker-user
[Install]
WantedBy=docker.service
EOF
systemctl daemon-reload
systemctl enable --now sh0-docker-user
iptables -S DOCKER-USER若要保留某个已发布端口可访问,请在 /usr/local/sbin/sh0-docker-user 中的 DROP 规则之前添加例外:
iptables -I DOCKER-USER 2 -i "$IF" -p tcp -m conntrack --ctorigdstport 5432 -j RETURN如果您的服务商在服务器前提供网络防火墙,无论是哪家服务商,也请一并使用:允许 22、80、443(在依赖 *.sh0.app 期间还包括 9000),拒绝其余流量。它在流量到达机器之前进行过滤,包括 Docker 的端口。
fail2ban
仅使用密钥时,猜测尝试不会造成危险,但会填满日志。fail2ban 会封禁持续尝试的地址:
apt-get install -y fail2ban python3-systemd
cat > /etc/fail2ban/jail.d/sh0-sshd.local <<'EOF'
[sshd]
enabled = true
backend = systemd
journalmatch = _COMM=sshd + _COMM=sshd-session
maxretry = 5
findtime = 10m
bantime = 1h
EOF
systemctl enable fail2ban
systemctl restart fail2ban
fail2ban-client status sshd更新与重启
安装安全更新,并让系统自动安装它们:
apt-get update && apt-get upgrade
apt-get install -y unattended-upgrades && dpkg-reconfigure -plow unattended-upgrades当内核或核心库更新后,修复只有在重启后才生效(存在 /var/run/reboot-required)。请在流量较低时安排重启:sh0 会随系统一起启动。
通过 HTTPS 访问面板
没有自己的域名时,面板通过明文 HTTP 提供服务,所有者密码会以未加密的形式在网络上传输。将 DNS A 记录指向服务器,然后:
sh0 panel-domain set panel.example.com让安装程序来完成
在新服务器上,安装程序会在您要求时执行上述 SSH、防火墙和 fail2ban 步骤。默认关闭;在终端中,安装程序也会询问(30 秒内未回答即视为否)。
curl -fsSL https://get.sh0.dev | bash -s -- --harden检查结果
控制面板的“服务器安全”页面(所有者和管理员可见)会实时显示这些检查,并在每个警告下给出修复方法;导航栏中的圆点表示存在有效警告。在服务器的终端中:
sudo sh0 doctor