Repository navigation
nordvpn: add meshnet support - #564752
nordvpn: add meshnet support#564752novalkun wants to merge 3 commits into
Conversation
d363fa0 to
8652a05
Compare
8652a05 to
406d730
Compare
406d730 to
b3365d6
Compare
|
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/prs-ready-for-review/3032/7646 |
b3365d6 to
d7735ba
Compare
There was a problem hiding this comment.
Thanks for contributing to the documentation.
Follow the documentation style guide, especially:
- Show, don’t tell. Start with a minimal working example. Explain after the code.
- Avoid meta-commentary. Don’t write "This section explains how to…".
- Use present tense, imperative mood, and active voice. For example: "Run the command," not "The user should run the following command."
- Avoid vague references like "this" when the referent is unclear. Write "This command creates a folder," not "This will create a folder."
- Be direct. Avoid "should", "might", "typically", and "usually".
- Cut filler words like "simply", "just", "easily", and "basically". Use "to" instead of "in order to".
For larger changes, such as adding or removing whole sections, ask the NixOS documentation team for review.
|
cc @andersonjoseph, would appreciate a review. |
✅
|
d7735ba to
1b2d105
Compare
1c4ca84 to
5426c55
Compare
|
Thank you very much @SuperSandro2000 |
✅
|
5426c55 to
bd23a5d
Compare
bd23a5d to
c02670b
Compare
|
Rebased onto master now that #547437 is merged — CI is green and this is conflict-free. @different-error, would appreciate your review since the meshnet design here is based on your original work. |
different-error
left a comment
There was a problem hiding this comment.
Hello @novalkun, thank you for the changes. After review I've realized that many of my request changes effectively mean use what I have instead. Let me create a meshnet PR with most of my present meshnet branch and some of the new changes I've obtained in this PR. Feel free to close this.
| 'TestTransports|'\ | ||
| 'TestUpWGInterface|'\ | ||
| 'TestVPNRuleset' | ||
| skipPattern='Test.*FileList_RealURL|TestAddAllowlistRules|TestAddDevice|TestConnectionInfo_TransferRatesShallBeProvidedOnlyForConnectedState|TestCustomTable|TestDiscoverNameserverIp|TestFwmarkRule|TestH1Transport_RoundTrip|TestMeshnetRuleset|TestMultiFwmarkRule|TestNetlinkManager_SetUnset|TestRouter_Add|TestSetMTU|TestSuppressRule|TestTransports|TestUpWGInterface|TestVPNRuleset' |
There was a problem hiding this comment.
I prefer the old format as it reads better.
| description = "Native fileshare library used by NordVPN's meshnet feature"; | ||
| homepage = "https://github.com/NordSecurity/libdrop"; | ||
| license = lib.licenses.gpl3Only; | ||
| maintainers = with lib.maintainers; [ novalkun ]; |
| description = "Native meshnet library used by NordVPN's meshnet feature"; | ||
| homepage = "https://github.com/NordSecurity/libtelio"; | ||
| license = lib.licenses.gpl3Only; | ||
| maintainers = with lib.maintainers; [ novalkun ]; |
|
|
||
| # save shared object before cargo test relinks it with a test only variant | ||
| postBuild = '' | ||
| install -Dm755 "$(find target -name libtelio.so -path '*/release/*' | head -1)" "$TMPDIR/libtelio.so" |
There was a problem hiding this comment.
This looks like a code smell. Rust packages don't normally install .so files in their postBuild
| postFixup = '' | ||
| python3 -c " | ||
| path = '$out/lib/libtelio.so' | ||
| placeholder = b'VERSION_PLACEHOLDER' + b'@' * 109 + b'\0' | ||
| assert len(placeholder) == 129 | ||
| new = ('${finalAttrs.version}'.encode() + b'\0' * 129)[:129] | ||
| with open(path, 'r+b') as f: | ||
| data = f.read() | ||
| assert data.count(placeholder) == 1 | ||
| f.seek(0) | ||
| f.write(data.replace(placeholder, new)) | ||
| " | ||
| ''; |
There was a problem hiding this comment.
I find directly modifying a .so file a little strange.
| require making `/etc/hosts` writable, which conflicts with NixOS's | ||
| declarative `/etc`. As a workaround you can connect to peers by their meshnet IP | ||
| instead. | ||
|
|
There was a problem hiding this comment.
Could you add an example. Something like
networking.hosts = {
"1.2.3.4" = [ "some-alias" ];
};
| export LD_LIBRARY_PATH=${ | ||
| lib.makeLibraryPath [ | ||
| libtelio | ||
| libdrop | ||
| ] | ||
| }''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH |
There was a problem hiding this comment.
I don't think you need this to make meshnet operational.
| go test -tags "telio drop cdnrc" ./cli/... | ||
| go test -tags "telio drop cdnrc" ./fileshare/... | ||
| go test -tags "telio drop cdnrc" ./norduser/... |
There was a problem hiding this comment.
Until proven otherwise we should simply run the entire test suite (not just these tagged ones) as some tests cases may not belong in the tag but impact end-user functionality.
There was a problem hiding this comment.
after you open the PR, i will close this PR. thank you |
bf6b5ba to
5ab2088
Compare
Native (Rust) meshnet library consumed by nordvpn-linux's cgo bindings (github.com/NordSecurity/libtelio-go, already vendored as a Go dependency). Version must stay in lockstep with LIBTELIO_VERSION in nordvpn-linux's lib-versions.env, hence "nixpkgs-update: no auto update". Co-authored-by: different-error <[email protected]> Assisted-by: Claude Code (Sonnet 5, claude-sonnet-5)
Native (Rust) fileshare library consumed by nordvpn-linux's cgo bindings (github.com/NordSecurity/libdrop-go, already vendored as a Go dependency). Version must stay in lockstep with LIBDROP_VERSION in nordvpn-linux's lib-versions.env, hence "nixpkgs-update: no auto update". Co-authored-by: different-error <[email protected]> Assisted-by: Claude Code (Sonnet 5, claude-sonnet-5)
Adds meshnet (libtelio) and fileshare (libdrop) support, both fully open-source/GPLv3 and gated behind upstream's own telio/drop/cdnrc Go build tags (moose/quench stay out of scope, proprietary-only). - nordvpnd gains a --hosts-readonly flag backed by a NoopHostsSetter (daemon/dns/hosts.go), so /etc/hosts is never written to. Peer hostnames can be mapped declaratively via networking.hosts instead (documented). - builds and installs cmd/fileshare as nordfileshare; its and norduserd's unix sockets are chowned to the nordvpn group so processes running as a different user than nordvpnd (which runs unprivileged) can reach them. - only start the norduserd user service for members of the configured group, since other users cannot assign their socket to that group. - adds CAP_NET_RAW (libtelio needs it for ping) and nordlynx to networking.firewall.trustedInterfaces. - sets the RemotePath ldflag to upstream's documented default (.env.sample: /apps/linux/config). Without it, remote-config downloads that gate meshnet/libtelio resolve to the wrong CDN path. - run daemon/dns tests, including the read-only hosts setter, except nameserver discovery, which needs a gateway absent from the sandbox. - expand nixosTests.nordvpn to check trusted interfaces, socket modes and groups, the expected fileshare exit code while meshnet is disabled, and skipped services for non-members across all user/group combinations. - document meshnet support and its hostname limitation in the release notes. Rebased onto master's merged nixos/nordvpn: make more secure and robust (NixOS#547437): reconciled the refactored nixosTests.nordvpn UserGroupTestCase, the broader checkPhase daemon test coverage, and the full systemd sandboxing directive set with this branch's meshnet-specific additions on top. Based on independent work by different-error, who could not push this directly due to a disputed account suspension. Credited via Co-authored-by. Co-authored-by: different-error <[email protected]> Assisted-by: Claude Code (Sonnet 5, claude-sonnet-5) Assisted-by: OpenCode (GPT-6.1 Sol, openai/gpt-6.1-sol) Assisted-by: Claude Code (Opus 5.5, claude-opus-5-5)
5ab2088 to
b880b97
Compare
|
Closing in favor of #576413. Thank you @different-error |
Upstream sources: nordvpn-linux 5.4.0, libtelio 6.2.4, libdrop 9.0.0.
Background
The
nordvpnpackage and module were originally written bydifferent-error, whose GitHub account is currently suspended (a suspension they dispute). I (@novalkun) took over maintainership at 5.4.0 and am picking up meshnet as unfinished work flagged from the module's first commit. This PR uses techniques fromdifferent-error's parallel implementation, credited viaCo-authored-by.Changes
libtelioandlibdroppackages, built from source with Rust tests enabled. Their versions tracknordvpn-linux'slib-versions.env; automatic independent updates are disabled.nordvpn-linuxwith the public/FOSStelio,drop, andcdnrcGo tags, and installcmd/fileshareasnordfileshare.--hosts-readonlyflag backed byNoopHostsSetter, so the daemon leaves/etc/hostsunchanged. Peer hostnames do not resolve; use meshnet IP addresses instead. The upstream submission and previously reported rejection are documented in the review thread.norduserdand fileshare sockets groupnordvpnand mode0660, allowing the unprivileged main daemon to communicate across users. Start thenorduserduser service only for members of the configured group, since non-members cannot assign their socket to that group. Custom groups remain supported.CAP_NET_RAWfor libtelio's ping support and trust thenordlynxfirewall interface.main.RemotePath=/apps/linux/configto match upstream's documented production configuration; otherwise remote configuration downloads use the wrong CDN path.LD_LIBRARY_PATHwrappers because adding an RPATH withpatchelfcorrupts these Go binaries' ELF layout.TestDiscoverNameserverIpfrom that package because the build sandbox has no default gateway.Live testing previously caught
cargo testoverwriting the releaselibtelio.sowith a mock-adapter variant despite successful builds and VM tests. The package snapshots the production shared object beforecheckPhaseand installs that snapshot.This PR remains independent of the hardening PR. NordWhisper remains unsupported because it requires the proprietary
quenchlibrary; the proprietarymoosetag is also excluded.How to test
Enable
services.nordvpn.enable = true;, add the testing user to thenordvpngroup, and setnetworking.firewall.checkReversePath = "loose";when using the firewall. Build against this PR with:Inside the VM, check
nordvpn status. A real NordVPN account is required fornordvpn loginandnordvpn set meshnet on; usenordvpn mesh peer listandnordvpn fileshare listto inspect the services.AI disclosure
Originally prepared with Claude Code (Claude Sonnet 5 /
claude-sonnet-5), then reviewed and revised with OpenCode using GPT-6.1 Sol (openai/gpt-6.1-sol). AI assistance covered code and test changes, review, commit messages, and this description. Build and VM checks and live-test commands were executed through OpenCode; I performed the privileged activation and restoration of test configurations on my hardware. Relevant commits carryAssisted-by:trailers, anddifferent-error's work retainsCo-authored-by:attribution.Things done
./result/bin/.nixpkgs-reviewon this PR. See nixpkgs-review usage.passthru.tests.Testing performed locally
nordvpn.clionx86_64-linux, including thelibdropandlibtelioRust test suites and Go tests with the meshnet/fileshare build tags. The DNS package tests pass with the gateway-dependent discovery test excluded.nixosTests.nordvpn: all five scenarios pass, covering the disabled module and four user/group combinations. Tests check trusted interfaces, socket ownership/mode, the expected fileshare exit code when meshnet is disabled, and that non-members are skipped without socket creation or restarts while authorized users continue to work.chownfailure in a separate VM withConditionGroupdisabled, then verified the condition avoids it in all four user/group scenarios.--fail-on-changeon the changed files: zero changes.git diff --checkpasses.x86_64-linuxNixOS 26.05 host with only the NordVPN module/package replaced: the native adapter createsnordlynx, connects to a DERP relay, and survives two additional off/on cycles./etc/hostsstays byte-identical throughout.nordvpnand mode0660, the fileshare socket is listening, andnordvpn fileshare listsuccessfully queries the daemon. No peers were registered, so peer-to-peer traffic and actual file transfers were not tested.nordvpn meshandnordfileshareare unavailable again, nonordlynxinterface or fileshare process/listener remains, and HTTPS access works.The previous nixpkgs-review report built the earlier HEAD on
x86_64-linuxandaarch64-linux. This revision was tested locally onx86_64-linux; I have not runnixpkgs-reviewmyself.