mirror of
https://github.com/tailscale/tailscale.git
synced 2025-12-23 10:12:07 +01:00
working example using TLS termination
Signed-off-by: Harry Harpham <harry@tailscale.com>
This commit is contained in:
parent
180e100a82
commit
39b84281e0
@ -2,8 +2,11 @@
|
|||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
// The tsnet-services example demonstrates how to use tsnet with Services.
|
// The tsnet-services example demonstrates how to use tsnet with Services.
|
||||||
// TODO: explain that a Service must be defined for the tailent and link to KB
|
// TODO:
|
||||||
// on defining a Service
|
// - explain that a Service must be defined for the tailent and link to KB on
|
||||||
|
// defining a Service
|
||||||
|
// - recommend using an auth key with associated tags
|
||||||
|
// - recommend an auto-approval rule for service tags
|
||||||
//
|
//
|
||||||
// To use it, generate an auth key from the Tailscale admin panel and
|
// To use it, generate an auth key from the Tailscale admin panel and
|
||||||
// run the demo with the key:
|
// run the demo with the key:
|
||||||
@ -15,7 +18,6 @@ import (
|
|||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
@ -24,7 +26,6 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
svcName = flag.String("service", "", "the name of your Service, e.g. svc:demo-service")
|
svcName = flag.String("service", "", "the name of your Service, e.g. svc:demo-service")
|
||||||
port = flag.Uint("port", 0, "the port to listen on")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: this worked several times, then my host got stuck in 'Partially configured: has-config, config-valid'
|
// TODO: this worked several times, then my host got stuck in 'Partially configured: has-config, config-valid'
|
||||||
@ -34,12 +35,8 @@ func main() {
|
|||||||
if *svcName == "" {
|
if *svcName == "" {
|
||||||
log.Fatal("a Service name must be provided")
|
log.Fatal("a Service name must be provided")
|
||||||
}
|
}
|
||||||
if *port == 0 {
|
|
||||||
log.Fatal("the listening port must be provided")
|
const port uint16 = 443
|
||||||
}
|
|
||||||
if *port > math.MaxUint16 {
|
|
||||||
log.Fatal("invalid port number")
|
|
||||||
}
|
|
||||||
|
|
||||||
s := &tsnet.Server{
|
s := &tsnet.Server{
|
||||||
Dir: "./services-demo-config",
|
Dir: "./services-demo-config",
|
||||||
@ -47,16 +44,14 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
|
|
||||||
ln, err := s.ListenService(*svcName, uint16(*port))
|
ln, err := s.ListenService(*svcName, port, tsnet.ServiceOptionTerminateTLS())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
defer ln.Close()
|
defer ln.Close()
|
||||||
|
|
||||||
fmt.Printf("Listening on http://%v\n", tailcfg.AsServiceName(*svcName).WithoutPrefix())
|
fmt.Printf("Listening on https://%v\n", tailcfg.AsServiceName(*svcName).WithoutPrefix())
|
||||||
|
|
||||||
// TODO: maybe just respond to TCP connections? (since we don't know the port)
|
|
||||||
// Actually, let's hard-code port 80 and provide an example Service definition to use
|
|
||||||
err = http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
err = http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintln(w, "<html><body><h1>Hello, tailnet!</h1>")
|
fmt.Fprintln(w, "<html><body><h1>Hello, tailnet!</h1>")
|
||||||
}))
|
}))
|
||||||
|
|||||||
@ -1320,6 +1320,7 @@ func (s *Server) ListenService(name string, port uint16, opts ...ServiceOption)
|
|||||||
return nil, fmt.Errorf("fetching node preferences: %w", err)
|
return nil, fmt.Errorf("fetching node preferences: %w", err)
|
||||||
}
|
}
|
||||||
if !slices.Contains(prefs.AdvertiseServices, name) {
|
if !slices.Contains(prefs.AdvertiseServices, name) {
|
||||||
|
// TODO: do we need to undo this edit on error?
|
||||||
_, err = lc.EditPrefs(ctx, &ipn.MaskedPrefs{
|
_, err = lc.EditPrefs(ctx, &ipn.MaskedPrefs{
|
||||||
AdvertiseServicesSet: true,
|
AdvertiseServicesSet: true,
|
||||||
Prefs: ipn.Prefs{
|
Prefs: ipn.Prefs{
|
||||||
@ -1345,7 +1346,9 @@ func (s *Server) ListenService(name string, port uint16, opts ...ServiceOption)
|
|||||||
return nil, fmt.Errorf("starting local listener: %w", err)
|
return nil, fmt.Errorf("starting local listener: %w", err)
|
||||||
}
|
}
|
||||||
// Forward all connections from service-hostname:port to our socket.
|
// Forward all connections from service-hostname:port to our socket.
|
||||||
srvConfig.SetTCPForwarding(port, ln.Addr().String(), terminateTLS, proxyProtocol, name)
|
srvConfig.SetTCPForwardingForService( // TODO: tangent, but can we reduce the number of args here?
|
||||||
|
port, ln.Addr().String(), tailcfg.ServiceName(name),
|
||||||
|
terminateTLS, proxyProtocol, st.CurrentTailnet.MagicDNSSuffix)
|
||||||
|
|
||||||
if err := lc.SetServeConfig(ctx, srvConfig); err != nil {
|
if err := lc.SetServeConfig(ctx, srvConfig); err != nil {
|
||||||
ln.Close()
|
ln.Close()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user