标签 ros 下的文章

RouterOS单系统实现透明网关

20231218更新:优化hysteria启动脚本。

自从接触mikrotik公司的RouterOS系统以来,一直都想以routeros单系统实现内外网自动分流、dns防污染的透明网关。
由于routeros是商业公司开发的闭源路由系统,虽然是基于linux内核,但是并不像openwrt一样可以安装任意软件。
所以在v6版本时代尝试过ipsec、ipip、gre隧道等方式穿墙,效果并不是很好,要么会受到墙的干扰,要么运营商qos太厉害,
要么协议本身限制再公网跑不起速度来。

所以引入了openwrt旁路由,routeros导入国内IP地址表,通过rooting mark的方式实现国内外IP地址分流,把国外IP地址转发给openwrt,openwrt通过ssr+或者passwall等使用ss、ssr、trojen、vless、hysteria等穿墙协议实现国外流量送出墙。

由于openwrt自身的复杂、开源软件质量,以及编译时的细节选项的各种问题,导致openwrt并不是十分稳定,且排查较为困难。
一直认为使用openwrt作为旁路由并不完美。后来routeros系统增加了wireguard,选择合适线路的vps后,可以实现勉强能做到单系统的透明网关,但是最近一段时间wireguard被墙阻断越来越严重,更换端口勉强能用几天。
再后来routeros内置了容器功能,极大的增大了发挥空间,虽然是个严重严格的容器功能。

通过以容器方式起mosdns实现了dns防污染、IPv4和IPv6自定义优先级等功能。
最近研究了一些前人的教程方法后,实现了容器内clash、sing-box、hysteria等程序路由功能。

RouterOS容器实现路由方式穿墙的方法,以hysteria这个简单程序为例。
1,通过hub.docker.com远程仓库拉去镜像或者导入tar文件方式创建容器。
以tar文件方式为例
电脑安装docker desktop并启动
命令行

docker pull alpine
docker save -o alpine.tar alipine

如果routeros是arm版的话

docker pull alpine@sha256:30e6d35703c578ee703230b9dc87ada2ba958c1928615ac8a674fcbbcbb0f281
#sha256:30e6d35703c578ee703230b9dc87ada2ba958c1928615ac8a674fcbbcbb0f281可在docker hub的网页上找到

2,然后把tar文件上传到routeros,建议开启smb功能,通过smb新建的文件权限比sftp或者scp要高
3,然后是创建容器,详细参考官方文档
创建完后,修改cmd属性

tail -f /dev/null

然后启动容器
4,通过shell 0 容器编号进入容器字符界面
使用wget命令下载hysteria,并解压
创建hysteria的配置文件,供参考,以服务端配置为准

{
  "insecure": true,
  "protocol": "wechat-video",
  "down_mbps": 330,
  "server": "x.x.x.x:x",
  "tun": {
  "name": "tun0"
  },
  "auth_str": "xxxx",
  "disable_mtu_discovery": false,
  "up_mbps": 110,
  "alpn": "h3",
  "server_name": "wechat.com"
}

5,然后创建tun

apk update
apk add iproute2
ip tuntap add mode tun dev tun0
ip addr add 198.18.0.1/15 dev tun0
ip link set dev tun0 up

6,修改路由,可以通过修改默认路由metric方式
假设 eth0 是原本的网卡,网关地址为 192.168.1.1,x.x.x.x是vps的IP地址

ip route del default
ip route add default via 198.18.0.1 dev tun0 metric 1
ip route add default via 192.168.1.1 dev eth0 metric 10
ip route add 192.168.0.0/16 via 192.168.1.1
ip route add 10.0.0.0/8 via 192.168.1.1
ip route add x.x.x.x via 192.168.1.1

也可以通分解0.0.0.0/0方式添加路由

ip route add 0.0.0.0/1 via 198.18.0.1
ip route add 128.0.0.0/1 via 198.18.0.1
ip route add 192.168.0.0/16 via 192.168.1.1
ip route add 10.0.0.0/8 via 192.168.1.1
ip route add x.x.x.x via 192.168.1.1

7,退出容器,停止容器
修改容器cmd参数

/root/hysteria client --config /root/hk.json

启动容器
8,配置routeros转发国外流量给容器,参考Routeros V7配置策略路由

9,容器内hysteia一键启动脚本start.sh

#!/bin/sh
GW="192.168.1.1"
cp /hysteria/hysteria /bin/
ip route replace 10.0.0.0/8 via $GW
ip route replace 192.168.0.0/16 via $GW
awk -F'"|:' '/"server"/ {cmd="ip route replace "$5" via '$GW'";system(cmd)}' /hysteria/$1
sleep 2&&ip addr add 198.18.0.1 dev tun0&&ip link set dev tun0 up&&ip route replace default via 198.18.0.1 &
hysteria client --config /hysteria/$1

在routeros上传hysteria可执行文件、hysteria配置文件和上面启动脚本到/container/etc/hysteria里
routeros新建容器命令

/container/mounts add name="hysteria" src="/container/etc/hysteria" dst="/hysteria"
/container add file=container/tmp/alpine_v3.18.2.tar interface=container-hysteria hostname=hysteria mounts=hysteria root-dir=container/root-dir/hysteria cmd="sh /hysteria/start.sh hk.json" start-on-boot=yes
/container start [find hostname=hysteria]

