ER-X 分流问题,如何维护国内 IP 列表。

2021-06-21 18:23:13 +08:00
 ca1123
上一贴: https://v2ex.com/t/784393
前情提要:上一次讲到需要针对国内和国际线路创建路由表,由防火墙按照 IP 规则绑定到指定的路由表上去,以实现流量分发。

那么用防火墙的话,carrionlee 老哥提出使用 network-group x Policy-Based-Routing(PBR),是很好的办法。比 chiphell 老哥逐条添加的办法好。这个办法底层是 Linux 的 ipset,很快。实际上 ER-X 用的 EdgeOS 就是换皮 VyOS,而 VyOS 的 PBR 底层就是用 ipset 实现的。自然 ER-X 的 PBR 也是用 ipset 的。

这样的话,我需要 a,b,c,d 四步
a) china ip list, 这个好办,github 上有。Archeb 提到用这个: https://github.com/17mon/china_ip_list

b) PBR 这个也好办,carrionlee 告诉我用这个,主要意思就是目标 ip 在国内的话属于 chnroute,就用国内的路由表 main


c) 接下来要用 bash 脚本把 a)中的 china ip list 导入,这是我迷惑的地方,看不太懂这个脚本,请大家帮我看看。问题想到哪儿说到哪儿多有重复。当一回伸手党不好意思了。
我理解这个脚本是先检查 cache,有 cache 就从 cache 导入,否则从 ip 列表写入,同时保存到 cache 。

第一:方括号里面的 -e 是检查是否存在的谓词么?
第二:-! restore < 为啥要用叹号啊?是从缓存文件恢复的意思吧?
第三:‘sed -e’ 是按行处理的意思么?是每一行就从管道线往下送一次么?
第四:听说'awk'是匹配模式,可是这里是什么意思啊?$0 是什么?最后是补了一个 commit 么?如果没有匹配到模式,下一个管道线收到的是空么?
第五:是全部一起传到 ipset -R 里,还是一行一行传的?
第六:管道线是把上一个的结果作为参数,是一股脑弄下来的,还是一行一行弄下来的?
第七:‘fi’是整个脚本结束,还是 if-then-else 结构结束啊?
第八:就整个脚本老说。是不是每次更新了 ip 库都要把 cache 清除了?是不是这个脚本每次重启都要运行?

d) ip 分流解决了,我就需要去弄 dns 了,暂时还没有什么想法。我能指定 ER-X 从特定的 WAN 口取 DNS 么?权益的可以先这么用一下。
4484 次点击
所在节点    宽带症候群
13 条回复
sutra
2021-06-21 23:12:35 +08:00
```
#!/bin/sh
cache="/var/cache"

rirs="${cache}/delegated-apnic-latest"
expanded_rirs="${cache}/expanded-delegated-apnic-latest"
asn_cache="${cache}/asn"

geoip_database="http://geolite.maxmind.com/download/geoip/database"
geoip_country_cache="${cache}/GeoIP/country"
geoip_country_csv="${geoip_country_cache}/GeoLite2-Country-CSV"
geoip_country_csv_zip="${geoip_country_csv}.zip"

ip2location_lite_db1="https://download.ip2location.com/lite"
ip2location_lite_db1_cache="${cache}/ip2location_lite_db1"
ip2location_lite_db1_csv="${ip2location_lite_db1_cache}/IP2LOCATION-LITE-DB1.CSV"
ip2location_lite_db1_csv_zip="${ip2location_lite_db1_csv}.ZIP"

mkdir -p "${asn_cache}"
mkdir -p "${geoip_country_csv}"
mkdir -p "${ip2location_lite_db1_cache}"

get.sh \
-o "${rirs}" \
-r 10 \
"http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest" \
&& expand-rir-asn.sh \
-i "${rirs}" \
-o "${expanded_rirs}" \
-C "${asn_cache}" \
|| exit 1

get.sh \
-o "${geoip_country_csv_zip}" \
-r 10 \
-m 200 \
-n 204 \
"${geoip_database}/GeoLite2-Country-CSV.zip"
exit_status=$?
if [ ${exit_status} -eq 200 ]; then
unzip \
-oqd "${geoip_country_cache}" \
"${geoip_country_csv_zip}" \
&& rsync \
"${geoip_country_cache}"/*/* \
"${geoip_country_csv}/" \
&& rm \
-r "${geoip_country_csv}"_*
#elif [ ${exit_status} -ne 204 ]; then
# exit $?
fi

get.sh \
-o "${ip2location_lite_db1_csv_zip}" \
-r 10 \
-m 200 \
-n 204 \
"${ip2location_lite_db1}/IP2LOCATION-LITE-DB1.CSV.ZIP"
exit_status=$?
if [ ${exit_status} -eq 200 ]; then
unzip \
-oqd "${ip2location_lite_db1_cache}" \
"${ip2location_lite_db1_csv_zip}"
fi

update-ipset.sh \
-n "chnroute" \
-i "${expanded_rirs}" \
-g "${geoip_country_csv}" \
-l "${ip2location_lite_db1_csv}" \
-c "CN" \
```
sutra
2021-06-21 23:35:36 +08:00
> 第一:方括号里面的 -e 是检查是否存在的谓词么?
https://en.wikibooks.org/wiki/Bash_Shell_Scripting

