JoinMarket-Org / joinmarket-clientserver

Bitcoin CoinJoin implementation with incentive structure to convince people to take part
GNU General Public License v3.0
729 stars 179 forks source link

Directory node service setup Tor permission issues #1729

Open techy2 opened 2 months ago

techy2 commented 2 months ago

lubuntu 22.04.05 LTS joinmarket-clientserver 9.11 tor 4.6.10

I am trying to setup a directory node on a dedicated host running joinmarket-clientserver and Tor

Following the directions in the joinmarket docs I have added the user 'johndoe' to debian-tor group and set hidden_service_dir to /home/johndoe/dirnode/

Tor fails to create dirnode

If is set hidden_service to tor's preferred /var/lib/tor/hidden_service/

the directory is created with the appropriate contents, however start-dn.py can not access that directory

Workarounds I have tried include adding a line to 1 apparmor.d/system.tor /home/johndoe/dirnode** rwk

2 /lib/systemd/system/tor@defaults ReadWriteDirectories=-/home/johndoe/dirnode

3 use /opt/tor as base for hidden service, Tor can not write there

all of the above with various file ownership of either johndoe.johndoe, debian-tor.debian-tor

This problem is obviously solvable as there are many directory nodes presuemably some on Linux + ubuntu. I'm just missing something

documentation, chat searches, etc... offer no clues other than what I've tried above

Perhaps when this is resolved we can update the documentation to be more specific on how to setup a directory node. Suggested updates: 1 how to setup permissions and directories for torrc/joinmarket.cfg 2 which port to designate for HiddenServicePort ??? 127.0.0.1:27183 3 what NAT port to open on firewall for return traffic for tor 80, 443, 5222 ??? when host is on a local network

I will gladly document all of this and submit as a PR once it is sorted out.

techy2 commented 3 weeks ago

5 weeks, no comments. Is the project still active? I have a dedicated Linux micro box in a data center to run a directory node. Anyone help with this issue?

kristapsk commented 2 weeks ago

Project is alive, just people busy with other stuff, I recently often miss GitHub notifications, there are too much of them.

the directory is created with the appropriate contents, however start-dn.py can not access that directory

What is exact error message / output?

techy2 commented 2 weeks ago

"permission denied" I'm a long time linux user and this one has me stumped. I've tried every combination of permission and directories and still no-go I think this has to do with the so-called security improvements in ubuntu 22.04 On start, tor gets jailed as debian-tor and even though my users is part of that group, the permission restrictions (directory must be 0700) prevent access and since they can't be changed because it makes tor unhappy. there does not seem to be a solution that I can see. Docs are not help. I've google searched and tried all the solutions found, + moved the tor-jm directory to different places, etc.. Nada My setup is a virtual box running ubuntu 22.04 with only tor and joinmarket as active programs. I have run jm mixer this way with no difficulty, directory mode is resisting my efforts

kristapsk commented 2 weeks ago

Could you paste whole output of start-dn.py script?

My guess is that it's permission denied when trying to access Tor control. Do you have these in your /etc/tor/torrc?

ControlPort 9051
CookieAuthentication 1
CookieAuthFileGroupReadable 1
techy2 commented 2 weeks ago

missing CookieAuthFileGroupReadable 1 NOTE: not in sample config file, not mentioned in docs adding it did not make a difference

torrc ControlPort 9051 CookieAuthentication 1 CookieAuthFileGroupReadable 1 HiddenServiceDir /var/lib/tor/hidden_service/ HiddenServicePort 80 127.0.0.1:80

joinmarket.cfg says hidden_service_dir = /var/lib/tor/hidden_service

starting from scripts directory start-dn.sh as user, no jmvenv E!/usr/bin/env bash

shellcheck source=/dev/null

