前言
当我们身处咖啡厅、公司或在旅途中时,经常需要访问家里的局域网资源(比如 NAS、内部服务器),或者单纯希望通过家里的宽带 IP 上网以保证数据安全。
相比于搭建复杂的 VPN(如 OpenVPN, WireGuard),SSH 隧道(SOCKS5 代理) 是一种更加轻量级、无需客户端安装额外软件的解决方案。
本文将教你如何使用 Docker 快速部署一个经过特殊配置的 SSH 服务器,无论你身在何处,一条命令即可“回家”。
准备工作
- 一台家里的设备:安装了 Docker 的 Linux 服务器、NAS(群晖/威联通)或树莓派。
- 公网访问能力:
- 你需要有公网 IP(IPv4 或 IPv6)。
- 如果不经常变动,直接使用 IP;如果是动态 IP,建议配置 DDNS(动态域名解析)。
- 注:如果你没有公网 IP,你需要一台云服务器做内网穿透(FRP),这超出了本文范围,但本镜像同样适用作为中转节点。
第一步:编写 Dockerfile
我们需要一个定制化的 SSH 容器。为了支持完整的代理转发功能(包括远程端口转发),我们需要覆盖 Ubuntu 默认的 SSH 配置,并修复 Docker 中特有的 PAM 权限问题。
新建一个文件夹 my-ssh-server,在里面创建文件 Dockerfile:
# 基础镜像
FROM ubuntu:latest
# 1. 安装必要的软件
# openssh-server: SSH 服务端
# sudo: 常用工具
# iproute2/net-tools: 调试网络时可能用到(可选)
RUN apt-get update &&
apt-get install -y openssh-server sudo iproute2 net-tools &&
rm -rf /var/lib/apt/lists/*
# 2. 创建 sshd 运行目录
RUN mkdir /var/run/sshd
# 3. 设置 root 密码
# 【警告】生产环境强烈建议使用 SSH Key,这里设置密码仅为初始化演示
RUN echo 'root:password' | chpasswd
# 4. 写入自定义 SSH 配置
# GatewayPorts yes: 允许远程转发绑定到非本地地址(关键配置)
# PermitRootLogin yes: 允许 root 登录
# AllowTcpForwarding yes: 允许 TCP 转发(默认为 yes,显式声明更安全)
RUN echo 'GatewayPorts yes' >> /etc/ssh/sshd_config.d/custom_proxy.conf &&
echo 'PubkeyAuthentication yes' >> /etc/ssh/sshd_config.d/custom_proxy.conf &&
echo 'PasswordAuthentication yes' >> /etc/ssh/sshd_config.d/custom_proxy.conf &&
echo 'ChallengeResponseAuthentication yes' >> /etc/ssh/sshd_config.d/custom_proxy.conf &&
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config.d/custom_proxy.conf &&
echo 'AllowTcpForwarding yes' >> /etc/ssh/sshd_config.d/custom_proxy.conf
# 5. 【核心修复】修复 Docker 中 SSH 登录会被踢出的 PAM 问题
RUN sed -i 's@sessions*requireds*pam_loginuid.so@session optional pam_loginuid.so@g' /etc/pam.d/sshd
# 6. 暴露端口
EXPOSE 22
# 7. 启动服务
CMD ["/usr/sbin/sshd", "-D"]
第二步:构建并启动容器
在 Dockerfile 所在目录下执行构建命令:
docker build -t ssh-proxy-server .
启动容器。为了方便在外部访问,我们将容器的 22 端口映射到宿主机的 2222 端口(或其他非标准端口,避免与宿主机自带的 SSH 冲突)。
docker run -d
--name my-proxy
--restart unless-stopped
-p 2222:22
ssh-proxy-server
进阶提示:如果你想让容器直接拥有宿主机的网络能力(比如更容易地扫描局域网设备),可以加上
--net=host参数(Linux下有效),但此时不需要-p参数。
第三步:配置路由器端口转发
这是最关键的一步。你需要登录家里的路由器后台:
- 找到 虚拟服务器 或 端口转发 (Port Forwarding) 设置。
- 添加一条规则:
- 外部端口:
2222(或者你想用的任何端口) - 内部 IP:运行 Docker 的宿主机内网 IP (例如 192.168.1.100)
- 内部端口:
2222(这取决于上一步docker run中的映射,如果你映射的是-p 2222:22,这里内部端口就是 2222) - 协议:TCP
- 外部端口:
配置完成后,你在外网就可以通过 ssh root@你的公网IP -p 2222 访问这个容器了。
第四步:在外网开启“回家模式”
当你带着笔记本在外面时,不需要安装任何 VPN 客户端,只需要打开终端(Terminal 或 PowerShell),输入以下命令:
# 格式:ssh -D [本地代理端口] -N -C [用户名]@[你的公网IP/域名] -p [外部端口]
ssh -D 1080 -N -C root@your.home.ddns.org -p 2222
参数解释:
-D 1080: 核心参数。建立一个 SOCKS5 动态代理,监听你笔记本的localhost:1080。-N: 不执行远程命令,只建立连接(如果不加这个,你会进入服务器的 shell,加了则会卡住在终端,代表隧道已建立)。-C: 开启压缩,网速慢时可提升浏览速度。
输入密码后,这个终端窗口会保持连接状态,这就代表隧道通了。
第五步:浏览器/系统配置
现在隧道通了,你需要告诉浏览器走这个隧道。
方案 A:SwitchyOmega (推荐 Chrome/Edge 用户)
安装 SwitchyOmega 插件,新建一个情景模式:
- 协议:SOCKS5
- 服务器:127.0.0.1
- 端口:1080
启用该模式后,你的浏览器流量就会经过家里的宽带发出,你现在就像坐在家里的沙发上一样,可以访问 192.168.x.x 的内网服务,IP 地址也变成了家里的 IP。
方案 B:Firefox 直接设置 (最简单)
Firefox 浏览器自带独立的代理设置:
- 设置 -> 常规 -> 网络设置。
- 选择“手动代理配置”。
- SOCKS 主机:
127.0.0.1,端口:1080。 - 勾选 SOCKS v5。
- 重要:勾选“使用 SOCKS v5 时代理 DNS 查询”(防止 DNS 污染)。
安全性加固(必读)
上面的教程为了演示使用了密码 root:password,这在公网上是极度危险的。
强烈建议做以下修改:
- 生成密钥对:在你的笔记本上运行
ssh-keygen。 - 挂载公钥:在启动 Docker 时,将你的公钥文件挂载进去,禁用密码登录。
修改启动命令如下:
# 假设你的公钥内容保存在宿主机的 /home/user/my_key.pub
docker run -d
--name my-proxy
--restart unless-stopped
-p 2222:22
-v /home/user/my_key.pub:/root/.ssh/authorized_keys:ro
ssh-proxy-server
这样,只有持有私钥的电脑才能连接回家,黑客即使扫描到了端口也无法暴力破解密码。
总结
通过 Docker 封装 SSH 服务,我们获得了一个干净、可移植且功能强大的代理服务器。利用 SSH 的 -D 参数,我们轻松实现了:
- 加密传输:公共 WiFi 下防止被窃听。
- 内网穿透:直接访问家里的 NAS 和局域网设备。
- IP 漫游:在任何地方使用家里的 IP 地址。
快去试试吧!