{"id":28704876,"url":"https://github.com/anacrolix/btlink","last_synced_at":"2025-06-14T14:08:50.271Z","repository":{"id":71650976,"uuid":"398427773","full_name":"anacrolix/btlink","owner":"anacrolix","description":"a HTTP(s) addressing scheme for BitTorrent","archived":false,"fork":false,"pushed_at":"2024-01-03T04:22:40.000Z","size":358,"stargazers_count":30,"open_issues_count":2,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-06-21T19:54:11.490Z","etag":null,"topics":["bittorrent","certificate-authority","dns","dnslink","gateway","overlay-network","proxy"],"latest_commit_sha":null,"homepage":"https://btlink.io/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anacrolix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"anacrolix","patreon":"anacrolix","issuehunt":"anacrolix"}},"created_at":"2021-08-21T00:08:06.000Z","updated_at":"2024-05-22T00:26:15.000Z","dependencies_parsed_at":"2024-01-03T05:31:25.319Z","dependency_job_id":"61d02337-cf73-4d10-9b6d-a54da0a9d6c5","html_url":"https://github.com/anacrolix/btlink","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/anacrolix/btlink","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anacrolix%2Fbtlink","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anacrolix%2Fbtlink/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anacrolix%2Fbtlink/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anacrolix%2Fbtlink/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anacrolix","download_url":"https://codeload.github.com/anacrolix/btlink/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anacrolix%2Fbtlink/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259827667,"owners_count":22917714,"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":["bittorrent","certificate-authority","dns","dnslink","gateway","overlay-network","proxy"],"created_at":"2025-06-14T14:08:48.635Z","updated_at":"2025-06-14T14:08:50.263Z","avatar_url":"https://github.com/anacrolix.png","language":"Go","funding_links":["https://github.com/sponsors/anacrolix","https://patreon.com/anacrolix","https://issuehunt.io/r/anacrolix"],"categories":[],"sub_categories":[],"readme":"# btlink\n\nbtlink is a peer-to-peer web hosting implementation. It uses constructs provided by BitTorrent and the BitTorrent DHT to handle DNS and serve websites. It supports domain certificates, subdomains, origin isolation and CORS. btlink can be progressively integrated, starting from no user integration at all, to having users run their own private gateway on their device for maximum control, with a range of options between. The current implementation makes use of the ubiquitous HTTP(S) proxy and proxy auto-config support to extend the web experience at the system level to include native btlink handling. \n\nbtlink defines a HTTP(s) addressing scheme for BitTorrent. This means no special cases for each application: All applications on a configured device will work transparently with btlink without any changes in code, and without knowing that some domains are served from a peer-to-peer network.\n\n## Naming\n\nbtlink is the working name, due to the combination of BitTorrent, HTTP URL \"links\" and the plan to implement something similar to [DNSLink](https://dnslink.io/). Alternative names might invoke something to do with swarms and webs, due to the overlap in terminology there in the use of BitTorrent and HTTP. Shelob, or the Flood for example. Less BitTorrent-specific names like distweb are an option if other backing data platforms are supported (like IPFS, or blockchains).\n\n## Architecture\n\nDotted lines represent flows that aren't implemented yet. In some cases that may mean there are multiple paths for the same question, the dotted one is intended in the future.\n\n```mermaid\nflowchart TD\n    regularWeb[Send request to regular web]\n    gatewayDomain[Is gateway domain?]\n    subgraph user [User HTTP Client]\n        start[User initiates HTTP request]\n        checkPAC[User has proxy auto-configuration?]\n        btlinkTLD\n        dnslinkHost        \n        proxyDomain[Host matches a proxy domain?]\n        proxy[Send request to proxy]\n    end\n    start --\u003e checkPAC\n    checkPAC --\u003e |No| proxyDomain\n    checkPAC --\u003e |Yes| btlinkTLD\n    btlinkTLD ==\u003e |No| proxyDomain\n    btlinkTLD[Host ends with .btlink?] -.-\u003e |No| dnslinkHost[Domain has btlink DNSLink entry?]\n    dnslinkHost --\u003e |No| proxyDomain\n    dnslinkHost --\u003e |Yes| proxy\n    btlinkTLD --\u003e |Yes| proxy\n    proxyDomain --\u003e |No| gatewayDomain\n    proxyDomain --\u003e |Yes| proxy \n    gatewayDomain --\u003e |No| regularWeb\n    gatewayDomain --\u003e |Yes| gateway\n    proxy --\u003e proxyReceive\n    subgraph proxySubgraph [proxy]\n        proxyReceive[Proxy receives request]\n        proxySpecialPaths[Request path contains special proxy path?]\n        proxyBtlinkDomain[Request host ends in .btlink?]\n        proxyDnslinkHost[Host domain has DNSLink entry?]\n        serveProxySpecialPath[Serve special proxy path]\n    end\n    proxyReceive --\u003e proxySpecialPaths\n    proxySpecialPaths --\u003e |Yes| serveProxySpecialPath\n    proxySpecialPaths --\u003e |No| proxyBtlinkDomain\n    proxyBtlinkDomain --\u003e |No| proxyDnslinkHost\n    proxyBtlinkDomain --\u003e |Yes| gateway\n    proxyDnslinkHost --\u003e |No| gatewayDomain\n    proxyDnslinkHost --\u003e |Yes| gateway\n    subgraph gatewaySubgraph [gateway]\n        gateway[Request sent to gateway]\n        serveBep44Value[Serve BEP44 value]\n        btlinkSubdomain[Resolve btlink domain schema]\n        gatewayResolveDnslink[Resolve DNSLink]\n        gatewayCheckBtlinkSubdomain[Is btlink subdomain?]\n        gatewayRootDomain[Is gateway or btlink root domain?]\n        serveGatewayRootUploader[Serve gateway root domain page]\n        checkSpecialTorrentPath[Does path require special handling?]\n        serveSpecialTorrentPath[Serve special torrent path]\n        gatewayServeTorrentFile[Serve torrent file over HTTP]\n        subgraph torrentClient [\"BitTorrent client\"]\n            fetchBep44Value[Get DHT item using BEP44]\n            dhtBep46Lookup\n            getTorrentInfo\n            openTorrentFileReader[Open torrent file reader]\n        end    \n    end\n    gateway --\u003e gatewayRootDomain --\u003e |Yes| serveGatewayRootUploader  \n    gatewayRootDomain --\u003e |No| gatewayCheckBtlinkSubdomain\n    gatewayCheckBtlinkSubdomain --\u003e |No| gatewayResolveDnslink --\u003e btlinkSubdomain\n    gatewayCheckBtlinkSubdomain --\u003e |Yes| btlinkSubdomain\n    btlinkSubdomain --\u003e |pk| dhtBep46Lookup(Resolve salt and public key to infohash using BEP46) --\u003e getTorrentInfo(Get info for infohash)\n    btlinkSubdomain --\u003e |ih| getTorrentInfo --\u003e checkSpecialTorrentPath --\u003e serveSpecialTorrentPath\n    checkSpecialTorrentPath --\u003e openTorrentFileReader --\u003e gatewayServeTorrentFile\n    btlinkSubdomain -.-\u003e |44| fetchBep44Value -.-\u003e serveBep44Value\n```\n\n### Domain schema\n\n#### Top-level domain\n\nThe top-level domain to trigger proxy intervention, and for general identification of btlink domain addressing (referred to as `tld`) was `.bt`. However that may be incompatible with the [ccTLD of Bhutan](https://en.wikipedia.org/wiki/.bt) (See issue [#2](https://github.com/anacrolix/btlink/issues/2)). The current `tld` in use is `btlink`.\n\nWhere possible, separate domains are used to reference different torrents to provide [origin isolation].\n\n[origin isolation]: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy\n\n#### {infohash}-ih.{tld}/{[torrent path schema](#torrent-path-schema)}}\n\nFiles within a torrent are exposed via the URL path being the path components of the files join with `/`. Suitable headers may be included as determined. How is the info name field handled? Perhaps it is ignored, except for single-file torrents?\n    \n#### ({salt..}[.-])?{base36(public key)}-pk.{tld}/{[torrent path schema](#torrent-path-schema)}}\n\nServes torrent corresponding to lookup of mutable DHT item. Salt is optional per [BEP 46]. This means that owners of a public key can also manage cookies for their salted subdomains (and potentially other resources that support a subdomain relationship like this). The salt may or may not be part of the same label as the public key for wildcard certificate reasons.\n\n#### {target}-44.{tld}\nFetches an immutable item from the DHT. `44` is a reference to [BEP 44]. The returned item is an encoded bencode value. Various path and query values might support conversion into other formats. Currently unimplemented.\n\n[BEP 44]: http://bittorrent.org/beps/bep_0044.html\n[BEP 46]: http://bittorrent.org/beps/bep_0046.html\n\n### Path schema\n\n#### Torrent path schema\n\nFiles within a torrent are exposed with a path equal to the components of the `path` list in the `info` `files` field joined with `/`. There may be additional special paths exposed within at `/.btlink/` and `/.well-known/` as found appropriate. Currently the info `name` is ignored, however for compatibility with webseeding, it may be exposed in a special directory for that purpose (possibly in `/.btlink/`).\n\n#### Proxy btlink schema\n\nProxies can serve a dynamic PAC file from `/.btlink/proxy.pac`, and their CA certificate from `/.btlink/rootca.pem`.\n\n## Link Records\n\nDomains may link/alias into the `.{tld}` address scheme by use of a `_btlink` DNS record on the linked domain. For example `chromecast.link` might be hosted on btlink, by way of a `_btlink.chromecast.link` TXT record. The `_btlink` record contains a [magnet link] (or just the btlink domain) where the content will be found.\n\nIf a link record exists, it is possible to CNAME or ALIAS the parent domain to a btlink gateway to allow use by non-proxy-using clients.\n\n### Magnet links\n\nPer [BEP 46], `magnet:?xs=urn:btpk:[ Public Key (Hex) ]\u0026s=[ Salt (Hex) ]`, corresponding to the `.pk.{tld}` domain space.\n\nRegular BitTorrent magnet links correspond to the `.ih.{tld}` domain space.\n\n## Infrastructure\n\nHere proxies and gateways are described separately, but it's likely that in initial implementations they will be combined. There could be good reasons to separate them for more advanced use.\n\n```mermaid\nflowchart TD\n    user --\u003e proxy\n    user --\u003e gateway\n    subgraph btlink proxy\n        proxy\n        gateway\n    end\n    proxy --\u003e gateway\n    subgraph confluence\n        gateway --\u003e client\n        client --\u003e bittorrent\n    end\n```\n\n### Proxies\n\nProxies are used to transparently provide a mapping from URLs to BitTorrent without modifying HTTP client software. Support for configuring HTTP proxies is well-supported and common due to ubiquitous use on corporate and government systems, as well as by anti-censorship and privacy advocates.\n\nProxies route `.{tld}` and domains with `_btlink` records to a gateway. They may also expose [special paths](#proxy-btlink-schema) for configuration.\n\nProxies can set a header to tell origin servers that their clients support btlink. This means that dynamic sites can provide generic btlink URLs without explicitly selecting a public gateway as a fallback.\n\n[PAC]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file\n\n### Gateways\n\nGateways are HTTP servers that serve according to the [Addressing schema](#addressing-schema). They will also intercept requests to domains with `_btlink` records and serve those via BitTorrent if possible. Gateways can run behind reverse proxies and CDNs as they serve immutable, long-lived content.\n\n## Browsers\n\n### Chrome\n\nChrome must be restarted on Windows after installing root CA certificate.\nYou can manually re-apply proxy settings via \u003cchrome://net-internals/#proxy\u003e.\n\n### Firefox\n\nFirefox will reject certificates with wildcard domains with less than 2 fixed labels (https://bugzilla.mozilla.org/show_bug.cgi?id=1728009). It seems to require ownership information (subject O and OU fields?) on issuer and leaf certificate. It also appears to need restarting to load certificates from the system keychain. It will establish http2 connections to proxies if possible, which doesn't work.\n\n### Safari\n\nSafari will hang on proxy CONNECT attempts if they respond with `Transfer-Encoding: chunked` (https://feedbackassistant.apple.com/feedback/9578066, possibly not publicly viewable). Safari does not seem to support HTTPS proxies.\n\n### curl\n\nDoes not appear to use the system keychain on MacOS. Passing `--proxy-cacert` and `--cacert` will let you specify a btlink CA file.\n\n## TODO\n\n * Implement a secure channel to proxies for Safari.\n * See if Firefox supports name constraints on intermediate CAs.\n * Separate gateways and proxies.\n\n## Open questions\n\n * Can we have a common root certificate shared by all gateways/proxies?\n * Does Safari support SOCKS? Via PAC?\n * Should the domain schema be collapsed so that a single wildcard certificate is sufficient?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanacrolix%2Fbtlink","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanacrolix%2Fbtlink","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanacrolix%2Fbtlink/lists"}