多节点通过PPP连接,节点/用户/客户机之间互相访问ping
转载注明来源: 本文链接 来自osnosn的博客,写于 2019-04-14.
有A, B, C 三台客户机,通过ppp虚拟拨号连接到服务器。
- 搜索"ppp over ssh"
- VPN PPP-SSH Mini-HOWTO
- Poor man's VPN using PPP over SSH
- VPN over SSH
发现A, B, C分别能访问服务器,但A,B,C之间不能互访,不能互ping,即使ppp的IP都配置到一个网段。
经过反复测试,解决问题,A,B,C之间可以互相ping通,互相访问了。
以下是配置的关键点:
-
server:
- 打开内核IP转发
sysctl -w net.ipv4.ip_forward=1 - 开放iptables的转发规则,允许转发
iptables -A FORWARD -s 192.168.33.0/24 -d 192.168.33.0/24 -j ACCEPT
如果你的服务器是centos8,使用了nft,见下文,nft设置转发规则。 - 允许接收此网段的数据包(可选)
iptables -A INPUT -s 192.168.33.0/24 -d 192.168.33.0/24 -j ACCEPT - 禁止此网段的数据包(TCP),从物理网口出去(可选)
iptables -A OUTPUT -p tcp -o eth0 -d 192.168.33.0/24 -j REJECT --reject-with tcp-reset
如果你的服务器是centos8,使用了nft,见下文,nft设置reject规则。 - 禁止此网段的数据包(其他类型的包),从物理网口出去(可选)
iptables -A OUTPUT -o eth0 -d 192.168.33.0/24 -j REJECT --reject-with icmp-host-prohibited
- 打开内核IP转发
-
client: (每个客户端都需要加上192.168.33.0/24的路由)
#!/bin/sh -e
# debain: copy this file to "/etc/ppp/ip-up.d/" , and chmod +x file.
# centos: append this lines to "/etc/ppp/ip-up.local" , and chmod +x ip-up.local
# openwrt:append this lines to "/etc/ppp/ip-up" , and chmod +x ip-up
# PPP_IFACE="$1", PPP_LOCAL="$4", PPP_REMOTE="$5"
if [ "$5" = "192.168.33.2" ]; then
#/sbin/ip route add 192.168.33.0/24 via $5 dev $1 proto static
/sbin/ip route add 192.168.33.0/24 via $5 proto static
fi
exit 0
nft设置转发规则
- centos8,默认使用nft作为防火墙。开启net.ipv4.ip_forward=1之后。
你会发现A,B,C直接可以ping通。但不能traceroute,不能互相访问端口,会得到No route to host的错误。 - 方法一:
- 首先
nft -a list ruleset | less找到 `table inet firewalld{ chain filter_FORWARD { } } 中最后一条规则的handle。在我机器上是147。
- 首先
table inet firewalld { # handle 17
...
chain filter_FORWARD { # handle 120
...
reject with icmpx type admin-prohibited # handle 147
}
...
}
-
- 执行
nft insert rule inet firewalld filter_FORWARD handle 147 ip saddr 192.168.33.0/24 ip daddr 192.168.33.0/24 accept - 如果要删除这条规则,先
nft -a list ruleset找到之前加入的规则的handle,比如是258。
执行nft delete rule inet firewalld filter_FORWARD handle 258
- 执行
- 方法二:
- 因为filter_FORWARD_IN_ZONES_SOURCE是个空chain,直接执行
nft add rule inet firewalld filter_FORWARD_IN_ZONES_SOURCE ip saddr 192.168.33.0/24 ip daddr 192.168.33.0/24 accept - 删除的方法类似,先找handle,再删除。
nft delete rule inet firewalld filter_FORWARD_IN_ZONES_SOURCE handle 259
- 因为filter_FORWARD_IN_ZONES_SOURCE是个空chain,直接执行
- 方法三:
- 因为filter_FWDI_public_allow也是个空chain,直接执行
nft add rule inet firewalld filter_FWDI_public_allow ip saddr 192.168.33.0/24 ip daddr 192.168.33.0/24 accept
- 因为filter_FWDI_public_allow也是个空chain,直接执行
- 以上三种办法,任选一种即可。都是基于CentOS8,firewalld启动后的默认nft表。
CentOS8的默认表,请看: 关于 iptables 和 nftables 在 CentOS 新版本的使用
- 使用 firewall-cmd 命令添加转发规则的办法,
-
firewalld官网说,firewall-cmd-0.9.0 才支持
--add-forward参数。
centos8的firewall-cmd版本还是 0.8.0,所以不支持给nft加入forward规则。 - 如果把这个 add rule 指令放在 /etc/rc.local 也不行. 因为 rc.local 执行时,firewalld 还没建立好规则表。
只能等机器启动好,再登录上去,手工添加这条规则。 - 为了免去手工登录,手工添加。只好创建个脚本,放入root的crontab中,60分钟执行一次。
脚本先检查firewalld的规则表是否已经建立,再检查forward规则是否已经加入。如果没有加入,则添加。
-
firewalld官网说,firewall-cmd-0.9.0 才支持
nft设置reject规则 (禁止此网段的TCP数据包,从物理网口出去) (可选)/usr/sbin/nft add rule inet firewalld filter_OUTPUT meta oifname "eth0" ip protocol tcp ip daddr 192.168.33.0/24 reject with tcp reset
----完----
以下是几个脚本的备份。
# server
visudo:
vpn ALL=(root) NOPASSWD: /usr/sbin/pppd
vpn-shell
#!/bin/sh
# vpn-shell , server
#echo "$*" >> /home/vpn/log
if [ -z "$*" ];then
echo 'Login succeed.'
exit 0
fi
a="`expr "$*" : '-c /usr/bin/sudo /usr/sbin/pppd '`"
b="`expr "$*" : '-c /usr/sbin/ppp -direct '`"
g="`expr "$*" : '-c sudo /usr/sbin/pppd '`"
h="`expr "$*" : '-c /usr/sbin/pppd '`"
if [ "$a" = "32" -o "$b" = "25" -o "$g" = "23" -o "$h" = "18" ] ;then
a="`expr "$*" : '-c \(.*\)'`"
# eval "$a"
exec $a
# echo "$a"
fi
exit 0
logout
vpn-pppssh.sh
#!/bin/sh
# vpn-pppssh.sh , client
#### check hostkey in file ".ssh/known_hosts" #####
LINK_NAME=my-ppp-vpn
LINK_PEER_NAME=my-ppp-vpn
SERVER_HOSTNAME=6.6.6.6
SERVER_PORT=22
SERVER_USERNAME=vpn
SERVER_IFIPADDR=192.168.33.1 #fix IP
CLIENT_IFIPADDR=192.168.33.7
LOCAL_SSH_OPTS="-P"
PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/X11/:
PPPD=/usr/sbin/pppd
SSH=/usr/bin/ssh
if ! test -f $PPPD ; then echo "can't find $PPPD"; exit 3; fi
if ! test -f $SSH ; then echo "can't find $SSH"; exit 4; fi
case "$1" in
start)
# echo -n "Starting vpn to $SERVER_HOSTNAME: "
${PPPD} ipparam ${LINK_NAME} updetach noauth passive pty "${SSH} ${LOCAL_SSH_OPTS} ${SERVER_HOSTNAME} -t -l${SERVER_USERNAME} -p ${SERVER_PORT} -o Batchmode=yes /usr/bin/sudo ${PPPD} nodetach noauth ipparam ${LINK_PEER_NAME} idle 3700" ${CLIENT_IFIPADDR}:${SERVER_IFIPADDR} nodefaultroute idle 1800 connect-delay 8000
# echo "connected."
;;
stop)
# echo -n "Stopping vpn to $SERVER_HOSTNAME: "
PID=`ps ax | grep "${PPPD} ipparam ${LINK_NAME} updetach noauth passive" | grep -v 'grep ' | awk '{print $1}'`
if [ "${PID}" != "" ]; then
kill $PID
echo "disconnected."
else
echo "Failed to find PID for the connection"
fi
;;
config)
echo "LINK_NAME=$LINK_NAME"
echo "LINK_PEER_NAME=$LINK_PEER_NAME"
echo "SERVER_HOSTNAME=$SERVER_HOSTNAME"
echo "SERVER_USERNAME=$SERVER_USERNAME"
echo "SERVER_IFIPADDR=$SERVER_IFIPADDR"
echo "CLIENT_IFIPADDR=$CLIENT_IFIPADDR"
;;
*)
echo "Usage: vpn-pppssh {start|stop|config}"
exit 1
;;
esac
exit 0
add_forward_rule.sh
#!/bin/bash
# 此程序没有检查 chain 是否存在。
fwd_chain=$( /sbin/nft -a list chain inet firewalld filter_FWDI_public_allow )
fwd_rule=$( echo "${fwd_chain}" |/bin/grep 'ip saddr 192.168.33.0/24' )
if [ -n "${fwd_chain}" -a -z "${fwd_rule}" ]; then
echo 'add forward rule.'
# 此命令,无论是放在 /etc/rc.local 还是放在 root的crontab @reboot项
# 执行的时机都早于 firewalld 创建缺省规则表。导致添加失败。
# firewalld not started, so add rule fail.
/usr/sbin/nft add rule inet firewalld filter_FWDI_public_allow ip saddr 192.168.33.0/24 ip daddr 192.168.33.0/24 accept
else
echo 'already have forward rule.'
echo "$fwd_chain"
echo 'to delete:'
#echo ' nft delete rule inet firewalld filter_FWDI_public_allow handle xx'
IFS=$'\n'; for cc in "$fwd_rule"; do
echo "$cc"|/bin/awk -F'#' '{print " nft delete rule inet firewalld filter_FWDI_public_allow" $2}'
done
fi
转载注明来源: 本文链接 https://www.cnblogs.com/osnosn/p/10703841.html 来自osnosn的博客.