mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
autocert (Let's Encrypt) for broker.
Replaces --cert and --key with --acme-hostnames and --acme-email.
This commit is contained in:
parent
1966612113
commit
2d89aa0b7b
2 changed files with 56 additions and 38 deletions
|
@ -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.
|
||||
|
|
|
@ -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 (
|
||||
|
@ -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()
|
||||
|
@ -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…
Add table
Add a link
Reference in a new issue