HTTPS-enabled onion reseeds

This commit is contained in:
idk
2019-06-27 19:49:05 -04:00
parent 6a606bda4d
commit 57065323c4
6 changed files with 144 additions and 54 deletions

View File

@ -32,6 +32,12 @@ i2p-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --tlsHost=yo
i2p-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion i2p-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion
``` ```
### Without a webserver, standalone, automatic OnionV3 with TLS support
```
i2p-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --tlsHost=your-domain.tld --onion
```
If this is your first time running a reseed server (ie. you don't have any existing keys), If this is your first time running a reseed server (ie. you don't have any existing keys),
you can simply run the command and follow the prompts to create the appropriate keys, crl and certificates. you can simply run the command and follow the prompts to create the appropriate keys, crl and certificates.
Afterwards an HTTPS reseed server will start on the default port and generate 6 files in your current directory Afterwards an HTTPS reseed server will start on the default port and generate 6 files in your current directory

View File

@ -124,6 +124,10 @@ func reseedAction(c *cli.Context) {
var tlsCert, tlsKey string var tlsCert, tlsKey string
tlsHost := c.String("tlsHost") tlsHost := c.String("tlsHost")
if c.Bool("onion") {
tlsHost = "onion"
}
if tlsHost != "" { if tlsHost != "" {
tlsKey = c.String("tlsKey") tlsKey = c.String("tlsKey")
// if no key is specified, default to the host.pem in the current dir // if no key is specified, default to the host.pem in the current dir
@ -208,35 +212,70 @@ func reseedAction(c *cli.Context) {
if err != nil { if err != nil {
log.Fatalln(err.Error()) log.Fatalln(err.Error())
} else { } else {
log.Fatalln( if tlsCert != "" && tlsKey != "" {
server.ListenAndServeOnion( log.Fatalln(
nil, server.ListenAndServeOnionTLS(
&tor.ListenConf{ nil,
LocalPort: port, &tor.ListenConf{
Key: ed25519.PrivateKey(ok), LocalPort: port,
RemotePorts: []int{80}, Key: ed25519.PrivateKey(ok),
Version3: true, RemotePorts: []int{443},
NonAnonymous: c.Bool("singleOnion"), Version3: true,
DiscardKey: false, NonAnonymous: c.Bool("singleOnion"),
}, DiscardKey: false,
c.String("onionKey"), },
), tlsCert, tlsKey,
) c.String("onionKey"),
),
)
}else{
log.Fatalln(
server.ListenAndServeOnion(
nil,
&tor.ListenConf{
LocalPort: port,
Key: ed25519.PrivateKey(ok),
RemotePorts: []int{80},
Version3: true,
NonAnonymous: c.Bool("singleOnion"),
DiscardKey: false,
},
c.String("onionKey"),
),
)
}
} }
} else if os.IsNotExist(err) { } else if os.IsNotExist(err) {
log.Fatalln( if tlsCert != "" && tlsKey != "" {
server.ListenAndServeOnion( log.Fatalln(
nil, server.ListenAndServeOnionTLS(
&tor.ListenConf{ nil,
LocalPort: port, &tor.ListenConf{
RemotePorts: []int{80}, LocalPort: port,
Version3: true, RemotePorts: []int{443},
NonAnonymous: c.Bool("singleOnion"), Version3: true,
DiscardKey: false, NonAnonymous: c.Bool("singleOnion"),
}, DiscardKey: false,
c.String("onionKey"), },
), tlsCert, tlsKey,
) c.String("onionKey"),
),
)
}else{
log.Fatalln(
server.ListenAndServeOnion(
nil,
&tor.ListenConf{
LocalPort: port,
RemotePorts: []int{80},
Version3: true,
NonAnonymous: c.Bool("singleOnion"),
DiscardKey: false,
},
c.String("onionKey"),
),
)
}
} else { } else {
} }

View File

@ -1,3 +1,6 @@
2019-06-27
* automatically configuring Tor Onionv3 Server
2019-04-21 2019-04-21
* app.Version = "0.1.7" * app.Version = "0.1.7"
* enabling TLS 1.3 *only* * enabling TLS 1.3 *only*

View File

@ -9,9 +9,9 @@ import (
) )
func main() { func main() {
// TLS 1.3 is available only on an opt-in basis in Go 1.12. // TLS 1.3 is available only on an opt-in basis in Go 1.12.
// To enable it, set the GODEBUG environment variable (comma-separated key=value options) such that it includes "tls13=1". // To enable it, set the GODEBUG environment variable (comma-separated key=value options) such that it includes "tls13=1".
// To enable it from within the process, set the environment variable before any use of TLS: // To enable it from within the process, set the environment variable before any use of TLS:
os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",tls13=1") os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",tls13=1")
// use at most half the cpu cores // use at most half the cpu cores

View File

@ -15,10 +15,10 @@ import (
"github.com/cretz/bine/tor" "github.com/cretz/bine/tor"
"github.com/cretz/bine/torutil/ed25519" "github.com/cretz/bine/torutil/ed25519"
"github.com/throttled/throttled"
"github.com/throttled/throttled/store"
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/justinas/alice" "github.com/justinas/alice"
"github.com/throttled/throttled"
"github.com/throttled/throttled/store"
) )
const ( const (
@ -34,18 +34,18 @@ type Server struct {
func NewServer(prefix string, trustProxy bool) *Server { func NewServer(prefix string, trustProxy bool) *Server {
config := &tls.Config{ config := &tls.Config{
// MinVersion: tls.VersionTLS10, // MinVersion: tls.VersionTLS10,
// PreferServerCipherSuites: true, // PreferServerCipherSuites: true,
// CipherSuites: []uint16{ // CipherSuites: []uint16{
// tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, // tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
// tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, // tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
// tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, // tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
// tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, // tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
// tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, // tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
// tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, // tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
// tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, // tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
// tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, // tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
// }, // },
MinVersion: tls.VersionTLS13, MinVersion: tls.VersionTLS13,
PreferServerCipherSuites: true, PreferServerCipherSuites: true,
CipherSuites: []uint16{ CipherSuites: []uint16{
@ -122,8 +122,50 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
return srv.Serve(tlsListener) return srv.Serve(tlsListener)
} }
func (srv *Server) ListenAndServeOnionTLS(startConf *tor.StartConf, listenConf *tor.ListenConf, certFile, keyFile, onionKey string) error {
log.Println("Starting and registering OnionV3 HTTPS service, please wait a couple of minutes...")
tor, err := tor.Start(nil, startConf)
if err != nil {
return err
}
defer tor.Close()
listenCtx, listenCancel := context.WithTimeout(context.Background(), 3*time.Minute)
defer listenCancel()
if srv.TLSConfig == nil {
srv.TLSConfig = &tls.Config{}
}
if srv.TLSConfig.NextProtos == nil {
srv.TLSConfig.NextProtos = []string{"http/1.1"}
}
srv.OnionListener, err = tor.Listen(listenCtx, listenConf)
if err != nil {
return err
}
srv.Addr = srv.OnionListener.ID
// var err error
srv.TLSConfig.Certificates = make([]tls.Certificate, 1)
srv.TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return err
}
err = ioutil.WriteFile(onionKey, []byte(srv.OnionListener.Key.(ed25519.KeyPair).PrivateKey()), 0644)
if err != nil {
return err
}
log.Printf("Onionv3 server started on https://%v.onion\n", srv.OnionListener.ID)
tlsListener := tls.NewListener(srv.OnionListener, srv.TLSConfig)
return srv.Serve(tlsListener)
}
func (srv *Server) ListenAndServeOnion(startConf *tor.StartConf, listenConf *tor.ListenConf, onionKey string) error { func (srv *Server) ListenAndServeOnion(startConf *tor.StartConf, listenConf *tor.ListenConf, onionKey string) error {
log.Println("Starting and registering onion service, please wait a couple of minutes...") log.Println("Starting and registering OnionV3 service, please wait a couple of minutes...")
tor, err := tor.Start(nil, startConf) tor, err := tor.Start(nil, startConf)
if err != nil { if err != nil {
return err return err

View File

@ -14,15 +14,15 @@ type headerTable struct {
func TestGetIP(t *testing.T) { func TestGetIP(t *testing.T) {
headers := []headerTable{ headers := []headerTable{
{xForwardedFor, "8.8.8.8", "8.8.8.8"}, // Single address {xForwardedFor, "8.8.8.8", "8.8.8.8"}, // Single address
{xForwardedFor, "8.8.8.8, 8.8.4.4", "8.8.8.8"}, // Multiple {xForwardedFor, "8.8.8.8, 8.8.4.4", "8.8.8.8"}, // Multiple
{xForwardedFor, "[2001:db8:cafe::17]:4711", "[2001:db8:cafe::17]:4711"}, // IPv6 address {xForwardedFor, "[2001:db8:cafe::17]:4711", "[2001:db8:cafe::17]:4711"}, // IPv6 address
{xForwardedFor, "", ""}, // None {xForwardedFor, "", ""}, // None
{xRealIP, "8.8.8.8", "8.8.8.8"}, // Single address {xRealIP, "8.8.8.8", "8.8.8.8"}, // Single address
{xRealIP, "8.8.8.8, 8.8.4.4", "8.8.8.8, 8.8.4.4"}, // Multiple {xRealIP, "8.8.8.8, 8.8.4.4", "8.8.8.8, 8.8.4.4"}, // Multiple
{xRealIP, "[2001:db8:cafe::17]:4711", "[2001:db8:cafe::17]:4711"}, // IPv6 address {xRealIP, "[2001:db8:cafe::17]:4711", "[2001:db8:cafe::17]:4711"}, // IPv6 address
{xRealIP, "", ""}, // None {xRealIP, "", ""}, // None
{forwarded, `for="_gazonk"`, "_gazonk"}, // Hostname {forwarded, `for="_gazonk"`, "_gazonk"}, // Hostname
{forwarded, `For="[2001:db8:cafe::17]:4711`, `[2001:db8:cafe::17]:4711`}, // IPv6 address {forwarded, `For="[2001:db8:cafe::17]:4711`, `[2001:db8:cafe::17]:4711`}, // IPv6 address
{forwarded, `for=192.0.2.60;proto=http;by=203.0.113.43`, `192.0.2.60`}, // Multiple params {forwarded, `for=192.0.2.60;proto=http;by=203.0.113.43`, `192.0.2.60`}, // Multiple params
{forwarded, `for=192.0.2.43, for=198.51.100.17`, "192.0.2.43"}, // Multiple params {forwarded, `for=192.0.2.43, for=198.51.100.17`, "192.0.2.43"}, // Multiple params