一、安装nextcloud的配置:
首先创建一个新网络,用于桥接caddy和nextcloud。
docker network create proxy-netcaddy的docker-compose.yml:
services: caddy: image: caddy:latest container_name: caddy restart: always ports: - "80:80" - "443:443" - "443:443/udp" # 支持 HTTP/3 networks: - proxy-net - nextcloud-aio volumes: - ./Caddyfile:/etc/caddy/Caddyfile - caddy_data:/data - caddy_config:/config networks: proxy-net: external: true nextcloud-aio: external: true name: nextcloud-aio volumes: caddy_data: caddy_config:- Caddyfile:
#全局配置块必须在最前面
{
# 全局日志输出标准化 JSON,供 Fail2Ban 读取
log {
output file /var/log/caddy/access.log {
roll_size 50mb
roll_keep 5
roll_keep_for 30d # 建议加上这个:保留不超过30天,防止占用过多磁盘
}
format json
}
}
# 2. 定义你的代码片段 (Snippet)
(common_security) {
header {
# 强制 HTTPS
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# 防止 MIME 类型嗅探
X-Content-Type-Options "nosniff"
# 隐藏 Server 软件信息
-Server
# 【新增】防止点击劫持 (Clickjacking)
# 禁止你的网页被别人以 <iframe> 的形式嵌入到他们的网站中
X-Frame-Options "SAMEORIGIN"
# 【新增】跨站脚本防护 (XSS)
# 遇到跨站脚本攻击时强制浏览器拦截渲染
X-XSS-Protection "1; mode=block"
# 【新增】控制 Referrer 信息泄露
# 当从 HTTPS 降级访问 HTTP 时不发送来源信息,平时跨域只发送域名
Referrer-Policy "strict-origin-when-cross-origin"
}
}
your-nextcloud-aio.domain {
encode gzip
reverse_proxy nextcloud-aio-apache:11000 {
header_up X-Forwarded-For {http.request.header.X-Forwarded-For},{remote_host}
header_up Host {host}
header_up X-Real-IP {remote_host}
}
}注:Nextcloud AIO 内部其实自带了一部分安全 Header,但在总网关层再覆盖/加强一次是标准的纵深防御最佳实践。
二、因为nextcloud不适合通过cloudflare代理访问(文件大小,其他跨站问题等),而这个主机延迟又较高,所以给它加上一个优化机入口。
优化机的Caddyfile:
services:
caddy:
image: caddy:latest
container_name: caddy
restart: always
network_mode: host
# 直接使用宿主机网络;性能最好;安全取决于防火墙;
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
- ./certs:/etc/caddy/certs
volumes:
caddy_data:
caddy_config:💡 如果你必须使用docker网桥(v6桥接),那么需要下面的配置,并确保宿主机的内核开启了 IPv6 转发功能
sysctl -w net.ipv6.conf.all.forwarding=1
#需要固化到systctl.d设置里services:
caddy:
image: caddy:latest
container_name: caddy
restart: always
ports:
- "80:80"
- "443:443"
- "443:443/udp"
networks:
- proxy-net
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
- ./certs:/etc/caddy/certs
networks:
proxy-net:
enable_ipv6: true
ipam:
config:
- subnet: fd00:d63a:61:2::/64
# 这是底层网络引擎分配 IP 所必须的,不能省;查看/etc/docker/daemon.json获得。
volumes:
caddy_data:
caddy_config:三、同步nextcloud主机上的caddy下面的certs目录到反代机
反代机的Caddyfile
your-nextcloud.com {
tls /etc/caddy/certs/your-nextcloud.com/your-nextcloud.com.crt /etc/caddy/certs/your-nextcloud.com/your-nextcloud.com.key
# 2. 反向代理到家中的 IPv6
reverse_proxy [2a02---v6地址]:443 {
header_up Host your-nextcloud.com
transport http {
# 开启后端 TLS 验证
tls
# 关键:告诉外部 Caddy 握手时发送这个域名
# 否则外部 Caddy 可能会因为无法验证“自签/私有”证书而拒绝连接
tls_server_name your-nextcloud.com
# 如果证书链不完整导致 502,临时开启下面这行测试
#tls_insecure_skip_verify
}
}
}四. 修改
// 1. 确保信任列表覆盖了你的所有本地容器网段和外部 IPv6
'trusted_proxies' =>
array (
0 => '127.0.0.1',
1 => '::1',
2 => '172.18.0.0/16', // 请确认这是你 AIO 所在的 docker 网络段
3 => '172.19.0.0/16', // 如果本地 Caddy 在另一个 docker 网络,也加上
4 => '240e:xxxx:xxxx:xxxx::/64', // 【必须】外部 Caddy 的公网 IP(v4和v6都填上)
),
// 2. 告诉 Nextcloud 必须去读取哪个头部来获取真实 IP
'forwarded_for_headers' =>
array (
0 => 'HTTP_X_FORWARDED_FOR',
),
// 3. 覆盖协议和主机名(确保前端显示正常,避免死循环)
'overwritehost' => 'your-nxcloud-domain.com',
'overwriteprotocol' => 'https',
'overwritecondaddr' => '^.*$', // 允许任何 IP 触发覆盖规则
'forwarded_for_headers' =>
array (
0 => 'HTTP_X_FORWARDED_FOR',
),
'overwritehost' => 'de.imzen.de',
'overwriteprotocol' => 'https',
'overwritecondaddr' => '^.*$',完成。
💡 顺便也解决了仅v4的线路访问ipv6服务的问题。(反代机是双栈)
可以检查下nextcloud的安全设置里,是否显示了你的真实IP,而不是127.0.0.1或127.0.18.1这样的docker内网地址。上面的设置已经正确的设置了header。caddy日志和nextcloud应该显示真实的IP来源。