Bine
Bine is a Go API for using and controlling Tor. It is similar to Stem.
Features:
- Full support for the Tor controller API
- Support for
net.Conn
andnet.Listen
style APIs - Supports statically compiled Tor to embed Tor into the binary
- Supports both V2 and V3 onion services
It is really easy to create an onion service. For example, assuming tor
is on the PATH
, this bit of code will show a directory server of the current directory:
package main
import (
"context"
"fmt"
"log"
"net/http"
"time"
"github.com/cretz/bine/tor"
)
func main() {
// Start tor with default config (can set start conf's DebugWriter to os.Stdout for debug logs)
fmt.Println("Starting and registering onion service, please wait a couple of minutes...")
t, err := tor.Start(nil, nil)
if err != nil {
log.Panicf("Unable to start Tor: %v", err)
}
defer t.Close()
// Wait at most a few minutes to publish the service
listenCtx, listenCancel := context.WithTimeout(context.Background(), 3*time.Minute)
defer listenCancel()
// Create an onion service to listen on any port but show as 80
onion, err := t.Listen(listenCtx, &tor.ListenConf{RemotePorts: []int{80}})
if err != nil {
log.Panicf("Unable to create onion service: %v", err)
}
defer onion.Close()
fmt.Printf("Open Tor browser and navigate to http://%v.onion\n", onion.ID)
fmt.Println("Press enter to exit")
// Serve the current folder from HTTP
errCh := make(chan error, 1)
go func() { errCh <- http.Serve(onion, http.FileServer(http.Dir("."))) }()
// End when enter is pressed
go func() {
fmt.Scanln()
errCh <- nil
}()
if err = <-errCh; err != nil {
log.Panicf("Failed serving: %v", err)
}
}
If in main.go
it can simply be run with go run main.go
. Of course this uses a separate tor
process. To embed Tor statically in the binary, follow the embedded package docs which will require building Tor statically. Then with github.com/cretz/bine/process/embedded
imported, change the start line above to:
t, err := tor.Start(nil, &tor.StartConf{ProcessCreator: embedded.NewCreator()})
Tested on Windows, the original exe file is ~7MB. With Tor statically linked it comes to ~24MB, but Tor does not have to be distributed separately. Of course take notice of all licenses in accompanying projects.
Also take a look at the API docs and the examples. The project is MIT licensed. The Tor docs/specs and https://github.com/yawning/bulb were great helps when building this.