Committable VPS artifacts for the native reverse-tunnel (no live-ops, no secrets):
- gen-device-ca.sh: EC P-256 self-signed device CA (CA:TRUE pathlen:0, keyCertSign+cRLSign),
openssl ca db + empty CRL, idempotent, --kind frp-client scaffolds the control-channel CA.
- issue-device-cert.sh: P-256 leaf, EKU=clientAuth only, 825d, emits .p12 (-legacy) + .pem/.key/.fullchain,
copy_extensions=none prevents CSR-injected serverAuth/CA:TRUE; CN traversal guard.
- revoke-device.sh: openssl ca revoke -> regenerate crl.pem (revocation enforced via -crl_check).
- frp/{frps.toml.example,frpc.example.toml}: control-channel mTLS+token, disableCustomTLSFirstByte=true.
- nginx/frp-mtls.conf: :8470 TLS-term, ssl_verify_client on + device-CA + ssl_crl, WS-upgrade proxy to :7080.
- nginx/stream-sni-additions.md: the two additive SNI map lines (merge-only, coexistence-safe).
Verified: gen->issue->openssl verify->revoke->CRL chain green in a tmp dir (OpenSSL 3.0.18).
30 lines
1.4 KiB
Plaintext
30 lines
1.4 KiB
Plaintext
# frps.toml — VPS control server (Native mTLS tunnel · V1).
|
|
#
|
|
# Install target on the VPS: /etc/relay/frp/frps.toml (chmod 600, owned frp:frp).
|
|
# This is a TEMPLATE with PLACEHOLDERS ONLY — NO REAL SECRETS are committed.
|
|
#
|
|
# auth.token: replace <FRP_TOKEN> with `openssl rand -hex 32`, stored in /etc/relay/secrets.env
|
|
# (0600). The token is NOT the sole gate — control-channel mTLS below is required too,
|
|
# so a leaked token alone cannot register a subdomain (PLAN R3 / V1b, Model A).
|
|
#
|
|
# Both ports are LOOPBACK-only (nginx stream terminates/routes :443 → these; they must stay absent
|
|
# from the Aliyun security group — PLAN P-B).
|
|
|
|
bindAddr = "127.0.0.1"
|
|
bindPort = 7000 # control channel (SNI frp.terminal.yaojia.wang → here, TLS passthrough)
|
|
vhostHTTPPort = 7080 # vhost HTTP (nginx :8470 proxies verified requests here by Host)
|
|
|
|
auth.method = "token"
|
|
auth.token = "<FRP_TOKEN>"
|
|
|
|
subDomainHost = "terminal.yaojia.wang"
|
|
|
|
# --- control-channel mTLS: token is NOT the sole gate (per-host frp-client CA) ---
|
|
transport.tls.force = true
|
|
transport.tls.certFile = "/etc/relay/frp-tls/frps-ctrl.cert.pem" # frps control SERVER cert (V1)
|
|
transport.tls.keyFile = "/etc/relay/frp-tls/frps-ctrl.key.pem" # (0600)
|
|
transport.tls.trustedCaFile = "/etc/relay/frp-client-ca/frp-client-ca.cert.pem" # verifies each host's frpc cert
|
|
|
|
log.to = "/var/log/frp/frps.log"
|
|
log.level = "info"
|