Namecoin Integration in Whonix -- Technical Discussion

This thread is for technical discussion of how Namecoin might be integrated into Whonix. Conceptual / high level discussion (e.g. “Should Namecoin integration happen in Whonix?”) should go in Namecoin Integration in Whonix instead (see that thread for background info). (I’m splitting the discussion into 2 threads at Patrick’s request.)

2 Likes

A couple of starting points for discussion:

We’re working on getting the Tor-relevant Namecoin components packaged in Debian, but since Bullseye has (AFAIK) already reached its freeze date, I don’t think it’s possible for us to get Namecoin into Bullseye. Getting into Bullseye-Backports may be feasible though, depending on how the Debian folks feel about it (I’m not certain what their policies are on getting into Backports). However, it should be noted that most of the Tor-relevant Namecoin components are available as either an AppImage (e.g. Electrum-NMC) or a statically linked Go binary (e.g. ncprop279). (I think both the AppImage and the Go binaries build reproducibly, though the build reproducibility is not routinely audited yet [1].) I’m curious whether it would be feasible to get those components into binaries-freedom, or if it would be strongly preferred to get packaged in Debian itself (which might incur some delay).

Namecoin uses StemNS (our fork of meejah’s TorNS, which adds some security features like stream isolation support) to intercept STREAM events from the Tor control port, and perform resolution on them via the REDIRECTSTREAM command. This raises some questions about what the best approach is to running this under Whonix. The REDIRECTSTREAM command is somewhat dangerous if not contained. I’m not sure of the best way to contain it with onion-grater… perhaps there’s a way for onion-grater to block StemNS from redirecting any streams that don’t initially have a .bit (Namecoin) domain as their destination. Care would also need to be taken to make sure that multiple Whonix-Workstation VM’s don’t interfere with each other. StemNS should, I think, be safe to run in its own Workstation VM, and handle all the Namecoin resolution for all other Workstation VM’s that are hooked up to that Gateway, but this may be unreasonable from a resource usage perspective (a lot of users may not want to run an extra Workstation VM just to use Namecoin). The core security considerations here are (1) we don’t want multiple StemNS instances to try to handle the same STREAM event, and (2) if a StemNS instance is in a compromised Workstation VM, then that could compromise whatever streams in other Workstation VM’s are resolved by that compromised StemNS.

Probably plenty of other technical discussion points to be had, but I’ll start with those. Thoughts?

[1] I gave a presentation at a recent Tor Demo Day on using Cirrus CI as a reproducible build co-signer for Tor Browser’s RBM build system; this work should result in an improvement with respect to regular auditing of build reproducibility of anything that uses RBM, which includes Namecoin’s Go binaries.

1 Like

This is mostly about resolving .bit inside Whonix? Or and/or namecoin wallet?

To resolve .bit is installation of namecoind required? Would namecoind (or anything) need to download a ~ 300 GB blockchain? What are the disk space requirements? Or can ncdns be used standalone?

A separate VM for namecoin only seems overkill indeed at this point.

Realistic to get namecoin integrated into Tor instead the browser (Tor Browser)?

How to start simpler…? Using namecoin on Debian? The web search results for that aren’t great.

I am asking because perhaps namecoin integration would be easier if done on Whonix-Gateway.

Would also be interesting to see how Tails integration would go. (Tails used to have monkeysphere and i2p integration. Wondering if that indicates openness for namecoin integration.)

Ideally this could be implemented as an add-on package. That would be cleaner. This is even unspecific to Whonix. Also for users of Debian it would be much better if they could “sudo apt install namecoin”.

(The request for being an add-on package is unrelated to Namecoin Integration in Whonix, opt-in vs default installation.)

Using ncdns requires modification of system DNS configuration file /etc/resolv.conf as far as I understand. For sake of being an add-on package, for better usability, could you please support something like /etc/resolv.conf.d? I think that requires package resolvconf. Long ago since I looked into that. Avoided for lower complexity. Maybe now would be a time to reconsider that.

By supporting dropping a snippet into /etc/resolv.conf.d things would look much better. In my very strong opinion, Debian (and similar for other Linux distribution) installation experience needs to boil down to a “sudo apt install namecoin” level of simplicity. An “oh but you need to edit /etc/resolv.conf” would be a major usability issue.

