想从家里访问公司局域网内的服务器,最直接的方式就是搭建VPN,我尝试过Ubuntu下使用PPTPD搭建VPN,实际使用下来并不稳定,经常断线,后来有类似需求的时候我都是通过SSH Tunnel完成的。
先说一下环境,公司服务器在局域网192.168.1.0/24网段,公司网关路由器192.168.1.1上通过端口映射暴露了192.168.1.99的22端口:
<公司公网IP>:20742 ->192.168.1.99:22
我要从家里访问公司局域网内的 192.168.1.99:5432 和 192.168.1.166:6379
我们可以通过
1 2
| autossh -M 0 -CNg -L 5432:192.168.1.99:5432 root@<公司公网IP> -p 20742 autossh -M 0 -CNg -L 6379:192.168.1.166:6379 root@<公司公网IP> -p 20742
|
可以先开通本地对跳板机192.168.1.99的密钥登录,然后增加-f参数直接在后台运行,详请搜索SSH密钥登录,使用密码登录时不能加-f
这样就建立了端口转发
localhost:5432 -> (公司局域网)192.168.1.99:5432
localhost:6379 -> (公司局域网)192.168.1.166:6379
我有一些程序和脚本里写好了访问的服务器地址就是192.168.1.99 和192.168.1.166,我不想修改成localhost或者127.0.0.1,
我们可以通过
1 2
| ifconfig enp1s0:0 192.168.1.99 netmask 255.255.255.255 up ifconfig enp1s0:1 192.168.1.166 netmask 255.255.255.255 up
|
创建虚拟网卡并把IP设置为192.168.1.99和192.168.1.166,这样这两个IP都指向了本地。
至此需求就解决了。
但是更进一步,如果我想访问的两个服务器上的相同端口,例如 192.168.1.99:6379 和 192.168.1.166:6379 怎么办呢?
我想到了做两个容器分别去建立SSH Tunnel,并把两个容器的IP设置分别设置为 192.168.1.99和192.168.1.166
首先我们创建一个docker network在 192.168.1.0/24网段
1
| docker network create --gateway=192.168.1.1 --subnet=192.168.1.0/24 company
|
创建一个ubuntu容器加入company网络并指定IP地址为192.168.1.99,同时暴露6379端口
1
| docker run -dit --name proxy99 -h proxy99 --net company --ip 192.168.1.99 --expose 6379 daimingzhuang/ubuntu:18.04 bash
|
连上去
1
| docker exec -it proxy99 bash
|
和前面一样建立SSH Tunnel
1
| autossh -M 0 -CNg -L 6379:192.168.1.99:6379 root@<公司公网IP> -p 20742
|
在宿主机上通过redis-cli连接192.168.1.99:6379
1
| redis-cli -h 192.168.1.99
|
成功
192.168.1.166:6379 也同样操作
总结起来就是用docker创建跳板机容器,用ssh tunnel做端口映射。
我做了一个docker镜像(daimingzhuang/ssh_proxy)来方便进行上面的操作
Dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| FROM ubuntu:18.04 MAINTAINER DaiMingzhuang "kyo86.dai@gmail.com" ENV REFRESHED_AT=2022-04-07 RUN echo deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse>/etc/apt/sources.list\ && echo deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse>>/etc/apt/sources.list\ && echo deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse>>/etc/apt/sources.list\ && echo deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse>>/etc/apt/sources.list\ && echo deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse>>/etc/apt/sources.list\ && echo deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse>>/etc/apt/sources.list\ && echo deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse>>/etc/apt/sources.list\ && echo deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse>>/etc/apt/sources.list RUN apt update -yqq \ && apt install -y vim-tiny autossh expect \ && rm -rf /var/lib/apt/lists/* \ && ln -s /usr/bin/vim.tiny /usr/bin/vim
EXPOSE 22 80 8080 1433 3306 6379 9092 5432 27017
ADD setup.sh /root/setup.sh WORKDIR "/root/" CMD ["bash"]
|
/root/setup.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #!/bin/bash
user='root' passwd='跳板机密码' LAN_IP='跳板机局域网IP' WAN_IP='网关的公网IP' WAN_PORT=跳板机通过端口映射暴露在公网的SSH端口 ports=(22 80 8080 1433 3306 6379 9092 5432 27017)
for((i=0;i<${#ports[@]};i++)); do
/usr/bin/expect <<-EOF set time 10 spawn autossh -M 0 -CNg -L ${ports[$i]}:$LAN_IP:${ports[$i]} $user@$WAN_IP -p $WAN_PORT expect { "*(yes/no)?" { send "yes\n"; exp_continue } "*password:" { send "$passwd\n" } }
expect eof EOF
done
|