Skip to content

Instantly share code, notes, and snippets.

@devnoname120
Last active November 26, 2024 08:09
Show Gist options
  • Save devnoname120/48fbb352b061facc122c65a353c5f9ba to your computer and use it in GitHub Desktop.
Save devnoname120/48fbb352b061facc122c65a353c5f9ba to your computer and use it in GitHub Desktop.
frp — Example of TLS termination in Caddy on the client side

This Gist explains how to establish a tunnel between a server with a public IPv4 and a server that runs an HTTPS service behind a NAT so as to make the HTTPS service available through the tunnel on the public IPv4 while completely keeping the certificate challenge and the TLS termination on the server behind the NAT. This is different from e.g. Cloudflare Tunnels which forcibly terminates the TLS connection on their own server with a public IPv4.

Prerequisites

How

  • Create an A DNS record that points to the public IPv4 of the server where frps runs.
    • In my case I added an A record on testcert.your.domain pointing to 123.123.123.123
  • Copy frps.toml to the server with the public IPv4 and run frps -c frps.toml.
  • Copy frpc.toml to the server behind the tunnel and run frpc -c frpc.toml.
    • It should successfully connect to the frps server.
  • On the server behind the tunnel, run caddy run:
    • Caddy should start, obtain the LetsEncrypt challenge, validate it, and download the certificate returned by LetsEncrypt.
  • From any machine, run curl https://testcert.your.domain/caddy.html (replace the domain name with yours) and confirm that it works.

(Optional) Hardening using the DNS-01 challenge type

  • To keep the example simple (and because I trust the server on which frps runs) I use the easy TLS-ALPN-01 challenge type rather than DNS-01 which would run client-side behind the NAT and make it secure even if the frps server is pwned.
  • If you can't/don't want to entirely trust the server running frps, then you can instead use the DNS-01 challenge type and run it client-side behind the NAT. You should then blacklist the HTTP/HTTPS-based challenge methods (to only keep DNS challenges) by adding a specific TXT record in your DNS (look it up on the internet) and enable HSTS preload. Your now safe even if the frps server is pwned.
<!DOCTYPE html>
<html>
<head>
<title>Caddy tutorial</title>
</head>
<body>
Page loaded at: {{now | date "Mon Jan 2 15:04:05 MST 2006"}}
</body>
</html>
{
https_port 44312
auto_https disable_redirects
admin localhost:2020
}
testcert.your.domain {
templates
file_server
tls {
issuer acme {
# Optional: disable the HTTP-01 challenge type
disable_http_challenge
}
}
}
# Change the IPv4 to your server where frps runs.
serverAddr = "123.123.123.123"
serverPort = 7000
[auth]
method = "token"
token = "mysecrettoken"
[[proxies]]
name = "nextcloud-caddy"
type = "tcp"
localIP = "127.0.0.1"
localPort = 44312
remotePort = 443
bindPort = 7000
[auth]
method = "token"
token = "mysecrettoken"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment