mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
Merge branch 'standalone-broker'
This commit is contained in:
commit
36debdfdd2
8 changed files with 212 additions and 19 deletions
|
@ -22,18 +22,27 @@ The Broker expects:
|
|||
|
||||
### Running your own
|
||||
|
||||
You can run your own Broker on either localhost or appengine.
|
||||
(Other CDNs will be supported soon.)
|
||||
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.
|
||||
|
||||
To run on localhost, run `dev_appserver.py` or equivalent from this
|
||||
directory. (on arch, I use the wrapper script `dev_appserver-go`)
|
||||
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 --addr option.
|
||||
|
||||
To run on appengine, you can spin up your own instance with an arbitrary
|
||||
name, and use `appcfg.py`.
|
||||
|
||||
In both cases, 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.
|
||||
|
||||
See more detailed appengine instructions
|
||||
[here](https://cloud.google.com/appengine/docs/go/).
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
# override this with appcfg.py -A $YOUR_APP_ID
|
||||
application: snowflake-reg
|
||||
version: 1
|
||||
runtime: go
|
||||
api_version: go1
|
||||
|
||||
handlers:
|
||||
- url: /.*
|
||||
script: _go_app
|
||||
secure: always
|
|
@ -3,16 +3,21 @@ Broker acts as the HTTP signaling channel.
|
|||
It matches clients and snowflake proxies by passing corresponding
|
||||
SessionDescriptions in order to negotiate a WebRTC connection.
|
||||
*/
|
||||
package snowflake_broker
|
||||
package main
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -217,7 +222,27 @@ func robotsTxtHandler(w http.ResponseWriter, r *http.Request) {
|
|||
w.Write([]byte("User-agent: *\nDisallow:\n"))
|
||||
}
|
||||
|
||||
func init() {
|
||||
func ipHandler(w http.ResponseWriter, r *http.Request) {
|
||||
remoteAddr := r.RemoteAddr
|
||||
if net.ParseIP(remoteAddr).To4() == nil {
|
||||
remoteAddr = "[" + remoteAddr + "]"
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||||
w.Write([]byte(remoteAddr))
|
||||
}
|
||||
|
||||
func main() {
|
||||
var acmeEmail string
|
||||
var acmeHostnamesCommas string
|
||||
var addr string
|
||||
var disableTLS bool
|
||||
|
||||
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.StringVar(&addr, "addr", ":443", "address to listen on")
|
||||
flag.BoolVar(&disableTLS, "disable-tls", false, "don't use HTTPS")
|
||||
flag.Parse()
|
||||
|
||||
log.SetFlags(log.LstdFlags | log.LUTC)
|
||||
|
||||
ctx := NewBrokerContext()
|
||||
|
@ -230,4 +255,31 @@ func init() {
|
|||
http.Handle("/client", SnowflakeHandler{ctx, clientOffers})
|
||||
http.Handle("/answer", SnowflakeHandler{ctx, proxyAnswers})
|
||||
http.Handle("/debug", SnowflakeHandler{ctx, debugHandler})
|
||||
|
||||
var err error
|
||||
server := http.Server{
|
||||
Addr: addr,
|
||||
}
|
||||
|
||||
if acmeHostnamesCommas != "" {
|
||||
acmeHostnames := strings.Split(acmeHostnamesCommas, ",")
|
||||
log.Printf("ACME hostnames: %q", acmeHostnames)
|
||||
|
||||
certManager := autocert.Manager{
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist(acmeHostnames...),
|
||||
Email: acmeEmail,
|
||||
}
|
||||
|
||||
server.TLSConfig = &tls.Config{GetCertificate: certManager.GetCertificate}
|
||||
err = server.ListenAndServeTLS("", "")
|
||||
} else if disableTLS {
|
||||
err = server.ListenAndServe()
|
||||
} else {
|
||||
log.Fatal("the --acme-hostnames or --disable-tls option is required")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package snowflake_broker
|
||||
package main
|
||||
|
||||
import (
|
||||
// "golang.org/x/net/internal/timeseries"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package snowflake_broker
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Keeping track of pending available snowflake proxies.
|
||||
*/
|
||||
|
||||
package snowflake_broker
|
||||
package main
|
||||
|
||||
/*
|
||||
The Snowflake struct contains a single interaction
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue