ER-X 分流问题,如何维护国内 IP 列表。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
ca1123
V2EX    宽带症候群

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

  •  
  •   ca1123 2021-06-21 18:23:13 +08:00 5068 次点击
    这是一个创建于 1660 天前的主题,其中的信息可能已经有所发展或是发生改变。
    上一贴: 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 么?权益的可以先这么用一下。
    13 条回复    2021-06-22 21:01:25 +08:00
    sutra
        1
    sutra  
       2021-06-21 23:12:35 +08:00   1
    ```
    #!/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
        2
    sutra  
       2021-06-21 23:35:36 +08:00   1
    > 第一:方括号里面的 -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
        3
    zdndk598  
       2021-06-22 07:21:03 +08:00 via iPhone
    建议重新学 shell script
    9yu
        4
    9yu  
       2021-06-22 08:20:34 +08:00 via Android
    建议重新学 shell script
    shyy228
        5
    shyy228  
       2021-06-22 08:28:41 +08:00
    建议重新学 shell script
    nbsn
        6
    nbsn  
       2021-06-22 12:24:40 +08:00
    @ca1123 楼主可以看下 ER-X 好像支持 bgp,我还是建议用动态路由。
    ca1123
        7
    ca1123  
    OP
       2021-06-22 13:48:52 +08:00
    @shyy228 你们三个队形这么整齐,我感觉自己都可以重开了。
    gqkkk
        8
    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
        9
    gqkkk  
       2021-06-22 15:20:43 +08:00   1
    @sutra 人家问感叹号代表什么 不是标准输入
    gqkkk
        10
    gqkkk  
       2021-06-22 15:23:05 +08:00
    建议去看下 《 OReilly - Sed & Awk 2nd Edition 》
    zengming00
        11
    zengming00  
       2021-06-22 15:37:58 +08:00   1
    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
        12
    sutra  
       2021-06-22 16:15:13 +08:00
    #1 的代码来着 https://github.com/sutra/update-ipset.sh ,贴得有点乱。
    ca1123
        13
    ca1123  
    OP
       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
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4568 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 01:07 PVG 09:07 LAX 17:07 JFK 20:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86