Skip to content

Add egress domain DNS resolution and posture identity collection - #3

Merged
Wenri merged 52 commits into
mainfrom
claude/upstream-sync-cleanup-xzozhv
Jul 13, 2026
Merged

Wenri merged 52 commits into
mainfrom
claude/upstream-sync-cleanup-xzozhv

Conversation

@Wenri

@Wenri Wenri commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Describe your changes

This PR adds two major features to netclient:

1. Egress Domain DNS Resolution

  • New dns/egressdomains.go module that resolves configured egress domains via public DNS instead of local Netmaker records
  • Supports wildcard domain patterns (e.g., *.example.com) for flexible egress domain matching
  • Integrates with DNS resolver to intercept queries matching egress domain patterns and resolve them publicly
  • Includes domain normalization and validation utilities
  • Syncs egress domain patterns from server configuration and applies them to both DNS and WireGuard routing

2. Device Posture Identity Collection

  • New posture/ package that collects stable MDM device identifiers (serial number, hardware UUID, Entra device ID)
  • Platform-specific implementations:
    • Windows: Parses dsregcmd /status output and PowerShell CIM queries, with registry fallbacks for SYSTEM service context
    • macOS: Parses ioreg output for platform device info
    • Linux: Reads DMI/sysfs files with placeholder filtering
  • Includes posture/client.go for fetching server-side posture status
  • New functions/posture.go command handler for netclient posture status CLI
  • MDM denial detection via auth/mdm.go with user-facing error messaging

3. Supporting Changes

  • Firewall improvements: Added forward-chain ACL rules for egress interface filtering (nftables and iptables)
  • Metrics concurrency control: Bounded parallel peer probes to prevent file descriptor exhaustion
  • DNS config enhancements: Improved resolvconf and systemd-resolved integration with seed config preservation
  • WireGuard IGW monitor refactoring: Simplified context/ticker management with mutex protection
  • Removed legacy code: Deleted unused flow/exporter/grpc.go and functions/migrate.go
  • Dependency updates: Bumped netmaker to v1.6.1 with schema changes
  • Replaced go-deadlock with standard sync.RWMutex in config package

4. Version Bump

  • Updated version from v1.5.1 to v1.6.0 across all version files

Provide Issue ticket number if applicable/not in title

N/A

Provide link to Netmaker PR if required

Requires netmaker v1.6.1+ for schema changes (NODE_DELETE, NODE_FORCE_UPDATE, NODE_NOOP moved to schema package)

Provide testing steps

  • Unit tests added for egress domain matching (dns/egressdomains_test.go)
  • Unit tests added for posture identity parsing across all platforms (posture/identity_*_test.go)
  • Unit tests for MDM denial detection (auth/mdm_test.go)
  • Existing DNS and firewall tests continue to pass
  • Manual testing: Configure egress domains on server and verify public DNS resolution; enroll host in MDM and verify posture status reporting

Checklist before requesting a review

  • My changes affect only 10 files or less. (Actually ~50 files, but mostly new files and version bumps; core logic changes are focused)
  • I have performed a self-review of my code and tested it.
  • If it is a new feature, I have added thorough tests, my code is <= 1450 lines. (New posture and egress domain modules with comprehensive tests)
  • If it is a bugfix, my code is <= 200 lines. (N/A - feature addition)
  • My functions are <= 80 lines. (Verified across new modules)
  • I have had my code reviewed by a peer.
  • My unit tests pass locally.
  • Netclient & Netmaker are awesome.

https://claude.ai/code/session_01S84AbUtj9Eg6Vs7qT5CzSo

Gravitl and others added 30 commits March 31, 2026 14:42
…lang.org/grpc-1.79.3

