[tor-commits] [snowflake/master] Use Manager.HTTPHandler for automatic TLS support in the server.
dcf at torproject.org
dcf at torproject.org
Tue Mar 6 05:17:43 UTC 2018
commit d0686b1c8df037413f32bef891ef90638b75a080
Author: David Fifield <david at bamsoftware.com>
Date: Mon Mar 5 15:25:48 2018 -0800
Use Manager.HTTPHandler for automatic TLS support in the server.
As with commit fcc274ac68dcb9063ca631fac9e8905e90088660 for the broker,
we need to start using the HTTP-01 challenge type in the Snowflake
websocket server transport plugin.
https://bugs.torproject.org/25346
---
server/README.md | 13 ++++++-------
server/server.go | 41 ++++++++++++++++++-----------------------
2 files changed, 24 insertions(+), 30 deletions(-)
diff --git a/server/README.md b/server/README.md
index d0fd91d..312a506 100644
--- a/server/README.md
+++ b/server/README.md
@@ -7,10 +7,10 @@ and the proxy connects to the server (this program) using WebSocket.
# Setup
-The server needs to be able to listen on port 443
+The server needs to be able to listen on port 80
in order to generate its TLS certificates.
On Linux, use the `setcap` program to enable
-the server to listen on port 443 without running as root:
+the server to listen on port 80 without running as root:
```
setcap 'cap_net_bind_service=+ep' /usr/local/bin/snowflake-server
```
@@ -48,12 +48,11 @@ The server will cache TLS certificate data in the directory
`pt_state/snowflake-certificate-cache` inside the tor state directory.
In order to fetch certificates automatically,
-the server needs to listen on port 443.
+the server needs to listen on port 80,
+in addition to whatever ports it is listening on
+for WebSocket connections.
This is a requirement of the ACME protocol used by Let's Encrypt.
-If your `ServerTransportListenAddr` is not on port 443,
-the server will open an listener on port 443 in addition
-to the port you requested.
-The program will exit if it can't bind to port 443.
+The program will exit if it can't bind to port 80.
On Linux, you can use the `setcap` program,
part of libcap2, to enable the server to bind to low-numbered ports
without having to run as root:
diff --git a/server/server.go b/server/server.go
index a0ddb3e..5ec3ff9 100644
--- a/server/server.go
+++ b/server/server.go
@@ -41,8 +41,8 @@ func usage() {
WebSocket server pluggable transport for Snowflake. Works only as a managed
proxy. Uses TLS with ACME (Let's Encrypt) by default. Set the certificate
hostnames with the --acme-hostnames option. Use ServerTransportListenAddr in
-torrc to choose the listening port. When using TLS, if the port is not 443, this
-program will open an additional listening port on 443 to work with ACME.
+torrc to choose the listening port. When using TLS, this program will open an
+additional HTTP listener on port 80 to work with ACME.
`, os.Args[0])
flag.PrintDefaults()
@@ -297,19 +297,11 @@ func main() {
}
}
- // The ACME responder only works when it is running on port 443. In case
- // there is not already going to be a TLS listener on port 443, we need
- // to open an additional one. The port is actually opened in the loop
- // below, so that any errors can be reported in the SMETHOD-ERROR of
- // another bindaddr.
- // https://letsencrypt.github.io/acme-spec/#domain-validation-with-server-name-indication-dvsni
- need443Listener := !disableTLS
- for _, bindaddr := range ptInfo.Bindaddrs {
- if !disableTLS && bindaddr.Addr.Port == 443 {
- need443Listener = false
- break
- }
- }
+ // The ACME HTTP-01 responder only works when it is running on port 80.
+ // We actually open the port in the loop below, so that any errors can
+ // be reported in the SMETHOD-ERROR of some bindaddr.
+ // https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#http-challenge
+ needHTTP01Listener := !disableTLS
listeners := make([]net.Listener, 0)
for _, bindaddr := range ptInfo.Bindaddrs {
@@ -318,18 +310,21 @@ func main() {
continue
}
- if need443Listener {
+ if needHTTP01Listener {
addr := *bindaddr.Addr
- addr.Port = 443
- log.Printf("opening additional ACME listener on %s", addr.String())
- ln443, err := startListenerTLS("tcp", &addr, certManager)
+ addr.Port = 80
+ log.Printf("Starting HTTP-01 ACME listener")
+ lnHTTP01, err := net.ListenTCP("tcp", &addr)
if err != nil {
- log.Printf("error opening ACME listener: %s", err)
- pt.SmethodError(bindaddr.MethodName, "ACME listener: "+err.Error())
+ log.Printf("error opening HTTP-01 ACME listener: %s", err)
+ pt.SmethodError(bindaddr.MethodName, "HTTP-01 ACME listener: "+err.Error())
continue
}
- listeners = append(listeners, ln443)
- need443Listener = false
+ go func() {
+ log.Fatal(http.Serve(lnHTTP01, certManager.HTTPHandler(nil)))
+ }()
+ listeners = append(listeners, lnHTTP01)
+ needHTTP01Listener = false
}
var ln net.Listener
More information about the tor-commits
mailing list