cd "$(dirname "$0")/.." && \ source jmvenv/bin/activate && \ cd scripts && \ python3 start-dn.py 'hola' --datadir=/var/lib/tor/hidden_service ------- response User data location: /var/lib/tor/hidden_service Traceback (most recent call last): File "/home/michael/joinmarket-clientserver/scripts/start-dn.py", line 107, in directory_node_startup() File "/home/michael/joinmarket-clientserver/scripts/start-dn.py", line 85, in directory_node_startup load_program_config(config_path=options["datadir"], bs="no-blockchain") File "/home/michael/joinmarket-clientserver/jmvenv/lib/python3.10/site-packages/jmclient/configure.py", line 706, in load_program_config os.makedirs(global_singleton.datadir) File "/usr/lib/python3.10/os.py", line 225, in makedirs mkdir(name, mode) PermissionError: [Errno 13] Permission denied: '/var/lib/tor/hidden_service'

start from scripts directory start-dn.py, jmvenv activated ./start-dn.py 'hola' --datadir=/var/lib/tor/hidden_service ------------------- response ser data location: /var/lib/tor/hidden_service Traceback (most recent call last): File "/home/michael/joinmarket-clientserver/scripts/./start-dn.py", line 107, in directory_node_startup() File "/home/michael/joinmarket-clientserver/scripts/./start-dn.py", line 85, in directory_node_startup load_program_config(config_path=options["datadir"], bs="no-blockchain") File "/home/michael/joinmarket-clientserver/jmvenv/lib/python3.10/site-packages/jmclient/configure.py", line 706, in load_program_config os.makedirs(global_singleton.datadir) File "/usr/lib/python3.10/os.py", line 225, in makedirs mkdir(name, mode) PermissionError: [Errno 13] Permission denied: '/var/lib/tor/hidden_service'

techy2 commented 2 weeks ago

directory permissions drwx--S--- 3 debian-tor debian-tor 4096 Nov 4 09:19 /var/lib/tor/hidden_service

techy2 commented 2 weeks ago

I suspect this has something to do with 'apparmor' but I am totally in the dark on how that works except that it seems to break lots of things like SELinux does.

It is not helpful when your server is so secure that it will not run, sigh...

kristapsk commented 2 weeks ago

python3 start-dn.py 'hola' --datadir=/var/lib/tor/hidden_service

This is the problem. You should not specify --datadir. It's for storing JoinMarket data, unrelated to Tor onion (hidden) service. It will default to ~/.joinmarket/.

techy2 commented 2 weeks ago

ok, so I removed the --datadir =, started, got error KeyError: 'directory_nodes' made a guess that it was from not having the hostname from the hidden directory .... bad guess since I added that into the joinmarket.cfg file, restarted and got the same error

techy2 commented 2 weeks ago

.joinmarket is still empty except for the cfg file and the empty directories for all else

kristapsk commented 2 weeks ago

ok, so I removed the --datadir =, started, got error KeyError: 'directory_nodes' made a guess that it was from not having the hostname from the hidden directory .... bad guess since I added that into the joinmarket.cfg file, restarted and got the same error

It would be helpful if you would paste full output, then I can see which line of code is throwing error and possibly other useful info, KeyError is just Python error.

.joinmarket is still empty except for the cfg file and the empty directories for all else

That's ok, I don't think anything else than configuration file should be there for directory node.

techy2 commented 2 weeks ago

Traceback (most recent call last): File "/home/johndoe/joinmarket-clientserver/scripts/./start-dn.py", line 107, in directory_node_startup() File "/home/johndoe/joinmarket-clientserver/scripts/./start-dn.py", line 89, in directory_node_startup node_location = mchan_config["directory_nodes"] KeyError: 'directory_nodes'

without the 'hola' it complains: start-dn.py: error: One argument required: string to be published in the MOTD of the directory node.

kristapsk commented 2 weeks ago

See comments in start-dn.py script:

    # note: you *must* only have the onionmc, no IRC, for this to work,
    # and of course you must only have your own d-node configured here:

Basically, you should comment out or delete all [MESSAGING...] sections in joinmarket.cfg, except [MESSAGING:onion].

