Preface
In today’s internet landscape, it’s common for third-party Emby services to be placed behind Cloudflare’s CDN. While this strategy effectively defends against DDoS attacks and mitigates potential source IP leaks, it creates a significant performance issue for users in mainland China.
For the vast majority of these users, Cloudflare’s CDN effectively functions as a bottleneck rather than an accelerator. This is because their traffic is rarely routed to nearby nodes in Hong Kong or Japan; instead, it is almost always directed to nodes located in the United States. For a service category like streaming media, this latency is nothing short of crippling.
Caddy Example
Below, I will use a Caddyfile configuration to set up a reverse proxy for the Zox Emby domain.
embyrp.shaynewong.xyz {
encode zstd gzip
reverse_proxy https://entry.zox.show {
header_up Host entry.zox.show
header_up X-Forwarded-Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
transport http {
tls_server_name entry.zox.show
}
}
}
Naturally, you will need to replace the domain in the Caddyfile configuration with your own and ensure that domain’s DNS records point to your server. This is a simple but mandatory prerequisite, so it won’t be detailed further here. Aside from the domain name, no other content needs to be altered.
Additionally, if you are not using the Zox Emby service, you must update the reverse proxy domain and its corresponding response headers. Other response headers generally do not require modification, unless the official provider of that specific Emby service instructs otherwise.
Detialed Explanation
This is a Caddy reverse proxy configuration. Here is a detailed explanation of each component:
Domain Declaration
embyrp.shaynewong.xyz {
This directive specifies that the configuration block applies to all requests directed to embyrp.shaynewong.xyz.
Response Compression
encode zstd gzip
This directive enables compression of response content. Caddy will prioritize the zstd algorithm (a modern, high-efficiency compression method) and fall back to gzip if the client does not support zstd.
Reverse Proxy Core
reverse_proxy https://entry.zox.show {
This directive forwards all incoming requests to the upstream server entry.zox.show via HTTPS.
Request Header Configuration
header_up Host entry.zox.show— Modifies the Host header to the upstream server address, informing the backend server of the request origin.header_up X-Forwarded-Host {host}— Preserves the original request domain name (embyrp.shaynewong.xyz) by passing it to the upstream server.header_up X-Real-IP {remote_host}— Passes the client’s actual IP address to the upstream server.header_up X-Forwarded-For {remote_host}— Records the client’s IP address using the standard proxy header convention.header_up X-Forwarded-Proto {scheme}— Indicates the protocol scheme (http or https) of the original client request.
Transport Layer Configuration
transport http {
tls_server_name entry.zox.show
}
This specifies that communication with the upstream server uses HTTP, while setting the TLS Server Name Indication (SNI) to entry.zox.show. This is essential when the upstream server uses self-signed certificates or certificates for multiple domains.
Overall Function
This configuration transparently proxies user requests to embyrp.shaynewong.xyz to the upstream server entry.zox.show, while preserving the original request metadata for use by the backend application.
Nginx Demo
# /etc/nginx/conf.d/embyrp.shaynewong.xyz.conf
server {
listen 443 ssl;
server_name embyrp.shaynewong.xyz;
# TLS certs (replace with your actual paths)
ssl_certificate /etc/ssl/nginx/embyrp.shaynewong.xyz.crt;
ssl_certificate_key /etc/ssl/nginx/embyrp.shaynewong.xyz.key;
# --- Compression (Caddy's `encode zstd gzip`) ---
# Nginx has gzip built in; zstd needs extra modules, so we do gzip here.
gzip on;
gzip_types text/plain text/css application/json application/javascript application/xml text/xml;
gzip_vary on;
location / {
# This is the Caddy `reverse_proxy https://entry.zox.show`
proxy_pass https://entry.zox.show;
# Match Caddy's header_up lines:
proxy_set_header Host entry.zox.show; # header_up Host entry.zox.show
proxy_set_header X-Forwarded-Host $host; # header_up X-Forwarded-Host {host}
proxy_set_header X-Real-IP $remote_addr; # header_up X-Real-IP {remote_host}
proxy_set_header X-Forwarded-For $remote_addr; # header_up X-Forwarded-For {remote_host}
proxy_set_header X-Forwarded-Proto $scheme; # header_up X-Forwarded-Proto {scheme}
# --- TLS to upstream (Caddy's `transport http { tls_server_name ... }`) ---
proxy_ssl_server_name on;
proxy_ssl_name entry.zox.show;
# Sensible proxy timeouts (optional but good for media-ish backends)
proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
# If you also need HTTP -> HTTPS redirect:
server {
listen 80;
server_name embyrp.shaynewong.xyz;
return 301 https://$host$request_uri;
}
Detailed Explanation
This is an Nginx configuration that functionally replicates the previously discussed Caddy configuration. Here is a comprehensive explanation:
HTTPS Server Block
server {
listen 443 ssl;
server_name embyrp.shaynewong.xyz;
Declares an Nginx server block that listens on port 443 (HTTPS) and responds to requests for embyrp.shaynewong.xyz.
TLS Certificate Configuration
ssl_certificate /etc/ssl/nginx/embyrp.shaynewong.xyz.crt;
ssl_certificate_key /etc/ssl/nginx/embyrp.shaynewong.xyz.key;
Specifies the paths to the SSL certificate and private key files required for TLS encryption.
Response Compression
gzip on;
gzip_types text/plain text/css application/json application/javascript application/xml text/xml;
gzip_vary on;
Enables gzip compression for responses. The gzip_types directive specifies which MIME types should be compressed. The gzip_vary on directive ensures the Vary: Accept-Encoding header is included in responses, enabling proper caching behavior. Note: Nginx does not natively support zstd compression; only gzip is employed here.
Reverse Proxy Location Block
location / {
proxy_pass https://entry.zox.show;
Routes all requests to the upstream server entry.zox.show via HTTPS.
Request Header Mapping
proxy_set_header Host entry.zox.show;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
These directives map request headers to pass client metadata to the upstream server:
Hostis set to the upstream domainX-Forwarded-Hostretains the original request domain (embyrp.shaynewong.xyz)X-Real-IPandX-Forwarded-Forpreserve the client’s IP addressX-Forwarded-Protoindicates the client request protocol (http or https)
Upstream TLS Configuration
proxy_ssl_server_name on;
proxy_ssl_name entry.zox.show;
These directives enable SNI (Server Name Indication) for connections to the upstream server. proxy_ssl_server_name on activates SNI, and proxy_ssl_name specifies the hostname to be sent during the TLS handshake. This is necessary when the upstream server uses self-signed or multi-domain certificates.
Proxy Timeouts
proxy_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
These directives configure connection and communication timeouts:
proxy_connect_timeout: Maximum time to establish a connection to the upstream serverproxy_send_timeout: Maximum time to send a request to the upstream serverproxy_read_timeout: Maximum time to receive a response from the upstream server
HTTP to HTTPS Redirect
server {
listen 80;
server_name embyrp.shaynewong.xyz;
return 301 https://$host$request_uri;
}
This secondary server block listens on port 80 (HTTP) and redirects all requests to their HTTPS equivalents using a permanent 301 redirect. This ensures clients are automatically upgraded to secure connections.
Overall Function
This Nginx configuration provides equivalent functionality to the Caddy configuration, proxying requests from embyrp.shaynewong.xyz to entry.zox.show while preserving client metadata and enabling HTTPS encryption for both client-to-proxy and proxy-to-upstream communications.