Needing to edit a configuration file such as /etc/resolv.conf is bad. Not exactly but Modifying Default Configuration of Third Party Packages is realted. I can make a stronger case for that if needed.

ncdns supports using Tor’s SocksPort? (If ncdns isn’t needed / supposed for this use case then might question might not make sense / not be important.)

Lots of good questions here.

Resolving .bit inside Whonix is most interesting to me, and is the intended purpose of this thread. I would not be opposed to having a Namecoin wallet in Whonix, but it’s not why I started the thread.

Namecoin Core (the daemon version of which is called namecoind) is one option, but not the only option; Electrum-NMC is an option as well. The Tor Browser developers prefer Electrum-NMC due to its lower bandwidth requirements (as per your next question).

If Namecoin Core is used, it would need to download the Namecoin blockchain, which is ~4.6 GiB. Much smaller than the Bitcoin blockchain, but still significant. Electrum-NMC only downloads recent block headers (specifically, headers that are after the checkpoint). A chunk of 2016 headers typically uses ~3.5 MB of download bandwidth (we think this can be optimized down to ~1.4 MB if needed). We typically include a checkpoint when tagging a release that is circa 2 chunks behind the release date. So that’s about 7 MB of download bandwidth on the first run. A new chunk of ~3.5 MB accumulates approximately every 2 weeks, which users will need to download in order to stay synced. So, the bandwidth usage of Electrum-NMC is pretty low. My guess is that Whonix would prefer Electrum-NMC over Namecoin Core for this reason (but this is up to you).

Namecoin Core supports pruning. Most of the storage used by Namecoin Core when pruning is enabled is in the UTXO database (i.e. the chainstate folder). That folder on my Namecoin Core node is currently 806.1 MiB.

The Electrum-NMC data folder in my regularly-used Tor Browser Nightly instance is 41.5 MiB (most of which is the blockchain headers file). However, I noticed that if I compress that folder via Dolphin’s default tar.gz settings, it compresses quite well down to 3.0 MiB, which suggests that the 41.5 MiB figure could maybe be significantly reduced if you consider it too high.

(Again, up to you whether you prefer Namecoin Core or Electrum-NMC, only one of them is required.)

ncdns is buildable as either an executable or a library. The executable is intended for integrating .bit into a standard DNS recursive resolver like Unbound. In Whonix’s case, that doesn’t make much sense, since DNS resolution in Whonix is usually done by Tor. ncdns as a library is used by ncprop279, which is a Prop279 plugin that (when combined with StemNS, which interfaces with the Tor control port) allows .bit resolution with Tor. I suspect that ncprop279 will make more sense for Whonix than ncdns as an executable. Either way, they need a Namecoin client (either Namecoin Core or Electrum-NMC) to be present.

I concur. Maybe reasonable to support as an optional configuration for users with unusually strong security requirements, in the distant future, but probably not a default recommended configuration, and probably not the first step.

There’s almost no code in the Tor Browser Nightly integration that depends on Firefox. Pretty much everything is interfacing with Tor rather than Firefox. It happened to end up in the Tor Browser packaging (as opposed to the Tor daemon packaging) for UX and practical reasons, but those reasons don’t matter for Whonix.

It should be possible to do this entirely on the Gateway, but I would be concerned about the risk of proxy leaks from Electrum-NMC. I did some brief testing of Electrum-NMC for proxy leaks and did not find any (and I assume there’s been significant testing of upstream Electrum for proxy leaks since it’s used in Tails and Whonix), but if there were such a proxy leak, having Electrum-NMC running on the Gateway would be a deanonymization hazard, since the network traffic it issues reveals which names are being looked up.

Interesting, I wasn’t aware that Tails used to support Monkeysphere and I2P. I intend to reach out to the Tails devs as well about this; I decided to reach out to Whonix first since Whonix is my daily driver and I’ve submitted patches to you before, whereas my familiarity with the Tails ecosystem is pretty minimal.

Parts of this could definitely be done as a generic Debian package (and I would definitely be in favor of that), but the parts that integrate with the Tor control port may need special consideration with respect to Whonix given the unique security-by-isolation requirements of Whonix.

This is definitely relevant to non-Tor usage, e.g. Kicksecure. For Whonix (and other Tor use cases), messing with resolv.conf is not needed; resolve operations are hooked via the Tor control port, not the system DNS resolver.

For non-Tor usage (e.g. Kicksecure or standard Debian), the typical setup would not involve ncdns modifying resolv.conf; rather, resolv.conf would be modified by a recursive resolver package (e.g. Unbound), and ncdns would place a file in unbound.conf.d. AFAIK this works fine right now; unbound.conf.d globbing is supported by Unbound, and the ncdns docs instruct to do it that way. (Presumably as we get ncdns packaged in Debian, the package will do that automatically.)

ncprop279 (as well as ncdns) doesn’t generate external network traffic; it only passes requests to Electrum-NMC (or Namecoin Core). Electrum-NMC produces external network traffic per lookup (and when downloading block headers), and supports Tor’s SOCKS port (with stream isolation via SOCKS username/password). Namecoin Core (if you decided to use it instead of Electrum-NMC) produces external network traffic when downloading the blockchain (and also supports Tor’s SOCKS port, with stream isolation via SOCKS username/password), but does not produce any network traffic on lookup operations (since Namecoin Core is able to cache the name database locally because it has the full blockchain available).

1 Like

We don’t have a great rough implementation idea yet.

  • Dedicated VM → overkill.
  • Namecoin on gateway → leak risk. (But not higher than running in Tails.)
  • Namecoin using ControlPort in workstation → difficult ControlPort filtering.

Why not hook into system the DNS resolver too?

  • No dedicated namecoin VM required.
  • No ControlPort filtering required.
  • No leak risks.

Disadvantage: not stream isolated. Well, but system default DNS isn’t either.

(And before someone quotes me on that and asks (much) later what that is about, see Stream Isolation)

Using that method, even the generic namecoin Debian package would work out of the box inside Whonix.

(With a small limitation I am happy to work on. Whonix might need to change to resolvconf of unbound (?) to support /etc/resolv.conf configuration drop-ins.

Why unbound? I haven’t looked into it. Is that a strong dependency? Or would resolvconf work too in principle? I imagine with resolvconf there could be two snippets.

Non-Tor use case:

    1. namecoin (virtual) IP drop-in
    1. real DNS drop-in

Whonix use case:

    1. namecoin (virtual) IP
    1. Whonix-Gateway IP

Once the first (1) resolver (namecoin) noticed “not a .bit domain” it says “no” and the next entry (2) takes over.


Above might work well for system DNS with namecoin support inside Whonix?

But if Tor Browser enables namecoin by default inside Whonix that could be an issue? Because Tor Browser expects to talk to talk to a Tor that understands namecoin and stream isolation? If Tor Browser ships its own namecoin, I guess there is no way around the control port filtering anyhow without having limited functionality inside a Tor Browser that runs inside Whonix-Workstation?

Pondering this more… the primary risk of proxy leaks is from Electrum-NMC, since it’s the only component that intentionally opens external network connections. (StemNS only connects to the Tor control port, and ncprop279 only connects to the Electrum-NMC RPC port. StemNS communicates with ncprop279 via stdin/stdout.) However, Electrum-NMC doesn’t need to be in the same VM as StemNS+ncprop279.

So, an approach we could take here is that StemNS and ncprop279 run on the Gateway, and Electrum-NMC runs on the Workstation. StemNS will detect which IP the STREAM event came from (i.e. the IP of the Workstation), and can instruct ncprop279 to connect to Electrum-NMC on that IP. This would require me to make some minor patches to StemNS (and maybe ncprop279), but that’s not a problem for me.

Hmm, this point may benefit from some more pondering too. As far as I can tell, the main threats we need to prevent are:

  1. Calling REDIRECTSTREAM on a stream where the Target doesn’t have a .bit suffix. (Prevents a Namecoin vulnerability from affecting non-Namecoin domains.)
  2. Calling REDIRECTSTREAM from one Workstation on a stream where the SOURCE_ADDR is a different Workstation. (Prevents a vulnerability in one Workstation from hijacking Namecoin lookups in other Workstations. Also avoids situations where two StemNS instances try to resolve the same stream.)
  3. Calling ATTACHSTREAM with a nonzero CircuitID or with a non-null HopNum. (Prevents a vulnerability in Namecoin from messing with how circuits are assigned to streams.)
  4. Calling ATTACHSTREAM on a stream with a StreamStatus not equal to CONTROLLER_WAIT. (Prevents a vulnerability in Namecoin from DoSing local applications by causing their streams to disconnect.)

(3) can be easily prevented by standard onion-grater regex. The others are all dependent on knowing the stream status, which we could handle in 3 ways:

  1. onion-grater could cache all STREAM events, and check their status as part of the filtering of REDIRECTSTREAM and ATTACHSTREAM. Perhaps by applying a regex whitelist to the STREAM event when choosing whether to filter REDIRECTSTREAM and ATTACHSTREAM.
  2. onion-grater could send GETINFO to Tor when it sees REDIRECTSTREAM and ATTACHSTREAM, in order to fetch the current stream status, and use the result to determine whether to filter the command. Again, possibly by applying a regex whitelist to the GETINFO result.
  3. Tor could add some optional arguments to REDIRECTSTREAM and ATTACHSTREAM that contain the extra status variables, which cause the command to be a NOP if the stream’s status doesn’t match the args; onion-grater could then apply standard regex whitelisting to those args.

(1) seems unpleasant since it makes onion-grater keep track of state. (2) seems relatively straightforward, but does slightly increase the complexity of onion-grater. (3) might be the simplest, but would require Tor to merge a patch. Tor has merged control protocol patches related to Namecoin use cases before, so it’s not out of the question that Tor could merge such a patch.

Wouldn’t this only work for applications that use the system DNS resolver? I.e. any application that uses a SOCKS port won’t have Namecoin resolution. That would be rather unfortunate.

My take is that losing stream isolation is a pretty bad privacy hit; I’d be a lot happier about the approaches described above. Running StemNS and ncprop279 in the Gateway while running Electrum-NMC in the workstation seems to me to be the most straightforward approach, though if for some reason you strongly prefer another approach (e.g. one of the control port filtering methods I described), I’m not ruling that out.

In Tor Browser Nightly, the Namecoin support can be toggled with an environment variable. I suspect that disabling Tor Browser’s Namecoin support in the Workstation via environment variable, while enabling Namecoin on the Gateway’s Tor instance, will mostly work fine; Namecoin resolution should work approximately the same way. There may be a few rare edge cases that would need to be handled, but I expect they would be manageable (especially because the code in the Tor Browser integration that might produce such edge cases hasn’t been written yet, and when I write that code, I should be able to do it in a way that will minimize the impact on Whonix).

(Skipped replying to a few paragraphs that I suspect are less applicable given my reply; let me know if you still want me to reply to those.)

1 Like

That sounds good!

Keeping as much away of the gateway + onion-grater modifications sounds good.

From Whonix (and perhaps Tails) perspective this might be ideal since then complexity is abstracted in Tor, not Whonix.

I hope this would be considered during packaging.

Indeed.

I’ve filed a Tor issue about adding this feature to the Tor control protocol. Nick has replied and appears open to it. So, looks like that is the most suitable path forward. I will work on implementing that patch; not sure how long it’ll take me. (I don’t enjoy writing C, so it may not happen super quickly.)

ncprop279 is the component that would need a config option set to use Electrum-NMC in another VM, and ncprop279 already supports that config option (and supports conf.d), so I think this should be pretty easy.

1 Like

Any news on Tor Browser Namecoin integration?

Unfortunately no substantive news I can share; we are still waiting for this to reach the front of the Tor Browser Team’s priority queue. The Tor Network Team informed us a few days ago that the C Tor daemon is nearing a formal feature freeze, and as a result they don’t want to merge our control port patches; they are asking that we wait for Arti instead. We are evaluating what to do next to push things forward.

1 Like

Alas, the Tor team don’t want to merge our patches to REDIRECTSTREAM, because of the feature freeze.

But I don’t see why we need to patch Tor. Can’t we just have onion-grater do something like this:

  • If request isn’t REDIRECTSTREAM, forward
  • If request has no MATCH_TARGET, forward
  • If request has MATCH_TARGET, send a GETINFO request to Tor with stream-status key. It will then check the list of results:
  • If the Stream ID is not in there, reject the request
  • If the Stream ID is in there, check that target matches. If so, forward

Likewise for similar calls, like ATTACHSTREAM, DETACHSTREAM, etc, and for other options (MATCH_SOURCEPORT etc).

The advantage of this is that it doesn’t have any state; just a callback/synchronous blocking. It is a bit hacky though, but not terrible.

Thoughts?

1 Like

This generally (this whole forum thread) seems really complex to me. Maybe I am getting old.

As mentioned earlier, my hope was to keep the complexity away from onion-grater and the gateway.

Would it be possible to implement this using an onion-grater profile? If so, that would be great. That would keep most complexity away from me.

onion-grater was developed by Tails, not Whonix. I wouldn’t want to carry any patches directly to onion-grater (outside onion-grater profiles) in Whonix. That’s because I expect such a a patch would seems pretty difficult to review for me as well as keeping backporting future updates to onion-grater by Tails, potential future merge conflicts.

If onion-grater modifications are required, may I hope that these would be useful in Tails too? In that case, may I request that onion-grater is patched in Tails first? Then Whonix would shortly later run the same version.

If request has MATCH_TARGET, send a GETINFO request to Tor with stream-status key. It will then check the list of results:

Unfortunately, GETINFO’s stream-status key doesn’t return the full set of fields that a STREAM event does. In particular, the SOURCE_ADDR isn’t included. So that’s not going to work. This seems like a Tor daemon bug, but since our last patch was rejected due to the feature freeze pending Arti, this bug is not likely to get fixed even if we send in a patch.

However, I just realized there is a simpler way.

onion-grater already maintains a list of stream ID’s for each client (grep for self.client_streams). So, it looks like we can make this work with some very trivial onion-grater patches:

  1. If restrict-stream-events is true, make onion-grater filter ATTACHSTREAM, REDIRECTSTREAM, and CLOSESTREAM if the stream ID supplied by the client isn’t already in self.client_streams. That prevents one Workstation from messing with another Workstation’s streams.
  2. The target is included in GETINFO’s response, so we could in principle get that data with yanmaani’s approach, but we don’t need to introduce that complexity. Currently, self.client_streams is a set of stream ID’s, but we could easily change it to a dict whose keys are stream ID’s, and whose values are StreamEvents. We could then add an onion-grater config option that specifies a RegEx pattern (or even a list of simple string suffixes), which is matched against the target of the StreamEvent for the stream ID supplied by the client for REDIRECTSTREAM.
  3. I am inclined not to worry about the DoS vector of attaching streams whose status is not CONTROLLER_WAIT, because if StemNS is malicious/compromised, it can already do a pretty effective DoS of local streams by simply not attaching them at all; therefore I don’t think the extra complexity from mitigating this is worth it.

(We could also match against the SOCKS5 username of the StreamEvent in the same way as Patch 2, which would prevent websites from fingerprinting whether Namecoin is enabled; I think this is desirable but it’s not a hard requirement.)

Patch 1 seems irrelevant to Namecoin in Tails since there won’t be multiple Namecoin instances using a single Tails Tor daemon, but it’s presumably still important if Tails ever wanted to use onion-grater with some other application that used those commands, so I can’t see any reason why Tails would be hostile to such a patch.

Patch 2 would be directly relevant to Namecoin in Tails too, so getting it merged to Tails seems a very sane approach.

I do see one issue: the onion-grater docs indicate that restrict-stream-events only works for “local clients”. Does that imply that it’s only a thing for Tails and does not work on Whonix? I looked at the code and I don’t understand why it shouldn’t work for Whonix clients if that explicit check is removed. Patrick, do you happen to know what the rationale of that restriction is?

Thoughts on this approach?

1 Like

This looks maybe relevant? restrict-stream-events is not enforced for Tor Browser anymore (#18417) · Issues · tails / tails · GitLab

EDIT: Found the answer (I think), it’s in this thread: onion-grater race condition: move OnionShare to its netns (#18123) · Issues · tails / tails · GitLab . So it sounds like Tails intends to support remote clients (via IP matching) but they don’t yet.

1 Like

If easy for you, then that sounds great!

Awesome! That is more than I would have dreamed possible.

Yes.

Yes.

Dunno. Never had a use case for it.

No.

Generally good. If you could get that submitted, merged in Tails, that would be awesome!