Anti-censorship issueshttps://gitlab.torproject.org/groups/tpo/anti-censorship/-/issues2023-01-11T15:54:13Zhttps://gitlab.torproject.org/tpo/anti-censorship/team/-/issues/114GetTor is replying with TB win32 binary by default2023-01-11T15:54:13ZGusGetTor is replying with TB win32 binary by defaultWhen I email gettor@tpo with "windows" on the subject, the service is sharing automatically win32 binary:
```
This is an automated email response from GetTor.
You requested Tor Browser for win32.
Step 1: Download Tor Browser
...When I email gettor@tpo with "windows" on the subject, the service is sharing automatically win32 binary:
```
This is an automated email response from GetTor.
You requested Tor Browser for win32.
Step 1: Download Tor Browser
First, try downloading Tor Browser from our mirrors:
```meskiomeskio@torproject.orgmeskiomeskio@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/connectivity-measurement/bridgestatus/-/issues/2Bridgestatus Readme2023-02-21T12:24:14ZDecade6641Bridgestatus ReadmeI imagine the readme file is a generic one and I was not able to figure out how to contribute to it.I imagine the readme file is a generic one and I was not able to figure out how to contribute to it.https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40243fix(proxy): memory leak2024-03-21T20:02:09ZWofWcawofwca@protonmail.comfix(proxy): memory leakAccording to [this forum post](https://forum.torproject.net/t/snowflake-proxy-connections-limit/4113/8?u=wofwca) and the one below it, Snowflake proxy appears to start at 100MB RAM consumption and goes up to 1.5GB.
A fix would be nice, ...According to [this forum post](https://forum.torproject.net/t/snowflake-proxy-connections-limit/4113/8?u=wofwca) and the one below it, Snowflake proxy appears to start at 100MB RAM consumption and goes up to 1.5GB.
A fix would be nice, but a catch-all alternative would be to automatically restart the proxy every so often. Maybe add the instructions here https://community.torproject.org/relay/setup/snowflake/standalone/.
UPD: It's probably a duplicate of #40154.https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake-webext/-/issues/71fix: stops working after 500 connections in Chromium2023-01-22T07:24:03ZWofWcawofwca@protonmail.comfix: stops working after 500 connections in ChromiumRestarting the browser (or reloading the extension) helps.
Apparently in Chromium there's a limit of 500 on how many `RTCPeerConnection`s you can create. Closing or GCing them doesn't help.
```js
let i;
for (i = 0; i < 10000; i++) {
...Restarting the browser (or reloading the extension) helps.
Apparently in Chromium there's a limit of 500 on how many `RTCPeerConnection`s you can create. Closing or GCing them doesn't help.
```js
let i;
for (i = 0; i < 10000; i++) {
(new RTCPeerConnection()).close()
}
```
```
Uncaught DOMException: Failed to construct 'RTCPeerConnection': Cannot create so many PeerConnections
```
```
i
499
```
Guess we'll need to reuse old connections, or get this limit bumped.
Need to consider not creating a `RTCPeerConnection` before each poll, or better yet not discarding it if the poll doesn't return a client.
A hack that could work: call [`(browser|chrome).runtime.reload()`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/reload)
Related: https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake-webext/-/issues/72https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40172Host the privacy policy on snowflake.torproject.org2023-04-11T18:28:29Zmeskiomeskio@torproject.orgHost the privacy policy on snowflake.torproject.orgLet's host the privacy policy (https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake-webext/-/issues/34) on the website:
https://addons.mozilla.org/en-US/firefox/addon/torproject-snowflake/privacy/Let's host the privacy policy (https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake-webext/-/issues/34) on the website:
https://addons.mozilla.org/en-US/firefox/addon/torproject-snowflake/privacy/https://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/issues/52Translate GetTor messages2024-02-27T18:20:31ZtraumschuleTranslate GetTor messagesThis is the parent ticket to translate GetTor into more languages, especially for censored areas.This is the parent ticket to translate GetTor into more languages, especially for censored areas.Sponsor 96: Rapid Expansion of Access to the Uncensored Internet through Tor in China, Hong Kong, & Tibetmeskiomeskio@torproject.orgmeskiomeskio@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/team/-/issues/22Get more private bridges2023-08-07T11:18:19ZCecylia BocovichGet more private bridgesWe maintain a list of private bridges that we distribute to NGOs and individuals in places that block most of our other distribution methods. BridgeDB sets aside some bridges for private distribution in the "unallocated" or "reserved" po...We maintain a list of private bridges that we distribute to NGOs and individuals in places that block most of our other distribution methods. BridgeDB sets aside some bridges for private distribution in the "unallocated" or "reserved" pool.
At the end of March we are losing some private bridges that volunteers run so we need a few actions to get more private (stable if possible) bridges:
- [ ] Create and document a pipeline for distributing "unallocated" bridges as private bridges. We should document a pipeline for taking bridges the reserved this pool and getting them into the hands of users. (meskio)
- [x] Ask organizations to run obfs4 bridges (gus)
- [x] Check with the donated hw we may get (gaba)
_Update on October 12th: Documentation is the only issue missing here._Sponsor 96: Rapid Expansion of Access to the Uncensored Internet through Tor in China, Hong Kong, & Tibetmeskiomeskio@torproject.orgmeskiomeskio@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/bridgedb/-/issues/40018Evaluation of bridge statistics2023-08-24T15:15:04ZCecylia BocovichEvaluation of bridge statisticsSee what we information we have, what we need, and how we can use these statistics.See what we information we have, what we need, and how we can use these statistics.meskiomeskio@torproject.orgmeskiomeskio@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/issues/118support multiple moat-shim tokens2022-12-16T12:05:21Zmeskiomeskio@torproject.orgsupport multiple moat-shim tokensRight now moat has a configuration field for a [shim_token](https://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/blob/main/conf/config.json#L99) used to authenticate connections coming from the domain fronting so we provide differen...Right now moat has a configuration field for a [shim_token](https://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/blob/main/conf/config.json#L99) used to authenticate connections coming from the domain fronting so we provide different bridges if is from domain fronting or from the open internet. Let's provide a list of shim-tokens so all of them are used to authenticate and provide the same kind of bridges if a valid token is provided, so other clients can have their own token.Sponsor 96: Rapid Expansion of Access to the Uncensored Internet through Tor in China, Hong Kong, & Tibetmeskiomeskio@torproject.orgmeskiomeskio@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/gettor-project/OnionSproutsBot/-/issues/27review a replacement for setup.py2022-10-06T10:35:41Zn0toosereview a replacement for setup.pyIt recently came to my attention that apparently, invoking `setup.py install` directly is deprecated and I'm kind of late to the party, as I modeled this project heavily based on what I saw other projects doing and what I did myself *bef...It recently came to my attention that apparently, invoking `setup.py install` directly is deprecated and I'm kind of late to the party, as I modeled this project heavily based on what I saw other projects doing and what I did myself *before* it got deprecated. Tough luck.
It should be replaced and properly documented, though. The hard part will be dealing with the locales.https://gitlab.torproject.org/tpo/anti-censorship/team/-/issues/91Scan existing bridges for the obfs4 distinguishability bug (pre-v0.0.12 obfs4...2023-01-10T21:18:55ZDavid Fifielddcf@torproject.orgScan existing bridges for the obfs4 distinguishability bug (pre-v0.0.12 obfs4proxy)tl;dr, this is nothing urgent. It's about a distinguishability bug in obfs4proxy that was fixed at the same time as another bug. The ticket is private because we have an opportunity to scan existing bridges for both bugs simultaneously, ...tl;dr, this is nothing urgent. It's about a distinguishability bug in obfs4proxy that was fixed at the same time as another bug. The ticket is private because we have an opportunity to scan existing bridges for both bugs simultaneously, and we might want to do that before public disclosure.
We have talked about [a bug in a package that obfs4proxy relied on](https://lists.torproject.org/pipermail/anti-censorship-team/2022-January/000213.html) that supposedly made handshakes distinguishable from random, and which, after being fixed in version v0.0.12, caused [probabilistic interoperability problems](tpo/applications/tor-browser#40804) when one side had upgraded and the other had not. I have been making progress at understanding the nature of the bug and the interoperability problems resulting from the fix. It should be possible to write a remote prober (or a passive distinguisher) to detect the bug, though it will require doing some actual elliptic curve math.
Something I have not seen discussed yet, and which I discovered only yesterday, is that old versions of obfs4proxy have another, distinct bug: **the most significant bit (the 255th bit, counting from 0) of Elligator-encoded ephemeral public keys is always 0**. Encoded public keys are 32 bytes long and are stored in little-endian order; therefore bit 255 is the most significant bit of byte 31. This bit is always 0 in any TCP stream produced by a pre-v0.0.12 obfs4proxy, client or server.
To be clear, there are two different bugs. Elligator-encoded keys are 254 bits long; the top 2 bits must be randomized separately, in order to get a uniformly random string of 32 bytes. The [noncanonical representative bug in agl/ed25519](https://github.com/agl/ed25519/issues/27), the bug we knew about, was that the second-most significant bit, bit 254, one of the two bits that encoding is supposed to leave unset, was sometimes set and sometimes not, in a way not statistically independent of the lower-order bits. This bug in obfs4proxy is that it does not randomize the most significant bit, bit 255, which instead remains 0, as it is output by the Elligator encoder. See the [`tweak` parameter](https://gitlab.com/yawning/obfs4/-/commit/393aca86cc3b1a5263018c10f87ece09ac3fd5ed#028a7e0fefce096ef9214e82412a8168b2514b5c_282_288) in the patched v0.0.12 code, and how it is used to [randomize the top 2 bits](https://gitlab.com/yawning/obfs4/-/blob/393aca86cc3b1a5263018c10f87ece09ac3fd5ed/internal/x25519ell2/x25519ell2.go#L133); that part is missing in versions before v0.0.12. Compare with ["It is the caller's responsibility to randomize the 2 high bits of the representative..."](https://github.com/Yawning/libelligator/commit/eeefe989f9ced861cb6239eca0632b511aa498cb#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5R26) in libelligator.
The bit that is always 0 makes for an easy distinguisher that doesn't require any math: watch connections to a suspected server, and if the 255th bit is always 0, the server is pre-v0.0.12 obfs4proxy. It works for clients too, because the obfs4 protocol has both [clients](https://gitlab.com/yawning/obfs4/-/blob/obfs4proxy-0.0.13/doc/obfs4-spec.txt#L163) and [servers](https://gitlab.com/yawning/obfs4/-/blob/obfs4proxy-0.0.13/doc/obfs4-spec.txt#L218) send Elligator-encoded ephemeral public keys at the same place in the stream. If you know a server's node ID and public key (which are encoded in the `cert` parameter of the bridge line), you can even actively scan the server to see if it is affected.
The good news is that both bugs were fixed in the [same commit](https://gitlab.com/yawning/obfs4/-/commit/393aca86cc3b1a5263018c10f87ece09ac3fd5ed), which overhauled how Elligator is done in obfs4proxy. Therefore you can remotely scan an obfs4 server, and if it is free of the always-0 bug, it is also free of the noncanonical representative bug. Below is a program to scan for the always-0 bug. You provide it a host:port address and the `cert` parameter from a bridge line. The program connects to the server 20 times, and if bit 255 is 0 all 20 times it outputs "FAIL"; otherwise it outputs "PASS".
```python
#!/usr/bin/env python3
# Usage: obfs4-bug-check 192.95.36.142:443 qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ
import base64
import getopt
import hmac
import os
import socket
import re
import sys
import time
NUM_TRIALS = 20 # control with -n option
TIMEOUT = 5 # control with -t option
opts, (addr, cert) = getopt.gnu_getopt(sys.argv[1:], "n:t:")
for o, a in opts:
if o == "-n":
NUM_TRIALS = int(a)
elif o == "-t":
TIMEOUT = float(a)
host, port = re.match(r'^\[?(.*?)\]?:(\d+)$', addr).groups()
port = int(port)
cert = base64.b64decode(cert + "==="[:(4-len(cert)%4)%4])
nodeid = cert[:20]
pubkey = cert[20:]
assert len(nodeid) == 20
assert len(pubkey) == 32
def mac(msg):
return hmac.digest(pubkey + nodeid, msg, "sha256")[0:16]
def trial():
# https://gitlab.com/yawning/obfs4/-/blob/obfs4proxy-0.0.13/doc/obfs4-spec.txt#L156-163
repr = os.urandom(32)
padding = os.urandom(85)
mark = mac(repr)
epoch_hours = str(int(time.time()) // 3600).encode()
s = socket.create_connection((host, port), TIMEOUT)
try:
s.send(repr + padding + mark + mac(repr + padding + mark + epoch_hours))
r = s.recv(32)
return (r[31] & 0x80) != 0
finally:
s.close()
num_ones = 0
err = None
try:
for _ in range(NUM_TRIALS):
if trial():
dot = "1"
num_ones += 1
else:
dot = "."
print(dot, flush = True, end = "")
except Exception as e:
print("X", flush = True, end = "")
err = e
report = ("ERROR", str(err))
else:
report = ("PASS" if num_ones > 0 else "FAIL", f"{num_ones}/{NUM_TRIALS}")
print(*(("", addr) + report))
if err is not None:
sys.exit(2)
elif num_ones == 0:
sys.exit(1)
else:
sys.exit(0)
```
## Tests of existing bridges
I grabbed three bridges from bridges.torproject.org and scanned them. Two of them had not upgraded and had bit 255 stuck at 0.
```
$ perl -an -e '/^obfs4 (\S*) (?:\S+) cert=(\S+)/ && print "$1 $2\n";' bridges.txt | while read addr cert; do ./obfs4-bug-check $addr $cert; done
.................... 185.31.174.60:443 FAIL 0/20
.................... 142.132.237.143:2538 FAIL 0/20
1.111...1...1..11..1 90.127.32.238:42024 PASS 9/20
```
All the default Tor Browser bridges have upgraded:
```
$ perl -an -e '/^obfs4 (\S*) (?:\S+) cert=(\S+)/ && print "$1 $2\n";' tor-browser-build/projects/common/bridges_list.obfs4.txt | while read addr cert; do ./obfs4-bug-check $addr $cert; done
1..111.111.11.1111.. 192.95.36.142:443 PASS 13/20
1.111.111.11..1.1111 38.229.1.78:80 PASS 14/20
1..111.1.1.11....11. 38.229.33.83:80 PASS 10/20
.11111..11.....1..11 37.218.245.14:38224 PASS 10/20
11..111.11....111..1 85.31.186.98:443 PASS 11/20
1111...1.1111.1.111. 85.31.186.26:443 PASS 13/20
1.1.111.1111..1111.. 193.11.166.194:27015 PASS 13/20
11..1.....111.1.1111 193.11.166.194:27020 PASS 11/20
.111.1....11.......1 193.11.166.194:27025 PASS 7/20
...1.....11..111.111 209.148.46.65:443 PASS 9/20
1111....1.1.111..... 146.57.248.225:22 PASS 9/20
1.11.1111.1.1....111 45.145.95.6:27015 PASS 12/20
..11..1...1.11...11. [2a0c:4d80:42:702::1]:27015 PASS 8/20
1.111..1..1111.1..1. 51.222.13.177:80 PASS 11/20
```
## How to reproduce locally
Build a pre-v0.0.12 version of obfs4proxy:
```
$ git clone https://gitlab.com/yawning/obfs4
$ cd obfs4/obfs4proxy
$ git checkout e330d1b7024b4ab04f7d96cc1afc61325744fafc
$ go build
```
Create this torrc file:
```
SocksPort 0
ORPort 127.0.0.1:auto
PublishServerDescriptor 0
BridgeRelay 1
DataDirectory datadir
ServerTransportListenAddr obfs4 127.0.0.1:12345
ServerTransportPlugin obfs4 exec ./obfs4proxy -unsafeLogging -logLevel DEBUG -enableLogging
```
Run tor:
```
$ tor -f torrc
```
Grab the `cert` parameter from datadir/pt_state/obfs4_bridgeline.txt. Run the bug checker script and see "FAIL":
```
$ ./obfs4-bug-check 127.0.0.1:12345 hNzHgvwEUmPV7PhuhRasLGyWx/TjnCIUxYcOQ7fDl2p7EmQ9Tm8EzLmuAtevceE6LoS9Dw
.................... 127.0.0.1:12345 FAIL 0/20
```
Stop the tor process. Build a post-v0.0.12 version of obfs4proxy:
```
$ git checkout 77af0cba934d73c4baeb709560bcfc9a9fbc661c
$ go build
```
Run tor again:
```
$ tor -f torrc
```
Run the bug checker script again and see "PASS":
```
$ ./obfs4-bug-check 127.0.0.1:12345 hNzHgvwEUmPV7PhuhRasLGyWx/TjnCIUxYcOQ7fDl2p7EmQ9Tm8EzLmuAtevceE6LoS9Dw
.1...11...1111111.11 127.0.0.1:12345 PASS 12/20
```meskiomeskio@torproject.orgmeskiomeskio@torproject.org2023-01-09https://gitlab.torproject.org/tpo/anti-censorship/connectivity-measurement/logcollector/-/issues/2Connection Speed Info Collection2023-10-25T15:47:43ZshelikhooConnection Speed Info CollectionCurrently we are not collecting connection speed info, which is required for performance evaluation. We should collect this info.Currently we are not collecting connection speed info, which is required for performance evaluation. We should collect this info.shelikhooshelikhoohttps://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/issues/1Implement the Salmon bridge distribution mechanism2020-10-29T18:08:40ZPhilipp Winterphw@torproject.orgImplement the Salmon bridge distribution mechanismBridgeDB currently has three bridge distribution mechanisms: Email, HTTPS, and moat. Email is problematic because its interaction mechanism is complicated, not everyone has a Gmail or Riseup address, and it's easy to crawl. HTTPS is prob...BridgeDB currently has three bridge distribution mechanisms: Email, HTTPS, and moat. Email is problematic because its interaction mechanism is complicated, not everyone has a Gmail or Riseup address, and it's easy to crawl. HTTPS is problematic because bridges.torproject.org is blocked in most places that matter and our CAPTCHA is good at keeping out users (legacy/trac#29695) but not so good at keeping out bots (legacy/trac#31252). Moat remains relatively useful because it uses domain fronting but it also relies on a CAPTCHA to fight off bots.
It's time to think about new and/or significantly improved bridge distribution methods. How can we get bridges into the hands of users while making it difficult for adversaries to get them all? How can we make BridgeDB's CAPTCHA more resistant against bots and easier for users?
The Salmon bridge distribution system (first presented in a [PETS'16 paper](https://censorbib.nymity.ch/#Douglas2016a)) is promising. Let's use this issue to build a prototype and fill in the missing pieces to get Salmon deployed.Sponsor 30 - Objective 2.3Philipp Winterphw@torproject.orgPhilipp Winterphw@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/issues/40167debian-testing pipeline failed2022-10-10T15:56:59ZCecylia Bocovichdebian-testing pipeline failedFailed job: https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/jobs/159231
This seems to be a problem with packaged debian dependencies. I don't think it actually has anything to do with the most recent c...Failed job: https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/jobs/159231
This seems to be a problem with packaged debian dependencies. I don't think it actually has anything to do with the most recent commit. But rather that the pipeline hasn't been triggered for a while now. The last time it was run (and passed) [was a month ago](https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/-/jobs/147158).
The exact error is:
```
$ apt-get -qy install --no-install-recommends build-essential ca-certificates git golang golang-github-cheekybits-genny-dev golang-github-jtolds-gls-dev golang-github-klauspost-reedsolomon-dev golang-github-lucas-clemente-quic-go-dev golang-github-smartystreets-assertions-dev golang-github-smartystreets-goconvey-dev golang-github-tjfoc-gmsm-dev golang-github-xtaci-kcp-dev golang-github-xtaci-smux-dev golang-golang-x-crypto-dev golang-golang-x-net-dev golang-goptlib-dev golang-golang-x-sys-dev golang-golang-x-text-dev golang-golang-x-xerrors-dev lbzip2
Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package golang-github-xtaci-kcp-dev
```meskiomeskio@torproject.orgmeskiomeskio@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/gettor-project/OnionSproutsBot/-/issues/471.2.0+ mysteriously hangs when users request a cached file under unknown cond...2022-12-22T10:19:39Zn0toose1.2.0+ mysteriously hangs when users request a cached file under unknown conditionsThe bot works absolutely as it should on my machine, but not in the deployed version. Requesting a cached file renders the bot completely unresponsive.The bot works absolutely as it should on my machine, but not in the deployed version. Requesting a cached file renders the bot completely unresponsive.meskiomeskio@torproject.orgmeskiomeskio@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/conjure/-/issues/35Conjure stalls in retry loop since gotapdance library update2023-09-21T14:22:52ZCecylia BocovichConjure stalls in retry loop since gotapdance library updateI just noticed a regression that happened since the gotapdance library was updated in 51e52bfbc9dfab600a981cf94d05fa376f7b3e02. It might explain some of the more recent issues described in #22. The client does not seem to return from the...I just noticed a regression that happened since the gotapdance library was updated in 51e52bfbc9dfab600a981cf94d05fa376f7b3e02. It might explain some of the more recent issues described in #22. The client does not seem to return from the `register` function when a connection to the phantom proxy fails and can't continue retrying.Cecylia BocovichCecylia Bocovichhttps://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/issues/175moat should use mime application/json2023-10-04T15:03:40Zmeskiomeskio@torproject.orgmoat should use mime application/jsonmeskiomeskio@torproject.orgmeskiomeskio@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/issues/174Send authentication cookie to onbasca2023-10-05T16:33:55Zmeskiomeskio@torproject.orgSend authentication cookie to onbascaLet's add a header with an authentication cookie.Let's add a header with an authentication cookie.meskiomeskio@torproject.orgmeskiomeskio@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/issues/131Make easier to develop rdsys2023-09-20T15:33:37Zmeskiomeskio@torproject.orgMake easier to develop rdsysThings that can be improved
* [ ] generate dummy bridge descriptors (#171)
* [ ] make conf/config.json work out of the box
* [ ] review README instructions to make them easier to followThings that can be improved
* [ ] generate dummy bridge descriptors (#171)
* [ ] make conf/config.json work out of the box
* [ ] review README instructions to make them easier to followmeskiomeskio@torproject.orgmeskiomeskio@torproject.orghttps://gitlab.torproject.org/tpo/anti-censorship/rdsys/-/issues/171Make a script to create fake bridge descriptors2023-09-20T15:33:37Zmeskiomeskio@torproject.orgMake a script to create fake bridge descriptorsFor the staging server and to make it easier to develop rdsys (#131) we need a script to automatically generate fake bridge descriptors.
BridgeDB has one, but the output is not totally compatible with rdsys: https://gitlab.torproject.or...For the staging server and to make it easier to develop rdsys (#131) we need a script to automatically generate fake bridge descriptors.
BridgeDB has one, but the output is not totally compatible with rdsys: https://gitlab.torproject.org/tpo/anti-censorship/bridgedb/-/blob/main/scripts/create_descriptorsmeskiomeskio@torproject.orgmeskiomeskio@torproject.org