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
|
### Running your own
|
||||||
|
|
||||||
You can run your own Broker on localhost, you'll need to pass a TLS
|
The server uses TLS by default.
|
||||||
certificate file using `--cert` option and the corresponding private key
|
There is a `--disable-tls` option for testing purposes,
|
||||||
file using `--key` option.
|
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
|
You'll need to provide the URL of the custom broker
|
||||||
to the client plugin using the `--url $URL` flag.
|
to the client plugin using the `--url $URL` flag.
|
||||||
|
|
|
@ -7,15 +7,17 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/heap"
|
"container/heap"
|
||||||
|
"crypto/tls"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"strings"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/acme/autocert"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -230,26 +232,18 @@ func ipHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var cert, cert_key, http_port, https_port string
|
var acmeEmail string
|
||||||
|
var acmeHostnamesCommas string
|
||||||
flag.StringVar(&cert, "cert", "", "TLS certificate file")
|
var disableTLS bool
|
||||||
flag.StringVar(&cert_key, "key", "", "TLS key file")
|
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(&http_port, "webPort", "80", "HTTP port number")
|
||||||
flag.StringVar(&https_port, "tlsPort", "443", "HTTPS port number")
|
flag.StringVar(&https_port, "tlsPort", "443", "HTTPS port number")
|
||||||
|
|
||||||
flag.Parse()
|
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()
|
ctx := NewBrokerContext()
|
||||||
|
|
||||||
go ctx.Broker()
|
go ctx.Broker()
|
||||||
|
@ -262,26 +256,30 @@ func main() {
|
||||||
http.Handle("/answer", SnowflakeHandler{ctx, proxyAnswers})
|
http.Handle("/answer", SnowflakeHandler{ctx, proxyAnswers})
|
||||||
http.Handle("/debug", SnowflakeHandler{ctx, debugHandler})
|
http.Handle("/debug", SnowflakeHandler{ctx, debugHandler})
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var err error
|
||||||
wg.Add(2)
|
var server http.Server
|
||||||
|
|
||||||
//Run HTTP server
|
if acmeHostnamesCommas != "" {
|
||||||
go func() {
|
acmeHostnames := strings.Split(acmeHostnamesCommas, ",")
|
||||||
defer wg.Done()
|
log.Printf("ACME hostnames: %q", acmeHostnames)
|
||||||
err := http.ListenAndServe(":"+http_port, nil)
|
|
||||||
if err != nil {
|
certManager := autocert.Manager{
|
||||||
log.Println("ListenAndServe: ", err)
|
Prompt: autocert.AcceptTOS,
|
||||||
|
HostPolicy: autocert.HostWhitelist(acmeHostnames...),
|
||||||
|
Email: acmeEmail,
|
||||||
}
|
}
|
||||||
}()
|
|
||||||
|
|
||||||
//Run HTTPS server
|
server.Addr = net.JoinHostPort("", https_port)
|
||||||
go func() {
|
server.TLSConfig = &tls.Config{GetCertificate: certManager.GetCertificate}
|
||||||
defer wg.Done()
|
err = server.ListenAndServeTLS("", "")
|
||||||
err := http.ListenAndServeTLS(":"+https_port, cert, cert_key, nil)
|
} else if disableTLS {
|
||||||
if err != nil {
|
server.Addr = net.JoinHostPort("", http_port)
|
||||||
log.Println("ListenAndServeTLS: ", err)
|
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