Gzctf搭建与维护
基本框架
1. 依照官网示例配置
配置各种密码和参数
gzctf:
image: gztime/gzctf:latest
restart: unless-stopped
environment:
- "GZCTF_ADMIN_PASSWORD=${GZCTF_ADMIN_PASSWORD}"
# choose your backend language `en_US` / `zh_CN` / `ja_JP`
- "LC_ALL=zh_CN.UTF-8"
# ports:
# - "80:8080"
volumes:
- "./gzctf/data/files:/app/files"
- "./gzctf/appsettings.json:/app/appsettings.json:ro"
# - "./kube-config.yaml:/app/kube-config.yaml:ro" # this is required for k8s deployment
- "/var/run/docker.sock:/var/run/docker.sock" # this is required for docker deployment
depends_on:
- postgres-db
postgres-db:
image: postgres:alpine
restart: unless-stopped
environment:
- "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}"
volumes:
- "./gzctf/data/postgres-db:/var/lib/postgresql/data"
ports:
- 5432:5432
redis-cache:
image: redis:4
restart: unless-stopped
volumes:
- ./gzctf/data/redis:/data
2. 接入caddy
caddy提供自动签ssl证书的功能,非常好用
caddy:
build:
context: ./caddy/build
args:
CADDY_BASE_VERSION: ${CADDY_BASE_VERSION}
volumes:
- ./caddy/config/Caddyfile:/etc/caddy/Caddyfile
- ./caddy/data:/data
- ./wwwroot:/var/www
- /etc/localtime:/etc/localtime:ro
command: caddy run --config /etc/caddy/Caddyfile
environment:
- CLOUDFLARE_TOKEN=${CLOUDFLARE_TOKEN}
ports:
- 80:80
- 443:443/udp
- 443:443
- 8080:8080
restart: unless-stopped
extra_hosts:
- "host.docker.internal:host-gateway"
logging:
driver: "json-file"
options:
max-size: "20M"
caddy Dockfile
ARG CADDY_BASE_VERSION=caddy:2.7.5
FROM caddy:2.7.5-builder AS builder
ARG GO111MODULE=on
RUN xcaddy build \
--with github.com/caddy-dns/cloudflare \
--with github.com/caddy-dns/dnspod
FROM caddy:2.7.5
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
Caddyfile
{
acme_dns cloudflare {env.CLOUDFLARE_TOKEN}
}
...
ctf.guetsec.cn {
encode gzip
reverse_proxy * gzctf:8080
header -Strict-Transport-Security # 让浏览器不强制使用https,因为题目容器和平台在一个域名上
}
...
3. 开启对外服务
动态容器端口映射按照官方文档设置
4. 后台显示真实ip
对于官网 appsettings.json 中 ForwardedOptions 的解释
All | 15 | 进程 X-Forwarded-For、X-Forwarded-Host、X-Forwarded-Proto 和 X-forwarded-Prefix。 |
---|---|---|
None | 0 | 不处理任何转发器 |
XForwardedFor | 1 | 进程 X-Forwarded-For,用于标识客户端的源 IP 地址。 |
XForwardedHost | 2 | 处理 X-Forwarded-Host,它标识客户端请求的原始主机。 |
XForwardedPrefix | 8 | 处理 X-Forwarded-Prefix,用于标识客户端使用的原始路径基。 |
XForwardedProto | 4 | 处理 X-Forwarded-Proto,它标识用于连接的客户端) HTTP 或 HTTPS (协议。 |
caddy 反代默认携带 XForwardedFor XForwardedHost XForwardedProto
TrustedNetworks 很重要,TrustedNetworks是指仅相信来源ip发送过来的 ForwardedHeaders,在本案例中,我们需要让gzctf信任caddy,故需要指定caddy的ip
以下docker compose配置指定了容器所在的网段
networks:
default:
ipam:
driver: default
config:
- subnet: "172.xx.0.0/24"
对应appsettings.json中
"ForwardedOptions": {
"ForwardedHeaders": 7,
"ForwardLimit": 1,
"TrustedNetworks": ["172.xx.0.0/24"]
}
5. 邮箱注册验证
使用飞书国际版企业邮箱,注册飞书国际版参照:https://51.ruyo.net/17996.html
然后开通一个公共邮箱,获取imap密码
修改 gzctf appsettings 的EmailConfig
"EmailConfig": {
"SendMailAddress": "info@guetsec.cn",
"UserName": "info@guetsec.cn",
"Password": "xxxxxxxxx",
"Smtp": {
"Host": "smtp.larksuite.com",
"Port": 465
}
},
6. 验证码
使用 CloudflareTurnstile (太有公益了cf)
修改appsettings
"CaptchaConfig": {
"Provider": "CloudflareTurnstile",
"SiteKey": "xxxxxxxxxxxxxxxxxxx",
"SecretKey": "xxxxxxxxxxxxxxxxxxxxx",