说明
由于routeros的容器功能细节一直在变动,有时候上一个版本还能使用,更新之后容器就不能启动了,而且日志一点信息都没有,所以采取了最保守的方式手动配置容器内应用的方式。
容器的网卡配置既不在容器内部存储,也不在routeros的veth里存储,似乎在一个容器外部不可见的地方,只能在容器内部操作,删除重建容器使用原来veth发现原有tun、静态路由居然还在。在routeros里修改veth的ip地址,居然不会同步修改容器内IP地址。
7.6版能启动的openwrt容器,新版就不能启动,一点日志都没有。
之前容器内可以写入mount的目录,新版就没有写权限,也没有执行权限,虽然容器内显示有权限。

也研究了tinyserve的bird+clash容器实现ospf动态路由透明网关方式,他使用了s6在容器内看护了几个应用,导致容器内存需求较大,小于4G内存的就别测试了。我使用rb5009,内存只有1gb,遇到routeros内存不足重启的问题。
动态路由这种透明网关方式早在ssr出现之前就有人提出,使用树莓派上跑bird+ss实现,但是我一直觉得一旦穿墙失效,所有数据包都会被运营商和墙捕捉到,为了高可用牺牲安全性不太值得,所以一直没用。

Routeros配置openvpn服务器和客户端

网上很多教程了,但是Routeros使用openvpn over shadowsocks避免使用机场安全隐患中需要一些内容,所以在此简单写一下。

Routeros配置openvpn服务器步骤如下
1,创建根证书
routeros网络配置地址(下同):/webfig/#System:Certificates.Certificates.new
以下信息根据自己更改,注意证书有效期
证书配置
保存后点击上图中sign按钮签发证书,成功后会如下图,证书前显示KAT
证书KAT标记
2,配置openvpn客户端地址池
/webfig/#IP:Pool.Pools.new
如图openvpn地址池
3,配置openvpn配置profile
/webfig/#PPP.Profiles.new
填写前三项,其他默认,注意本地地址和地址池尽量在同一网段,远程地址选择上面地址池名
Screen Shot 2020-04-06 at 01.46.04.png
4,配置openvpn服务器
/webfig/#PPP.OVPN_Server
配置以下红圈位置
openvpn服务器配置
5,配置openvpn账号
/webfig/#PPP.Secrets.new
openvpn账号
需要几个就添加几个

Routeros配置openvpn客户端
/webfig/#PPP.Interface.new.OVPN_Client
openvpn客户端

routeros配置vpn分流大陆ip

20201203更新:Routeros V7的分流方法参考Routeros V7配置策略路由
20201202更新:Routeros V7连接境外服务器的vpn方式可以参考Routeros 配置WireGuard
20200503更新:添加dnsmasq白名单分流解析
20200416更新:添加使用ipip.net的大陆ip列表生成命令并添加了私有ip地址

ros使用pppoe连网,ros上配置vpn连接香港服务器上的ros。目标:内网需要翻墙的ip通过大陆ip列表分流,大陆ip走默认路由,境外ip走vpn。其他内网ip全部走默认路由。
首先下载大陆ip列表,推荐方法2
方法1:

curl 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > chnroute.txt

生成的txt文件使用sublime的多行编辑功能或其他方式转换成ros的cn-ip.rsc脚本格式。

/ip firewall address-list
add list=cn-ip address=1.0.1.0/24
add list=cn-ip address=1.0.2.0/23
。。。

方法2:使用ipip.net发布在github的大陆ip列表生成

curl -s https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt |sed -e 's/^/add address=/g' -e 's/$/ list=CNIP/g'|sed -e $'1i\\\n/ip firewall address-list' -e $'1i\\\nremove [/ip firewall address-list find list=CNIP]' -e $'1i\\\nadd address=10.0.0.0/8 list=CNIP comment=private-network' -e $'1i\\\nadd address=172.16.0.0/12 list=CNIP comment=private-network' -e $'1i\\\nadd address=192.168.0.0/16 list=CNIP comment=private-network'>cnip.rsc

以上脚本在CNIP列表里添加了私有ip地址192.168.0.0/16,172.16.0.0/12和10.0.0.0/8

方法3:下载别人制作好的脚本
http://www.iwik.org/ipcountry/mikrotik/CN

使用import cnip.rsc导入ros。添加内网需要翻墙的ip列表。
配置ip firewall的mangle
prerouting,source address list,destination address list取反,destination address type,address type local,invert,mark routing,cross-gfw。
配置ip routes的网关
0.0.0.0/0,gateway设置为vpn对端地址,routing mark 使用上面的cross-gfw。

现在解决dns问题,由于ros的dns功能比较弱,这里使用dnsmasq
内网一台linux系统,可以是虚拟机,可以是容器,安装dnsmasq。配置dnsmasq的源dns为google dns,然后使用github上的大陆网址白名单生成脚本添加需要使用大陆解析的域名。https://github.com/felixonmars/dnsmasq-china-list
具体方法参考使用dnsmasq基于大陆域名白名单分流解析域名