openssh是支持隧道的,所以很简单就可以在ssh中再套个管道,直接用来vpn,场景如下:
如上图,A机能ssh无密码登录B机
A机的IP:172.16.8.106
B机的IP:172.16.8.108
A机拨通vpn tunnel后tun的ip:192.168.244.2
B机拨通vpn tunnel后tun的ip:192.168.244.1
- 首先编辑A和B的/etc/ssh/sshd_config,允许tunnel,缺省是不允许的,然后service sshd restart ,重启sshd
1...
2PermitTunnel yes
3...
- A和B安装linux下的tunctl软件,并启动一个tunnel设备
1yum install tunctl
2tunctl -t tun5 -u root
- 在A(172.16.8.106)机器上生成key,并设置能无密码证书直接登录B(172.16.8.108)
1ssh-keygen
2ssh-copy-id root@172.16.8.108
- 在A上执行命令,建立ssh tunnel:
1ssh -w 5:5 root@172.168.8.108
- 在A上执行
1ifconfig tun5 192.168.244.2 pointopoint 192.168.244.1 netmask 255.255.255.0
- 在B上执行
1ifconfig tun5 192.168.244.1 pointopoint 192.168.244.2 netmask 255.255.255.0
- 这样分别在A和B上ping 192.168.244.1和192.168.244.2,都能通就表示已经ok了。
优化一下,A和B两边都先把tun5起来以后,直接在A上一句话搞定,这个不会自动退出,所以得ctrl+z,然后bg放后台去:
1ssh \
2 -o PermitLocalCommand=yes \
3 -o LocalCommand="ifconfig tun5 192.168.244.2 pointopoint 192.168.244.1 netmask 255.255.255.0" \
4 -o ServerAliveInterval=60 \
5 -w 5:5 root@172.16.8.108 \
6 'ifconfig tun5 192.168.244.1 pointopoint 192.168.244.2 netmask 255.255.255.0; echo tun5 ready'
如果要用在翻墙的环境,那就得保持长链接了。假设A机器是在一个防火墙后,且被NAT了,那么就得先这样打通隧道:
1ssh -f -w5:5 vpn@example.com \
2 -o ServerAliveInterval=30 \
3 -o ServerAliveCountMax=5 \
4 -o TCPKeepAlive=yes \
5 -i ~/.ssh/id_rsa "sleep 1000000000"
然后在A和B上分别单独配置ip即可。
再进阶:假设A要建立独立的netns空间,加ip及网关如下:
1ip net add ns-vpn
2ip net exec ip addr add 100.64.42.2/24 dev tun42
3ip net exec ip link set up dev tun42
4ip net exec ip route add default via 100.64.42.1
再在B的/etc/sysctl.conf打开转发
1net.ipv4.ip_forward = 1
2sysctl -p
3iptables -t nat -A POSTROUTING -s 192.168.244.0/24 -j SNAT --to 172.16.8.108
A就可以通过B代理出去了。