> 第二:-! restore < 为啥要用叹号啊?是从缓存文件恢复的意思吧?
重定向读入文件内容

> 第三:‘sed -e’ 是按行处理的意思么?是每一行就从管道线往下送一次么?
man sed

> 第四:听说'awk'是匹配模式,可是这里是什么意思啊?$0 是什么?最后是补了一个 commit 么?如果没有匹配到模式,下一个管道线收到的是空么?
https://github.com/wuzhouhui/awk

> 第五:是全部一起传到 ipset -R 里,还是一行一行传的?
全部

第六:管道线是把上一个的结果作为参数,是一股脑弄下来的,还是一行一行弄下来的?
> 全部

第七:‘fi’是整个脚本结束,还是 if-then-else 结构结束啊?
> if 倒过来写表示 if 结束了。

第八:就整个脚本老说。是不是每次更新了 ip 库都要把 cache 清除了?是不是这个脚本每次重启都要运行?
> 你重启看看 ipset list 有没有内容,ipset 有其它机制保证重启后还能恢复的。
zdndk598
2021-06-22 07:21:03 +08:00
建议重新学 shell script
9yu
2021-06-22 08:20:34 +08:00
建议重新学 shell script
shyy228
2021-06-22 08:28:41 +08:00
建议重新学 shell script
nbsn
2021-06-22 12:24:40 +08:00
@ca1123 楼主可以看下 ER-X 好像支持 bgp,我还是建议用动态路由。
ca1123
2021-06-22 13:48:52 +08:00
@shyy228 你们三个队形这么整齐,我感觉自己都可以重开了。
gqkkk
2021-06-22 15:19:19 +08:00
-!, -exist
Ignore errors when exactly the same set is to be created or already added entry is added or missing entry is deleted.

restore
Restore a saved session generated by save. The saved session can be fed from stdin or the option -file can be used to specify a filename instead of stdin.
Please note, existing sets and elements are not erased by restore unless specified so in the restore file. All commands are allowed in restore mode except list, help, version, interactive mode and restore itself.
gqkkk
2021-06-22 15:20:43 +08:00
@sutra 人家问感叹号代表什么 不是标准输入
gqkkk
2021-06-22 15:23:05 +08:00
建议去看下 《 OReilly - Sed & Awk 2nd Edition 》
zengming00
2021-06-22 15:37:58 +08:00
wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | awk -F\| '/CN\|ipv4/ { printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > /etc/chinaIP.txt
sutra
2021-06-22 16:15:13 +08:00
#1 的代码来着 https://github.com/sutra/update-ipset.sh ,贴得有点乱。
ca1123
2021-06-22 21:01:25 +08:00
我找了个老哥帮我看了一下,下面是结果
--------------------------------------------
#!/bin/bash
CHNROUTE_RULES=/config/user-data/chnroute.txt
CHNROUTE_RULES_CHCHE=/config/user-data/chnroute.ipset

if [-e $CHNROUTE_RULES_CHCHE]; then
#中括号内 -e 判断文件是否存在

ipset -! restore < $CHNROUTE_RULES_CHCHE
# -! 参数忽略错误和提示信息,比如已经存在的 set 提示是否覆盖, 文件不存在报错
# < 重定向符, 作为 ipset 的输入, 把文件内容输入到 ipset 命令中
else
sed -e "s/^/add chnroute &/g" $CHNROUTE_RULES | awk '{print $0} END {print "COMMIT"}' | ipset -R
# | 管道符, 左边的输出 传到右边, 作为右边的输入
# sed -e "s/^/add chnroute &/g" $CHNROUTE_RULES : 一行一行读取$CHNROUTE_RULES 文件,每行在开头插入"add chnroute &", -e 执行正则表达式脚本 "s/^/add chnroute &/g" s 替换 ^每行首段 /g 全行替换
# awk $0 输出每行, END 在结束时候, 输出 COMMIT
# 一行一行读取并执行,测试命令,实时输出,而不是最后整体输出: find .| awk '{print NR $0 " line end"} END {print "COMMIT"}'
ipset save chnroute > $CHNROUTE_RULES_CHCHE
#保存名为 chnroute 的集合,输出到文件当中
fi
#fi 结束,对应 if


#参考:
#一. -e 参数
# if [[ -e readme.txt ]] ; then
# echo '文件"readme.txt" 存在.'
# else
# echo '文件"readme.txt" 不存在.'
# fi
#二.ipset 参考链接 https://www.cnblogs.com/wn1m/p/10919940.html
#三.sed 参考链接 http://c.biancheng.net/view/4028.html
#四.awk 参考链接 https://www.runoob.com/linux/linux-comm-awk.html
# 命令验证指令,NR 是打印输入的行号 sed -e "s/^/add chnroute &/g" 1.txt | awk '{print NR $0 " line end"} END {print "COMMIT"}' > 2.txt

# 1.txt 内容为
# 1
# 2
# 3

# 输出的 2.txt
# 1add chnroute 1 line end
# 2add chnroute 2 line end
# 3add chnroute 3 line end
# COMMIT

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/784894

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX