{"id":13508274,"url":"https://github.com/ipsn/go-libtor","last_synced_at":"2025-03-30T11:31:46.538Z","repository":{"id":41225833,"uuid":"139160629","full_name":"ipsn/go-libtor","owner":"ipsn","description":"Self-contained Tor from Go","archived":false,"fork":false,"pushed_at":"2021-12-14T12:35:08.000Z","size":15150,"stargazers_count":548,"open_issues_count":20,"forks_count":47,"subscribers_count":17,"default_branch":"master","last_synced_at":"2024-11-17T12:51:00.144Z","etag":null,"topics":["anonymity","go","golang","library","onion-routing","privacy","tor"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ipsn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-29T14:42:57.000Z","updated_at":"2024-10-02T05:08:13.000Z","dependencies_parsed_at":"2022-08-27T20:02:59.029Z","dependency_job_id":null,"html_url":"https://github.com/ipsn/go-libtor","commit_stats":null,"previous_names":[],"tags_count":381,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipsn%2Fgo-libtor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipsn%2Fgo-libtor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipsn%2Fgo-libtor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ipsn%2Fgo-libtor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ipsn","download_url":"https://codeload.github.com/ipsn/go-libtor/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246314011,"owners_count":20757450,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anonymity","go","golang","library","onion-routing","privacy","tor"],"created_at":"2024-08-01T02:00:50.706Z","updated_at":"2025-03-30T11:31:41.529Z","avatar_url":"https://github.com/ipsn.png","language":"C","readme":"# go-libtor - Self-contained Tor from Go\n\n[![GoDoc](https://godoc.org/github.com/ipsn/go-libtor?status.svg)](https://godoc.org/github.com/ipsn/go-libtor) [![Travis](https://travis-ci.org/ipsn/go-libtor.svg?branch=master)](https://travis-ci.org/ipsn/go-libtor)\n\nThe `go-libtor` project is a self-contained, fully statically linked Tor library for Go. It consists of an elaborate suite of Go/CGO wrappers around the original C/C++ Tor library and its dependencies ([zlib](https://github.com/madler/zlib), [libevent](https://github.com/libevent/libevent) and [openssl](https://github.com/openssl/openssl)).\n\n| Library  | Version | Commit |\n|:--------:|:-------:|:------:|\n| zlib     | 1.2.11     | [`cacf7f1d4e3d44d871b605da3b647f07d718623f`](https://github.com/madler/zlib/commit/cacf7f1d4e3d44d871b605da3b647f07d718623f)               |\n| libevent | 2.2.0-alpha-dev | [`d433f847334fff9da8e13e2dc7fdf5c0997b20b0`](https://github.com/libevent/libevent/commit/d433f847334fff9da8e13e2dc7fdf5c0997b20b0) |\n| openssl  | 1.1.1-stable  | [`46dc0bca6cd623c42489c57e62c69cf568335664`](https://github.com/openssl/openssl/commit/46dc0bca6cd623c42489c57e62c69cf568335664)     |\n| tor      | 0.3.5.14-dev      | [`1693b6151e1369ce0938761cac95e7a0a524f5f3`](https://gitweb.torproject.org/tor.git/commit/?id=1693b6151e1369ce0938761cac95e7a0a524f5f3)      |\n\nThe library is currently supported on:\n\n - Linux `amd64`, `386`, `arm64` and `arm`; both with `libc` and `musl`.\n - Android `amd64`, `386`, `arm64` and `arm`; specifically via `gomobile`.\n\n## Installation (GOPATH)\n\nThe goal of this library is to be a self-contained Tor package for Go. As such, it plays nice with the usual `go get` workflow. That said, building Tor and all its dependencies locally can take quite a while, so it's recommended to run `go get` in verbose mode.\n\n```\n$ go get -u -v -x github.com/ipsn/go-libtor\n```\n\nYou'll also need the [`bine`](https://github.com/cretz/bine) bindings to interface with the library:\n\n```\ngo get -u github.com/cretz/bine/tor\n```\n\n## Installation (Go modules)\n\nThis library is compatible with Go modules. All you should need is to import `github.com/ipsn/go-libtor` and wait out the build. We suggest running `go build -v -x` the first time after adding the `go-libtor` dependency to avoid frustration, otherwise Go will build the 1000+ C files without any progress report.\n\n## Usage\n\nThe `go-libtor` project does not contain a full Go API to interface Tor with, rather only the smallest building block to start up an embedded instance. The reason is because there is already a solid Go project out there ([github.com/cretz/bine](https://github.com/cretz/bine)) which focuses on interfacing.\n\nUsing both projects in combination however is straightforward:\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/cretz/bine/tor\"\n\t\"github.com/ipsn/go-libtor\"\n)\n\nfunc main() {\n\t// Start tor with some defaults + elevated verbosity\n\tfmt.Println(\"Starting and registering onion service, please wait a bit...\")\n\tt, err := tor.Start(nil, \u0026tor.StartConf{ProcessCreator: libtor.Creator, DebugWriter: os.Stderr})\n\tif err != nil {\n\t\tlog.Panicf(\"Failed to start tor: %v\", err)\n\t}\n\tdefer t.Close()\n\n\t// Wait at most a few minutes to publish the service\n\tctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)\n\tdefer cancel()\n\n\t// Create an onion service to listen on any port but show as 80\n\tonion, err := t.Listen(ctx, \u0026tor.ListenConf{RemotePorts: []int{80}})\n\tif err != nil {\n\t\tlog.Panicf(\"Failed to create onion service: %v\", err)\n\t}\n\tdefer onion.Close()\n\n\tfmt.Printf(\"Please open a Tor capable browser and navigate to http://%v.onion\\n\", onion.ID)\n\n\t// Run a Hello-World HTTP service until terminated\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tfmt.Fprintf(w, \"Hello, Tor!\")\n\t})\n\thttp.Serve(onion, nil)\n}\n```\n\nThe above code will:\n\n * Start up a new Tor process from within your statically linked binary\n * Register a new anonymous onion TCP endpoint for remote clients\n * Start an HTTP server using the Tor network as its transport layer\n\n```\n$ go run main.go\n\nStarting and registering onion service, please wait a bit...\n[...]\nEnabling network before waiting for publication\n[...]\nWaiting for publication\n[...]\nPlease open a Tor capable browser and navigate to http://s7t3iy76h54cjacg.onion\n```\n\n![Demo](https://raw.githubusercontent.com/ipsn/go-libtor/master/demo.png)\n\nWell, that was easy. With a few lines of Go code we've created a hidden TCP service inside the Tor network. The browser used to test the server with above was [Brave](https://brave.com/), which among others has built in experimental support for Tor.\n\n## Mobile devices\n\nThe advantage of `go-libtor` starts to show when building to more exotic platforms, since it's composed of simple CGO Go files. As it doesn't require custom build steps or tooling, it plays nice with the Go ecosystem, `gomobile` included:\n\nLet's see how much effort would it be to deploy onto Android:\n\n```go\npackage demo\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/cretz/bine/tor\"\n\t\"github.com/ipsn/go-libtor\"\n)\n\n// Run starts up an embedded Tor process, starts a hidden onion service on a new\n// goroutine and returns the onion address. We're cheating here and not caring\n// about actually cleaning up after ourselves.\nfunc Run(datadir string) string {\n\t// Start tor with some defaults + elevated verbosity\n\tfmt.Println(\"Starting and registering onion service, please wait a bit...\")\n\tt, err := tor.Start(nil, \u0026tor.StartConf{ProcessCreator: libtor.Creator, DebugWriter: os.Stderr, DataDir: datadir})\n\tif err != nil {\n\t\tlog.Panicf(\"Failed to start tor: %v\", err)\n\t}\n\t// Wait at most a few minutes to publish the service\n\tctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)\n\tdefer cancel()\n\n\t// Create an onion service to listen on any port but show as 80\n\tonion, err := t.Listen(ctx, \u0026tor.ListenConf{RemotePorts: []int{80}})\n\tif err != nil {\n\t\tlog.Panicf(\"Failed to create onion service: %v\", err)\n\t}\n\tfmt.Printf(\"Please open a Tor capable browser and navigate to http://%v.onion\\n\", onion.ID)\n\n\t// Run a Hello-World HTTP service until terminated\n\thttp.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tfmt.Fprintf(w, \"Hello, Tor! This is Android!!!\")\n\t})\n\tgo http.Serve(onion, nil)\n\n\treturn fmt.Sprintf(\"http://%v.onion\", onion.ID)\n}\n```\n\nThe above code does approximately the same thing as the one before, just in its own package with a trivial API since we want to make an Android archive, not an entire `.apk`. We can invoke `gomobile` to bind it:\n\n```\n$ gomobile bind -v -x .\n[...many logs, much wow...]\n$ ls -al demo*\n-rw-r--r-- 1 karalabe 38976071 Jul 19 18:46 demo.aar\n-rw-r--r-- 1 karalabe     6162 Jul 19 18:46 demo-sources.jar\n$ unzip -l demo.aar\nArchive:  demo.aar\n  Length      Date    Time    Name\n---------  ---------- -----   ----\n      143  1980-00-00 00:00   AndroidManifest.xml\n       25  1980-00-00 00:00   proguard.txt\n    11044  1980-00-00 00:00   classes.jar\n 26102356  1980-00-00 00:00   jni/armeabi-v7a/libgojni.so\n 27085856  1980-00-00 00:00   jni/arm64-v8a/libgojni.so\n 26327236  1980-00-00 00:00   jni/x86/libgojni.so\n 27757968  1980-00-00 00:00   jni/x86_64/libgojni.so\n        0  1980-00-00 00:00   R.txt\n        0  1980-00-00 00:00   res/\n---------                     -------\n107284628                     9 files\n```\n\nExplaining how to load an `.aar` into an Android project is beyond the scope of this article, but you can load the archive with Android Studio as a module and edit your Gradle build config to add it as a dependency. An overly crude app would just start the server and drop the onion URL into an Android label:\n\n![Android](https://raw.githubusercontent.com/ipsn/go-libtor/master/demo.jpg)\n\nThat's actually it! We've managed to get a Tor hidden service running from an Android phone and access it from another device through the Tor network, all through 40 lines of Go- and 3 lines of Java code.\n\n## Credits\n\nThis repository is maintained by Péter Szilágyi ([@karalabe](https://github.com/karalabe)), but authorship of all code contained inside belongs to the individual upstream projects.\n\n## License\n\n3-Clause BSD.\n","funding_links":[],"categories":["C","\u003ca id=\"6e80463404d46f0493cf6e84597e4b5c\"\u003e\u003c/a\u003e工具","privacy"],"sub_categories":["\u003ca id=\"e99ba5f3de02f68412b13ca718a0afb6\"\u003e\u003c/a\u003eTor\u0026\u0026\u0026Onion\u0026\u0026洋葱"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipsn%2Fgo-libtor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fipsn%2Fgo-libtor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fipsn%2Fgo-libtor/lists"}