Skip to content

Instantly share code, notes, and snippets.

@pinkeen
Last active September 10, 2020 18:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pinkeen/50f0bee3428115adb69bd15edfe866b6 to your computer and use it in GitHub Desktop.
Save pinkeen/50f0bee3428115adb69bd15edfe866b6 to your computer and use it in GitHub Desktop.
streamsnproxies caddy
###
# Vhost that terminates HTTPS and also proxies raw TLS connection
# for certain endpoints.
###
https://a-site.example.com {
# Get a certificate and decrypt the traffic as usual.
tls auto
handle /naked {
# Proxy the decrypted traffic to an HTTP backend effectively terminating the HTTPS
reverse_proxy http://unsecure-upstream.a-site.example.com
}
handle {
# Proxy the encrypted traffic verbatim to a backend that will handle HTTPS
reverse_proxy / https://secure-upstream.a-site.example.com {
transport stream
}
}
}
###
# HTTPS-only vhost proxying TLS traffic as-is without decryption.
#
# Note: Host is matched using SNI during initial TLS handshake.
###
https://b-site.example.com {
# Disables decryption - no certificate is needed or used.
tls stream
reverse_proxy upstream.b-site.example.com {
# Forward the raw connection data stream.
transport stream
}
}
###
# Dual http/https vhost that:
# - Proxies encrypted TLS connections for HTTPS requests.
# - Proxies modified unencrypted HTTP requests for /app endpoint.
###
c-site.example.com {
tls stream
@encryptedstream protocol https
reverse_proxy @encryptedstream {
to https://upstream.c-site.example.com
transport stream
}
###
# The further directives will be matched only for HTTP requests
# as HTTPS traffic stays encrypted.
###
# We can match unencrypted HTTP requests.
handle /hello {
respond "Hello World!"
}
handle /app/* {
###
# Since HTTP is unencrypted we can use it with HTTP transport reverse proxy
# and modify the request/response like it's normally possible.
###
uri strip_prefix /app
reverse_proxy https://app-service.example.com {
header_up X-Caddy-Via "{system.hostname}"
header_up X-Caddy-Timestamp "{time.now}"
}
}
###
# If nothing before matched - proxy the *unencrypted HTTP* connection data stream as-is.
#
# Note: This is almost the same as a "transparent" proxy but purer since the whole
# communication is unadulterated. This should also give better performance.
###
handle {
reverse_proxy http://upstream.c-site.example.com {
transport stream
}
}
}
###
# Vhost that tunnels other protocols over HTTP.
# - Proxies SSH verbatim over connection upgraded to custom protocol directly to an SSH port.
# - Proxies MySQL over websocket connection to a MySQL database listener socket.
###
ssh.example.com {
tls auto
route /ssh {
###
# Attempt to upgrade the connection to custom "ssh" protocol.
#
# The handshake is handled automatically:
# - If the upgrade succeeds - the request is a valid upgrade
# and accepts the "ssh" protocol or does not specify any protocols.
# 1) Immediately send a "101 Switching Protocols" response with headers:
# Connection: upgrade
# Upgrade: ssh
# 2) Clear the current request as if we had only an opaque stream.
# 3) Proceed to further handlers.
# - If the upgrade fails - either the request is not an upgrade or
# specifies a list of supported protocols which does not match "ssh":
# 1) Immediately send a "426 Upgrade Required" response.
# 2) Close the handler / middleware chain.
#
# Note: If you need to provide custom headers based on the upgrade result
# you need to set them via matchers checking the request validity.
###
upgrade ssh
###
# Proxy the raw connection data stream to the local SSH port.
#
# Note: The request headers have been already swallowed as they were read in order for the
# the upgrade response to be sent. The upstream will receive only the communication that
# takes place after the initial connection upgrade handshake.
###
reverse_proxy localhost:22 {
transport stream
}
}
route /mysql {
###
# Works the same as the previous "ssh" upgrade, with the exception
# that websocket connections have extra logic:
# If client request contains the `Sec-WebSocket-Key` header the
# successfull response will include "Sec-WebSocket-Accept" header
# with automatically calculated value.
###
upgrade {
# The verbose notation is just and example and can be abbreviated to `upgrade websocket`
protocol websocket
}
###
# Tunnel the mysql connection data into local mysql unix socket after
# unwrapping the websocket protocol.
###
reverse_proxy unix//var/run/mysql.sock {
transport stream {
###
# Since websocket connection uses a special data transmission protocol
# we need to configure a stream translator middleware which will convert
# websocket frames into raw data and back.
###
translator websocket
}
}
}
###
# Just return something for unmatched requests.
###
route * {
respond "Nothing to see here, move along!" 404
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment