IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    使用Linux实现透明网关代理取代OpenWrt

    chancel发表于 2024-06-13 00:00:00
    love 0
    <![CDATA[

    多年来,Openwrt作为旁路由方案非常完美的契合了我的需求,使用起来非常方便,加上OpenWrt可以自行编译,在保障了一定程度上的网络安全同时还有着数量相当广的插件来实现许多有意思的功能

    随着使用时间变多,对插件的依赖逐渐变小,Openwrt逐渐变得重起来了,而且在界面上去实现一些路由规则、Bash脚本有些隔靴搔痒,于是打算实现一个旁路由透明代理和分流的方案,为此查阅了一些资料,计划实现如下功能:

    1. 智能分流:对国内地址采用国内DNS解析直连访问,对国外地址则走网络代理进行访问
    2. 解决DNS污染:畅通地访问无需科学上网的网站(如GitHub)
    3. 支持旁路由:家庭网络中其他设备无需安装任何代理工具即可享受上述的一切

    思路如下:

    • Alpine:最迷你的Linux发行版,非常适用Docker/虚拟机
    • 分流方案:使用iptables搭配ipset实现国内外IP分流
    • DNS污染:使用overture解除国内的DNS污染

    下面将实践上述的方案,我的信息如下

    • 网络段:192.168.10.0/20
    • 路由器IP:192.168.10.1
    • 透明网关IP:192.168.10.2

    最终,我希望局域网中的其他设备将网关地址和DNS设置为192.168.10.2,将可以实现自动分流(国内直连,国外代理)

    透明网关:即网关的存在对网络用户来说是透明的,它们无需对其进行特殊的配置或设置(例如手动设置代理),用户可以像访问任何其他网络设备一样,与透明网关进行通信,无需关心网关做了什么代理策略

    原理如下图

    此文建议有一定网络基础知识的同学实践,如果卡在一些简单的步骤说明可能不那么合适自定义透明网关

    1. Alpine

    Alpine是一个非常迷你的操作系统,docker容器大小仅为5Mb,ISO镜像也仅有100+M,非常适合用来定制Linux透明网关

    1.1. Alpine安装

    下载Alpine

    • https://www.alpinelinux.org/downloads/

    下载使用任意虚拟机软件虚拟该系统,我的配置是 $2C4T/1024 RAM/1Gb Disk$

    开启虚拟机后,输入root用户登录,无需密码,然后输入setup-Alpine开始安装系统

    之后的安装过程与其他发行版安装无异,安装较为简单,此处不再赘述

    1.2. Alpine网络设置

    在系统安装完成后,编辑文件:/etc/network/interfaces

    内容参考如下如下

    Bash
    auto lo
    iface lo inet loopback
    
    auto eth0
    iface eth0 inet static
            address 192.168.10.2
            netmask 255.255.255.0
            gateway 192.168.10.1
            nameservers 114.114.114.114 # 暂时设置DNS为114.114.114.114
    

    修改完成后重启网络,测试网络是否畅通

    Bash
    service networking restart
    

    在确保网络正常后,设置允许机器转发局域网请求

    编辑文件:/etc/sysctl.conf

    添加如下字段到文件尾

    Bash
    net.ipv4.ip_forward=1
    

    并更新sysctl配置

    Bash
    sysctl -p
    

    1.3. Alpine软件源

    在重启网络之后,为了加快软件下载,将软件源重定义到清华源

    编辑文件:/etc/apk/repositories

    Bash
    #/media/cdrom/apks
    https://mirrors.tuna.tsinghua.edu.cn/Alpine/v3.16/main
    https://mirrors.tuna.tsinghua.edu.cn/Alpine/v3.16/community
    https://mirrors.tuna.tsinghua.edu.cn/Alpine/edge/main
    https://mirrors.tuna.tsinghua.edu.cn/Alpine/edge/community
    https://mirrors.tuna.tsinghua.edu.cn/Alpine/edge/testing
    

    然后更新apk仓库

    Bash
    apk update
    

    1.4. Alpine的准备工作

    接下来准备相关工具,安装以下软件,并初始化运行

    Bash
    apk add supervisor curl iptables vim wget ipset
    service iptables save
    service iptables start
    service supervisord start
    

    由于Alpine没有使用systemd来管理系统,需要借助crontab手动添加以上部分软件的自启动

    Bash
    crontab -e
    

    设置supervisord跟iptables服务在开机之后自启动

    Bash
    # do daily/weekly/monthly maintenance
    # min   hour    day     month   weekday command
    ...
    
    @reboot /sbin/service supervisord start
    @reboot /sbin/service iptables start
    

    到此,系统的初始化设置完毕

    2. gost

    gost是一款使用golang编写的网络安全隧道工具,支持大部分主流协议,目前更新到V3.0版本,本文使用v2.11版本

    仓库地址:https://github.com/ginuerzh/gost

    2.1. 服务端

    在服务端下载gost

    • https://github.com/ginuerzh/gost/releases/tag/v2.11.2

    并使用gzip解压

    Bash
    gzip -d gost-linux-amd64-2.11.2.gz
    

    运行最简单的代理服务

    Bash
    ./gost-linux-amd64-2.11.2 -L=ss://chacha20:password@:8338
    

    2.2. 客户端

    回到我们本地的Alpine系统,一样先下载gost

    • https://github.com/ginuerzh/gost/releases/tag/v2.11.2

    并使用gzip解压

    Bash
    gzip -d gost-linux-amd64-2.11.2.gz
    

    下载完成后先尝试运行

    Bash
    ./gost -L=:18080 -F="ss://chacha20:password@server_ip:8338"
    

    测试代理是否正常

    Bash
    ~$ export http_proxy=http://127.0.0.1:18080
    ~$ curl cip.cc                 
    IP      : 1.2.3.4
    地址    : 中国  香港  keaiduo.com
    数据二  : 香港 | 可爱多优先公司
    数据三  : 中国香港 | 可爱多优先公司
    URL     : http://www.cip.cc/1.2.3.4
    

    可以看到成功使用了服务端的IP

    2.3. 中继代理

    在确认直连测试ss连接是正常后,开启gost的透明网关模式(中继代理),如下

    Bash
    # 仅修改了监听协议为red
    ./gost -L=red://:28080 -F="ss://chacha20:password@server_ip:8338"
    

    检查以上命令运行无报错输出后结束,写入到supervisor中作为daemon程序运行

    编辑文件:/etc/supervisor.d/gost.ini

    INI
    [program:gost-18080]
    command=/root/gost/gost -L=:18080 -F="ss://chacha20:password@server_ip:8338"
    autostart=true
    autorestart=true
    stdout_logfile=/var/log/supervisor/%(program_name)s.log
    stderr_logfile=/var/log/supervisor/%(program_name)s.log
    user=root
    
    [program:gost-28080]
    command=/root/gost/gost -L=red://:28080 -F="ss://chacha20:password@server_ip:8338"
    autostart=true
    autorestart=true
    stdout_logfile=/var/log/supervisor/%(program_name)s.log
    stderr_logfile=/var/log/supervisor/%(program_name)s.log
    user=root
    

    上面的配置将运行2个监听,分别是代理监听18080和中继转发监听28080

    更新supervisor运行

    Bash
    supervisorctl update
    

    检查运行状态

    Bash
    supervisorctl status
    

    3. iptables

    iptables是Linux中用来管理网络包的用户态工具,大部分操作都需要超级用户权限,其路径通常位于/sbin/iptables

    iptables是由table、chain、rules组成的,用不同的表来处理不同类型的数据包,用链来处理不同时期的数据包,用规则来管理数据包的行为

    3.1. 基础概念(可跳过)

    要使用iptables,要掌握一定的基础网络知识,这里受限于篇幅,仅查阅了一些关于透明网关相关的iptables操作

    iptables的基本构成是4表5链

    • Filter表:iptables的默认表,包含INPUT/OUTPUT/FORWARD链
    • NAT表:地址转换表,包含了OUTPUT/PREROUTING/POSTROUTING链
    • Mangle表:用于管理数据包内容的表,包含了PREROUTING/OUTPUT/FORWARD/INPUT/POSTROUTING链
    • raw表:处理异常的表,包含了PREROUTING/OUTPUT链
    • security表:不常见,此处可忽略

    此外还包含以下动作(即-j参数值)

    1. ACCEPT
    2. DROP
    3. REDIRECT
    4. RETURN
    5. SNAT
    6. DNAT
    7. MASQUERADE
    8. LOG
    9. SEMARK

    以iptables -A INPUT -p all -s 192.168.1.0/24 -j ACCEPT为例

    其中-A表示append,-p表示协议类型,-s表示来源,-j表示动作

    由上可以看出iptables的基础命令形式

    Bash
    iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网络设备> -p 协议名 <-s 源IP/源子网> --sport 源端口 <-d 目标IP/目标子网> --dport 目标端口 -j 动作
    

    相关参数解释

    • <-A/I/D/R>:A代表添加,I代表插入,D代表删除,R代表替换
    • <-i/o 网络设备>:-i表示流入设备名称,-o表示流出设备名称
    • -p:表示protocol,常见的如tcp/udp/icmp/stcp等

    接下来,我们可以看看下面的例子,帮助理解iptables的命令行规则

    创建与删除规则示例

    Bash
    # 允许192.168.1.0/24网段访问本机22端口
    iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT
    # 查看刚才创建的规则
    iptables -L -n -v
    # 删除“允许192.168.1.0/24网段访问本机22端口”规则
    iptables -D INPUT -s 192.168.1.0/24 -p tcp --dport 22 -j ACCEPT
    

    iptables常见操作例子

    Bash
    # 允许访问本机22,80,443端口
    iptables -A INPUT  -p tcp -m multiport --dports 22,80,443 -j ACCEPT
    # 允许本机访问192.168.1.0/24网段的所有22端口
    iptables -A OUTPUT -p tcp -d 192.168.1.0/24 --dport 22 -j ACCEPT
    # 禁止访问192.168.1.1(注意协议类型为all)
    iptables -A OUTPUT -p all -d 192.168.1.1 -j DROP
    # 将本机端口12222的请求转发到22
    iptables -t nat -A PREROUTING -p tcp --dport 12222 -j REDIRECT --to-port 22
    # 限制本机端口80的并发数量最高为200,每分钟最高100个(应对DDOS攻击)
    iptables -A INPUT -p tcp --dport 80 -m limit --limit 100/minute --limit-burst 200 -j ACCEPT
    # 限制本机的ICMP请求
    iptables -A INPUT -p icmp -j DROP
    # 限制mac地址访问本机
    iptables -A INPUT -m mac --mac-source 32:e6:37:5c:40 -j DROP
    # 清除所有规则
    iptables -F
    

    下面是设置网关转发需要用到的NAT表操作

    Bash
    # 创建一个nat表,名为SSNAT
    iptables -t nat -N SSNAT
    # 为SSNAT表设置遇到192.168.1.1/20网段的目标IP网段则终止当前链返回上一个调用链
    iptables -t nat -A SSNAT -d 192.168.1.1/20 -j RETURN
    # 为SSNAT表设置将所有tcp请求转发到本机18080端口
    iptables -t nat -A SSNAT -p tcp -j REDIRECT --to-port 18080
    # 将SSNAT链中所有的规则追加到OUTPUT链中
    iptables -t nat -A SSNAT -p tcp -j SHADOWSOCKS
    # 查看所有NAT表规则
    iptables -t nat -L -v -n
    

    掌握了以上的iptables基础操作,就可以操作iptables转发来实现透明网关

    3.2. 实现分流

    iptables在进行地址集合查找时效率不高,可引入iptables的扩展插件ipset来处理地址合集

    要区分国内外ip,首先需要一份国内的IP网段

    • https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt

    有了国内ip地址合集就可以实现针对国内外ip走不同代理策略(国外走代理,国内直连)

    编辑文件:/root/iptables/iptables.sh

    Bash
    #/bin/bash
    #author:Chancel.Yang
    #date:2023/09/21
    
    remote_ip=[your_server_ip]
    local_port=[your_local_port]
    
    /usr/sbin/ipset -N china hash:net
    for i in $(cat ./china_ip_list.txt ); 
    do
        /usr/sbin/ipset -A china $i; 
    done
    
    # 创建一个NAT规则集`SSNAT`
    /sbin/iptables -t nat -N SSNAT
    # 在`SSNAT`规则中添加无需走ss流量的国内ip以及局域网ip
    /sbin/iptables -t nat -A SSNAT -p all -m set --match-set china dst -j RETURN
    /sbin/iptables -t nat -A SSNAT -d 0.0.0.0/8 -j RETURN
    /sbin/iptables -t nat -A SSNAT -d 10.0.0.0/8 -j RETURN
    /sbin/iptables -t nat -A SSNAT -d 127.0.0.0/8 -j RETURN
    /sbin/iptables -t nat -A SSNAT -d 169.254.0.0/16 -j RETURN
    /sbin/iptables -t nat -A SSNAT -d 172.16.0.0/12 -j RETURN
    /sbin/iptables -t nat -A SSNAT -d 192.168.0.0/16 -j RETURN
    /sbin/iptables -t nat -A SSNAT -d 224.0.0.0/4 -j RETURN
    /sbin/iptables -t nat -A SSNAT -d $remote_ip -j RETURN
    
    # `SSNAT`的网络代理包括udp、icmp、udp(请按需)
    /sbin/iptables -t nat -A SSNAT -p tcp -j REDIRECT --to-port $local_port
    /sbin/iptables -t nat -A SSNAT -p udp -j REDIRECT --to-port $local_port
    /sbin/iptables -t nat -A SSNAT -p icmp -j REDIRECT --to-port $local_port
    
    # 将所有数据包转入`SSNAT`规则集合中
    /sbin/iptables -t nat -A PREROUTING -p tcp -j SSNAT
    
    # 将出站数据包的源地址进行NAT,否则在部分网络场景下会100%丢包
    /sbin/iptables -t nat -I POSTROUTING -j MASQUERADE
    

    脚本说明:

    1. 首先使用ipset导入china_ip_list.txt文件并命名集合名为china
    2. 创建名为SSNAT的nat链,在此链中设置国外走代理,国内直连的处理策略
    3. 最后将入网流量全部转入SSNAT链中处理并进行NAT伪装

    运行上面的脚本缺少china_ip_list.txt 文件,china_ip_list.txt 文件在github.com可以下载,地址如下

    Bash
    wget https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
    

    脚本目录如下

    Bash
    Alpine:~# ls -l /root/iptables
    total 13212
    -rw-r--r--    1 root     root          1526 Aug  2 10:13 iptables.sh
    -rw-r--r--    1 root     root         95316 Jul 27 11:51 china_ip_list.txt
    

    执行脚本查看结果

    Bash
    sh /root/iptables/iptables.sh
    

    没有错误输出的话,就可以将这个脚本设置为开机执行

    Bash
    crontab -e
    

    设置开机执行

    Bash
    # do daily/weekly/monthly maintenance
    # min   hour    day     month   weekday command
    ...
    
    @reboot /bin/sh /root/iptables/iptables.sh
    

    我的NAT表规则如下(可供参考)

    Bash
    chancel@j3455 ~$ sudo iptables -L -n -v -t nat
    
    Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
      508 31917 SSNAT      6    --  *      *       0.0.0.0/0            0.0.0.0/0           
    
    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
    
    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
    
    Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
     2283  183K MASQUERADE  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
    
    Chain DOCKER (2 references)
     pkts bytes target     prot opt in     out     source               destination         
        0     0 RETURN     0    --  docker0 *       0.0.0.0/0            0.0.0.0/0           
    
    Chain SSNAT (1 references)
     pkts bytes target     prot opt in     out     source               destination         
       47  4192 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/0            match-set china dst
        0     0 RETURN     0    --  *      *       0.0.0.0/0            0.0.0.0/8           
        0     0 RETURN     0    --  *      *       0.0.0.0/0            10.0.0.0/8          
        0     0 RETURN     0    --  *      *       0.0.0.0/0            127.0.0.0/8         
        0     0 RETURN     0    --  *      *       0.0.0.0/0            169.254.0.0/16      
        2   185 RETURN     0    --  *      *       0.0.0.0/0            172.16.0.0/12       
        2   120 RETURN     0    --  *      *       0.0.0.0/0            192.168.0.0/16      
        0     0 RETURN     0    --  *      *       0.0.0.0/0            224.0.0.0/4         
      449 26940 REDIRECT   6    --  *      *       0.0.0.0/0            0.0.0.0/0            redir ports 28080
    

    在局域网内,找任意机器将网关设置成192.168.10.2,此时应该可以正常访问国内网站

    4. overture

    到上一步为止,可以访问国内网站,但仍然无法正常访问国外网站

    即使SSNAT内能根据国内外IP自动分流,由于DNS污染没有解决,google.com等域名的ip是错误的,分流是无法正常生效的

    注:DNS污染指通过国内DNS解析去解析国外的IP地址时,DNS服务器返回一个错误的IP(或者根本不存在的IP)

    所以我们需要自建一个正常的DNS解析服务,overture是一个基于Go语言开发的DNS解析服务程序

    比起经典的ChinaDNS的优点是设置更加丰富,也更简单一些

    4.1. 安装

    安装方法如下

    Bash
    mkdir -p /root/overture && cd /root/overture
    wget https://github.com/shawn1m/overture/releases/download/v1.8/overture-linux-amd64.zip
    unzip overture-linux-amd64.zip
    
    # 保留默认配置文件用于恢复(可选)
    cp config.yml config.yml.bak
    

    4.2. 配置

    编辑文件:/root/overture/config.yml

    YAML
    bindAddress: :53
    debugHTTPAddress: 127.0.0.1:55555
    dohEnabled: false
    primaryDNS:
      - name: DNS114
        address: 114.114.114.114:53
        protocol: udp
        socks5Address: 
        timeout: 6
        ednsClientSubnet:
          policy: disable
          externalIP:
          noCookie: true
      - name: AliDNS
        address: 223.5.5.5:53
        protocol: udp
        socks5Address:
        timeout: 6
        ednsClientSubnet:
          policy: disable
          externalIP:
          noCookie: true
    onlyPrimaryDNS: false
    alternativeDNS:
      - name: GoogleDNS
        address: 8.8.8.8:53
        protocol: tcp
        # 使用一开始设置的`gost`直连代理来访问Google的DNS服务
        socks5Address: 127.0.0.1:18080
        timeout: 6
        ednsClientSubnet:
          policy: disable
          externalIP:
          noCookie: true
    ipv6UseAlternativeDNS: false
    alternativeDNSConcurrent: false
    whenPrimaryDNSAnswerNoneUse: primaryDNS
    ipNetworkFile:
      # 如在`primary`2个DNS服务中匹配到`china_ip_list.txt`中的ip则直接返回
      primary: /root/overture/china_ip_list.txt
      alternative: /root/overture/ip_network_alternative_sample
    domainFile: 
      primary: /root/overture/domain_primary_sample
      # 如在`alternative`2个DNS服务中匹配到`gfw_all_domain.txt`中的域名则直接返回
      alternative: /root/overture/gfw_all_domain.txt
      matcher: full-map
    hostsFile:
      hostsFile: /etc/hosts
      finder: full-map
    minimumTTL: 0
    domainTTLFile: /root/overture/domain_ttl_sample
    cacheSize: 100
    cacheRedisUrl:
    cacheRedisConnectionPoolSize:
    rejectQType:
      - 255
    

    配置文件解释如下:

    1. primaryDNS表示主DNS列表(国内),alternativeDNS表示副DNS列表(国外)
    2. 关键配置在于ipNetworkFile和domainFile,一个确定匹配到国内ip段将直接返回,一个确定匹配到国外域名就直接返回

    配置中使用到的国内IP与国外域名来源:

    • 国内IP段:https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
    • 国外域名集合:https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt

    由于china_ip_list.txt与gfw_all_domain.txt文件都是需要定期更新,所以写一个脚本来实现

    编辑文件:/root/overture/ip_and_domain_update.sh

    Bash
    #/bin/bash
    #author:Chancel.Yang
    #date:2023/09/21
    
    wget https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
    curl https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt | base64 -d | sort -u | sed '/^$\|@@/d'| sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' | sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /qq\.com/d' | sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' | grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u > temp_gfwlist.txt
    curl https://raw.githubusercontent.com/hq450/fancyss/master/rules/gfwlist.conf | sed 's/ipset=\/\.//g; s/\/gfwlist//g; /^server/d' > temp_koolshare.txt
    cat temp_gfwlist.txt temp_koolshare.txt | sort -u > gfw_all_domain.txt
    rm -f temp_gfwlist.txt temp_koolshare.txt
    

    执行脚本,然后查看目录下是否包含了china_ip_list.txt和gfw_all_domain.txt

    Bash
    cd /root/overture && bash ip_and_domain_update.sh
    

    运行overture

    TEXT
    ./overture-linux-amd64 -c ./config.yml
    

    确保执行结果中没有error提示,然后用局域网内其他机器测试解析github.com的网址

    Bash
    ➜  dig @192.168.10.2 www.github.com
    
    ; <<>> DiG 9.18.4 <<>> @192.168.10.2 www.github.com
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8772
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 1232
    ;; QUESTION SECTION:
    ;www.github.com.                        IN      A
    
    ;; ANSWER SECTION:
    www.github.com.         1552    IN      CNAME   github.com.
    github.com.             60      IN      A       192.30.255.113
    
    ;; Query time: 243 msec
    ;; SERVER: 192.168.10.2#53(192.168.10.2) (UDP)
    ;; WHEN: Tue Jul 26 18:46:44 CST 2022
    ;; MSG SIZE  rcvd: 107
    

    最后使用supervisor将overture设置为daemon程序运行

    编辑文件:/etc/supervisor.d/overture.ini

    INI
    [program:overture]
    directory=/root/overture
    command=/root/overture/overture-linux-amd64 -c /root/overture/config.yml
    autostart=true
    autorestart=true
    user=root
    

    更新supervisor运行

    Bash
    supervisorctl update
    

    检查运行状态

    Bash
    supervisorctl status
    

    最后修改Alpine网络配置中dns服务地址

    编辑文件:/etc/network/interfaces

    Bash
    auto lo
    iface lo inet loopback
    
    auto eth0
    iface eth0 inet static
            address 192.168.10.2
            netmask 255.255.255.0
            gateway 192.168.10.1
            nameservers 127.0.0.1
    

    重启网络

    Bash
    service networking restart
    

    将局域网其他设备设置为192.168.10.2,并验证透明网关是否正确分流国内外ip

    5. 结束语

    本文仅抛砖引玉,若对透明网关有兴趣还需要多多查阅资料

    资料参考

    • GOST v2 帮助文档
    • 透明代理中iptables设置方法详细介绍
    • linux全局智能分流方案
    • 使用 iptables、ipset 的全局智能代理
    • 用树莓派2代打造智能家庭路由
    • Ubuntu: How To Free Up Port 53, Used By systemd-resolved
    • 使用Overture自建无污染DNS
    • overture 无污染的智能 DNS 折腾记 #4
    • 新 V2Ray 白话文指南
    • iptables - Wikipedia
    • 25 Useful IPtable Firewall Rules Every Linux Administrator Should Know



沪ICP备19023445号-2号
友情链接