techy2 commented 2 weeks ago

I deleted all the MESSAGE sections except [MESSAGING:onion], get the exact same error as before, with and without the 'hostname'

From your last comment I suspect there is a lot more from the default config file entries that should be removed here is the config file as it is now

[DAEMON] no_daemon = 1 daemon_host = localhost use_ssl = false

[BLOCKCHAIN] blockchain_source = bitcoin-rpc network = mainnet rpc_port = 8332 rpc_user = xxxxxxxx rpc_password = xxxxxxxxx rpc_wallet_file = jm_wallet

[MESSAGING:onion] type = onion socks5_host = localhost socks5_port = 9050 tor_control_host = localhost tor_control_port = 9051 onion_serving_host = 127.0.0.1 onion_serving_port = 8080 hidden_service_dir = /var/lib/tor/hidden_service regtest_count = 0,0

[LOGGING] console_log_level = INFO color = true

[TIMEOUT] maker_timeout_sec = 60 unconfirm_timeout_sec = 180 confirm_timeout_hours = 6

[POLICY] segwit = true native = true merge_algorithm = greediest gaplimit = 6 wallet_caching_disabled = false tx_fees = 10 tx_fees_factor = 0.2 absurd_fee_per_kb = 350000 max_sweep_fee_change = 0.8 tx_broadcast = random-peer minimum_makers = 4 max_sats_freeze_reuse = -1 interest_rate = 0.015 bondless_makers_allowance = 0.125 bond_value_exponent = 1.3 taker_utxo_retries = 3 taker_utxo_age = 5 taker_utxo_amtpercent = 20 accept_commitment_broadcasts = 1 commit_file_location = cmtdata/commitments.json commitment_list_location = cmtdata/commitmentlist

[PAYJOIN] payjoin_version = 1 disable_output_substitution = 0 max_additional_fee_contribution = default min_fee_rate = 1.1 onion_socks5_host = localhost onion_socks5_port = 9050 tor_control_host = localhost tor_control_port = 9051 onion_serving_host = 127.0.0.1 onion_serving_port = 8082 hidden_service_ssl = false

[YIELDGENERATOR] ordertype = reloffer cjfee_a = 500 cjfee_r = 0.0000003 cjfee_factor = 0.1 txfee_contribution = 0 txfee_contribution_factor = 0.3 minsize = 10000 size_factor = 0.1

[SNICKER] enabled = false lowest_net_gain = 0 servers = cn5lfwvrswicuxn3gjsxoved6l2gu5hdvwy5l3ev7kg6j7lbji2k7hqd.onion, polling_interval_minutes = 60

[GUI] max_mix_depth = 5

kristapsk commented 2 weeks ago

You have missing directory_nodes= setting under [MESSAGING:onion] that should be set to onion hostname of your node (cat /var/lib/tor/hidden_service/hostname).

