Add DC9 HAProxy TLS front door
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
# Stage on 8444 first. Change to 443 only after the Arcane Agent Caddy is
|
||||||
|
# reachable through its temporary management port and host TCP 443 is free.
|
||||||
|
HAPROXY_PUBLIC_PORT=8444
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# DC9 TLS front door
|
||||||
|
|
||||||
|
HAProxy inspects TCP SNI without terminating TLS:
|
||||||
|
|
||||||
|
- `dc9-tls-e2f48b.opfo.xyz` -> managed sing-box Trojan on host TCP 22591
|
||||||
|
- `sb-dd65a3.kais.cloud` -> managed sing-box AnyTLS on host TCP 43824
|
||||||
|
- `dc9.kais.cloud` -> the existing Arcane Agent Caddy on `arcane_default`
|
||||||
|
- unmatched SNI -> the dedicated Caddy fallback serving `dc9.opfo.xyz`
|
||||||
|
|
||||||
|
The first deployment uses host TCP 8444. Moving it to TCP 443 requires a staged
|
||||||
|
handoff from the existing Arcane Agent Caddy so the Direct HTTPS management path
|
||||||
|
remains reachable throughout the change.
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
servers {
|
||||||
|
protocols h1 h2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dc9.opfo.xyz {
|
||||||
|
encode zstd gzip
|
||||||
|
header {
|
||||||
|
X-Content-Type-Options nosniff
|
||||||
|
X-Frame-Options DENY
|
||||||
|
Referrer-Policy no-referrer
|
||||||
|
}
|
||||||
|
respond <<HTML 200
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Service Status</title></head>
|
||||||
|
<body><main><h1>Service online</h1><p>The requested service is available.</p></main></body>
|
||||||
|
</html>
|
||||||
|
HTML
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
services:
|
||||||
|
haproxy:
|
||||||
|
image: haproxy:3.4.4-alpine3.24
|
||||||
|
container_name: dc9-haproxy
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${HAPROXY_PUBLIC_PORT:-8444}:8443/tcp"
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
depends_on:
|
||||||
|
- decoy-caddy
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- arcane
|
||||||
|
volumes:
|
||||||
|
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: 200k
|
||||||
|
max-file: "2"
|
||||||
|
|
||||||
|
decoy-caddy:
|
||||||
|
image: caddy:2.11.4
|
||||||
|
container_name: dc9-decoy-caddy
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||||
|
- caddy-data:/data
|
||||||
|
- caddy-config:/config
|
||||||
|
logging:
|
||||||
|
driver: json-file
|
||||||
|
options:
|
||||||
|
max-size: 200k
|
||||||
|
max-file: "2"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
arcane:
|
||||||
|
external: true
|
||||||
|
name: arcane_default
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
caddy-data:
|
||||||
|
caddy-config:
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
global
|
||||||
|
log stdout format raw local0
|
||||||
|
maxconn 4096
|
||||||
|
|
||||||
|
defaults
|
||||||
|
log global
|
||||||
|
mode tcp
|
||||||
|
option tcplog
|
||||||
|
timeout connect 5s
|
||||||
|
timeout client 24h
|
||||||
|
timeout server 24h
|
||||||
|
|
||||||
|
frontend tls_443
|
||||||
|
bind 0.0.0.0:8443
|
||||||
|
tcp-request inspect-delay 5s
|
||||||
|
tcp-request content accept if { req.ssl_hello_type 1 }
|
||||||
|
|
||||||
|
acl sni_trojan req.ssl_sni -i dc9-tls-e2f48b.opfo.xyz
|
||||||
|
acl sni_anytls req.ssl_sni -i sb-dd65a3.kais.cloud
|
||||||
|
acl sni_arcane req.ssl_sni -i dc9.kais.cloud
|
||||||
|
|
||||||
|
use_backend singbox_trojan if sni_trojan
|
||||||
|
use_backend singbox_anytls if sni_anytls
|
||||||
|
use_backend arcane_agent if sni_arcane
|
||||||
|
default_backend decoy_https
|
||||||
|
|
||||||
|
backend singbox_trojan
|
||||||
|
server trojan host.docker.internal:22591
|
||||||
|
|
||||||
|
backend singbox_anytls
|
||||||
|
server anytls host.docker.internal:43824
|
||||||
|
|
||||||
|
backend arcane_agent
|
||||||
|
server arcane arcane-agent-caddy:443
|
||||||
|
|
||||||
|
backend decoy_https
|
||||||
|
server caddy decoy-caddy:443
|
||||||
@@ -5,16 +5,11 @@ USER1_PASSWORD=change-me
|
|||||||
CLOUDFLARE_API_TOKEN=change-me
|
CLOUDFLARE_API_TOKEN=change-me
|
||||||
|
|
||||||
ANYTLS_DOMAIN=sb-dd65a3.kais.cloud
|
ANYTLS_DOMAIN=sb-dd65a3.kais.cloud
|
||||||
ANYTLS_HY2_PORT=43824
|
ANYTLS_PORT=43824
|
||||||
ANYTLS_PASSWORD=change-me
|
ANYTLS_PASSWORD=change-me
|
||||||
HY2_PASSWORD=change-me
|
HY2_PASSWORD=change-me
|
||||||
HY2_OBFS_PASSWORD=change-me
|
HY2_OBFS_PASSWORD=change-me
|
||||||
|
HY2_PORT=443
|
||||||
VLESS_PORT=22590
|
|
||||||
VLESS_UUID=00000000-0000-4000-8000-000000000000
|
|
||||||
REALITY_SERVER_NAME=www.cloudflare.com
|
|
||||||
REALITY_PRIVATE_KEY=change-me
|
|
||||||
REALITY_SHORT_ID=0123456789abcdef
|
|
||||||
|
|
||||||
# sing-box uses version 5 for the Snell v4-compatible TCP wire protocol.
|
# sing-box uses version 5 for the Snell v4-compatible TCP wire protocol.
|
||||||
SNELL_V4_PORT=53469
|
SNELL_V4_PORT=53469
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
config-render:
|
config-render:
|
||||||
image: alpine:3.20
|
image: alpine:3.24
|
||||||
environment:
|
environment:
|
||||||
DOMAIN: ${DOMAIN}
|
DOMAIN: ${DOMAIN}
|
||||||
ACME_EMAIL: ${ACME_EMAIL}
|
ACME_EMAIL: ${ACME_EMAIL}
|
||||||
@@ -8,15 +8,11 @@ services:
|
|||||||
USER1_PASSWORD: ${USER1_PASSWORD}
|
USER1_PASSWORD: ${USER1_PASSWORD}
|
||||||
CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN}
|
CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN}
|
||||||
ANYTLS_DOMAIN: ${ANYTLS_DOMAIN}
|
ANYTLS_DOMAIN: ${ANYTLS_DOMAIN}
|
||||||
ANYTLS_HY2_PORT: ${ANYTLS_HY2_PORT}
|
ANYTLS_PORT: ${ANYTLS_PORT}
|
||||||
ANYTLS_PASSWORD: ${ANYTLS_PASSWORD}
|
ANYTLS_PASSWORD: ${ANYTLS_PASSWORD}
|
||||||
HY2_PASSWORD: ${HY2_PASSWORD}
|
HY2_PASSWORD: ${HY2_PASSWORD}
|
||||||
HY2_OBFS_PASSWORD: ${HY2_OBFS_PASSWORD}
|
HY2_OBFS_PASSWORD: ${HY2_OBFS_PASSWORD}
|
||||||
VLESS_PORT: ${VLESS_PORT}
|
HY2_PORT: ${HY2_PORT}
|
||||||
VLESS_UUID: ${VLESS_UUID}
|
|
||||||
REALITY_SERVER_NAME: ${REALITY_SERVER_NAME}
|
|
||||||
REALITY_PRIVATE_KEY: ${REALITY_PRIVATE_KEY}
|
|
||||||
REALITY_SHORT_ID: ${REALITY_SHORT_ID}
|
|
||||||
SNELL_V4_PORT: ${SNELL_V4_PORT}
|
SNELL_V4_PORT: ${SNELL_V4_PORT}
|
||||||
SNELL_V4_PSK: ${SNELL_V4_PSK}
|
SNELL_V4_PSK: ${SNELL_V4_PSK}
|
||||||
SNELL_V6_PORT: ${SNELL_V6_PORT}
|
SNELL_V6_PORT: ${SNELL_V6_PORT}
|
||||||
|
|||||||
@@ -1,4 +1,19 @@
|
|||||||
{
|
{
|
||||||
|
"certificate_providers": [
|
||||||
|
{
|
||||||
|
"type": "acme",
|
||||||
|
"tag": "public-cert",
|
||||||
|
"domain": [
|
||||||
|
"${DOMAIN}",
|
||||||
|
"${ANYTLS_DOMAIN}"
|
||||||
|
],
|
||||||
|
"email": "${ACME_EMAIL}",
|
||||||
|
"dns01_challenge": {
|
||||||
|
"provider": "cloudflare",
|
||||||
|
"api_token": "${CLOUDFLARE_API_TOKEN}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"inbounds": [
|
"inbounds": [
|
||||||
{
|
{
|
||||||
"type": "trojan",
|
"type": "trojan",
|
||||||
@@ -14,15 +29,7 @@
|
|||||||
"tls": {
|
"tls": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"server_name": "${DOMAIN}",
|
"server_name": "${DOMAIN}",
|
||||||
"acme": {
|
"certificate_provider": "public-cert"
|
||||||
"domain": "${DOMAIN}",
|
|
||||||
"data_directory": "/var/lib/sing-box/certmagic-anytls",
|
|
||||||
"email": "${ACME_EMAIL}",
|
|
||||||
"dns01_challenge": {
|
|
||||||
"provider": "cloudflare",
|
|
||||||
"api_token": "${CLOUDFLARE_API_TOKEN}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"multiplex": {
|
"multiplex": {
|
||||||
"enabled": true
|
"enabled": true
|
||||||
@@ -32,7 +39,7 @@
|
|||||||
"type": "anytls",
|
"type": "anytls",
|
||||||
"tag": "anytls-in",
|
"tag": "anytls-in",
|
||||||
"listen": "::",
|
"listen": "::",
|
||||||
"listen_port": ${ANYTLS_HY2_PORT},
|
"listen_port": ${ANYTLS_PORT},
|
||||||
"users": [
|
"users": [
|
||||||
{
|
{
|
||||||
"name": "user1",
|
"name": "user1",
|
||||||
@@ -42,22 +49,14 @@
|
|||||||
"tls": {
|
"tls": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"server_name": "${ANYTLS_DOMAIN}",
|
"server_name": "${ANYTLS_DOMAIN}",
|
||||||
"acme": {
|
"certificate_provider": "public-cert"
|
||||||
"domain": "${ANYTLS_DOMAIN}",
|
|
||||||
"data_directory": "/var/lib/sing-box/certmagic-anytls",
|
|
||||||
"email": "${ACME_EMAIL}",
|
|
||||||
"dns01_challenge": {
|
|
||||||
"provider": "cloudflare",
|
|
||||||
"api_token": "${CLOUDFLARE_API_TOKEN}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hysteria2",
|
"type": "hysteria2",
|
||||||
"tag": "hysteria2-in",
|
"tag": "hysteria2-in",
|
||||||
"listen": "0.0.0.0",
|
"listen": "0.0.0.0",
|
||||||
"listen_port": ${ANYTLS_HY2_PORT},
|
"listen_port": ${HY2_PORT},
|
||||||
"obfs": {
|
"obfs": {
|
||||||
"type": "salamander",
|
"type": "salamander",
|
||||||
"password": "${HY2_OBFS_PASSWORD}"
|
"password": "${HY2_OBFS_PASSWORD}"
|
||||||
@@ -74,44 +73,7 @@
|
|||||||
"alpn": [
|
"alpn": [
|
||||||
"h3"
|
"h3"
|
||||||
],
|
],
|
||||||
"acme": {
|
"certificate_provider": "public-cert"
|
||||||
"domain": "${ANYTLS_DOMAIN}",
|
|
||||||
"data_directory": "/var/lib/sing-box/certmagic-anytls",
|
|
||||||
"email": "${ACME_EMAIL}",
|
|
||||||
"dns01_challenge": {
|
|
||||||
"provider": "cloudflare",
|
|
||||||
"api_token": "${CLOUDFLARE_API_TOKEN}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "vless",
|
|
||||||
"tag": "vless-reality-in",
|
|
||||||
"listen": "::",
|
|
||||||
"listen_port": ${VLESS_PORT},
|
|
||||||
"users": [
|
|
||||||
{
|
|
||||||
"name": "user1",
|
|
||||||
"uuid": "${VLESS_UUID}",
|
|
||||||
"flow": "xtls-rprx-vision"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tls": {
|
|
||||||
"enabled": true,
|
|
||||||
"server_name": "${REALITY_SERVER_NAME}",
|
|
||||||
"reality": {
|
|
||||||
"enabled": true,
|
|
||||||
"handshake": {
|
|
||||||
"server": "${REALITY_SERVER_NAME}",
|
|
||||||
"server_port": 443
|
|
||||||
},
|
|
||||||
"private_key": "${REALITY_PRIVATE_KEY}",
|
|
||||||
"short_id": [
|
|
||||||
"${REALITY_SHORT_ID}"
|
|
||||||
],
|
|
||||||
"max_time_difference": "2m"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user