macOS设置L2TP类型的VPN转发指定的流量

在macOS系统下常常用到L2TP类型的VPN来接入公司网络. 但是通常情况下, 这种类型的VPN一旦接入, 会导致本机所有的流量流经该VPN. 包括对外网资源的访问. 如果公司外网较慢, 或者离公司距离太远. 会严重影响访问外网的速度. 本篇文章介绍了通过修改route表的方式只让指定范围的数据包流经VPN.

修改方法

1. 获取未连接vpn前的网关地址

运行netstat -nr, 查看Internet(IPV4)中第一条default路由

例如我的打印为:

1
2
3
Internet:
Destination Gateway Flags Refs Use Netif Expire
default 192.168.0.11 UGSc 16 5 en4

记下网关地址192.168.0.11

2. 设置指定流量通过路由表

以root身份编辑/etc/ppp/ip-up文件, 如果没有该文件则创建一个

1
2
#!/bin/sh
/sbin/route add -net 192.168.1.0/24 -interface $1

参考自此处
192.168.1.0/24是需要转发的网络地址$1是ppp0的接口, 打开vpn, 系统执行的时候会传入该参数

但是这样配置过后, 可能由于系统版本的问题, 我的外网流量还是经过vpn, 所以需要替换默认的网关:

1
2
/sbin/route delete default
/sbin/route add default 192.168.0.11

192.168.0.11为第一步记下的网关地址, 将ppp0生成的默认网关删除掉, 替换成原来的

到这里, 应该大多数同学已经可以达成目标了, 但是有的公司会架设自己的dns服务器, 因此需要dns服务器也经过ppp0接口 (如果没有特殊配置, 建议将dns改为当地dns, 因为对于大型网站, 不同地域的dns服务器解析出的ip地址可能就就近的服务器)

完整的配置是这样的:

1
2
3
4
5
6
#!/bin/sh
/sbin/route add -net 192.168.1.0/24 -interface $1
/sbin/route add -net 10.1.1.1 -interface $1 # 添加dns服务器的路由

/sbin/route delete default
/sbin/route add default 192.168.0.11

在开启L2TP VPN的时候系统会自动执行上述脚本

(update)


发现一个更简单的办法: 可将通过VPN连接发送所有流量选项去掉(我的vpn创建完后是默认勾选的). 然后不用再配置默认路由, 只需配置需要转发的网络地址即可.

常用命令

顺便介绍常用的网络命令

  • 查看路由表 netstat -nr

    • -n 表示不尝试将端口转换为协议名称, 直接显示端口号, 用来加快执行速度
    • -r route, 路由表
    • route表中的flag可在man netstat中看到
  • 修改路由表 route, 需要加sudo, 以root身份执行

    • route -n delete default 删除默认路由
    • route add -net 192.168.1.0/24 192.168.1.1 添加路由, 也可以用route add -net 192.168.1 192.168.1.1
  • 列出所有的网络连接方式networksetup -listallnetworkservices

  • 给指定的网络连接方式设定DNS服务器sudo networksetup -setdnsservers AirPort 192.168.10.200

  • 清空dnsdscacheutil –flushcache
  • 图形界面网络工具Network utility app
  • 数据包抓取
    • sudo tcpdump -i en0 监听en0接口的所有通信
    • sudo tcpdump -A -i en0 用ASCII显示en0接口的通信内容
    • sudo tcpdump -i en0 'port 8080' 显示en0接口的8080端口的通信
    • sudo tcpdump -i eth1 src 192.168.1.200 显示eth1接口,来自192.168.1.200的通信
    • sudo tcpdump -i eth1 dst 192.168.1.101 and port 80 显示eth1接口80端口,目的地为192.168.1.101的通信
    • sudo tcpdump -w record.pcap -i lo0将lo0接口的通信存入文件record.pcap
0%