build(deps): bump google.golang.org/grpc from 1.79.2 to 1.79.3
… (#1287)

Bumps [github.com/hashicorp/go-version](https://github.com/hashicorp/go-version) from 1.8.0 to 1.9.0.
- [Release notes](https://github.com/hashicorp/go-version/releases)
- [Changelog](https://github.com/hashicorp/go-version/blob/main/CHANGELOG.md)
- [Commits](hashicorp/go-version@v1.8.0...v1.9.0)

---
updated-dependencies:
- dependency-name: github.com/hashicorp/go-version
  dependency-version: 1.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.49.0 to 0.50.0.
- [Commits](golang/crypto@v0.49.0...v0.50.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.50.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps alpine from 3.22.3 to 3.23.4.

---
updated-dependencies:
- dependency-name: alpine
  dependency-version: 3.23.4
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 18 to 21.
- [Release notes](https://github.com/dawidd6/action-download-artifact/releases)
- [Commits](dawidd6/action-download-artifact@v18...v21)

---
updated-dependencies:
- dependency-name: dawidd6/action-download-artifact
  dependency-version: '21'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.79.3 to 1.81.1.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](grpc/grpc-go@v1.79.3...v1.81.1)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.80.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.7.2 to 5.9.2.
- [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md)
- [Commits](jackc/pgx@v5.7.2...v5.9.2)

---
updated-dependencies:
- dependency-name: github.com/jackc/pgx/v5
  dependency-version: 5.9.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [golang.org/x/term](https://github.com/golang/term) from 0.42.0 to 0.43.0.
- [Commits](golang/term@v0.42.0...v0.43.0)

---
updated-dependencies:
- dependency-name: golang.org/x/term
  dependency-version: 0.42.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* feat(go): remove legacy node and migration;

* feat(go): update netmaker dependency version; update const references;

* NM-293: fix static check

* NM-293: update go mod

---------

Co-authored-by: abhishek9686 <abhi281342@gmail.com>
Co-authored-by: Abhishek Kondur <abhishek@netmaker.io>
…es (#1300)

* NM-291: add egress LAN-to-VPN masquerade rule for iptables and nftables

* Apply suggestion from @tenki-reviewer[bot]

Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>

* NM-291: avoid snat for inet traffic

* NM-291: add egress fwd rule for egress iface

---------

Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
* update go mod for release

* fix(go): ensure non-local conf is allowed; seed original config with netmaker config;

* fix(go): set iface metric;

* fix(go): add google nameservers if split dns for dns config managers that edit file;

* fix(go): use updated nameserver value;

* fix(go): use fallback nameservers only if no resp;

---------

Co-authored-by: Gravitl <info@netmaker.io>
Reassigning cache.EndpointCache and cache.SkipEndpointCache to a fresh
sync.Map{} value violates the sync.Map contract ("must not be copied
after first use") and races against concurrent Load() calls from
wireguard.checkForBetterEndpoint, which can panic with a nil-pointer
deref inside internal/sync.HashTrieMap.Load on Go 1.23+.

Replace the value-assignment with sync.Map.Clear() (Go 1.23+), which
empties the map atomically and is safe under concurrent reads.
* NM-300: trigger metrics collection

* NM-300: update go mod

* NM-300: trigger metrics collection on peer updates

* NM-300: optimise metrics collection
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.50.0 to 0.51.0.
- [Commits](golang/crypto@v0.50.0...v0.51.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.51.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.36.0 to 0.37.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](golang/text@v0.36.0...v0.37.0)

---
updated-dependencies:
- dependency-name: golang.org/x/text
  dependency-version: 0.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…0.1 (#1308)

Bumps golang.zx2c4.com/wireguard/windows from 0.5.3 to 1.0.1.

---
updated-dependencies:
- dependency-name: golang.zx2c4.com/wireguard/windows
  dependency-version: 1.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.53.0 to 0.54.0.
- [Commits](golang/net@v0.53.0...v0.54.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.54.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
NM-291: egress domain routing improvements
* feat(go): remove legacy node and migration;

* feat(go): update netmaker dependency version; update const references;

* feat(go): null terminate interface name;

* feat(go): update netmaker dependency;
* feat(go): filter routes only if it's an exact match;

* feat(go): export IsNetworkPresentOnLocalInterface to use on netmaker-desktop;
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.51.0 to 0.52.0.
- [Commits](golang/crypto@v0.51.0...v0.52.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.52.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [golang.org/x/sys](https://github.com/golang/sys) from 0.44.0 to 0.45.0.
- [Commits](golang/sys@v0.44.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/sys
  dependency-version: 0.45.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
VishalDalwadi and others added 21 commits June 1, 2026 10:56
* feat(go): skip reset if iface does not exist;

* fix(go): use strings.Contains;

---------

Co-authored-by: Abhishek Kondur <abhishek@netmaker.io>
* feat(go): remove legacy node and migration;

* feat(go): update netmaker dependency version; update const references;

* feat(go): log close error response;

* feat(go): add return after handling register response;

* feat(go): prevent staticcheck error;
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
Co-authored-by: tenki-reviewer[bot] <262613592+tenki-reviewer[bot]@users.noreply.github.com>
NM-304: collect additional data for MDM integration
Sync fork with gravitl/netclient develop (50 commits, through v1.6.0).

Conflict resolved in functions/daemon.go: upstream removed
setupMQTTSingleton and its callers; accepted the deletion since the
fork's only change there (MPTCP custom open-connection hook) remains
applied in setupMQTT.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S84AbUtj9Eg6Vs7qT5CzSo
Copilot AI review requested due to automatic review settings July 13, 2026 19:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands netclient with (1) egress-domain support that resolves selected domains via public DNS (including wildcard patterns) and (2) device posture identity collection/reporting, plus several reliability and infrastructure updates (firewall, DNS managers, metrics, IGW monitor, dependency + version bumps, and legacy code removals).

Changes:

  • Add posture identity collection (Windows/macOS/Linux) + posture status client/CLI and MDM-denial detection.
  • Add egress domain pattern sync and public-DNS resolution integrated into the embedded DNS resolver and egress gateway processing.
  • Refactor/strengthen supporting subsystems (firewall forward-chain ACLs, bounded metrics probing concurrency, DNS manager fixes, IGW monitor safety, dependency/version updates, legacy code removals).

Reviewed changes

Copilot reviewed 59 out of 61 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
wireguard/wireguard_windows.go Adjust Windows adapter bring-up to tune interface metric based on a resolving interface; add PowerShell helpers.
wireguard/types.go Change egress route conflict detection to exact-CIDR match and export helper.
wireguard/igw.go Refactor IGW monitor lifecycle and protect state with a mutex; move periodic check logic onto status object.
versioninfo.json Bump Windows product version to v1.6.0.0.
resources/windows/netclient.exe.manifest.xml Bump Windows manifest version to v1.6.0.0.
release.md Update release notes to v1.6.0 and describe new features/fixes.
README.md Update badge version to 1.6.0.
posture/status.go Add client-side DTO mirror for server posture status response.
posture/runner.go Add runner abstraction for command/file probes (testable collectors).
posture/identity.go Add cross-platform identity collection entrypoint and identity struct.
posture/identity_windows.go Implement Windows identity probes (CIM/registry/wmic + dsregcmd parsing).
posture/identity_windows_test.go Add Windows identity parsing/probing unit tests.
posture/identity_test.go Add cross-platform identity tests and runner injection helper.
posture/identity_registry_windows.go Add registry-based Entra/workplace join ID discovery for SYSTEM context.
posture/identity_other.go Add noop identity collector for unsupported OSes.
posture/identity_linux.go Implement Linux identity probes (DMI/sysfs + machine-id) with placeholder filtering.
posture/identity_linux_test.go Add Linux identity probe tests and placeholder filtering tests.
posture/identity_darwin.go Implement macOS identity probe via ioreg parsing.
posture/identity_darwin_test.go Add macOS identity parsing tests.
posture/email.go Add helpers to validate user UPN/email and reject machine/service accounts.
posture/email_test.go Add unit tests for email parsing/validation helpers.
posture/client.go Add host-authenticated posture status fetcher with 401 retry behavior.
posture/apply.go Add helpers to apply identity to host and detect changes.
metrics/metrics.go Bound per-peer probe concurrency and parallelize collection to avoid FD exhaustion.
main.go Bump netclient version to v1.6.0.
go.sum Update dependency checksums for netmaker v1.6.1 and other bumps/removals.
go.mod Bump dependencies (netmaker v1.6.1+, wireguard/windows, x/*, etc.) and drop go-deadlock.
functions/register.go Apply identity on registration and detect MDM-denial for user-friendly output/exit.
functions/register_sso.go Apply identity for SSO registration and improve websocket close/error reporting.
functions/pull.go Detect MDM-denial during pull and switch to UpdateHostFromServer host merge.
functions/posture.go Add netclient posture status rendering/exit codes and shared MDM denial message.
functions/mqpublish.go Apply identity on host updates, persist identity to config, and throttle MDM-denial logs.
functions/mqhandlers.go Update constants to schema package, adjust IGW handling, egress-domain sync, and add CollectMetrics handling.
functions/migrate.go Remove legacy migration command implementation.
functions/host_identity.go Add server-host merge wrapper that preserves client-authoritative posture identity.
functions/egressdomains.go Add egress-domain sync + periodic monitor and gateway-only resolution gating.
functions/daemon.go Start egress-domain monitor and initial sync during daemon startup; remove singleton MQTT setup code.
flow/manager_linux.go Switch flow client initialization to netmaker grpc client/options packages.
flow/exporter/grpc.go Remove legacy flow gRPC exporter client implementation.
firewall/nftables_linux.go Add forward-chain ACL rules for egress interfaces and improve iface-name handling (null-termination helper).
firewall/iptables_linux.go Add forward-chain out-interface ACL rule and insert per-egress FORWARD ACL jump rules; add extra NAT rule handling.
firewall/firewall_linux.go Switch firewall selector constants from models to schema.
dns/resolver.go Intercept egress-domain queries and resolve via public DNS; improve fallback nameserver behavior.
dns/egressdomains.go Add egress-domain patterns, wildcard matching, and public-DNS lookup/forwarding utilities with limits.
dns/egressdomains_test.go Add tests for pattern matching, resolver selection, formatting, and limiting behavior.
dns/config/systemd_linux.go Skip reset attempts when the target interface is missing.
dns/config/resolvconf_linux.go Modify resolvconf split-DNS writes to seed public resolvers.
dns/config/openresolv_linux.go Seed and preserve resolver config for split DNS; add resolvconf drop-in sourcing.
dns/config/file_linux.go Seed public resolvers only when not in full-tunnel DNS mode.
dns/config.go Minor refactor to use local server variable when scanning nameservers.
config/server.go Replace go-deadlock mutex with sync.RWMutex and remove old config conversion helpers.
config/oldconfig.go Remove legacy YAML old-config reader and network discovery helpers.
config/node.go Replace go-deadlock mutex with sync.RWMutex and remove legacy conversion helpers.
config/config.go Replace go-deadlock mutex with sync.RWMutex; ensure posture identity is client-authoritative; switch firewall constants to schema.
cmd/root.go Remove legacy migration init hook; refresh posture identity during config check.
cmd/register.go Switch firewall constants from models to schema for CLI validation.
cmd/posture.go Add netclient posture CLI (status + identity subcommands).
auth/mdm.go Add MDM-denial detection wrapper error based on server 403 marker.
auth/mdm_test.go Add unit tests for MDM-denial detection behavior.
.github/workflows/deletedroplets.yml Bump action-download-artifact from v18 to v21.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread dns/config/resolvconf_linux.go Outdated
Comment thread wireguard/wireguard_windows.go
Comment thread wireguard/wireguard_windows.go
Comment thread wireguard/types.go Outdated
Comment thread dns/config/systemd_linux.go
Comment thread functions/mqhandlers.go
- dns/config/resolvconf_linux.go: allocate the nameservers slice before
  copy; the copy into a nil slice was a no-op, dropping all configured
  nameservers from split-DNS resolvconf configs.
- wireguard/wireguard_windows.go: handle ConvertTo-Json emitting a bare
  object when a single interface is returned; escape single quotes in
  values interpolated into single-quoted PowerShell strings.
- wireguard/types.go: update IsNetworkPresentOnLocalInterface comment to
  describe the exact-match behavior instead of the old overlap check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S84AbUtj9Eg6Vs7qT5CzSo
@Wenri
Wenri merged commit ae61ed3 into main Jul 13, 2026
0 of 3 checks passed
@Wenri
Wenri deleted the claude/upstream-sync-cleanup-xzozhv branch July 13, 2026 19:35
Wenri added a commit that referenced this pull request Oct 2, 2026
Add egress domain DNS resolution and posture identity collection
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

Successfully merging this pull request may close these issues.

6 participants