Skip to content

Commit

Permalink
DNM: Power make dev-tor with Arti
Browse files Browse the repository at this point in the history
The authenticated onion service stuff is still unmerged
(<https://gitlab.torproject.org/tpo/core/arti/-/merge_requests/2266>),
so we build Arti from the MR and it works! Generating a config.toml file
seems much cleaner than adding to `torrc` and generating `.auth` files.

The main upside for this is that using Arti is cool and gets it more
real-world testing. But the downside is that it takes a non-trivial
amount of time to build Arti locally and maybe it's not worth doing
until we have pre-package/downloadable binaries. 🤔
  • Loading branch information
legoktm committed Aug 1, 2024
1 parent 0703a94 commit 2d6fa7b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 37 deletions.
74 changes: 39 additions & 35 deletions securedrop/bin/dev-deps
Original file line number Diff line number Diff line change
Expand Up @@ -53,50 +53,54 @@ function maybe_create_config_py() {

function maybe_use_tor() {
if [[ -n "${USE_TOR:-}" ]]; then
echo "Setting up Tor..."
if [ ! -d "/var/lib/tor/services" ]; then
sudo chown -R debian-tor:debian-tor /var/lib/tor/services
else
sudo -u debian-tor mkdir -p /var/lib/tor/services
echo "Setting up Arti..."

mkdir -p /var/lib/arti
if [ ! -f "/var/lib/arti/config.toml" ]; then
# create config.toml for SI and JI
openssl genpkey -algorithm x25519 -out /var/lib/arti/ji_priv.key
ji_auth_public=$(openssl pkey -in /var/lib/arti/ji_priv.key -pubout | grep -v " PUBLIC KEY" | base64pem -d | tail --bytes=32 | base32 | sed 's/=//g')
cat > /var/lib/arti/config.toml << TOML
[proxy]
socks_listen = 9152
[storage]
# store temporarily
cache_dir = "/tmp/arti-cache"
# store persistently
state_dir = "/var/lib/arti/data"
[onion_services."source"]
proxy_ports = [
["80", "127.0.0.1:8080"]
]
[onion_services."journalist"]
proxy_ports = [
["80", "127.0.0.1:8081"]
]
[onion_services."journalist".restricted_discovery]
enabled = true
[onion_services."journalist".restricted_discovery.static_keys]
journalist = "descriptor:x25519:${ji_auth_public}"
TOML
fi
# append torrc lines for SI and JI
echo "HiddenServiceDir /var/lib/tor/services/source/" | sudo tee -a /etc/tor/torrc
echo "HiddenServicePort 80 127.0.0.1:8080" | sudo tee -a /etc/tor/torrc
echo "HiddenServiceDir /var/lib/tor/services/journalist/" | sudo tee -a /etc/tor/torrc
echo "HiddenServicePort 80 127.0.0.1:8081" | sudo tee -a /etc/tor/torrc
# start Tor to create service directories
sudo service tor start
if sudo test -f "/var/lib/tor/services/journalist_auth_token.prv.pem"; then
# recover x25519 key
sudo cat /var/lib/tor/services/journalist_auth_token.prv.pem | tee /tmp/k1.prv.pem
else
echo "Generating new client authorization..."
# create x25519 keypair and journalist client auth file
openssl genpkey -algorithm x25519 -out /tmp/k1.prv.pem
# store private auth token for regeneration after restarts
sudo cp /tmp/k1.prv.pem /var/lib/tor/services/journalist_auth_token.prv.pem
fi
grep -v " PRIVATE KEY" < /tmp/k1.prv.pem | base64pem -d | tail --bytes=32 | base32 | sed 's/=//g' > /tmp/k1.prv.key
openssl pkey -in /tmp/k1.prv.pem -pubout | grep -v " PUBLIC KEY" | base64pem -d | tail --bytes=32 | base32 | sed 's/=//g' > /tmp/k1.pub.key
echo "descriptor:x25519:$(cat /tmp/k1.pub.key)" | sudo -u debian-tor tee /var/lib/tor/services/journalist/authorized_clients/client.auth
# shellcheck disable=SC2024
sudo -u debian-tor cat /var/lib/tor/services/source/hostname > /var/lib/securedrop/source_v3_url
# kill and restart Tor to pick up authorized_clients change
# (restart a little flaky hence the kill)
sudo kill "$(cat /run/tor/tor.pid)"; sudo service tor restart
/opt/cargo/bin/arti -c /var/lib/arti/config.toml hss --nickname source onion-name -l none > /var/lib/securedrop/source_v3_url
/opt/cargo/bin/arti -c /var/lib/arti/config.toml proxy &
# print out the addresses and the JI client auth key

si_address="$(sudo -u debian-tor cat /var/lib/tor/services/source/hostname)"
ji_address="$(sudo -u debian-tor cat /var/lib/tor/services/journalist/hostname)"
ji_authkey="$(sudo -u debian-tor cat /tmp/k1.prv.key)"
si_address="$(/opt/cargo/bin/arti -c /var/lib/arti/config.toml hss --nickname source onion-name -l none)"
ji_address="$(/opt/cargo/bin/arti -c /var/lib/arti/config.toml hss --nickname journalist onion-name -l none)"
ji_auth_private=$(grep -v " PRIVATE KEY" /var/lib/arti/ji_priv.key | base64pem -d | tail --bytes=32 | base32 | sed 's/=//g')
sdkey_fpr="$(gpg --with-fingerprint --with-colons ./tests/files/test_journalist_key.pub | grep -e '^fpr' | tr -d 'fpr:')"

cat > /tmp/qubes-config.json <<EOF
{
"submission_key_fpr": "${sdkey_fpr}",
"hidserv": {
"hostname": "${ji_address}",
"key": "${ji_authkey}"
"key": "${ji_auth_private}"
},
"environment": "prod",
"vmsizes": {
Expand All @@ -110,7 +114,7 @@ EOF
echo "--------"
echo "Source Interface: http://${si_address}"
echo "Journalist Interface: http://${ji_address}"
echo "Journalist Auth Key: ${ji_authkey}"
echo "Journalist Auth Key: ${ji_auth_private}"
echo "--------"
echo
echo "SecureDrop Workstation config.json:"
Expand Down
2 changes: 1 addition & 1 deletion securedrop/bin/dev-shell
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ function docker_run() {
if [ -n "${USE_TOR:-}" ]; then
# Mount persistent onion services
$DOCKER_BIN volume inspect sd-onion-services -f " " || $DOCKER_BIN volume create sd-onion-services
DOCKER_RUN_ARGUMENTS="${DOCKER_RUN_ARGUMENTS} --volume sd-onion-services:/var/lib/tor/services"
DOCKER_RUN_ARGUMENTS="${DOCKER_RUN_ARGUMENTS} --volume sd-onion-services:/var/lib/arti"
fi

# The --shm-size argument sets up dedicated shared memory for the
Expand Down
6 changes: 5 additions & 1 deletion securedrop/dockerfiles/focal/python3/SlimDockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ RUN apt-get update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install
apache2-dev coreutils vim \
python3-pip python3-all python3-venv virtualenv python3-dev libssl-dev \
gnupg2 redis-server git curl wget jq \
enchant libffi-dev sqlite3 gettext sudo tor basez pkg-config
enchant libffi-dev libsqlite3-dev sqlite3 gettext sudo basez pkg-config

# Install Rust using the same steps as <https://github.com/rust-lang/docker-rust>
# 1) Download rustup-init and verify it matches hardcoded checksum
Expand All @@ -20,6 +20,7 @@ ENV RUSTUP_VERSION 1.24.3
ENV RUSTUP_INIT_SHA256 3dc5ef50861ee18657f9db2eeb7392f9c2a6c95c90ab41e45ab4ca71476b4338
ENV RUSTUP_HOME /opt/rustup
ENV CARGO_HOME /opt/cargo
#ENV ARTI_VERSION 1.2.5

RUN TMPDIR=`mktemp -d` && cd ${TMPDIR} \
&& curl --proto '=https' --tlsv1.2 -OO -sSf https://static.rust-lang.org/rustup/archive/${RUSTUP_VERSION}/x86_64-unknown-linux-gnu/rustup-init \
Expand All @@ -28,6 +29,9 @@ RUN TMPDIR=`mktemp -d` && cd ${TMPDIR} \
&& ./rustup-init --default-toolchain=${RUST_VERSION} --profile minimal -y \
&& cd && rm -rf ${TMPDIR}

# --version ${ARTI_VERSION}
RUN /opt/cargo/bin/cargo install --locked --git https://gitlab.torproject.org/gabi-250/arti arti --branch onion-svc-auth --features onion-service-service,restricted-discovery

COPY requirements requirements
RUN python3 -m venv /opt/venvs/securedrop-app-code && \
/opt/venvs/securedrop-app-code/bin/pip3 install --no-deps --require-hashes -r requirements/python3/bootstrap-requirements.txt && \
Expand Down

0 comments on commit 2d6fa7b

Please sign in to comment.