diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9f54c6fe4..aba823228 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,6 +42,7 @@ jobs: - logging_test.py - ln_basic_test.py - ln_test.py + - onion_test.py - plugin_test.py - rpc_test.py - services_test.py diff --git a/resources/charts/bitcoincore/templates/pod.yaml b/resources/charts/bitcoincore/templates/pod.yaml index 56cd61958..ea9679d2b 100644 --- a/resources/charts/bitcoincore/templates/pod.yaml +++ b/resources/charts/bitcoincore/templates/pod.yaml @@ -98,6 +98,9 @@ spec: value: {{ .Values.metrics }} {{- end }} {{- end}} + {{- with .Values.extraContainers }} + {{- toYaml . | nindent 4 }} + {{- end }} volumes: {{- with .Values.volumes }} {{- toYaml . | nindent 4 }} diff --git a/resources/images/tor/Dockerfile_tor_da b/resources/images/tor/Dockerfile_tor_da new file mode 100644 index 000000000..242f6f88f --- /dev/null +++ b/resources/images/tor/Dockerfile_tor_da @@ -0,0 +1,18 @@ +FROM debian:bookworm-slim +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y tor iproute2 dnsutils + +RUN mkdir -p /home/debian-tor/.tor/keys +RUN chown -R debian-tor:debian-tor /home/debian-tor +RUN mkdir -p /var/log/tor +RUN chown -R debian-tor:debian-tor /var/log/tor + +COPY ./tor-keys /home/debian-tor/.tor/keys +RUN chown -R debian-tor:debian-tor /home/debian-tor/.tor/keys +COPY ./torrc.da /etc/tor/torrc + +COPY ./tor-entrypoint.sh /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] + diff --git a/resources/images/tor/Dockerfile_tor_relay b/resources/images/tor/Dockerfile_tor_relay new file mode 100644 index 000000000..8cb63a7f9 --- /dev/null +++ b/resources/images/tor/Dockerfile_tor_relay @@ -0,0 +1,16 @@ +FROM debian:bookworm-slim +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y tor iproute2 dnsutils + +RUN mkdir -p /home/debian-tor/.tor +RUN chown -R debian-tor:debian-tor /home/debian-tor +RUN mkdir -p /var/log/tor +RUN chown -R debian-tor:debian-tor /var/log/tor + + +COPY ./torrc.relay /etc/tor/torrc + +COPY ./tor-entrypoint.sh /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/resources/images/tor/build-tor.sh b/resources/images/tor/build-tor.sh new file mode 100755 index 000000000..5efb5447e --- /dev/null +++ b/resources/images/tor/build-tor.sh @@ -0,0 +1,15 @@ +SCRIPT_PATH="$(realpath "${BASH_SOURCE[0]}")" + +docker buildx build \ + --platform linux/amd64,linux/arm64,linux/armhf \ + --push \ + -t bitcoindevproject/tor-da:latest \ + -f ./resources/images/tor/Dockerfile_tor_da \ + ./resources/images/tor/ + +docker buildx build \ + --platform linux/amd64,linux/arm64,linux/armhf \ + --push \ + -t bitcoindevproject/tor-relay:latest \ + -f ./resources/images/tor/Dockerfile_tor_relay \ + ./resources/images/tor/ \ No newline at end of file diff --git a/resources/images/tor/tor-entrypoint.sh b/resources/images/tor/tor-entrypoint.sh new file mode 100755 index 000000000..a2d70e54e --- /dev/null +++ b/resources/images/tor/tor-entrypoint.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -e + +echo "Starting tor-entrypoint.sh" + +IP_ADDR=$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1) + +until TORDA_IP=$(dig +short torda.default.svc.cluster.local); do + echo "Waiting for DNS: torda" + sleep 2 +done + +echo "My IP address: $IP_ADDR" +echo "Directory Authority IP address: $TORDA_IP" + +echo "Address $IP_ADDR" >> /etc/tor/torrc +echo "DirAuthority orport=9001 no-v2 v3ident=15E09A6BE3619593076D8324A2E1DBEEAD4539CD $TORDA_IP:9030 03E942A4F12D85B2CF7CBA4E910F321AE98EC233" >> /etc/tor/torrc + +cat /etc/tor/torrc + +su -s /bin/sh debian-tor -c 'tor' diff --git a/resources/images/tor/tor-keys/authority_certificate b/resources/images/tor/tor-keys/authority_certificate new file mode 100644 index 000000000..4c4bcaad9 --- /dev/null +++ b/resources/images/tor/tor-keys/authority_certificate @@ -0,0 +1,45 @@ +dir-key-certificate-version 3 +fingerprint 15E09A6BE3619593076D8324A2E1DBEEAD4539CD +dir-key-published 2023-09-08 18:28:10 +dir-key-expires 2025-09-08 18:28:10 +dir-identity-key +-----BEGIN RSA PUBLIC KEY----- +MIIBigKCAYEAs1eKRRP+mWy2XpLbkY3dPkEfdKIfPMDDiG3o/Xu0c3fin1aJ32uG +BY3PGtwS2KQZHEJETjSaACq+2x9+fb4RV5bWhaptbt6l7dvDn15NbEklnkV3sx86 +VxiKqybUp5IQ3cNkM0AxUmQ1M/N+zzIe95T1XplaHVBSQN4xhJgYlDkDkNexIHpP +0uFxjO+2hro3cMRotjqR6xZw5OWKVJh5Is8jiSUs57xomeUy5HaUsADw46b88Ff9 +iVfTP975jzuFF7H0kKOxRpIZGRnfnuDdAtYXWHYXtIVwKBdSeHeK/N53++kxtGET +AcyWoHqO2xlvhtPbiKLHkwq0nNFFfwnhgJJSWHqYs6YI300pEMRHJMFWNsZwgwVE +dplmxnOLv9/TnJsD06d+kc05/JTfZXE/3JFs4rMci0jIhMlw+HtFfRwpDMjGI00u +VyADI0DMYTFWr+wFWrhs5N17BdQVSZUZlfxL5trZFdQpUZhxuKJowNLV1EdWzHFJ +srwV+C0LLWr/AgMBAAE= +-----END RSA PUBLIC KEY----- +dir-signing-key +-----BEGIN RSA PUBLIC KEY----- +MIIBCgKCAQEAyARJ1Nano6bZsTf3UplBhaP8BfrhvDLrJmmk8x4sAot0aHPG/eOH +qGak3y3CM1I+uxozyE58w9mBOuueUIzZelUZVjgg91dsqT5/3lIYEhB4riV29Of0 +AJeh2uibEVrv1ecXo5HYFKEcCHMRTvZaWIWSKjV6TPqPbpXhDBwIcZ+/tHpAml8h +CfGMFRYIEmisNL9xjoNU1R4Iyu07xQw85+xeMU/9UJgsXnvkqkAPbAhwxZq9/8yj +/9V4jcE5NR0KdDuPblEcD5ZNjMckUeTzuVDLgdsazOROD05zaTx8kP1UixJdon8Z +oJ/fsNWsgpzNv6ns8BIwwEAOnd7seXlmfQIDAQAB +-----END RSA PUBLIC KEY----- +dir-key-crosscert +-----BEGIN ID SIGNATURE----- +DJzp0QmipBz3IJ6zWziyBEkNBPA5J6QDhq2XDFNjdq2RYcOh1hZ1D089587wP3Xg +FoQehBDQccZCrmerEegdZ89dk+QXeNWrGGVpRwp7v+ok7lRPooC1IV3BIHcLs0BQ +fm7d3kYByVl1IaY7D9mpKG6COS/WOrKEnxp75YW18KEH7oIA60c395DfEkUZvDWt +a2ba2eBizM76cFUknQNlExWkw32DNtj1Axz9QyS6IQmyGxvlA1kWL6hiIPAV16NS +E5FcU/wQHL7a7tqAM3UkuLKT3nhcbdYGcaYpbzU/4jF61bzm7ETcqqL40EMQg5Hs +y3kcXZ4ItPFBn/LISp/zCg== +-----END ID SIGNATURE----- +dir-key-certification +-----BEGIN SIGNATURE----- +e9OQlThM7Y1jBIvZHYsm00ZcCR4L0JRGnzPtZhPtrczAi7dT7gdLhJZSYY5BM1VU +EB24flAJXeP03BtnOuFOURaazvW7J154sVHGQf96OyuCjSOjTlDNQLc6kNL1f0WD +bIXoJ0mPfRJzGX5NmGUa3KmW7/PgNO49VJSCuQQpBmC2qzQBPTCkATehJxCfiB8p +B6toi/ODKmXtFce1J0K9TRmAEIhmA5jzxqd3JISgGx0iP1iXmnMPHESXMS8QJ13e +U4t46NbobZDCAk7xkF/DNjuu0ZSV/IFg7EbB7f/qdIGvvK9bu7Esq5FoVr8sFZ50 +jxeNBEJgNk7Z/DwmNyBODqUfWVSnOydaqRCAxyHIbHGJGHLXKOOdym4sqOBe1O4+ +lyXjp/iIcrTN8rCoKFI9uT4DZj9rzzRv2tzQYl7Iqlt1fImaPN4PAnFpG/LOMrxe +v8S85DhkLpzl5uhojmVKAp810T9ege5MqXXGMDsisUtCyXDtqeQE6xqBDvydTm1m +-----END SIGNATURE----- diff --git a/resources/images/tor/tor-keys/authority_identity_key b/resources/images/tor/tor-keys/authority_identity_key new file mode 100644 index 000000000..e3b484bae --- /dev/null +++ b/resources/images/tor/tor-keys/authority_identity_key @@ -0,0 +1,41 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +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 +AO5X54JZORhV3fvT0QE= +-----END ENCRYPTED PRIVATE KEY----- diff --git a/resources/images/tor/tor-keys/authority_signing_key b/resources/images/tor/tor-keys/authority_signing_key new file mode 100644 index 000000000..7c4723395 --- /dev/null +++ b/resources/images/tor/tor-keys/authority_signing_key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAyARJ1Nano6bZsTf3UplBhaP8BfrhvDLrJmmk8x4sAot0aHPG +/eOHqGak3y3CM1I+uxozyE58w9mBOuueUIzZelUZVjgg91dsqT5/3lIYEhB4riV2 +9Of0AJeh2uibEVrv1ecXo5HYFKEcCHMRTvZaWIWSKjV6TPqPbpXhDBwIcZ+/tHpA +ml8hCfGMFRYIEmisNL9xjoNU1R4Iyu07xQw85+xeMU/9UJgsXnvkqkAPbAhwxZq9 +/8yj/9V4jcE5NR0KdDuPblEcD5ZNjMckUeTzuVDLgdsazOROD05zaTx8kP1UixJd +on8ZoJ/fsNWsgpzNv6ns8BIwwEAOnd7seXlmfQIDAQABAoIBAAm+YGdgfpb5EOfy +cUICP8AgzS1Fu7s/4sHYCdD4cmM8WRMhOBDUWvPamOOwtmIVeq4Bgy4Z7reEEBN8 +o2rKoGnhHTnHRF8wOyr30GGrmksU/NVaSLQlBuIEK6kURZY/7xOP7VBKpvNYUYXd +hHrA2Fqxb72j0HL8DhfbGspiJOIotHMHVKcPN/qb7pEPg9UOlapE8HjZf+G82l0f +CPo3tLSOVCQdn4y4DSFbC/KlwVmvcJYEdBfs/XdjbGN0ytEcLihFgoPKnLDqnl3U +jy5VVL0VO1yY9r7Vq9UmKPfWnwntAE3P5FZv/ZnYSIMNG0JYGKVzSOdco8X3qyTX +69I87LECgYEA/0zcKCzRDOu8gUPAQjttSKeFXoR0uJMonMwiGWm8mhsuB8B+Tzqn +vL3zPSdfjnhhQVmLhhVLOJddKcg8gWECmu3UB/hX9hm/J8sZ355/pdEs+zOkw6WB +MHWXZ+JsqCflGMQKB1GCvnA00IfQnHBC2K6oVkMhSjh6eWU8IrYpU20CgYEAyJCj +C7UOxGFbS/7814j3w0B3niHCzYa0td5aYo8AvT8t6fC6Suba9wqt0qfcGbDGXMpq +O9yL5+SbQohm/nd7brGQfOKzpgqjHhpXctRgvBGqSHpJ0yhKDQJ8L5cfW3JHiArh +fQ2YvgSc03Y3RIRmj4OVfV1647cbLdWAPCDsZVECgYEAhaSzfuhvCseAp15TD5jS +TX08SM0n2NNYKDSICSubykQ+JVq0BD+dPSVmZnXtBMSpjK8WZbtR5C8AWvXyDnw9 +A+NJ4l4zlaXGtksQoUn0YlYMqPdQ4gYKidaUypHx9VjlCcDdyxT1T0GntB3Uq3/s +zkcn4fhEPfkwy8md4EHhgkUCgYARxwg8tGq/q2V9QffFXwWfD+rKYHG05/jCmhfm +3ogRPjVipAzPMNE9znuDzY8r08hxVxu9fJoGDvRYHGEMsyiEskZ9W1bTI+Q7edhA +fGSqpuIyFGzQw6R0rMC3Myz7XRDMFTLRc9ATH7OK5tKVRysUE3S/rPaEkqldEayR +J9XsUQKBgQCBidpMXIxmL0DLaOX45h7l9QWK2g0l6zWhmE1XjJ+fBbkyE1jLcnaN +fPvWJEATyKn/7hbwe+ay+bp04U+jwK37XoRmHCCA+WdNlfkO8qGY+RDDVH62WKS9 +MC5pE3n4didM8kSm1OCDBHWEL3tUPoLs09zHauaqnGFy8KYAN7Y5JA== +-----END RSA PRIVATE KEY----- diff --git a/resources/images/tor/tor-keys/ed25519_master_id_public_key b/resources/images/tor/tor-keys/ed25519_master_id_public_key new file mode 100644 index 000000000..b05aa494f Binary files /dev/null and b/resources/images/tor/tor-keys/ed25519_master_id_public_key differ diff --git a/resources/images/tor/tor-keys/ed25519_master_id_secret_key b/resources/images/tor/tor-keys/ed25519_master_id_secret_key new file mode 100644 index 000000000..ccc1f8039 Binary files /dev/null and b/resources/images/tor/tor-keys/ed25519_master_id_secret_key differ diff --git a/resources/images/tor/tor-keys/ed25519_signing_cert b/resources/images/tor/tor-keys/ed25519_signing_cert new file mode 100644 index 000000000..b3736275e Binary files /dev/null and b/resources/images/tor/tor-keys/ed25519_signing_cert differ diff --git a/resources/images/tor/tor-keys/ed25519_signing_secret_key b/resources/images/tor/tor-keys/ed25519_signing_secret_key new file mode 100644 index 000000000..c65350151 Binary files /dev/null and b/resources/images/tor/tor-keys/ed25519_signing_secret_key differ diff --git a/resources/images/tor/tor-keys/secret_id_key b/resources/images/tor/tor-keys/secret_id_key new file mode 100644 index 000000000..ddc07c5df --- /dev/null +++ b/resources/images/tor/tor-keys/secret_id_key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQDBP2bFQwWtVRu6Rb4N3yGQylyDnX9IL6kVO/XzqOH2Jy4z/VtC +FXkOiNFi1xT/MzZYG952LDqJuP3WMtN/kUC+hd6ofVt4MCDAdYUtVJgCkSLkvbd+ +XwGmVS5FB+veqiLzim0Fx8CCuut9274TKezzZ6udWZMW8xk+eJFlcU9zqQIDAQAB +AoGAMWt9ZMUXFpTFWoWrbPC7LMQTlLUab+OAYiXLaFywLLsoXbNVOzkylDz5D0Xh +4MHADBhUc/QrpDzi7XxiCiWjYKP6Xa3v23ikro/5ALNKRLXfCj1ex/IW13f0Qj23 +Lr7qrthOSMREomJXXkYRdy3O9tMjXF2W0alTOztEFDZSe2ECQQDrRUiXI4RVUxOA +gdVWlpMNc1baPlXI24x3drf8D1V6sWuX1R5bJaE0YGIRyWrf4qINF4uoujfnVyib +TjI/FlgfAkEA0kZBlxLIlvuC2cUixYF/Jz+fDQEUxwuu105Okvz4x27gfm3aMChn +d7sfP+DnWnFhVFAiyKBtpWfV21Fh9eDbNwJAZP97KBbBKnfdeV9DHEbLngyTjmEQ +JofJh0dZuEVE5sTfcXC19V70Ey4FK6mRzcbW1lPzSl2WviM2dWVeQKLw9QJAY85r +JY0J3vhElJ8IsRyVQQjmsqJ3vT6jX5jQnN4sK2VKc1gq/z6+Vctgus5CoeA9JWrg +B8B2KtONY4tOZwmyowJBAIL8ya6RPyOlTh2AGUvSxV9VnchGDpHPAWfrBeVsOIWH +hFoO9c5Nw9gm/Elc/SqFQe9uLElsTGjqxKqyPUK+Zro= +-----END RSA PRIVATE KEY----- diff --git a/resources/images/tor/tor-keys/secret_onion_key b/resources/images/tor/tor-keys/secret_onion_key new file mode 100644 index 000000000..ebb57748b --- /dev/null +++ b/resources/images/tor/tor-keys/secret_onion_key @@ -0,0 +1,15 @@ +-----BEGIN RSA PRIVATE KEY----- +MIICWwIBAAKBgQCx44LveS/8Z72FSGfKK9gs+wDTKjYRcIuL87Vn7x7v1x9ilosj +wL5q7yNeHxKPW5V27Ax/rjMvsbZ92THsxMIQvYdpU8QlCO9QWJC8y0WS6nYZ42MP +JwUkV9ZF0Pf4HM7PNlW0VXps9c+szyCu9qK89QpLHtIheY1blxFckRrTnwIDAQAB +AoGAfDzENpHx5JtjbpGaA0XJzehjtBcX+egbXdwQhw0nEySwQ7+WX5r+olpv3g1f +fgXdhlfnhsjX8Ohx5sTpLE5ipfnGaF9y05V2GWaWv7TA1qzI2PNNrEKVz92lWF9d +Tx+m+mO5pCO67WxUdZ+RqCKZTie830SxAbTWQx25/W+6DQECQQDiySS7a4SIZYgP +qRerdftDCwxKhdQEoiyzEVVpnp32i2ZYuPr+YNvp9ImCajfSYQnrmAPH0yIrXhAS +UepAxwSBAkEAyM3cTsSzlYIknHbgRg8N8ZiVBWTgWKfZVn5D2pLOkyjezXhv3LNx +KKkynQFTF8mIqHT8VW8f76rzxlCQLT1IHwJAQJedmKv04YxZhmxYy4Mc/2lkJM2d +J3yxUoc7VovQ3emySs7U3iLkP+xgRf7Oy2LMGof/e6iM8OEnnrAqEi0dAQJAC6Sk +GY0ePJUHOmtKJcXJsTB/s4hd2cYhu/omRQ4uHCpKgO9yzQE6lnj5DlF9V+u/mMTv +vKRs3aCz8dPKCFV9UQJATrpPkJorFlp323nxn3bCIXu/0n2iFDhk/GZoZYIe7Zqt +12Puw3Gi6PlVRd67Cf9IVdXYBeQurOgj5ZGM8jpxOw== +-----END RSA PRIVATE KEY----- diff --git a/resources/images/tor/tor-keys/secret_onion_key_ntor b/resources/images/tor/tor-keys/secret_onion_key_ntor new file mode 100644 index 000000000..d1ed0e48d Binary files /dev/null and b/resources/images/tor/tor-keys/secret_onion_key_ntor differ diff --git a/resources/images/tor/torrc b/resources/images/tor/torrc new file mode 100644 index 000000000..e1b3bf675 --- /dev/null +++ b/resources/images/tor/torrc @@ -0,0 +1,34 @@ +# Common +Log err file /var/log/tor/debug.log +DataDirectory /home/debian-tor/.tor/ +RunAsDaemon 1 +ControlPort 9051 +CookieAuthentication 1 +CookieAuthFileGroupReadable 1 +DataDirectoryGroupReadable 1 +TestingTorNetwork 1 +ClientUseIPv6 0 +ClientUseIPv4 1 + +# Relay +DirAuthority orport=9001 no-v2 v3ident=15E09A6BE3619593076D8324A2E1DBEEAD4539CD 100.20.15.18:9030 03E942A4F12D85B2CF7CBA4E910F321AE98EC233 +AssumeReachable 1 +ExitRelay 0 + +# Reduce resource usage +CircuitPadding 0 +MaxMemInQueues 10 Mbytes +BridgeRecordUsageByCountry 0 +DirReqStatistics 0 +ExtraInfoStatistics 0 +HiddenServiceStatistics 0 +OverloadStatistics 0 +PaddingStatistics 0 +# BandwidthBurst 10 Mbytes +# BandwidthRate 10 Mbytes +ConstrainedSockets 1 +ConstrainedSockSize 8192 Bytes +NumEntryGuards 1 +NumDirectoryGuards 1 + +# `Address ` will be added by docker_entrypoint.sh diff --git a/resources/images/tor/torrc.da b/resources/images/tor/torrc.da new file mode 100644 index 000000000..de60776e9 --- /dev/null +++ b/resources/images/tor/torrc.da @@ -0,0 +1,40 @@ +# Common +Log info stdout +DataDirectory /home/debian-tor/.tor +RunAsDaemon 0 +ControlPort 9051 +ORPort 9001 IPv4Only +DataDirectoryGroupReadable 1 + +ExitPolicy accept *:* +TestingTorNetwork 1 +ClientUseIPv6 0 +ClientUseIPv4 1 + +# Relay +AssumeReachable 1 + +# Directory Authority +DirPort 9030 IPv4Only +AuthoritativeDirectory 1 +V3AuthoritativeDirectory 1 +PathsNeededToBuildCircuits 0.25 +TestingDirAuthVoteExit * +TestingDirAuthVoteHSDir * +V3AuthNIntervalsValid 2 +ContactInfo winston_churchill@warnet.dev + +# Reduce resource usage +MaxMemInQueues 200 Mbytes +BridgeRecordUsageByCountry 0 +DirReqStatistics 0 +ExtraInfoStatistics 0 +HiddenServiceStatistics 0 +OverloadStatistics 0 +PaddingStatistics 0 +ConstrainedSockets 1 +ConstrainedSockSize 8192 Bytes + +# `Address ` will be added by tor-entrypoint. +# `DirAuthority v3ident=... ` will be added by tor-entrypoint. + diff --git a/resources/images/tor/torrc.relay b/resources/images/tor/torrc.relay new file mode 100644 index 000000000..f3131e99f --- /dev/null +++ b/resources/images/tor/torrc.relay @@ -0,0 +1,36 @@ +# Common +Log info stdout +DataDirectory /home/debian-tor/.tor +RunAsDaemon 0 +DataDirectoryGroupReadable 1 + +# Bitcoin +SocksPort 9050 +ControlPort 9051 + +# Relay +ORPort 9001 IPv4Only +ExitPolicy accept *:* +TestingTorNetwork 1 +ClientUseIPv6 0 +ClientUseIPv4 1 +AssumeReachable 1 +PathsNeededToBuildCircuits 0.25 +TestingDirAuthVoteExit * +TestingDirAuthVoteHSDir * +V3AuthNIntervalsValid 2 + +# Reduce resource usage +MaxMemInQueues 64 Mbytes +BridgeRecordUsageByCountry 0 +DirReqStatistics 0 +ExtraInfoStatistics 0 +HiddenServiceStatistics 0 +OverloadStatistics 0 +PaddingStatistics 0 +ConstrainedSockets 1 +ConstrainedSockSize 8192 Bytes + +# `Address ` will be added by tor-entrypoint. +# `DirAuthority v3ident=... ` will be added by tor-entrypoint. + diff --git a/resources/plugins/tor/charts/torda/.helmignore b/resources/plugins/tor/charts/torda/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/resources/plugins/tor/charts/torda/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/resources/plugins/tor/charts/torda/Chart.yaml b/resources/plugins/tor/charts/torda/Chart.yaml new file mode 100644 index 000000000..d7688b1ee --- /dev/null +++ b/resources/plugins/tor/charts/torda/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: torda +description: A Helm chart to deploy a Tor Directory Authority +version: 0.1.0 +appVersion: "0.1.0" diff --git a/resources/plugins/tor/charts/torda/templates/NOTES.txt b/resources/plugins/tor/charts/torda/templates/NOTES.txt new file mode 100644 index 000000000..30a130268 --- /dev/null +++ b/resources/plugins/tor/charts/torda/templates/NOTES.txt @@ -0,0 +1 @@ +Thank you for installing TorDA. diff --git a/resources/plugins/tor/charts/torda/templates/_helpers.tpl b/resources/plugins/tor/charts/torda/templates/_helpers.tpl new file mode 100644 index 000000000..f255490c8 --- /dev/null +++ b/resources/plugins/tor/charts/torda/templates/_helpers.tpl @@ -0,0 +1,46 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "torda.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "torda.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Release.Name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "torda.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "torda.labels" -}} +helm.sh/chart: {{ include "torda.chart" . }} +{{ include "torda.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "torda.selectorLabels" -}} +app.kubernetes.io/name: {{ include "torda.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/resources/plugins/tor/charts/torda/templates/pod.yaml b/resources/plugins/tor/charts/torda/templates/pod.yaml new file mode 100644 index 000000000..4739dabc2 --- /dev/null +++ b/resources/plugins/tor/charts/torda/templates/pod.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "torda.fullname" . }} + labels: + {{- include "torda.labels" . | nindent 4 }} + app: {{ include "torda.fullname" . }} +spec: + containers: + - name: {{ .Values.name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: toror + containerPort: 9001 + protocol: TCP + - name: torda + containerPort: 9030 + protocol: TCP \ No newline at end of file diff --git a/resources/plugins/tor/charts/torda/templates/service.yaml b/resources/plugins/tor/charts/torda/templates/service.yaml new file mode 100644 index 000000000..8b920fc7b --- /dev/null +++ b/resources/plugins/tor/charts/torda/templates/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "torda.fullname" . }} + labels: + app: {{ include "torda.fullname" . }} +spec: + type: ClusterIP + ports: + - port: 9001 + targetPort: 9001 + protocol: TCP + name: toror + - port: 9030 + targetPort: 9030 + protocol: TCP + name: torda + selector: + {{- include "torda.selectorLabels" . | nindent 4 }} + diff --git a/resources/plugins/tor/charts/torda/values.yaml b/resources/plugins/tor/charts/torda/values.yaml new file mode 100644 index 000000000..3a9376f2e --- /dev/null +++ b/resources/plugins/tor/charts/torda/values.yaml @@ -0,0 +1,5 @@ +name: "torda" +image: + repository: "bitcoindevproject/tor-da" + tag: "latest" + pullPolicy: IfNotPresent diff --git a/resources/plugins/tor/plugin.py b/resources/plugins/tor/plugin.py new file mode 100644 index 000000000..cfc0803a2 --- /dev/null +++ b/resources/plugins/tor/plugin.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 + +from pathlib import Path + +from warnet.process import run_command + +if __name__ == "__main__": + command = f"helm upgrade --install torda {Path(__file__).parent / 'charts' / 'torda'}" + run_command(command) diff --git a/src/warnet/k8s.py b/src/warnet/k8s.py index d5da36dc4..528dfe34f 100644 --- a/src/warnet/k8s.py +++ b/src/warnet/k8s.py @@ -347,7 +347,9 @@ def get_ingress_ip_or_host(): return None -def pod_log(pod_name, container_name=None, follow=False, namespace: Optional[str] = None): +def pod_log( + pod_name, container_name=None, follow=False, namespace: Optional[str] = None, tail_lines=None +): namespace = get_default_namespace_or(namespace) sclient = get_static_client() @@ -358,6 +360,7 @@ def pod_log(pod_name, container_name=None, follow=False, namespace: Optional[str container=container_name, follow=follow, _preload_content=False, + tail_lines=tail_lines, ) except ApiException as e: raise Exception(json.loads(e.body.decode("utf-8"))["message"]) from None diff --git a/test/data/onion/network.yaml b/test/data/onion/network.yaml new file mode 100644 index 000000000..be4aa77dc --- /dev/null +++ b/test/data/onion/network.yaml @@ -0,0 +1,23 @@ +caddy: + enabled: false +fork_observer: + configQueryInterval: 20 + enabled: false +nodes: +- image: + tag: '29.0' + name: tank-0000 +- image: + tag: '29.0' + name: tank-0001 +- image: + tag: '29.0' + name: tank-0002 +- image: + tag: '29.0' + name: tank-0003 + +plugins: + preDeploy: + tor: + entrypoint: "../../../resources/plugins/tor" \ No newline at end of file diff --git a/test/data/onion/node-defaults.yaml b/test/data/onion/node-defaults.yaml new file mode 100644 index 000000000..9038774c6 --- /dev/null +++ b/test/data/onion/node-defaults.yaml @@ -0,0 +1,22 @@ +chain: regtest +image: + repository: bitcoindevproject/bitcoin + pullPolicy: IfNotPresent +defaultConfig: | + debug=net + debug=tor + proxy=127.0.0.1:9050 + listen=1 + onlynet=onion + torcontrol=127.0.0.1:9051 + +collectLogs: false +metricsExport: false + +extraContainers: + - name: tor + image: bitcoindevproject/tor-relay:latest + ports: + - name: toror + containerPort: 9001 + protocol: TCP \ No newline at end of file diff --git a/test/onion_test.py b/test/onion_test.py new file mode 100755 index 000000000..75ec6b049 --- /dev/null +++ b/test/onion_test.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 + +import json +import os +from pathlib import Path + +from test_base import TestBase + +from warnet.k8s import pod_log + + +class OnionTest(TestBase): + def __init__(self): + super().__init__() + self.network_dir = Path(os.path.dirname(__file__)) / "data" / "onion" + + def run_test(self): + try: + self.setup_network() + self.check_tor() + finally: + self.cleanup() + + def setup_network(self): + self.log.info("Setting up network") + self.log.info(self.warnet(f"deploy {self.network_dir}")) + self.wait_for_all_tanks_status(target="running") + + def check_tor(self): + onions = {"tank-0001": None, "tank-0002": None} + + def get_onions(): + peers = ["tank-0001", "tank-0002"] + for tank in peers: + if not onions[tank]: + self.log.info(f"Getting local onion address from {tank}...") + info = json.loads(self.warnet(f"bitcoin rpc {tank} getnetworkinfo")) + for addr in info["localaddresses"]: + if "onion" in addr["address"]: + onions[tank] = addr["address"] + self.log.info(f" ... got: {addr['address']}") + return all(onions[tank] for tank in peers) + + self.wait_for_predicate(get_onions) + + self.log.info("Adding 1 block") + self.warnet("bitcoin rpc tank-0001 createwallet miner") + self.warnet("bitcoin rpc tank-0001 -generate 1") + + self.log.info("Adding connections via onion: 0000->0001->0002") + self.warnet(f"bitcoin rpc tank-0000 addnode {onions['tank-0001']} add") + self.warnet(f"bitcoin rpc tank-0001 addnode {onions['tank-0002']} add") + + def onion_connect(): + peers = json.loads(self.warnet("bitcoin rpc tank-0001 getpeerinfo")) + self.log.info("\n") + self.log.info("Waiting for tank-0001 to have at least two onion peers:") + self.log.info(json.dumps(peers, indent=2)) + if len(peers) >= 2: + for peer in peers: + assert peer["network"] == "onion" + return True + else: + self.log.info("tank-0001 tor log tail:") + stream = pod_log( + pod_name="tank-0001", + container_name="tor", + namespace="default", + follow=False, + tail_lines=5, + ) + for line in stream: + msg = line.decode("utf-8").rstrip() + msg = msg.split("]") + self.log.info(msg[-1]) + + self.wait_for_predicate(onion_connect, timeout=20 * 60) + + +if __name__ == "__main__": + test = OnionTest() + test.run_test()