Janvh's Blog

Janvh's Blog

Haproxy分流Caddy反代自建AdGuardHome的记录

10
2025-07-09

#Blog #haproxy #caddy #adg

最近买了一台阿里云的HK 200m,正好可以自建一个doh服务器,因为我的机器用了haproxy分流代理和转发,同时用caddy做反代服务器,所以想adghome使用http协议连接,ssl终止于caddy,网上并没有类似的教程,所以做一下记录

配置Haproxy

主要满足以下条件

  • 监听443端口
  • snidoh.a.com 转发给8443 端口的caddy服务器
  • sniwww.sega.com 转发给8445端口的代理服务器
  • tcp模式转发,由caddy负责终结ssl,主要是caddy 能自动获取证书

配置如下

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

    # Default SSL material locations
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

    # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate
    ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
    ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets

defaults
    log     global
    mode    tcp  # 重要:设置为 TCP 模式
    option  tcplog
    option  dontlognull
    timeout connect 5000
    timeout client  50000
    timeout server  50000

frontend http-in
    bind *:80
    mode http
    default_backend caddy_http_backend

frontend tls_frontend
    bind *:443
    mode tcp

    tcp-request inspect-delay 5s   # 等待 SNI 信息
    tcp-request content accept if { req_ssl_hello_type 1 }
    
    acl is_caddy_domains ssl_sni -i doh.a.com dns.a.com              use_backend caddy_backend if is_caddy_domains
    use_backend xray_backend if { req_ssl_sni -i www.sega.com }
    default_backend caddy_backend

backend caddy_http_backend
    mode http
    server caddy_server 127.0.0.1:880 

backend caddy_backend
    mode tcp
    server caddy_server 127.0.0.1:8443 send-proxy-v2

backend xray_backend
    mode tcp
    server singbox_server 127.0.0.1:902

配置Caddy

配置文件

{
    # 告诉 Caddy 它的标准 HTTPS 端口现在是 8443
    https_port 8443
    http_port 880
    # 定义所有服务的监听器
    servers {
        # 对监听器应用“包裹层”
        listener_wrappers {
            # 第一层:解析 PROXY Protocol
            proxy_protocol {
                # 只允许来自本地 HAProxy 的请求
                allow 127.0.0.1/8
            }
            # 第二层:处理 TLS
            tls
        }
    }
}
:880 {
        # Set this path to your site's directory.
        root * /usr/share/caddy

        # Enable the static file server.
        #file_server
        redir https://{host}:443{uri} permanent

        # Another common task is to set up a reverse proxy:
        # reverse_proxy localhost:8080

        # Or serve a PHP site through php-fpm:
        # php_fastcgi localhost:9000
}

# =================================
#  AdGuard Home 管理面板
# =================================
dns.a.com {
    reverse_proxy localhost:3000 {
        # 明确传递真实 IP、协议和主机名
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }
}

# =================================
#  AdGuard Home DoH 服务 (使用根路径)
# =================================
doh.a.com {
    # 1. 重写路径
    # 将所有到这个域名的请求路径,都重写为 AdGuard Home 需要的 /dns-query
    # Caddy 会自动保留原始的查询参数 (例如 ?dns=...)
    rewrite * /dns-query

    # 2. 反向代理
    reverse_proxy localhost:3000 {
        # 明确传递真实 IP、协议和主机名
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }
}

Adguard Home的安装和配置

Docker Compose安装AdGuard Home

compose.yml

services:
  adguardhome:
    image: adguard/adguardhome
    container_name: adguardhome
    restart: unless-stopped
    volumes:
      - ./work:/opt/adguardhome/work
      - ./conf:/opt/adguardhome/conf
    ports:
      - "1053:53/tcp"
      - "1053:53/udp"
      - "3000:3000/tcp"
      - "1853:853/tcp"
      - "1853:853/udp"

docker compose up -d 启动后停止,我们需要修改Adguardhome.yaml配置文件使其支持http协议连接doh
主要修改几处:

http:
	address: 0.0.0.0:3000
dns:
	trusted_proxies:
		- 172.18.0.0/16
	    - 127.0.0.1/32
tls:
	enabled: false
	allow_unencrypted_doh: true

重启容器即可

Dot

可以直接由haproxy sni分流,不过我没用就没有配置这个了。