{"id":18254621,"url":"https://github.com/torproject/chutney","last_synced_at":"2025-04-04T17:30:43.570Z","repository":{"id":10498161,"uuid":"12681481","full_name":"torproject/chutney","owner":"torproject","description":"unofficial git repo -- report bugs/issues/pull requests on https://gitlab.torproject.org/ --","archived":false,"fork":false,"pushed_at":"2021-11-18T19:34:14.000Z","size":784,"stargazers_count":54,"open_issues_count":0,"forks_count":41,"subscribers_count":13,"default_branch":"main","last_synced_at":"2024-05-01T11:46:33.463Z","etag":null,"topics":["python","tor"],"latest_commit_sha":null,"homepage":"https://gitweb.torproject.org/chutney.git","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/torproject.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-09-08T13:57:59.000Z","updated_at":"2024-04-14T19:36:45.000Z","dependencies_parsed_at":"2022-08-30T18:02:04.760Z","dependency_job_id":null,"html_url":"https://github.com/torproject/chutney","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/torproject%2Fchutney","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/torproject%2Fchutney/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/torproject%2Fchutney/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/torproject%2Fchutney/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/torproject","download_url":"https://codeload.github.com/torproject/chutney/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223150712,"owners_count":17095959,"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":["python","tor"],"created_at":"2024-11-05T10:13:05.462Z","updated_at":"2024-11-05T10:13:06.118Z","avatar_url":"https://github.com/torproject.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Chutney\n\nThis is chutney.  It doesn't do much so far.  It isn't ready for prime-time.\n\nIf it breaks, you get to keep all the pieces.\n\nIt is supposed to be a good tool for:\n\n- Configuring a testing tor network\n- Launching and monitoring a testing tor network\n- Running tests on a testing tor network\n\nRight now it only sorta does these things.\n\n## You will need\n- A supported version of Python 3\n  - (we support Python versions that are still getting updates), and\n- Tor binaries.\n\nChutney checks for Tor binaries in this order:\n\n- If you run chutney's `tools/test-network.sh` from a tor build directory,\n  (or set the environment variable `$TOR_DIR` to a tor build directory,)\n  chutney will automatically detect the tor binaries, or\n- If you put the location of the `tor` and `tor-gencert` binaries in the\n  environment variables `$CHUTNEY_TOR` and `$CHUTNEY_TOR_GENCERT`, respectively,\n  chutney will use those binaries, or\n- You will need `tor` and `tor-gencert` installed somewhere in your path.\n\n## Stuff to try\n\nAutomated Setup, Verification, and Shutdown:\n\n``` shell\n./tools/test-network.sh --flavor basic-min\n./tools/test-network.sh --coverage\n./tools/test-network.sh --tor-path \u003ctor-build-directory\u003e\n./tools/test-network.sh --tor \u003cname-or-path\u003e --tor-gencert \u003cname-or-path\u003e\n```\n(`--tor-path` and `$TOR_DIR` override `--tor` and `--tor-gencert`.)\n(The script tries hard to find `tor`.)\n\n``` shell\n./tools/test-network.sh --chutney-path \u003cchutney-directory\u003e\n```\n(The script is pretty good at finding `chutney`.)\n\n``` shell\n./tools/test-network.sh --allow-failures \u003cN\u003e\n```\n\n`test-network.sh` looks for some tor binaries (either in a nearby build\ndirectory or in your `$PATH`), configures a comprehensive Tor test network,\nlaunches it, then verifies data transmission through it, and cleans up after\nitself. Relative paths are supported.\n\nYou can modify its configuration using command-line arguments, or use the\nchutney environmental variables documented below:\n\n## Verification Options\n\n``` shell\n# repeats bootstrap and verify\n--allow-failures   CHUTNEY_ALLOW_FAILURES=N\n# repeats verify\n--rounds           CHUTNEY_ROUNDS=N\n# makes multiple connections within verify\n--connections      CHUTNEY_CONNECTIONS=N\n```\n\n## Timing Options\n\n``` shell\n--start-time       CHUTNEY_START_TIME=N\n--min-start-time   CHUTNEY_MIN_START_TIME=N\n--bootstrap-time   CHUTNEY_BOOTSTRAP_TIME=N\n--stop-time        CHUTNEY_STOP_TIME=N\n```\n\n## Traffic Options\n\n``` shell\n--data             CHUTNEY_DATA_BYTES=N\n--hs-multi-client  CHUTNEY_HS_MULTI_CLIENT=N\n```\n\n## Address/DNS Options\n\n``` shell\n--ipv4             CHUTNEY_LISTEN_ADDRESS=IPV4\n--ipv6             CHUTNEY_LISTEN_ADDRESS_V6=IPV6\n\n# Chutney uses /etc/resolv.conf if none of these options are set\n--dns-conf         CHUTNEY_DNS_CONF=PATH\n--offline          CHUTNEY_DNS_CONF=/dev/null\n\n# Use tor's compile-time default for ServerDNSResolvConfFile\n--dns-conf-default CHUTNEY_DNS_CONF=\"\"\n```\n\n## Sandbox Options\n\n``` shell\n--sandbox          CHUTNEY_TOR_SANDBOX=N (0 or 1)\n```\n\n## Warning Options\n\n``` shell\n--all-warnings     CHUTNEY_WARNINGS_IGNORE_EXPECTED=false\n                   CHUTNEY_WARNINGS_SUMMARY=false\n--no-warnings      CHUTNEY_WARNINGS_SKIP=true\n--only-warnings    CHUTNEY_WARNINGS_ONLY=true\n--diagnostics      CHUTNEY_DIAGNOSTICS=true\n--only-diagnostics CHUTNEY_DIAGNOSTICS_ONLY=true\n```\n\n## Expert Options\n\n``` shell\n--debug            CHUTNEY_DEBUG=true\n--coverage         USE_COVERAGE_BINARY=true\n--dry-run          NETWORK_DRY_RUN=true\n--quiet            ECHO=true\n\n--controlling-pid  CHUTNEY_CONTROLLING_PID=N\n--net-dir          CHUTNEY_DATA_DIR=PATH\n```\n(These are advanced options: in the past, they have had long-standing bugs.)\n\n## Standard Actions\n\n``` shell\n./chutney configure networks/basic\n./chutney start networks/basic\n./chutney status networks/basic\n./chutney wait_for_bootstrap networks/basic\n./chutney verify networks/basic\n./chutney hup networks/basic\n./chutney stop networks/basic\n```\n\n## Bandwidth Tests\n\n``` shell\n./chutney configure networks/basic-min\n./chutney start networks/basic-min\n./chutney status networks/basic-min\n```\n\nSend 100MB of data per client connection:\n``` shell\nCHUTNEY_DATA_BYTES=104857600 ./chutney verify networks/basic-min\n./chutney stop networks/basic-min\n```\n\nIf chutney sends at least `5 MB` of data, and it takes at least one second,\nverify produces performance figures for:\n\n- Single Stream Bandwidth: the speed of the slowest stream, end-to-end\n- Overall tor Bandwidth: the sum of the bandwidth across each tor instance\n\nThe overall bandwidth approximates the CPU-bound tor performance on the\ncurrent machine, assuming tor, chutney, and the OS are multithreaded, and\nnetwork performance is infinite.\n\n## Connection Tests\n\n``` shell\n./chutney configure networks/basic-025\n./chutney start networks/basic-025\n./chutney status networks/basic-025\n```\n\nMake 5 simultaneous connections from each client through a random exit\n\n``` shell\nCHUTNEY_CONNECTIONS=5 ./chutney verify networks/basic-025\n./chutney stop networks/basic-025\n```\n\nRun 5 sequential verification rounds\n\n``` shell\nCHUTNEY_ROUNDS=5 ./tools/test-network.sh --flavour basic\n```\n\n## HS Connection Tests\n\n``` shell\n./chutney configure networks/hs-025\n./chutney start networks/hs-025\n./chutney status networks/hs-025\n```\n\nMake a connection from each client to each hs Default behavior is one client\nconnects to each HS: \n``` shell\nCHUTNEY_HS_MULTI_CLIENT=1 ./chutney verify networks/hs-025\n./chutney stop networks/hs-025\n```\n\n\n## Bandwidth File Tests\n\n``` shell\n./tools/test-network.sh --flavour bwfile\n# Warning: Can't open bandwidth file at configured location: /tmp/bwfile\n# Create a bwfile with no bandwidths, that is valid for a few days\ndate +%s \u003e /tmp/bwfile\n./tools/test-network.sh --flavour bwfile\n```\n\n## Multiple Tests\n\nChutney can allow a certain number of failed tests. You can either set\n`CHUTNEY_ALLOW_FAILURES` or use an `--allow-failures` command-line option to\ncontrol this. Chutney will then reattempt the test, from bootstrap through\nshutdown, until either it succeeds, or until it has failed\n`$CHUTNEY_ALLOW_FAILURES+1` times. The default value is zero, so the default\nbehavior will not change.\n\nYou can also use `CHUTNEY_ROUNDS=N` to run multiple verification rounds, or\n`CHUTNEY_CONNECTIONS=N` to make multiple connections within each verification\nround. Any round or connection failure will fail the current test.\n\n## Bootstrapping the network\n\nChutney expects a tor network to bootstrap in these stages:\n\n1.  All directory authorities (`DirAuths`) bootstrap to 100%.\n2.  The `DirAuths` produce the first consensus.\n    Usually, this consensus only contains authorities.\n3.  The `DirAuths` produce a bootstrap consensus.\n    This consensus has enough relays for:\n      * clients and relays to bootstrap, and\n      * relays to perform reachability self-tests.\n\n    Usually, this consensus needs at least 3 nodes. This consensus is usually\n    the first or second consensus. \n4.  Relays bootstrap to 100%.\n5.  Relays with `AssumeReachable 1` publish their descriptors to the\n    `DirAuths`.\n6.  Relays perform `ORPort` reachability self-tests.\n    If the consensus contains at least 1 exit, relays also perform `DirPort`\n    reachability self-tests.\n7.  Relays publish their descriptors to the `DirAuths`.\n8.  The `DirAuths` produce a complete consensus, microdesc consensus, and\n    microdescriptors. A complete consensus contains:\n      * the authorities,\n      * any bridge authorities, if present, and\n      * all relays (including exits).\n    Bridges, clients, and onion services are not included in the consensus.\n9.  Bridges publish their descriptors to the Bridge Auth.\n10. The Bridge Auth produces a bridge networkstatus.\n11. Relays and bridges download all consensus flavours, then download\n    descriptors and microdescriptors.\n12. Bridge clients download the descriptors for their bridges.\n13. Clients (including bridge clients, and onion services), download the\n    most recent microdesc consensus, and microdescriptors.\n14. Clients bootstrap to 100%.\n    (Clients can bootstrap as soon as the consensus contains enough nodes,\n    so this step can depend on step 3, not step 13.)\n15. Onion Services publish their descriptors to Onion Service directories\n    (otherwise known as hidden service directories, or `HSDirs`).\n\nThe `tools/test-network.sh` script uses the chutney `wait_for_bootstrap`\ncommand to wait for the network to bootstrap.\n\n`wait_for_bootstrap` waits up to `CHUTNEY_START_TIME` seconds (default: 120),\nchecking whether:\n\n* the logged bootstrapped status for every node is 100% (steps 9 and 14),\n  and\n* directory information has been distributed throughout the network\n  (steps 7-8, 11-13).\n\nWhen waiting for dir info distribution, `wait_for_bootstrap` checks if:\n\n* each relay descriptor has been posted to every authority (step 7),\n* each relay is in the consensus, and the microdesc consensus, at every\n  authority (step 8),\n* a complete consensus and microdesc consensus has been distributed to\n  relays and bridges (step 11),\n* all authority and relay descriptors have been distributed to relays\n  and bridges (step 11),\n* all bridge descriptors have been distributed to all bridge clients\n  (step 12), and\n* a complete microdesc consensus has been distributed to clients\n  (step 13).\n\n`wait_for_bootstrap` does not currently check the following dir info:\n\n* microdescriptors (steps 8, 11, and 13, chutney ticket #33407),\n* bridge descriptors at the bridge authority (steps 9-10,\n  tor ticket #33582, chutney ticket #33428), and\n* onion services have published their descriptors to the HSDirs (step 15,\n  chutney ticket #33609).\n\nAfter bootstrapping and dir info distribution, `wait_for_bootstrap` waits\nuntil the network has been running for at least `CHUTNEY_MIN_START_TIME`\nseconds (default 0 seconds for `tor` \u003e 0.3.5., 65 seconds for `tor` \u003c= 0.3.5.),\nto compensate for microdesc download issues in older tor versions.\n\nIn addition, `wait_for_bootstrap` also waits an extra:\n\n- 10 seconds for clients to download microdescs, and\n- 30 seconds for onion services to upload their descriptors.\n\nWe expect that these delays will be removed, once the relevant checks are\nimplemented in chutney.\n\nIf the `CHUTNEY_START_TIME` has elapsed, and some nodes have not bootstrapped,\nor there are some nodes missing from the consensus, `wait_for_bootstrap` dumps\nthe bootstrap statuses, and exits with a failure.\n\n## Verifying the network\n\nCommands like `chutney verify` start immediately, and keep trying for\n`CHUTNEY_BOOTSTRAP_TIME` seconds (default: 60). If it hasn't been\nsuccessful after that time, it fails. If `CHUTNEY_BOOTSTRAP_TIME` is negative,\nthe script leaves the network running, and exits after `CHUTNEY_START_TIME`\n(without verifying).\n\n## Shutting down the network\n\nThe `tools/test-network.sh` script waits `CHUTNEY_STOP_TIME` seconds\nafter verifying, then exits (default: immediately). If `CHUTNEY_STOP_TIME` is\nnegative, the script leaves the network running, and exits after verifying.\n\nIf none of these options are negative, `test-network.sh` tells the tor\nprocesses to exit after it exits, using `CHUTNEY_CONTROLLING_PID`. To disable\nthis functionality, set `CHUTNEY_CONTROLLING_PID` to 1 or less.\n\n## Changing the network address\n\nChutney defaults to binding to `localhost`. To change the IPv4 bind address,\nset the `CHUTNEY_LISTEN_ADDRESS` environment variable. Similarly, change\n`CHUTNEY_LISTEN_ADDRESS_V6` for IPv6: it defaults to \"no IPv6 address\".\nSetting it to some interface's IP address allows us to make the simulated\nTor network available on the network.\n\nIPv6 support for both Tor and Chutney is a work in progress. Currently,\nchutney verifies IPv6 client, bridge client (?), hidden service, and exit\nconnections. It does not use IPv6 `SOCKSPorts` or `HiddenServicePorts`.\n\n## Using DNS\n\nChutney verify uses IP addresses by default. It does not need to look up\nany hostnames. We recommend that chutney users disable DNS using `--offline`\nor `CHUTNEY_DNS_CONF=/dev/null`, because any DNS failures causes tests to\nfail. Chutney's DNS queries also produce external traffic in a predictable\npattern.\n\nIf you want to use a hostname with `CHUTNEY_LISTEN_ADDRESS[_V6]`, or you want\nto run tests that use DNS, set `CHUTNEY_DNS_CONF` to the path to a file in\n`resolv.conf` format. Chutney's default of `/etc/resolv.conf` should be fine for\nmost UNIX-based operating systems. If your tor is compiled with a different\ndefault, use `--dns-resolv-conf-default` or `CHUTNEY_DNS_CONF=\"\"`.\n\nWhen the `CHUTNEY_DNS_CONF` file does not exist, or is a broken symlink,\n`chutney` uses `/dev/null` instead. This is a workaround for bugs in Tor's\nuse of `eventdns`. For example, macOS deletes the `resolv.conf` file when it\nthinks the network is down: this can make tor exits reject all traffic,\neven if a working DNS server is running on 127.0.0.1:53.\n\nWhen tor has no working name servers (including `--offline` mode), it can\ncrash on `SETCONF`. (Chutney does not use `SETCONF`, but some external tor\ncontrollers do.) To avoid this crash, set `CHUTNEY_DNS_CONF` to a file\ncontaining a working name server address. For your convenience, chutney\nprovides a local `resolv.conf` file containing IPv4, IPv6, and `localhost`.\nUse `--dns-conf resolv.conf` (relative paths work).\n\n## The Tor sandbox\n\nChutney can run with the Tor seccomp sandbox enabled. But if Tor's sandbox\nis broken on your local version of glibc, you can set `CHUTNEY_TOR_SANDBOX=0`\nto disable the sandbox. If `CHUTNEY_TOR_SANDBOX` is unset, Sandbox defaults\nto 1 on Linux, and 0 on other platforms.\n\n## The configuration files\n\n`networks/basic` holds the configuration for the network you're configuring\nabove. It refers to some torrc template files in `torrc_templates/`.\n\nChutney uses a templating system to produce torrc files from the templates.\nThese torrc files can be modified using various chutney options.\n\n## The working files\n\nChutney sticks its working files, including all generated torrc files,\ndata directories, log files, etc, in `./net/`.  Each tor instance gets a\nsubdirectory of `net/nodes`.\n\nYou can override the directory `./net` with the `CHUTNEY_DATA_DIR`\nenvironment variable.\n\n## Test scripts\n\nThe test scripts are stored in the `scripts/chutney_tests` directory. These\nPython files must define a `run_test(network)` function. Files starting with\nan underscore (\"_\") are ignored.\n\nTest scripts can be run using the following syntax:\n\n``` shell\n./chutney \u003cscript-name\u003e networks/\u003cnetwork-name\u003e\n```\n\nThe `chutney verify` command is implemented using a test script.\n\nTest scripts in the test directory with the same name as standard commands\nare run instead of that standard command. This allows expert users to replace\nthe standard chutney commands with modified versions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftorproject%2Fchutney","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftorproject%2Fchutney","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftorproject%2Fchutney/lists"}