commit d0686b1c8df037413f32bef891ef90638b75a080
Author: David Fifield <da...@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

_______________________________________________
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to