Created
May 29, 2025 00:29
-
-
Save jedda/62643893faffd9143f9587a12ca1db38 to your computer and use it in GitHub Desktop.
Envoy Configuration for Apple Network Relay (CONNECT & CONNECT-UDP) - HTTP/2 & HTTP/3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This Envoy config is intended for user with Apple Network Relay clients: | |
# https://support.apple.com/en-au/guide/deployment/dep91a6e427d/web | |
# and can be used to support both HTTP/3 and HTTP/2 with both Extended CONNECT and MASQUE (CONNECT-UDP). | |
# | |
# It features: | |
# - HTTP/2 listener (with client certificate validation) | |
# - HTTP/3 listener | |
# - Dynamic forward proxy cluster | |
# | |
# In its current form, it can be used for testing and experimenting with relay and MASQUE technologies, but it is | |
# not optimised for performance or hardened for security - please be careful as this config will allow very open arbitrary | |
# proxying of TCP and UDP! Also be careful with buffers - this config is designed for small scale testing. | |
# | |
# At the time of publishing, the latest version of Envoy (and the version used for testing and validation) was 1.34.1 | |
# | |
# A detailed write-up about Network Relay on Apple platforms is here: | |
# https://jedda.me/beneath-the-masque-network-relay-on-apple-platforms | |
static_resources: | |
listeners: | |
# HTTP/2 Listener Configuration (TCP/443) | |
- name: listener_h2 | |
address: | |
socket_address: | |
address: 0.0.0.0 | |
port_value: 443 | |
per_connection_buffer_limit_bytes: 8388608 # 8 MiB | |
listener_filters: | |
- name: "envoy.filters.listener.tls_inspector" | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector | |
filter_chains: | |
- transport_socket: | |
name: envoy.transport_sockets.tcp_stats | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tcp_stats.v3.Config | |
transport_socket: | |
name: envoy.transport_sockets.tls | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext | |
require_client_certificate: true | |
common_tls_context: | |
alpn_protocols: ["h2"] | |
tls_params: | |
tls_minimum_protocol_version: TLSv1_3 # TLS 1.3 is required | |
tls_certificates: | |
- certificate_chain: | |
filename: "/etc/envoy/ssl/cert.pem" | |
private_key: | |
filename: "/etc/envoy/ssl/key.pem" | |
validation_context: | |
trusted_ca: | |
filename: "/etc/envoy/ssl/devices_ca.pem" | |
filters: | |
- name: envoy.filters.network.http_connection_manager | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager | |
stat_prefix: h2_manager | |
codec_type: AUTO | |
common_http_protocol_options: | |
idle_timeout: 3600s # 1 hour | |
headers_with_underscores_action: REJECT_REQUEST | |
http2_protocol_options: | |
allow_connect: true | |
initial_stream_window_size: 2097152 # 2 MiB | |
initial_connection_window_size: 8388608 # 8 MiB | |
max_concurrent_streams: 1000 | |
use_remote_address: true | |
normalize_path: true | |
merge_slashes: true | |
path_with_escaped_slashes_action: UNESCAPE_AND_REDIRECT | |
access_log: | |
- name: envoy.access_loggers.file | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog | |
path: "/var/log/envoy/access_h2.log" | |
log_format: | |
text_format_source: | |
inline_string: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" response_code=%RESPONSE_CODE% duration=%DURATION% bytes_received=%BYTES_RECEIVED% bytes_sent=%BYTES_SENT% authority=%REQ(:AUTHORITY)% client_cert_uri_san=%DOWNSTREAM_PEER_URI_SAN% client_cert_dns_san=%DOWNSTREAM_PEER_DNS_SAN% client_cert_subject=%DOWNSTREAM_PEER_SUBJECT% client_cert_issuer=%DOWNSTREAM_PEER_ISSUER%\n" | |
stream_idle_timeout: 900s | |
request_timeout: 0s | |
route_config: | |
name: connect_route | |
virtual_hosts: | |
- name: allow_all | |
domains: ["*"] | |
routes: | |
- match: | |
connect_matcher: {} | |
route: | |
cluster: dynamic_forward_proxy_cluster | |
timeout: 0s | |
upgrade_configs: | |
- upgrade_type: CONNECT | |
connect_config: {} | |
- upgrade_type: CONNECT-UDP | |
connect_config: {} | |
http_filters: | |
- name: envoy.filters.http.dynamic_forward_proxy | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.http.dynamic_forward_proxy.v3.FilterConfig | |
dns_cache_config: | |
name: dynamic_dns_cache | |
dns_lookup_family: V4_ONLY | |
dns_refresh_rate: 60s | |
dns_min_refresh_rate: 60s | |
dns_failure_refresh_rate: | |
base_interval: 5s | |
max_interval: 300s | |
typed_dns_resolver_config: | |
name: envoy.network.dns_resolver.cares | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.network.dns_resolver.cares.v3.CaresDnsResolverConfig | |
resolvers: | |
- socket_address: | |
address: 172.16.80.11 | |
port_value: 53 | |
host_ttl: 300s | |
max_hosts: 4096 | |
- name: envoy.filters.http.router | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router | |
# HTTP/3 Listener Configuration (UDP/443) | |
- name: listener_h3 | |
address: | |
socket_address: | |
address: 0.0.0.0 | |
port_value: 443 | |
protocol: UDP | |
per_connection_buffer_limit_bytes: 8388608 # 8 MiB | |
udp_listener_config: | |
quic_options: | |
quic_protocol_options: | |
max_concurrent_streams: 1000 | |
initial_stream_window_size: 2097152 # 2 MiB | |
initial_connection_window_size: 8388608 # 8 MiB | |
filter_chains: | |
- transport_socket: | |
name: envoy.transport_sockets.quic | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.transport_sockets.quic.v3.QuicDownstreamTransport | |
downstream_tls_context: | |
common_tls_context: | |
alpn_protocols: ["h3"] | |
tls_certificates: | |
- certificate_chain: | |
filename: "/etc/envoy/ssl/cert.pem" | |
private_key: | |
filename: "/etc/envoy/ssl/key.pem" | |
filters: | |
- name: envoy.filters.network.http_connection_manager | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager | |
stat_prefix: h3_manager | |
codec_type: HTTP3 | |
use_remote_address: true | |
normalize_path: true | |
merge_slashes: true | |
path_with_escaped_slashes_action: UNESCAPE_AND_REDIRECT | |
common_http_protocol_options: | |
idle_timeout: 3600s | |
headers_with_underscores_action: REJECT_REQUEST | |
http3_protocol_options: | |
allow_extended_connect: true | |
stream_idle_timeout: 900s | |
request_timeout: 0s | |
access_log: | |
- name: envoy.access_loggers.file | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog | |
path: "/var/log/envoy/access_h3.log" | |
log_format: | |
text_format_source: | |
inline_string: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" response_code=%RESPONSE_CODE% duration=%DURATION% bytes_received=%BYTES_RECEIVED% bytes_sent=%BYTES_SENT% authority=%REQ(:AUTHORITY)%\n" | |
route_config: | |
name: quic_route | |
virtual_hosts: | |
- name: allow_all_quic | |
domains: ["*"] | |
routes: | |
- match: | |
connect_matcher: {} | |
route: | |
cluster: dynamic_forward_proxy_cluster | |
upgrade_configs: | |
- upgrade_type: CONNECT | |
connect_config: {} | |
- upgrade_type: CONNECT-UDP | |
connect_config: {} | |
http_filters: | |
- name: envoy.filters.http.dynamic_forward_proxy | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.http.dynamic_forward_proxy.v3.FilterConfig | |
dns_cache_config: | |
name: dynamic_dns_cache | |
dns_lookup_family: V4_ONLY | |
dns_refresh_rate: 60s | |
dns_min_refresh_rate: 60s | |
dns_failure_refresh_rate: | |
base_interval: 5s | |
max_interval: 300s | |
typed_dns_resolver_config: | |
name: envoy.network.dns_resolver.cares | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.network.dns_resolver.cares.v3.CaresDnsResolverConfig | |
resolvers: | |
- socket_address: | |
address: 172.16.80.11 | |
port_value: 53 | |
host_ttl: 300s | |
max_hosts: 4096 | |
- name: envoy.filters.http.router | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router | |
clusters: | |
- name: dynamic_forward_proxy_cluster | |
per_connection_buffer_limit_bytes: 131072 # 128 KiB | |
lb_policy: CLUSTER_PROVIDED | |
cluster_type: | |
name: envoy.clusters.dynamic_forward_proxy | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig | |
dns_cache_config: | |
name: dynamic_dns_cache | |
dns_lookup_family: V4_ONLY | |
host_ttl: 300s | |
max_hosts: 4096 | |
dns_refresh_rate: 60s | |
dns_min_refresh_rate: 60s | |
dns_failure_refresh_rate: | |
base_interval: 5s | |
max_interval: 300s | |
typed_dns_resolver_config: | |
name: envoy.network.dns_resolver.cares | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.network.dns_resolver.cares.v3.CaresDnsResolverConfig | |
resolvers: | |
- socket_address: | |
address: 172.16.80.11 | |
port_value: 53 | |
overload_manager: | |
refresh_interval: 0.25s | |
resource_monitors: | |
- name: "envoy.resource_monitors.global_downstream_max_connections" | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig | |
max_active_downstream_connections: 20000 | |
- name: "envoy.resource_monitors.fixed_heap" | |
typed_config: | |
"@type": type.googleapis.com/envoy.extensions.resource_monitors.fixed_heap.v3.FixedHeapConfig | |
max_heap_size_bytes: 8589934592 # 8 GiB | |
actions: | |
- name: "envoy.overload_actions.disable_http_keepalive" | |
triggers: | |
- name: "envoy.resource_monitors.fixed_heap" | |
threshold: | |
value: 0.92 | |
- name: "envoy.overload_actions.stop_accepting_requests" | |
triggers: | |
- name: "envoy.resource_monitors.fixed_heap" | |
threshold: | |
value: 0.95 | |
loadshed_points: | |
- name: "envoy.load_shed_points.tcp_listener_accept" | |
triggers: | |
- name: "envoy.resource_monitors.fixed_heap" | |
threshold: | |
value: 0.95 | |
admin: | |
access_log_path: /var/log/envoy/admin.log | |
address: | |
socket_address: | |
address: 127.0.0.1 | |
port_value: 9901 | |
profile_path: /tmp/envoy.prof |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment