🐳 用两个 Docker 容器搭建跳板机实验
—— 轻量、快速、可重复
✅ 实验目标
| 角色 | 容器 | 网络配置 |
|---|---|---|
| 跳板机(Bastion) | jump-server | 连接公网 + 内网 |
| 内网服务器(Web Server) | web-server | 仅连接内网,不能直连 |
✅ 最终效果:
- 你只能先登录
jump-server - 再从它 SSH 到
web-server - 无法直接从宿主机访问
web-server
🧰 一、准备工作
1. 安装 Docker
确保你的电脑已安装 Docker:
docker --version
# 输出:Docker version 24.x.x, build xxxxx
如果没有,请先安装:
- Docker Desktop(Windows/Mac)
- Linux:
curl -fsSL https://get.docker.com | sh
🌐 二、创建自定义网络(关键)
我们要模拟“公网”和“内网”,所以创建两个 Docker 网络:
# 1. 公网网络(模拟外部可访问)
docker network create public_net --subnet=10.0.1.0/24
# 2. 内网网络(仅内部通信)
docker network create private_net --subnet=192.168.100.0/24
💡 解释:
public_net:跳板机连接这里,你可以从宿主机访问private_net:只有跳板机和内网服务器能连,宿主机无法直接访问
🐳 三、启动两个容器
1. 启动内网服务器 web-server
docker run -d --name web-server \
--network private_net \
--hostname web-server \
ubuntu:22.04 sleep infinity
⚠️ 注意:它只连 private_net,没有公网访问能力。
2. 启动跳板机 jump-server(双网卡)
docker run -d --name jump-server \
--network public_net \
--hostname jump-server \
ubuntu:22.04 sleep infinity
然后把它也连到内网:
docker network connect private_net jump-server
✅ 现在 jump-server 有“双网卡”:
eth0:10.0.1.x(公网)eth1:192.168.100.x(内网)
而 web-server 只有 192.168.100.x,宿主机无法直接 ping 通它。
🔧 四、进入容器安装必要软件
我们需要在两个容器中都安装:
openssh-server(SSH服务)net-tools(ifconfig、ping等)
# 封装一个安装命令,对两个容器执行
for container in jump-server web-server; do
docker exec $container apt update
docker exec $container apt install -y openssh-server net-tools iproute2 ssh curl
docker exec $container mkdir -p /var/run/sshd
done
🔐 五、配置 SSH 服务
1. 为每个容器设置密码(实验用)
# 设置用户密码(默认 root 可用)
docker exec jump-server passwd root
# 输入密码:root123
docker exec web-server passwd root
# 输入密码:root123
或者用脚本批量设置:
echo "root:root123" | docker exec -i jump-server chpasswd
echo "root:root123" | docker exec -i web-server chpasswd
2. 启动 SSH 服务
docker exec jump-server /usr/sbin/sshd
docker exec web-server /usr/sbin/sshd
🧪 六、测试网络拓扑
1. 查看 IP 地址
# 跳板机(双IP)
docker exec jump-server ip a
# 内网服务器
docker exec web-server ip a
你应该看到:
jump-server:10.0.1.2(public),192.168.100.2(private)web-server:192.168.100.3(private)
2. 测试连通性
在跳板机上 ping 内网服务器:
docker exec jump-server ping -c 3 192.168.100.3
✅ 应该通。
在宿主机上 ping 内网服务器:
ping 192.168.100.3
❌ 应该不通!因为 private_net 是 Docker 内部网络,宿主机无法直接访问。
✅ 安全隔离成功!
🚪 七、实现跳板机访问(两种方式)
方式 1:手动跳转
1. 从宿主机登录跳板机
ssh root@10.0.1.2
# 密码:root123
❗ 如果提示 “Connection refused”,先检查 SSH 是否运行:
docker exec jump-server ps aux | grep sshd
2. 从跳板机登录内网服务器
ssh root@192.168.100.3
# 密码:root123
✅ 成功进入内网服务器!
方式 2:SSH ProxyJump(一键直达)
在你的宿主机配置 ~/.ssh/config:
Host jump
HostName 10.0.1.2
User root
Port 22
Host web
HostName 192.168.100.3
User root
ProxyJump jump
使用方式:
# 直接登录内网服务器
ssh web
# 拷贝文件
scp web:/root/hello.txt ./
✅ 就像在真实企业环境中一样流畅!
🛑 八、常见问题与解决
| 问题 | 原因 | 解决方案 |
|---|---|---|
ssh: connect to host 10.0.1.2 port 22: No route to host | 宿主机无法访问 public_net 子网 | 使用 --network-alias 或端口映射 |
Permission denied (publickey) | SSH 密钥问题 | 改用密码登录,或配置密钥 |
docker: Error response from daemon: network with name xxx already exists | 网络已存在 | 先 docker network rm xxx 删除 |
✅ 推荐:使用端口映射避免路由问题
修改跳板机启动方式:
docker run -d --name jump-server \
-p 2222:22 \ # 宿主机2222 → 容器22
--network public_net \
ubuntu:22.04 sleep infinity
然后启动 SSH:
docker exec jump-server /usr/sbin/sshd
现在你可以用:
ssh -p 2222 root@localhost
登录跳板机,无需担心网络路由问题。
🧩 九、进阶实验建议
-
使用 SSH 密钥代替密码
- 生成密钥,复制到两个容器
- 禁用密码登录:
PasswordAuthentication no
-
启用审计日志
- 在跳板机记录所有命令
- 使用
auditd或简单脚本
-
模拟多用户
- 创建
user1,user2 - 配置 sudo 权限
- 创建
-
部署 Web 服务
- 在
web-server上运行 Nginx - 通过跳板机访问网页
- 在
-
使用 Docker Compose 自动化
- 写
docker-compose.yml一键启动整个环境
- 写
📦 十、使用 Docker Compose(推荐)
创建 docker-compose.yml:
version: '3.8'
services:
jump-server:
image: ubuntu:22.04
container_name: jump-server
networks:
public_net:
ipv4_address: 10.0.1.10
private_net:
ipv4_address: 192.168.100.10
ports:
- "2222:22"
command: bash -c "
apt update &&
apt install -y openssh-server &&
mkdir -p /var/run/sshd &&
echo 'root:root123' | chpasswd &&
sed -i 's/#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config &&
/usr/sbin/sshd -D
"
web-server:
image: ubuntu:22.04
container_name: web-server
networks:
private_net:
ipv4_address: 192.168.100.20
command: bash -c "
apt update &&
apt install -y openssh-server &&
mkdir -p /var/run/sshd &&
echo 'root:root123' | chpasswd &&
sed -i 's/#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config &&
/usr/sbin/sshd -D
"
networks:
public_net:
driver: bridge
ipam:
config:
- subnet: 10.0.1.0/24
private_net:
driver: bridge
ipam:
config:
- subnet: 192.168.100.0/24
一键启动:
docker-compose up -d
登录:
ssh -p 2222 root@localhost # 登录跳板机
ssh root@192.168.100.20 # 从跳板机登录内网
🎯 总结
| 特性 | 容器方案 | 虚拟机方案 |
|---|---|---|
| 启动速度 | 秒级 | 分钟级 |
| 资源占用 | 极低 | 较高 |
| 环境一致性 | 高(镜像) | 依赖安装 |
| 网络控制 | 灵活(自定义网络) | 依赖虚拟机软件 |
| 适合场景 | 快速实验、CI/CD | 模拟真实硬件 |
✅ 结论:对于学习和实验,Docker 容器是更优解!
如果你想要:
- 我提供完整的可运行代码包
- 添加 HTTPS Web 服务演示
- 集成 JumpServer 开源堡垒机
- 支持 Windows 宿主机的详细指南
欢迎继续提问!我可以帮你把整个实验打包成一键脚本 😊