As per start-dn.py comment mentioned above (yes, that's the only documentation we have for this right now):

    # note: you *must* only have the onionmc, no IRC, for this to work,
    # and of course you must only have your own d-node configured here:
techy2 commented 2 weeks ago

cat hostname bfd2pv2zfa2uwuiana2oylbvorxqdtuboh2qcpac4gsbmm3bourdr7id.onion

user data location: /home/johndoe/.joinmarket/ 2024-11-04 12:34:12,822 [INFO] starting directory node 2024-11-04 12:34:12,823 [INFO] Joinmarket daemon listening on port 27183 2024-11-04 12:34:12,829 [ERROR] Failed to load directory nodes: InvalidLocationStringError('bfd2pv2zfa2uwuiana2oylbvorxqdtuboh2qcpac4gsbmm3bourdr7id.onion')

techy2 commented 2 weeks ago

port 27183 is open

techy2 commented 2 weeks ago

getting closer? added port 5222 to hostname string

ser data location: /home/johndoe/.joinmarket/ 2024-11-04 14:25:41,137 [INFO] starting directory node 2024-11-04 14:25:41,138 [INFO] Joinmarket daemon listening on port 27183 2024-11-04 14:25:41,143 [INFO] Attempting to start onion service on port: 5222 ... Unhandled error in Deferred:

Traceback (most recent call last): --- --- File "/home/johndoe/joinmarket-clientserver/jmvenv/lib/python3.10/site-packages/txtorcon/endpoints.py", line 651, in listen self.hiddenservice = yield create_d File "/home/johndoe/joinmarket-clientserver/jmvenv/lib/python3.10/site-packages/txtorcon/onion.py", line 253, in create yield config.save() txtorcon.torcontrolprotocol.TorProtocolError: 513 Unacceptable option value: Failed to configure rendezvous options. See logs for details.

ports 5222, 27183 are open on the firewall appliance and direct back to the ip of vm host running tor+joinmarket

kristapsk commented 2 weeks ago

getting closer? added port 5222 to hostname string

Right, I think port had to be specified.

txtorcon.torcontrolprotocol.TorProtocolError: 513 Unacceptable option value: Failed to configure rendezvous options. See logs for details.

I would suggest looking at Tor logs.

ports 5222, 27183 are open on the firewall appliance and direct back to the ip of vm host running tor+joinmarket

Ports should not be opened for 127.0.0.1 (localhost), by opening ports to public you just dox your directory node. Don't do it!

techy2 commented 2 weeks ago

127.0.0.1 is not open to outside what is open is this internet IP -> firewall appiance -> 192.168.x.x VM host lan address

techy2 commented 2 weeks ago

This is the torrc

Log debug file /var/log/tor/debug.log ControlPort 9051 CookieAuthentication 1 CookieAuthFileGroupReadable 1 HiddenServiceDir /var/lib/tor/hidden_service/ HiddenServicePort 80 127.0.0.1:80

techy2 commented 2 weeks ago

no errors in the log, tor seems busy with a lot of things but non related to joinmarket when it is started and gets stuck

techy2 commented 2 weeks ago

joinmarket LOGGING set to debug, nothing in log, it is empty

Just a thought. The unacceptable option error, does not stop the directory node, it is just published to stdout or stderr?? there are no lines in the tor log other than [debug] and they do not appear to be related to the error, they just look like normal tor running when joinmarket is not present. The [info]lines are fe w and also the same as when tor runs without joinmarket. Perhaps the node is running correctly. How to test?

techy2 commented 2 weeks ago

looking at the error, line 253 is a call to onion.py", line 253, in create yield config.save() The error message is all the debug info available, It appears this call fails but I am not familiar with python, I'm a C C++ perl guy

techy2 commented 2 weeks ago

attempting to connect via telnet to external IP either port 27123, 5222 from another network center gives connection refused

overcoin commented 2 weeks ago

https://github.com/bitcoin/bitcoin/blob/master/doc/tor.md

Privacy recommendations

Do not add anything but Bitcoin Core ports to the onion service created in section 3. If you run a web service too, create a new onion service for that. Otherwise it is trivial to link them, which may reduce privacy. Onion services created automatically (as in section 2) always have only one port open.

/etc/tor/torrc for control port and authcookie

ExitPolicy reject *:*
SocksPort 9050
ControlPort 9051
CookieAuthentication 1
CookieAuthFile /run/tor/control.authcookie
CookieAuthFileGroupReadable 1
DataDirectoryGroupReadable 1
HiddenServiceDir /var/lib/tor/jm-dn-service/
HiddenServicePort 5222 127.0.0.1:5222

stat -c '%G' /run/tor/control.authcookie should print "debian-tor"

techy2 commented 1 week ago

I have all of this set up per all the comments above, cookie auth ->debian-tor, ports, etc...Still getting permission denied on /var/lib/tor/hidden_service

Could someone that is actually running a directory node please post their joinmarket.cfg and torrc files so I can see what a working directory node looks like. Perhaps that can be added to a FAQ