Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directory node service setup Tor permission issues #1729

Open
techy2 opened this issue Sep 17, 2024 · 27 comments
Open

Directory node service setup Tor permission issues #1729

techy2 opened this issue Sep 17, 2024 · 27 comments

Comments

@techy2
Copy link

techy2 commented Sep 17, 2024

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
Copy link
Author

techy2 commented Oct 27, 2024

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
Copy link
Member

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
Copy link
Author

techy2 commented Nov 3, 2024

"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
Copy link
Member

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
Copy link
Author

techy2 commented Nov 4, 2024

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
Copy link
Author

techy2 commented Nov 4, 2024

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

@techy2
Copy link
Author

techy2 commented Nov 4, 2024

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
Copy link
Member

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
Copy link
Author

techy2 commented Nov 4, 2024

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
Copy link
Author

techy2 commented Nov 4, 2024

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

@kristapsk
Copy link
Member

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
Copy link
Author

techy2 commented Nov 4, 2024

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
Copy link
Member

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
Copy link
Author

techy2 commented Nov 4, 2024

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
Copy link
Member

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
Copy link
Author

techy2 commented Nov 4, 2024

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
Copy link
Author

techy2 commented Nov 4, 2024

port 27183 is open

@techy2
Copy link
Author

techy2 commented Nov 4, 2024

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
Copy link
Member

kristapsk commented Nov 4, 2024

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
Copy link
Author

techy2 commented Nov 5, 2024

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
Copy link
Author

techy2 commented Nov 5, 2024

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
Copy link
Author

techy2 commented Nov 5, 2024

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
Copy link
Author

techy2 commented Nov 5, 2024

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
Copy link
Author

techy2 commented Nov 5, 2024

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
Copy link
Author

techy2 commented Nov 5, 2024

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

@overcoin
Copy link

overcoin commented Nov 6, 2024

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
Copy link
Author

techy2 commented Nov 14, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants