我在制作基于 ssh 的 VPN 时遇到了一些问题。
情况:
LOCAL -> GATE -> SERVICES
(ssh server) (Many other servers with some services)
192.168.0.10 10.1.0.154 172.26.106.0/24
255.255.255.0 255.255.0.0
从本地,我可以通过 ssh 登录到 GATE,然后从这里我可以访问所有的服务服务器。
但是我想直接从本地计算机访问服务。我该如何实现?
这是我阅读 ssh 手册后尝试做的事情:
在本地:
# ssh -f -w 1:2 root@GATE true
# ifconfig tun1 10.66.1.1 10.66.1.2 netmask 255.255.255.252
# route add -net 172.26.106.0 netmask 255.255.255.0 gw 10.66.1.2
在 GATE 上:
# ifconfig tun2 10.66.1.2 10.66.1.1 netmask 255.255.255.252
它不起作用。当我尝试从本地 ssh 到某个服务时,我遇到了超时 ;-(
答案1
距离我问了这个问题已经过去两年半了...现在我发现了另一个非常简单的解决方案。您只需使用名为的工具即可sshuttle
。
来自sshuttle
手册:
sshuttle 允许您从您的机器创建到任何可以通过 ssh 连接的远程服务器的 VPN 连接,只要该服务器具有 python 2.3 或更高版本。
IE:
sshuttle -r user@gate 172.26.100.0/24 172.26.106.0/24 172.26.103.0/24
然后在另一个终端中,您可以直接从路由子网通过 ssh 连接到任何服务器:
IE:
ssh [email protected]
答案2
感谢 Jeff Meden 的评论,我成功做到了。我调整了该脚本: github.com/oicu/vpn-over-ssh/blob/master/svpn.sh满足我的需要,最后它起作用了:
我的版本:
#!/bin/bash
PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin
export PATH
[ "$(whoami)" != 'root' ] && echo "Run it as root." && exit 1
SERVER_SSH_PORT="22"
SERVER_SSH_IP="10.1.0.154"
CLIENT_TUNNEL="tun5"
SERVER_TUNNEL="tun4"
CLIENT_TUN_IP="192.168.55.5"
SERVER_TUN_IP="192.168.55.4"
TUN_NETMASK="255.255.255.0"
CLIENT_ETHERNET="enp12s0"
SERVER_ETHERNET="eth0"
ROUTES=("172.26.100.0/24" "172.26.106.0/24" "172.26.103.0/24")
function start() {
ssh -NTCf -w "${CLIENT_TUNNEL#tun}:${SERVER_TUNNEL#tun}" root@${SERVER_SSH_IP} -p ${SERVER_SSH_PORT}
if [ $? -ne 0 ];
then exit 1;
fi
echo "ssh tunnel is working."
ssh -T root@${SERVER_SSH_IP} -p ${SERVER_SSH_PORT} << eeooff
ifconfig ${SERVER_TUNNEL} ${SERVER_TUN_IP} pointopoint ${CLIENT_TUN_IP} netmask ${TUN_NETMASK}
iptables -t nat -A POSTROUTING -s ${CLIENT_TUN_IP}/32 -o ${SERVER_ETHERNET} -j MASQUERADE
iptables -A FORWARD -p tcp --syn -s ${CLIENT_TUN_IP}/32 -j TCPMSS --set-mss 1356
exit
eeooff
for ROUTE in ${ROUTES[*]}
do
ssh -T root@${SERVER_SSH_IP} -p ${SERVER_SSH_PORT} "iptables -t nat -A POSTROUTING -s $ROUTE -o ${CLIENT_TUNNEL} -j MASQUERADE"
done
if [ $? -ne 0 ];
then exit 1;
fi
echo "remote start."
ifconfig ${CLIENT_TUNNEL} > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo 1 > /proc/sys/net/ipv4/ip_forward
ifconfig ${CLIENT_TUNNEL} ${CLIENT_TUN_IP} pointopoint ${SERVER_TUN_IP} netmask ${TUN_NETMASK}
for ROUTE in ${ROUTES[*]}
do
ip route add $ROUTE via ${CLIENT_TUN_IP} metric 102
printf "Adding route: %s\n" $ROUTE
done
iptables -t nat -A POSTROUTING -s ${SERVER_TUN_IP}/32 -o ${CLIENT_ETHERNET} -j MASQUERADE
iptables -A FORWARD -p tcp --syn -s ${SERVER_TUN_IP}/32 -j TCPMSS --set-mss 1356
for ROUTE in ${ROUTES[*]}
do
iptables -t nat -A POSTROUTING -s $ROUTE -o ${CLIENT_TUNNEL} -j MASQUERADE
done
ping ${SERVER_TUN_IP} -i 60 > /dev/null 2>&1 & echo "local start."
else
exit 1
fi
}
function stop(){
echo "Flushing iptables on server..."
ssh -T root@${SERVER_SSH_IP} -p ${SERVER_SSH_PORT} "iptables -F"
echo "Flushing iptables on localhost..."
iptables -F
echo "Killing ssh tunnel..."
CLIENT_SSH_PID=`ps -ef | grep "ssh -NTCf -w ${CLIENT_TUNNEL#tun}:${SERVER_TUNNEL#tun}" | grep -v grep | head -n1 | awk '{print $2}'`
if [ -n "${CLIENT_SSH_PID}" ]; then
kill -9 ${CLIENT_SSH_PID}
fi
if [ -n "`pidof ping`" ]; then
pidof ping | xargs kill -9
fi
}
function usage(){
echo "usage:"
echo " $0 -start"
echo " $0 -stop"
echo ""
echo "for ssh:"
echo " nohup $0 -start > /dev/null 2>&1"
}
case $1 in
"--start" | "-start")
start
;;
"--stop" | "-stop")
stop
;;
*)
usage
;;
esac