2018-09-18 20:01:34 +00:00
|
|
|
# <img src="logo/bine-logo.png" width="180px">
|
2018-05-10 14:56:20 +00:00
|
|
|
|
2018-05-17 20:07:34 +00:00
|
|
|
[![GoDoc](https://godoc.org/github.com/cretz/bine?status.svg)](https://godoc.org/github.com/cretz/bine)
|
2018-05-10 14:56:20 +00:00
|
|
|
|
2018-05-17 20:07:34 +00:00
|
|
|
Bine is a Go API for using and controlling Tor. It is similar to [Stem](https://stem.torproject.org/).
|
|
|
|
|
|
|
|
Features:
|
|
|
|
|
|
|
|
* Full support for the Tor controller API
|
|
|
|
* Support for `net.Conn` and `net.Listen` style APIs
|
|
|
|
* Supports statically compiled Tor to embed Tor into the binary
|
2019-01-22 18:44:56 +00:00
|
|
|
* Supports both v2 and v3 onion services
|
2018-09-21 18:06:47 +00:00
|
|
|
* Support for embedded control socket in Tor >= 0.3.5 (non-Windows)
|
2018-05-17 20:07:34 +00:00
|
|
|
|
2018-05-19 14:46:12 +00:00
|
|
|
See info below, the [API docs](http://godoc.org/github.com/cretz/bine), and the [examples](examples). The project is
|
|
|
|
MIT licensed. The Tor docs/specs and https://github.com/yawning/bulb were great helps when building this.
|
|
|
|
|
|
|
|
## Example
|
|
|
|
|
2018-05-17 20:07:34 +00:00
|
|
|
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:
|
|
|
|
|
|
|
|
```go
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
|
2020-10-15 21:38:02 +00:00
|
|
|
"git.openprivacy.ca/openprivacy/bine/tor"
|
2018-05-17 20:07:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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()
|
2019-01-22 18:44:56 +00:00
|
|
|
// Create a v3 onion service to listen on any port but show as 80
|
|
|
|
onion, err := t.Listen(listenCtx, &tor.ListenConf{Version3: true, RemotePorts: []int{80}})
|
2018-05-17 20:07:34 +00:00
|
|
|
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
|
2020-10-15 21:38:02 +00:00
|
|
|
statically in the binary, follow the [embedded package docs](https://godoc.org/git.openprivacy.ca/openprivacy/bine/process/embedded)
|
2018-05-17 20:07:34 +00:00
|
|
|
which will require [building Tor statically](https://github.com/cretz/tor-static). Then with
|
2020-10-15 21:38:02 +00:00
|
|
|
`git.openprivacy.ca/openprivacy/bine/process/embedded` imported, change the start line above to:
|
2018-05-17 20:07:34 +00:00
|
|
|
|
|
|
|
```go
|
|
|
|
t, err := tor.Start(nil, &tor.StartConf{ProcessCreator: embedded.NewCreator()})
|
|
|
|
```
|
|
|
|
|
2019-01-22 18:44:56 +00:00
|
|
|
This defaults to Tor 0.3.5.x versions but others can be used from different packages. In non-Windows environments, the
|
|
|
|
`UseEmbeddedControlConn` field in `StartConf` can be set to `true` to use an embedded socket that does not open a
|
|
|
|
control port.
|
|
|
|
|
2018-05-17 20:07:34 +00:00
|
|
|
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.
|
|
|
|
|
2018-05-19 14:46:12 +00:00
|
|
|
## Testing
|
|
|
|
|
|
|
|
To test, a simple `go test ./...` from the base of the repository will work (add in a `-v` in there to see the tests).
|
|
|
|
The integration tests in `tests` however will be skipped. To execute those tests, `-tor` must be passed to the test.
|
|
|
|
Also, `tor` must be on the `PATH` or `-tor.path` must be set to the path of the `tor` executable. Even with those flags,
|
|
|
|
only the integration tests that do not connect to the Tor network are run. To also include the tests that use the Tor
|
|
|
|
network, add the `-tor.network` flag. For details Tor logs during any of the integration tests, use the `-tor.verbose`
|
2018-09-18 20:01:34 +00:00
|
|
|
flag.
|