mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
Use Manager.HTTPHandler for automatic TLS support in the server.
As with commit fcc274ac68
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
This commit is contained in:
parent
c62111c507
commit
d0686b1c8d
2 changed files with 24 additions and 30 deletions
|
@ -7,10 +7,10 @@ and the proxy connects to the server (this program) using WebSocket.
|
||||||
|
|
||||||
# Setup
|
# 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.
|
in order to generate its TLS certificates.
|
||||||
On Linux, use the `setcap` program to enable
|
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
|
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.
|
`pt_state/snowflake-certificate-cache` inside the tor state directory.
|
||||||
|
|
||||||
In order to fetch certificates automatically,
|
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.
|
This is a requirement of the ACME protocol used by Let's Encrypt.
|
||||||
If your `ServerTransportListenAddr` is not on port 443,
|
The program will exit if it can't bind to port 80.
|
||||||
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.
|
|
||||||
On Linux, you can use the `setcap` program,
|
On Linux, you can use the `setcap` program,
|
||||||
part of libcap2, to enable the server to bind to low-numbered ports
|
part of libcap2, to enable the server to bind to low-numbered ports
|
||||||
without having to run as root:
|
without having to run as root:
|
||||||
|
|
|
@ -41,8 +41,8 @@ func usage() {
|
||||||
WebSocket server pluggable transport for Snowflake. Works only as a managed
|
WebSocket server pluggable transport for Snowflake. Works only as a managed
|
||||||
proxy. Uses TLS with ACME (Let's Encrypt) by default. Set the certificate
|
proxy. Uses TLS with ACME (Let's Encrypt) by default. Set the certificate
|
||||||
hostnames with the --acme-hostnames option. Use ServerTransportListenAddr in
|
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
|
torrc to choose the listening port. When using TLS, this program will open an
|
||||||
program will open an additional listening port on 443 to work with ACME.
|
additional HTTP listener on port 80 to work with ACME.
|
||||||
|
|
||||||
`, os.Args[0])
|
`, os.Args[0])
|
||||||
flag.PrintDefaults()
|
flag.PrintDefaults()
|
||||||
|
@ -297,19 +297,11 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The ACME responder only works when it is running on port 443. In case
|
// The ACME HTTP-01 responder only works when it is running on port 80.
|
||||||
// there is not already going to be a TLS listener on port 443, we need
|
// We actually open the port in the loop below, so that any errors can
|
||||||
// to open an additional one. The port is actually opened in the loop
|
// be reported in the SMETHOD-ERROR of some bindaddr.
|
||||||
// below, so that any errors can be reported in the SMETHOD-ERROR of
|
// https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md#http-challenge
|
||||||
// another bindaddr.
|
needHTTP01Listener := !disableTLS
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
listeners := make([]net.Listener, 0)
|
listeners := make([]net.Listener, 0)
|
||||||
for _, bindaddr := range ptInfo.Bindaddrs {
|
for _, bindaddr := range ptInfo.Bindaddrs {
|
||||||
|
@ -318,18 +310,21 @@ func main() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if need443Listener {
|
if needHTTP01Listener {
|
||||||
addr := *bindaddr.Addr
|
addr := *bindaddr.Addr
|
||||||
addr.Port = 443
|
addr.Port = 80
|
||||||
log.Printf("opening additional ACME listener on %s", addr.String())
|
log.Printf("Starting HTTP-01 ACME listener")
|
||||||
ln443, err := startListenerTLS("tcp", &addr, certManager)
|
lnHTTP01, err := net.ListenTCP("tcp", &addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error opening ACME listener: %s", err)
|
log.Printf("error opening HTTP-01 ACME listener: %s", err)
|
||||||
pt.SmethodError(bindaddr.MethodName, "ACME listener: "+err.Error())
|
pt.SmethodError(bindaddr.MethodName, "HTTP-01 ACME listener: "+err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
listeners = append(listeners, ln443)
|
go func() {
|
||||||
need443Listener = false
|
log.Fatal(http.Serve(lnHTTP01, certManager.HTTPHandler(nil)))
|
||||||
|
}()
|
||||||
|
listeners = append(listeners, lnHTTP01)
|
||||||
|
needHTTP01Listener = false
|
||||||
}
|
}
|
||||||
|
|
||||||
var ln net.Listener
|
var ln net.Listener
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue