本文记录了一次完整的个人服务器搭建过程——从购买云服务器开始,到最终建立一个安全可靠的反向代理系统。包含 SSH 隧道穿透、基础认证保护、SSL/TLS 配置、流量限制和 fail2ban 加固,以及在此过程中踩过的各种坑。

服务器选型与基础配置

对于个人项目,云服务器的性价比是首要考量。经过对比,最终选择了腾讯云轻量应用服务器(4 核 4G、3Mbps 带宽),年费仅 99 元。相比按量计费的云服务器每月 86 元的开销,成本降低了约 90%。

服务器到手后的第一件事是安全加固:

# 禁用 root 登录
sudo sed -i 's/PermitRootLogin yes/PermitRootLogin no/' \
  /etc/ssh/sshd_config

# 禁用密码登录,仅允许密钥认证
echo "PasswordAuthentication no" | \
  sudo tee /etc/ssh/sshd_config.d/99-local.conf

# 重启 SSH 服务
sudo systemctl restart sshd

接下来配置防火墙。Ubuntu 默认使用 UFW,只需放行必要端口:

sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw enable

内网穿透:SSH 反向隧道

家庭网络通常没有公网 IP,需要将家里的服务暴露到云服务器上。常见的方案是 frp(Fast Reverse Proxy),但在我们的环境中遇到了一个棘手的问题:Mac 上运行的 Clash Verge 开启了 TUN 模式,它会拦截所有非 HTTP 的 TCP 流量,导致 frp 的连接被阻断。

最终选择了更简单可靠的方案——SSH 反向隧道:

# 在家里的 Mac 上执行
ssh -R 18700:localhost:8700 \
    -R 18702:localhost:8702 \
    -N -o ServerAliveInterval=60 \
    ubuntu@your-server-ip

这条命令将本地 8700 端口的服务映射到云服务器的 18700 端口,本地 8702 映射到 18702。由于 SSH 走的是标准 HTTP 端口 22,Clash 的 TUN 模式不会拦截。

为了确保隧道在 Mac 重启后自动恢复,配置了 launchd 自启动任务:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC ...>
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.yami.cloud-tunnel</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/bin/ssh</string>
    <string>-R</string>
    <string>18700:localhost:8700</string>
    <string>-N</string>
    <string>ubuntu@server</string>
  </array>
  <key>KeepAlive</key><true/>
</dict>
</plist>

Nginx 反向代理配置

在云服务器的 Nginx 中,将外部请求代理到内部的反向隧道端口:

server {{
    listen 80;
    server_name mio.town;

    location / {{
        proxy_pass http://localhost:18700;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }}

    location /photos/ {{
        proxy_pass http://localhost:18702;
    }}
}}

安全防护

除了基础的 SSH 加固和防火墙,还配置了 fail2ban 防止暴力破解。特别注意要给内网 IP 段设置白名单,否则调试过程中很容易把自己封禁在外。

防护措施配置作用
SSH 密钥认证Ed25519禁止密码登录
fail2ban3 次失败封 24h防暴力破解
Nginx 限流200r/s防 API 滥用
Basic Auth敏感路径额外认证层

整个搭建过程踩了不少坑——frp 被 Clash 拦截、fail2ban 误封自己的 IP、Ubuntu 24.04 的 sshd_config.d 优先级问题。但最终的系统运行稳定,成本低廉,是一个值得记录的经验。