diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 981e00b69ffcb0517916031b1318a5385341ae9a..bb6017768bf9830210997b2ceb00caeb7dd88665 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -138,7 +138,7 @@ integration:
   script:
     - apt update
     - apt install -y tor git python3 curl
-    - ./tests/chutney/setup
+    - ./tests/chutney/setup proxy
     - curl http://example.com -vs --socks5-hostname 127.0.0.1:9150 -o /dev/null
     - ./tests/chutney/stop-arti
     - RUST_LOG=debug target/x86_64-unknown-linux-gnu/release/arti-bench -c ./chutney/net/nodes/arti.toml --socks5 127.0.0.1:9008 -o benchmark_results.json
diff --git a/maint/coverage b/maint/coverage
index a1d3577c0659d2eb5b8a9f27b1929e14db17900c..65e7b755c40e0997383310da2dc75594c3fc6870 100755
--- a/maint/coverage
+++ b/maint/coverage
@@ -89,7 +89,7 @@ if [ "$INTEGRATION" = yes ] ; then
     # go into a basic extensible integration-testing script that gets
     # run both from here and from the .gitlab-ci.yml file.
     trap ./tests/chutney/teardown 0
-    ./maint/with_coverage -c -s ./tests/chutney/setup
+    ./maint/with_coverage -c -s ./tests/chutney/setup proxy
     curl http://example.com -vs --socks5-hostname 127.0.0.1:9150 -o /dev/null
     trap - 0
     ./tests/chutney/teardown
diff --git a/tests/chutney/arti-bench b/tests/chutney/arti-bench
index 00c3599fbe39a76821d1244df4b4cc4c879d784a..b0779ebae6ef91f61ff19ccaa6874025bfb59b9b 100755
--- a/tests/chutney/arti-bench
+++ b/tests/chutney/arti-bench
@@ -9,33 +9,7 @@ fi
 target="networks/basic"
 cd "$(git rev-parse --show-toplevel)"
 
-# TODO: Much of the setup logic below is boilerplate.  Maybe the
-# common parts of this script and setup/teardown should be
-# extracted.
-if [ -z "${CHUTNEY_PATH}" ]; then
-    # CHUTNEY_PATH isn't set; try cloning or updating a local chutney.
-    if [ -d chutney ]; then
-	(cd ./chutney && git pull)
-    else
-	git clone https://gitlab.torproject.org/tpo/core/chutney
-    fi
-    CHUTNEY_PATH="$(pwd)/chutney"
-    export CHUTNEY_PATH
-else
-    # CHUTNEY_PATH is set; tell the user so.
-    echo "CHUTNEY_PATH is ${CHUTNEY_PATH}; using your local copy of chutney."
-fi
-
-if [ ! -e "${CHUTNEY_PATH}/${target}" ]; then
-    echo "Target network description ${CHUTNEY_PATH}/${target} not found."
-    exit 1
-fi
-
-"${CHUTNEY_PATH}/chutney" configure "${CHUTNEY_PATH}/$target"
-"${CHUTNEY_PATH}/chutney" start "${CHUTNEY_PATH}/$target"
-CHUTNEY_START_TIME=180 "${CHUTNEY_PATH}"/chutney wait_for_bootstrap "${CHUTNEY_PATH}/$target"
-"${CHUTNEY_PATH}"/chutney verify "${CHUTNEY_PATH}/$target"
-# TODO (end of boilerplate)
+./tests/chutney/setup
 
 cargo run -p arti-bench --release -- -c "${CHUTNEY_PATH}/net/nodes/arti.toml" "$@"
 
diff --git a/tests/chutney/setup b/tests/chutney/setup
index 952e39a3834816610d74882b43cfa478fa5812ea..7e929e1f753e8151acf4a17d4126c9638c903cc2 100755
--- a/tests/chutney/setup
+++ b/tests/chutney/setup
@@ -1,11 +1,58 @@
 #!/bin/bash
+
 set -xe
 
-target="${1:-networks/basic}"
+SCRIPT_NAME=$(basename "$0")
+
+function usage()
+{
+    cat <<EOF
+${SCRIPT_NAME}: Launch a chutney network to test arti
+
+Usage:
+  ${SCRIPT_NAME} [modules] : Launch chutney, and the provided modules.
+
+Options:
+  -h: Print this message.
+  -n <network>: Name of the chutney network to launch (default: basic)
+
+Modules:
+  "proxy": Launch a arti-based SOCKS proxy.
+EOF
+}
+
+PROXY=no
+NETWORK="basic"
+while getopts "hn:" opt ; do
+    case "$opt" in
+	h) usage
+	   exit 0
+	   ;;
+	n) NETWORK="$OPTARG"
+	   ;;
+	*) echo "Unknown option. (Run $0 -h for usage)"
+	   exit 1
+	   ;;
+    esac
+done
+
+# Remove the parsed flags
+shift $((OPTIND-1))
+
+for module in "$@"; do
+    case "$module" in
+	proxy) PROXY=yes
+	       ;;
+	*) echo "Unrecognized module. (Run $0 -h for usage)"
+	   ;;
+    esac
+done
+
+target="networks/$NETWORK"
 cd "$(git rev-parse --show-toplevel)"
 
 if [ -z "${CHUTNEY_PATH}" ]; then
-    # CHUTNEY_PATH isn't set; try cloning a local chutney.
+    # CHUTNEY_PATH isn't set; try cloning or updating a local chutney.
     if [ -d chutney ]; then
 	(cd ./chutney && git pull)
     else
@@ -14,7 +61,7 @@ if [ -z "${CHUTNEY_PATH}" ]; then
     CHUTNEY_PATH="$(pwd)/chutney"
     export CHUTNEY_PATH
 else
-    # CHUTNEY_PATH is set; tell the user about that.
+    # CHUTNEY_PATH is set; tell the user so.
     echo "CHUTNEY_PATH is ${CHUTNEY_PATH}; using your local copy of chutney."
 fi
 
@@ -24,10 +71,14 @@ if [ ! -e "${CHUTNEY_PATH}/${target}" ]; then
 fi
 
 "${CHUTNEY_PATH}/chutney" configure "${CHUTNEY_PATH}/$target"
-"${CHUTNEY_PATH}"/chutney start "${CHUTNEY_PATH}/$target"
+"${CHUTNEY_PATH}/chutney" start "${CHUTNEY_PATH}/$target"
 CHUTNEY_START_TIME=180 "${CHUTNEY_PATH}"/chutney wait_for_bootstrap "${CHUTNEY_PATH}/$target"
 "${CHUTNEY_PATH}"/chutney verify "${CHUTNEY_PATH}/$target"
 
+if [ "$PROXY" = "no" ] ; then
+    exit 0
+fi
+
 if [ -x ./target/x86_64-unknown-linux-gnu/debug/arti ]; then
 	cmd=./target/x86_64-unknown-linux-gnu/debug/arti
 else