Loading broker/README.md +23 −3 Original line number Diff line number Diff line Loading @@ -22,9 +22,29 @@ The Broker expects: ### Running your own You can run your own Broker on localhost, you'll need to pass a TLS certificate file using `--cert` option and the corresponding private key file using `--key` option. The server uses TLS by default. There is a `--disable-tls` option for testing purposes, but you should use TLS in production. The server automatically fetches certificates from [Let's Encrypt](https://en.wikipedia.org/wiki/Let's_Encrypt) as needed. Use the `--acme-hostnames` option to tell the server what hostnames it may request certificates for. You can optionally provide a contact email address, using the `--acme-email` option, so that Let's Encrypt can inform you of any problems. In order to fetch certificates automatically, the server needs to be listening on port 443 (the default). On Linux, you can use the `setcap` program, part of libcap2, to enable the broker to bind to low-numbered ports without having to run as root: ``` setcap 'cap_net_bind_service=+ep' /usr/local/bin/broker ``` You can control the listening port with the --tlsPort or --webPort options (--webPort is honored only when also using --disable-tls). You'll need to provide the URL of the custom broker to the client plugin using the `--url $URL` flag. broker/broker.go +33 −35 Original line number Diff line number Diff line Loading @@ -7,15 +7,17 @@ package main import ( "container/heap" "crypto/tls" "flag" "fmt" "io/ioutil" "log" "net" "net/http" "os" "sync" "strings" "time" "golang.org/x/crypto/acme/autocert" ) const ( Loading Loading @@ -230,26 +232,18 @@ func ipHandler(w http.ResponseWriter, r *http.Request) { } func main() { var cert, cert_key, http_port, https_port string flag.StringVar(&cert, "cert", "", "TLS certificate file") flag.StringVar(&cert_key, "key", "", "TLS key file") var acmeEmail string var acmeHostnamesCommas string var disableTLS bool var http_port, https_port string flag.StringVar(&acmeEmail, "acme-email", "", "optional contact email for Let's Encrypt notifications") flag.StringVar(&acmeHostnamesCommas, "acme-hostnames", "", "comma-separated hostnames for TLS certificate") flag.BoolVar(&disableTLS, "disable-tls", false, "don't use HTTPS") flag.StringVar(&http_port, "webPort", "80", "HTTP port number") flag.StringVar(&https_port, "tlsPort", "443", "HTTPS port number") flag.Parse() if cert == "" || cert_key == "" { log.Println("Missing options, exiting.") fmt.Println("Usage:") flag.PrintDefaults() os.Exit(1) } log.Println("Using cert file:", cert) log.Println("Using cert key file: ", cert_key) ctx := NewBrokerContext() go ctx.Broker() Loading @@ -262,26 +256,30 @@ func main() { http.Handle("/answer", SnowflakeHandler{ctx, proxyAnswers}) http.Handle("/debug", SnowflakeHandler{ctx, debugHandler}) var wg sync.WaitGroup wg.Add(2) var err error var server http.Server //Run HTTP server go func() { defer wg.Done() err := http.ListenAndServe(":"+http_port, nil) if err != nil { log.Println("ListenAndServe: ", err) if acmeHostnamesCommas != "" { acmeHostnames := strings.Split(acmeHostnamesCommas, ",") log.Printf("ACME hostnames: %q", acmeHostnames) certManager := autocert.Manager{ Prompt: autocert.AcceptTOS, HostPolicy: autocert.HostWhitelist(acmeHostnames...), Email: acmeEmail, } }() //Run HTTPS server go func() { defer wg.Done() err := http.ListenAndServeTLS(":"+https_port, cert, cert_key, nil) if err != nil { log.Println("ListenAndServeTLS: ", err) server.Addr = net.JoinHostPort("", https_port) server.TLSConfig = &tls.Config{GetCertificate: certManager.GetCertificate} err = server.ListenAndServeTLS("", "") } else if disableTLS { server.Addr = net.JoinHostPort("", http_port) err = server.ListenAndServe() } else { log.Fatal("the --acme-hostnames or --disable-tls option is required") } }() wg.Wait() if err != nil { log.Fatal(err) } } Loading
broker/README.md +23 −3 Original line number Diff line number Diff line Loading @@ -22,9 +22,29 @@ The Broker expects: ### Running your own You can run your own Broker on localhost, you'll need to pass a TLS certificate file using `--cert` option and the corresponding private key file using `--key` option. The server uses TLS by default. There is a `--disable-tls` option for testing purposes, but you should use TLS in production. The server automatically fetches certificates from [Let's Encrypt](https://en.wikipedia.org/wiki/Let's_Encrypt) as needed. Use the `--acme-hostnames` option to tell the server what hostnames it may request certificates for. You can optionally provide a contact email address, using the `--acme-email` option, so that Let's Encrypt can inform you of any problems. In order to fetch certificates automatically, the server needs to be listening on port 443 (the default). On Linux, you can use the `setcap` program, part of libcap2, to enable the broker to bind to low-numbered ports without having to run as root: ``` setcap 'cap_net_bind_service=+ep' /usr/local/bin/broker ``` You can control the listening port with the --tlsPort or --webPort options (--webPort is honored only when also using --disable-tls). You'll need to provide the URL of the custom broker to the client plugin using the `--url $URL` flag.
broker/broker.go +33 −35 Original line number Diff line number Diff line Loading @@ -7,15 +7,17 @@ package main import ( "container/heap" "crypto/tls" "flag" "fmt" "io/ioutil" "log" "net" "net/http" "os" "sync" "strings" "time" "golang.org/x/crypto/acme/autocert" ) const ( Loading Loading @@ -230,26 +232,18 @@ func ipHandler(w http.ResponseWriter, r *http.Request) { } func main() { var cert, cert_key, http_port, https_port string flag.StringVar(&cert, "cert", "", "TLS certificate file") flag.StringVar(&cert_key, "key", "", "TLS key file") var acmeEmail string var acmeHostnamesCommas string var disableTLS bool var http_port, https_port string flag.StringVar(&acmeEmail, "acme-email", "", "optional contact email for Let's Encrypt notifications") flag.StringVar(&acmeHostnamesCommas, "acme-hostnames", "", "comma-separated hostnames for TLS certificate") flag.BoolVar(&disableTLS, "disable-tls", false, "don't use HTTPS") flag.StringVar(&http_port, "webPort", "80", "HTTP port number") flag.StringVar(&https_port, "tlsPort", "443", "HTTPS port number") flag.Parse() if cert == "" || cert_key == "" { log.Println("Missing options, exiting.") fmt.Println("Usage:") flag.PrintDefaults() os.Exit(1) } log.Println("Using cert file:", cert) log.Println("Using cert key file: ", cert_key) ctx := NewBrokerContext() go ctx.Broker() Loading @@ -262,26 +256,30 @@ func main() { http.Handle("/answer", SnowflakeHandler{ctx, proxyAnswers}) http.Handle("/debug", SnowflakeHandler{ctx, debugHandler}) var wg sync.WaitGroup wg.Add(2) var err error var server http.Server //Run HTTP server go func() { defer wg.Done() err := http.ListenAndServe(":"+http_port, nil) if err != nil { log.Println("ListenAndServe: ", err) if acmeHostnamesCommas != "" { acmeHostnames := strings.Split(acmeHostnamesCommas, ",") log.Printf("ACME hostnames: %q", acmeHostnames) certManager := autocert.Manager{ Prompt: autocert.AcceptTOS, HostPolicy: autocert.HostWhitelist(acmeHostnames...), Email: acmeEmail, } }() //Run HTTPS server go func() { defer wg.Done() err := http.ListenAndServeTLS(":"+https_port, cert, cert_key, nil) if err != nil { log.Println("ListenAndServeTLS: ", err) server.Addr = net.JoinHostPort("", https_port) server.TLSConfig = &tls.Config{GetCertificate: certManager.GetCertificate} err = server.ListenAndServeTLS("", "") } else if disableTLS { server.Addr = net.JoinHostPort("", http_port) err = server.ListenAndServe() } else { log.Fatal("the --acme-hostnames or --disable-tls option is required") } }() wg.Wait() if err != nil { log.Fatal(err) } }