基于SSH反向代理实现公网访问

介绍

目前家中有一个Liunx服务器,运行在内网环境,没有公网IP可用,现在想通过公网访问到家中服务器上搭建的服务。在网上查了很多资料最终选择了SSH反向代理,SSH反向代理优缺点如下:

优点

  1. 安全性高:SSH协议提供了很强的安全保障,所有的数据传输都会被加密,这可以防止数据在传输过程中被窃取或篡改。
  2. 易于设置:SSH反向代理的设置相对简单,一般只需要在SSH命令中添加几个参数即可。
  3. 不需要特殊硬件或网络配置:SSH反向代理不依赖特定的硬件设备,也不需要修改网络路由或防火墙规则,这使得它可以在许多网络环境中使用。
  4. 动态性:SSH反向代理可以随时建立或断开,这使得你可以根据需要动态地更改网络访问策略。

缺点

  1. 可能会影响网络性能:由于SSH协议对数据进行加密,这可能会增加计算负载,从而影响网络性能。
  2. 不适合大规模部署:如果你需要为大量的内部服务或用户提供访问,管理各个SSH反向代理可能会变得复杂和难以维护。
  3. 可能存在安全风险:虽然SSH协议本身是安全的,但如果SSH服务的配置不当或者SSH密钥被泄露,可能会导致安全问题。
  4. 可用性依赖于SSH服务器:如果SSH服务器出现故障,反向代理将无法工作。

总的来说,SSH反向代理是一个方便且安全的内网访问解决方案,但在进行大规模部署或者处理高性能需求时,可能需要考虑其他的解决方案。

具体步骤

购买云服务器

购买云服务器,建议购买香港或者境外的云服务器,不用域名备案,这里推荐阿里的轻量级云服务器,买24块钱一月的那款,很香,1T流量还可以用来自由翱翔。

image-20230724115223462

设置密钥

在内网服务器上执行,autossh需要提前安装,很简单,大家可以直接百度,由于 autossh 在后台运行,你需要为 autossh 提供一个无密码的 SSH 私钥,或者使用 SSH 代理来提供私钥。你可以参考 autossh 的文档来了解如何设置这些选项。

# 生成密钥
ssh-keygen
# 和代理服务器交换密钥,ip更换为云服务器ip
ssh-copy-id root@<你的云服务器ip地址>

创建SSH代理

在内网服务器上执行,可以将 autossh 命令添加到一个初始化脚本中,以实现在系统启动时自动启动 autossh。这通常通过使用系统的初始化系统来实现,比如 systemd

下面是一个如何创建一个 systemd 服务来自动运行 autossh 的例子:

  1. 创建一个新的 systemd 服务文件。这个文件通常放置在 /etc/systemd/system/ 目录中。比如,你可以创建一个叫做 autossh.service 的文件:
sudo nano /etc/systemd/system/autossh.service
  1. 在这个文件中,粘贴以下内容,根据需求修改,保存并关闭文件。

    [Unit]
    Description=AutoSSH tunnel service
    After=network.target
    
    [Service]
    Environment="AUTOSSH_GATETIME=0"
    ExecStart=/usr/bin/autossh -M 4001 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -R *:<云服务器端口>:localhost:<家中服务器服务端口> user@<云服务器ip>
    
    [Install]
    WantedBy=multi-user.target
    

    在这个示例中,autossh 命令连接家中服务器的 22 端口到公网服务器的 2222 端口。需要将 user@your_public_server_ip 和端口号更改为你的实际情况。

    如果你需要设置多个端口,那就在ExecStart中继续追加-R *:<远程端口>:localhost:<本地服务端口>

  2. 使用 systemctl 命令来启动你的新服务:

    sudo systemctl start autossh.service
    
  3. 检查服务是否运行成功:

    sudo systemctl status autossh.service
    
  4. 如果一切正常,你可以设置这个服务在启动时自动运行:

    sudo systemctl enable autossh.service
    
  5. 假如要编辑 /etc/systemd/system/autossh.service 文件,来添加新的端口,那么执行以下指令。

    # 重新加载服务配置
    sudo systemctl daemon-reload
    # 重新启动 `autossh` 服务。
    sudo systemctl restart autossh.service 
    # 检查服务状态。如果一切正常,应该会看到 "Active: active (running)" 的状态信息
    sudo systemctl status autossh.service
    
  6. 完成后访问云服务器的端口就可以访问到内网服务器的服务,注意设置云服务器的安全组放开指定端口。假如不想用在访问时填写端口,那么可以使用nginx进行代理,监听443或者80端口进行分发,建议配合域名使用。