Caddy2插件Geocn

本文最后更新于 998 天前, 如有失效请评论区留言.

为什么要Geocn

大部分场景下,我们网站允许任何人访问, 某些特殊场景下我们需要限制大陆ip访问。
但是已有插件caddy-maxmind-geolocation为啥不用。

默认使用的 GeoIP2 数据库是来自于 MaxMind 的 GeoLite2 免费数据库。这个数据库目前存在一下几个问题:

  • 获取不便:从 2019 年 12 月 30 日起,必须注册后才能下载
  • 数据量大:数据库庞大,包含全球的 IP 地址段,约 4 MB
  • 准确度低:对中国大陆的 IP 地址判定不准,如:香港阿里云的 IP 被判定为新加坡、中国大陆等

新的政策要求注册才能下载会增加时间成本,而且会让自动化下载的难度大大增加。庞大的数据量无可厚非,但是对于大多数中国大陆的用户来说,仅需要去判断 IP 的地理位置是否属于中国大陆境内,其他国家的 IP 一律代理。过多的数据量会增加载入时间,降低查询效率。

基于上述考虑, 结合caddy-maxmind-geolocationHackl0us/GeoIP2-CN两者, 只有判断ip是否是中国大陆ip即可。

核心设计

  • 使用Hackl0us/GeoIP2-CN提供的准确度高、用户使用体验好的仅含有中国大陆 IP 信息的 GeoIP2 数据库
  • 使用caddyhttp.RequestMatcher, 不得不说 Request Matchers
    • 获取request.RemoteAddr地址, 优先级最高
    • request.Header获取X-Forwarded-For地址, 如果RemoteAddr为内网地址,才考虑

使用caddy

编译caddy2

可以参考 ysicing/caddy2

默认情况下, 直接使用提供的二进制即可。不过我们需要集成第三方插件,需要使用xcaddy自行编译

# 本地安装xcaddy
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
# github action安装
    - name: Install Go
      uses: actions/setup-go@v1
      with:
        go-version: 1.17.x
    - name: install xcaddy
      run: |
          echo "install xcaddy"
          go get -u github.com/caddyserver/xcaddy/cmd/xcaddy@latest
    - name: build bin
      run: |
        export TZ='Asia/Shanghai'
        export PATH=$PATH:$(go env GOPATH)/bin
        xcaddy build --with github.com/ysicing/caddy2-geocn

构建caddy二进制

# 使用remote code
xcaddy build --with github.com/ysicing/caddy2-geocn
# 使用local code
xcaddy build --with github.com/ysicing/caddy2-geocn=../caddy2-geocn

插件本地化测试

cd go/src/github.com/ysicing/
git clone https://github.com/ysicing/caddy2-geocn.git
cd caddy2-geocn
# 二进制
make build
make run
# docker
GOOS=linux xcaddy build --with github.com/ysicing/caddy2-geocn=../caddy2-geocn
rm -rf Country.mmdb
wget https://github.com/Hackl0us/GeoIP2-CN/raw/release/Country.mmdb
docker build -t ghcr.io/ysicing/caddy2-geocn -f example/Dockerfile .

docker-compose.yaml示例如下:

version: '2'
services:
  caddy2-geocn:
    image: ghcr-proxy.hk1.godu.dev/ysicing/caddy2-geocn
    container_name: caddy2-geocn
    ports:
      - '80:80'
    volumes:
      - './Caddyfile:/etc/caddy/Caddyfile'

Caddyfile示例如下:

(LOG) {
    log {
        output file /var/log/caddy.log {
            roll_size 1mb
		    roll_keep 5
		    roll_keep_for 1h
        }
        format console {
            time_format "iso8601"
        }
    }
}

(COMCFG) {
    encode zstd gzip
}

{
    debug
}

:80 {
    import COMCFG
    import LOG
    metrics /metrics
    @geofilter {
        not geocn {
            db_file "/etc/caddy/Country.mmdb"
        }
    }
    # file_server @geofilter {
    #    root /etc/caddy/example/deny
    #}
    redir @geofilter  https://www.baidu.com{uri} permanent
    file_server {
        root /etc/caddy/example/allow
    }
}
EOF 
docker-compose up -d

云环境

docker run -itd 80:80 ghcr.io/ysicing/caddy2-geocn:latest

应用场景

我的博客 就是很好的示例, 分别使用代理和非代理方式访问

致谢

Sponsor

Like this article? $1 reward

Comments

According to the relevant laws and regulations of the People's Republic of China, the comment function of the current website has been disabled. If you need to comment, please visit ysicing.me, but the comments still need to be reviewed by AI.