Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package nebula for openSUSE:Factory checked in at 2026-01-22 15:13:38 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nebula (Old) and /work/SRC/openSUSE:Factory/.nebula.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "nebula" Thu Jan 22 15:13:38 2026 rev:12 rq:1328570 version:1.10.2 Changes: -------- --- /work/SRC/openSUSE:Factory/nebula/nebula.changes 2025-12-08 11:55:22.273049268 +0100 +++ /work/SRC/openSUSE:Factory/.nebula.new.1928/nebula.changes 2026-01-22 15:13:40.756988280 +0100 @@ -1,0 +2,17 @@ +Wed Jan 21 20:34:05 UTC 2026 - Richard Rahl <[email protected]> + +- Update to version 1.10.2: + * Fix panic when using use_system_route_table + +------------------------------------------------------------------- +Tue Jan 20 23:44:43 UTC 2026 - Richard Rahl <[email protected]> + +- Update to version 1.10.1: + * Fix a bug where an unsafe route derived from the system route table could + be lost on a config reload + * Fix the PEM banner for ECDSA P256 public keys + * Fix a bug in handshake processing when a peer sends an unexpected public key + * Add a config option to control accepting recv_error packets which defaults + to always + +------------------------------------------------------------------- Old: ---- nebula-1.10.0.tar.gz New: ---- nebula-1.10.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nebula.spec ++++++ --- /var/tmp/diff_new_pack.m7m864/_old 2026-01-22 15:13:41.597023287 +0100 +++ /var/tmp/diff_new_pack.m7m864/_new 2026-01-22 15:13:41.597023287 +0100 @@ -1,7 +1,7 @@ # # spec file for package nebula # -# Copyright (c) 2025 SUSE LLC and contributors +# Copyright (c) 2026 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: nebula -Version: 1.10.0 +Version: 1.10.2 Release: 0 Summary: A scalable overlay networking tool License: MIT ++++++ _service ++++++ --- /var/tmp/diff_new_pack.m7m864/_old 2026-01-22 15:13:41.637024954 +0100 +++ /var/tmp/diff_new_pack.m7m864/_new 2026-01-22 15:13:41.641025121 +0100 @@ -3,7 +3,7 @@ <service name="tar_scm" mode="manual"> <param name="url">https://github.com/slackhq/nebula.git</param> <param name="scm">git</param> - <param name="revision">refs/tags/v1.10.0</param> + <param name="revision">refs/tags/v1.10.2</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="package-meta">yes</param> ++++++ nebula-1.10.0.tar.gz -> nebula-1.10.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.git/HEAD new/nebula-1.10.2/.git/HEAD --- old/nebula-1.10.0/.git/HEAD 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.git/HEAD 2026-01-21 18:42:34.000000000 +0100 @@ -1 +1 @@ -59e24b98bd4726179750071bec34b9288ba90565 +0b02d982b256dffc9c215306a2e550d8a1bd16ab diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.git/ORIG_HEAD new/nebula-1.10.2/.git/ORIG_HEAD --- old/nebula-1.10.0/.git/ORIG_HEAD 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.git/ORIG_HEAD 2026-01-21 18:42:34.000000000 +0100 @@ -1 +1 @@ -59e24b98bd4726179750071bec34b9288ba90565 +0b02d982b256dffc9c215306a2e550d8a1bd16ab Binary files old/nebula-1.10.0/.git/index and new/nebula-1.10.2/.git/index differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.git/logs/HEAD new/nebula-1.10.2/.git/logs/HEAD --- old/nebula-1.10.0/.git/logs/HEAD 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.git/logs/HEAD 2026-01-21 18:42:34.000000000 +0100 @@ -1,2 +1,2 @@ -0000000000000000000000000000000000000000 59e24b98bd4726179750071bec34b9288ba90565 user <[email protected]> 1765020549 +0000 clone: from https://github.com/slackhq/nebula.git -59e24b98bd4726179750071bec34b9288ba90565 59e24b98bd4726179750071bec34b9288ba90565 user <[email protected]> 1765020549 +0000 checkout: moving from master to refs/tags/v1.10.0 +0000000000000000000000000000000000000000 0b02d982b256dffc9c215306a2e550d8a1bd16ab Richard Rahl <[email protected]> 1769027621 +0100 clone: from https://github.com/slackhq/nebula.git +0b02d982b256dffc9c215306a2e550d8a1bd16ab 0b02d982b256dffc9c215306a2e550d8a1bd16ab Richard Rahl <[email protected]> 1769027621 +0100 checkout: moving from master to refs/tags/v1.10.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.git/logs/refs/heads/master new/nebula-1.10.2/.git/logs/refs/heads/master --- old/nebula-1.10.0/.git/logs/refs/heads/master 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.git/logs/refs/heads/master 2026-01-21 18:42:34.000000000 +0100 @@ -1 +1 @@ -0000000000000000000000000000000000000000 59e24b98bd4726179750071bec34b9288ba90565 user <[email protected]> 1765020549 +0000 clone: from https://github.com/slackhq/nebula.git +0000000000000000000000000000000000000000 0b02d982b256dffc9c215306a2e550d8a1bd16ab Richard Rahl <[email protected]> 1769027621 +0100 clone: from https://github.com/slackhq/nebula.git diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.git/logs/refs/remotes/origin/HEAD new/nebula-1.10.2/.git/logs/refs/remotes/origin/HEAD --- old/nebula-1.10.0/.git/logs/refs/remotes/origin/HEAD 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.git/logs/refs/remotes/origin/HEAD 2026-01-21 18:42:34.000000000 +0100 @@ -1 +1 @@ -0000000000000000000000000000000000000000 59e24b98bd4726179750071bec34b9288ba90565 user <[email protected]> 1765020549 +0000 clone: from https://github.com/slackhq/nebula.git +0000000000000000000000000000000000000000 0b02d982b256dffc9c215306a2e550d8a1bd16ab Richard Rahl <[email protected]> 1769027621 +0100 clone: from https://github.com/slackhq/nebula.git Binary files old/nebula-1.10.0/.git/objects/pack/pack-35317a581769d2f0ac26c1f3118761db585cb646.idx and new/nebula-1.10.2/.git/objects/pack/pack-35317a581769d2f0ac26c1f3118761db585cb646.idx differ Binary files old/nebula-1.10.0/.git/objects/pack/pack-35317a581769d2f0ac26c1f3118761db585cb646.pack and new/nebula-1.10.2/.git/objects/pack/pack-35317a581769d2f0ac26c1f3118761db585cb646.pack differ Binary files old/nebula-1.10.0/.git/objects/pack/pack-35317a581769d2f0ac26c1f3118761db585cb646.rev and new/nebula-1.10.2/.git/objects/pack/pack-35317a581769d2f0ac26c1f3118761db585cb646.rev differ Binary files old/nebula-1.10.0/.git/objects/pack/pack-b033e16290a23d4f10a6c31b294a618aa79862e3.idx and new/nebula-1.10.2/.git/objects/pack/pack-b033e16290a23d4f10a6c31b294a618aa79862e3.idx differ Binary files old/nebula-1.10.0/.git/objects/pack/pack-b033e16290a23d4f10a6c31b294a618aa79862e3.pack and new/nebula-1.10.2/.git/objects/pack/pack-b033e16290a23d4f10a6c31b294a618aa79862e3.pack differ Binary files old/nebula-1.10.0/.git/objects/pack/pack-b033e16290a23d4f10a6c31b294a618aa79862e3.rev and new/nebula-1.10.2/.git/objects/pack/pack-b033e16290a23d4f10a6c31b294a618aa79862e3.rev differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.git/packed-refs new/nebula-1.10.2/.git/packed-refs --- old/nebula-1.10.0/.git/packed-refs 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.git/packed-refs 2026-01-21 18:42:34.000000000 +0100 @@ -2,6 +2,7 @@ 0af7e6a1ddadd96dfe967ba49e456f2c67969b1e refs/remotes/origin/add-http-pprof 2d128a3254cef202a81c88d5d7b6922f632bcc2c refs/remotes/origin/batched-path e7423d39f936f801697f70516c4f5c778d912f9a refs/remotes/origin/botched-path +43bdf9066ec7758afee3a33cbb8cf5efaa109d64 refs/remotes/origin/cert-v2-mixed-af-unsafe-nets f8fe454972d740556600cf2ec9e69caf7a18ff75 refs/remotes/origin/cert-v2-more-todo 5fa386bb703fec75a7a59ac6de9350013a52293d refs/remotes/origin/cert-v2-reloads-with-relay-stuff 824cd3f0d6bc2c36a6515bc93a2c56c3fa8b90b5 refs/remotes/origin/changelog-v1.9.7 @@ -13,23 +14,23 @@ a0f8cb209854b140410f0832559622c16d20ec5a refs/remotes/origin/channels_and_minimal_gsogro 9101b62162b2f55a21e37e800cc84a18be9b5278 refs/remotes/origin/cross-stack-relay f597aa71e325eb52f57d2ac404862ecc79822f79 refs/remotes/origin/cross-stack-relay-overlaps -8e09f26165f36363862ff2c1168b973165ba6a76 refs/remotes/origin/dependabot/github_actions/actions/checkout-6 -662a3358ee572429e0c1257712adbe71b9352b05 refs/remotes/origin/e2e-bench-update b418a081a8feebe5740574a43a3364578c9e1c61 refs/remotes/origin/fips140 e25016a94692b668d4c37833e2f8a25c2fa6b874 refs/remotes/origin/firewall-forward-table +12bf7a154d476af976e7f6b11f9d859853e6df4a refs/remotes/origin/github-release-upload db11e2f1af19017d21ef5912a5613d48b9db3d02 refs/remotes/origin/interface-hooks a4b7f624da48761fff4122ab4d0aaec1deb2ef92 refs/remotes/origin/io-uring-gso-gro-offtherails 5ceac2b078bcb816d9d738c570a35a0a3bc33c78 refs/remotes/origin/jay.wren-dns-ctx 2400e2392be3fcb87bf6ef3badc30ee6689ba848 refs/remotes/origin/jay.wren-lint +97977982cb56f334db00bb67c801359c1a671188 refs/remotes/origin/jay.wren-maybe-ipv4-6-fix 8d4dd2648445c1482c7b35d93261d94b2132df63 refs/remotes/origin/jay.wren-wireguard-tun be90e4aa0511a43f11b419eb1707eb41c3744b29 refs/remotes/origin/jay.wren-wireguard-tun-2 +1cdc7b41494836ff21a3569a704f38e45eed5977 refs/remotes/origin/jay.wren-wireguard-tun-3 9c6fb08a6dd15e950731a0440691c234e4227b30 refs/remotes/origin/make-boringcrypto-checklinkname -59e24b98bd4726179750071bec34b9288ba90565 refs/remotes/origin/master +0b02d982b256dffc9c215306a2e550d8a1bd16ab refs/remotes/origin/master d6c5c00ef75fe0b4dcac7bc57c28a009cc2bd7fe refs/remotes/origin/master-1-9-tag -510a8912a931d578d28a7dddcb2ad5aa3bfb9f82 refs/remotes/origin/multiport +0824035906474c6f815e4b1388b008f1ec57ea3d refs/remotes/origin/multiport d4aea03dd1236a032fe5508e29cf0494768ba71c refs/remotes/origin/mutex-debug 064831cf21020d42200a9399fcf0253e4efcfa6a refs/remotes/origin/no-exit -9cef6752c928bfcaa9bb544ad0e708c7195a635b refs/remotes/origin/one-nine-bart-update 06372e12f1a2fd763c2a8a9d465f5b80511de614 refs/remotes/origin/prometheus-static-labels 6d5299715ebb720197f0095b8c287ff0b94928f5 refs/remotes/origin/psk 0681195da3f68b6bcda375a2c8f31fca105fec61 refs/remotes/origin/psk-v2 @@ -38,16 +39,22 @@ 4c745e8cfe032899e6188f12e241d1adb13a3856 refs/remotes/origin/remove-olddead-tunnels 29157f413c727e937b73acb12035be13520f8b7f refs/remotes/origin/stinkier 703ac81fa6cf5a8e4c2d68c91ffa87c40301425e refs/remotes/origin/stinky +886141decfc087ffed71b22eb3a7a515634edf14 refs/remotes/origin/stream-cas-scanner 03ab9a1208a32cb59d1f4a917ad66b1ed618d803 refs/remotes/origin/synctrace 3583a3f7aba2cccc6f8d1a1e16338430771c5b64 refs/remotes/origin/tun-name-template 9642afa14989ee490cda2f6e8c6ceef1ae5b11bd refs/remotes/origin/update-lh-on-netlink-addr -bdfc2f5809d955d9e952e7845e3ecc615a4d48e2 refs/remotes/origin/vhost +2c30c2edb93e9d116c3a4832684b85fc9bcde4eb refs/remotes/origin/v6hax +71bf3744b14c0c11338b603b130e4c9f175e4f30 refs/remotes/origin/vhost b6c6b96c79a5c64d98fd77162c4427811e69c2e1 refs/remotes/origin/windows_udp_buffer_setting f9d3d521b62aa52463d008ef4e2f2133daaa0b4c refs/tags/v1.0.0 0312a3e4408836e2a58a08171c31d7b13ae917e2 refs/tags/v1.1.0 ^13941aa7232765efc671c6d0d6e1a8c0d4704603 b7e608f0d744dac34e171a3af21cc50a776f977e refs/tags/v1.10.0 ^59e24b98bd4726179750071bec34b9288ba90565 +63208c0ab6f0879b8f1c10774582b6a2fd8f4671 refs/tags/v1.10.1 +^72a40007ea873d914a099b77916e4933befc85b6 +f16df96a63328ddfb82b03de853139b5c0ab66b2 refs/tags/v1.10.2 +^0b02d982b256dffc9c215306a2e550d8a1bd16ab 019d573fd023224454e7dce0d68fcf4155f77b91 refs/tags/v1.2.0 ^fb252db4a153ba7467d1d7320b3821d897640791 14bd5487d818474fcd39a12b12789a6daeaa210a refs/tags/v1.3.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.git/refs/heads/master new/nebula-1.10.2/.git/refs/heads/master --- old/nebula-1.10.0/.git/refs/heads/master 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.git/refs/heads/master 2026-01-21 18:42:34.000000000 +0100 @@ -1 +1 @@ -59e24b98bd4726179750071bec34b9288ba90565 +0b02d982b256dffc9c215306a2e550d8a1bd16ab diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.github/workflows/gofmt.yml new/nebula-1.10.2/.github/workflows/gofmt.yml --- old/nebula-1.10.0/.github/workflows/gofmt.yml 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.github/workflows/gofmt.yml 2026-01-21 18:42:34.000000000 +0100 @@ -14,7 +14,7 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.github/workflows/release.yml new/nebula-1.10.2/.github/workflows/release.yml --- old/nebula-1.10.0/.github/workflows/release.yml 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.github/workflows/release.yml 2026-01-21 18:42:34.000000000 +0100 @@ -10,7 +10,7 @@ name: Build Linux/BSD All runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: @@ -24,7 +24,7 @@ mv build/*.tar.gz release - name: Upload artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: linux-latest path: release @@ -33,7 +33,7 @@ name: Build Windows runs-on: windows-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: @@ -55,7 +55,7 @@ mv dist\windows\wintun build\dist\windows\ - name: Upload artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: windows-latest path: build @@ -66,7 +66,7 @@ HAS_SIGNING_CREDS: ${{ secrets.AC_USERNAME != '' }} runs-on: macos-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: @@ -75,7 +75,7 @@ - name: Import certificates if: env.HAS_SIGNING_CREDS == 'true' - uses: Apple-Actions/import-codesign-certs@v5 + uses: Apple-Actions/import-codesign-certs@v6 with: p12-file-base64: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_P12_BASE64 }} p12-password: ${{ secrets.APPLE_DEVELOPER_CERTIFICATE_PASSWORD }} @@ -104,7 +104,7 @@ fi - name: Upload artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: darwin-latest path: ./release/* @@ -124,11 +124,11 @@ # be overwritten - name: Checkout code if: ${{ env.HAS_DOCKER_CREDS == 'true' }} - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Download artifacts if: ${{ env.HAS_DOCKER_CREDS == 'true' }} - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: name: linux-latest path: artifacts @@ -160,10 +160,10 @@ needs: [build-linux, build-darwin, build-windows] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Download artifacts - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: path: artifacts diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.github/workflows/smoke-extra.yml new/nebula-1.10.2/.github/workflows/smoke-extra.yml --- old/nebula-1.10.0/.github/workflows/smoke-extra.yml 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.github/workflows/smoke-extra.yml 2026-01-21 18:42:34.000000000 +0100 @@ -20,7 +20,7 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.github/workflows/smoke.yml new/nebula-1.10.2/.github/workflows/smoke.yml --- old/nebula-1.10.0/.github/workflows/smoke.yml 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.github/workflows/smoke.yml 2026-01-21 18:42:34.000000000 +0100 @@ -18,7 +18,7 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/.github/workflows/test.yml new/nebula-1.10.2/.github/workflows/test.yml --- old/nebula-1.10.0/.github/workflows/test.yml 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/.github/workflows/test.yml 2026-01-21 18:42:34.000000000 +0100 @@ -18,7 +18,7 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: @@ -45,7 +45,7 @@ - name: Build test mobile run: make build-test-mobile - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 with: name: e2e packet flow linux-latest path: e2e/mermaid/linux-latest @@ -56,7 +56,7 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: @@ -77,7 +77,7 @@ runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: @@ -98,7 +98,7 @@ os: [windows-latest, macos-latest] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: @@ -125,7 +125,7 @@ - name: End 2 end run: make e2evv - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 with: name: e2e packet flow ${{ matrix.os }} path: e2e/mermaid/${{ matrix.os }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/CHANGELOG.md new/nebula-1.10.2/CHANGELOG.md --- old/nebula-1.10.0/CHANGELOG.md 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/CHANGELOG.md 2026-01-21 18:42:34.000000000 +0100 @@ -7,6 +7,37 @@ ## [Unreleased] +## [1.10.2] - 2026-01-21 + +### Fixed + +- Fix panic when using `use_system_route_table` that was introduced in v1.10.1. (#1580) + +### Changed + +- Fix some typos in comments. (#1582) +- Dependency updates. (#1581) + +## [1.10.1] - 2026-01-16 + +See the [v1.10.1](https://github.com/slackhq/nebula/milestone/26?closed=1) milestone for a complete list of changes. + +### Fixed + +- Fix a bug where an unsafe route derived from the system route table could be lost on a config reload. (#1573) +- Fix the PEM banner for ECDSA P256 public keys. (#1552) +- Fix a regression on Windows from 1.9.x where nebula could fall back to a less performant UDP listener if + non-critical ioctls failed. (#1568) +- Fix a bug in handshake processing when a peer sends an unexpected public key. (#1566) + +### Added + +- Add a config option to control accepting `recv_error` packets which defaults to `always`. (#1569) + +### Changed + +- Various dependency updates. (#1541, #1549, #1550, #1557, #1558, #1560, #1561, #1570, #1571) + ## [1.10.0] - 2025-12-04 See the [v1.10.0](https://github.com/slackhq/nebula/milestone/16?closed=1) milestone for a complete list of changes. @@ -744,7 +775,9 @@ - Initial public release. -[Unreleased]: https://github.com/slackhq/nebula/compare/v1.10.0...HEAD +[Unreleased]: https://github.com/slackhq/nebula/compare/v1.10.2...HEAD +[1.10.2]: https://github.com/slackhq/nebula/releases/tag/v1.10.2 +[1.10.1]: https://github.com/slackhq/nebula/releases/tag/v1.10.1 [1.10.0]: https://github.com/slackhq/nebula/releases/tag/v1.10.0 [1.9.7]: https://github.com/slackhq/nebula/releases/tag/v1.9.7 [1.9.6]: https://github.com/slackhq/nebula/releases/tag/v1.9.6 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/cert/cert.go new/nebula-1.10.2/cert/cert.go --- old/nebula-1.10.0/cert/cert.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/cert/cert.go 2026-01-21 18:42:34.000000000 +0100 @@ -119,6 +119,7 @@ // Recombine will attempt to unmarshal a certificate received in a handshake. // Handshakes save space by placing the peers public key in a different part of the packet, we have to // reassemble the actual certificate structure with that in mind. +// Implementations MUST assert the public key is not in the raw certificate bytes if the passed in public key is not empty. func Recombine(v Version, rawCertBytes, publicKey []byte, curve Curve) (Certificate, error) { if publicKey == nil { return nil, ErrNoPeerStaticKey diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/cert/cert_v1.go new/nebula-1.10.2/cert/cert_v1.go --- old/nebula-1.10.0/cert/cert_v1.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/cert/cert_v1.go 2026-01-21 18:42:34.000000000 +0100 @@ -426,7 +426,7 @@ unsafeNetworks: make([]netip.Prefix, len(rc.Details.Subnets)/2), notBefore: time.Unix(rc.Details.NotBefore, 0), notAfter: time.Unix(rc.Details.NotAfter, 0), - publicKey: make([]byte, len(rc.Details.PublicKey)), + publicKey: nil, isCA: rc.Details.IsCA, curve: rc.Details.Curve, }, @@ -437,12 +437,19 @@ copy(nc.details.groups, rc.Details.Groups) nc.details.issuer = hex.EncodeToString(rc.Details.Issuer) + // If a public key is passed in as an argument, the certificate pubkey must be empty + // and the passed-in pubkey copied into the cert. if len(publicKey) > 0 { - nc.details.publicKey = publicKey + if len(rc.Details.PublicKey) != 0 { + return nil, ErrCertPubkeyPresent + } + nc.details.publicKey = make([]byte, len(publicKey)) + copy(nc.details.publicKey, publicKey) + } else { + nc.details.publicKey = make([]byte, len(rc.Details.PublicKey)) + copy(nc.details.publicKey, rc.Details.PublicKey) } - copy(nc.details.publicKey, rc.Details.PublicKey) - var ip netip.Addr for i, rawIp := range rc.Details.Ips { if i%2 == 0 { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/cert/cert_v1_test.go new/nebula-1.10.2/cert/cert_v1_test.go --- old/nebula-1.10.0/cert/cert_v1_test.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/cert/cert_v1_test.go 2026-01-21 18:42:34.000000000 +0100 @@ -62,6 +62,62 @@ assert.Equal(t, nc.Groups(), nc2.Groups()) } +func TestCertificateV1_Unmarshal(t *testing.T) { + t.Parallel() + before := time.Now().Add(time.Second * -60).Round(time.Second) + after := time.Now().Add(time.Second * 60).Round(time.Second) + pubKey := []byte("1234567890abcedfghij1234567890ab") + invalidPubkey := []byte("00000000000000000000000000000000") + + nc := certificateV1{ + details: detailsV1{ + name: "testing", + networks: []netip.Prefix{ + mustParsePrefixUnmapped("10.1.1.1/24"), + mustParsePrefixUnmapped("10.1.1.2/16"), + }, + unsafeNetworks: []netip.Prefix{ + mustParsePrefixUnmapped("9.1.1.2/24"), + mustParsePrefixUnmapped("9.1.1.3/16"), + }, + groups: []string{"test-group1", "test-group2", "test-group3"}, + notBefore: before, + notAfter: after, + publicKey: pubKey, + isCA: false, + issuer: "1234567890abcedfghij1234567890ab", + }, + signature: []byte("1234567890abcedfghij1234567890ab"), + } + + // This certificate has a pubkey included + certWithPubkey, err := nc.Marshal() + require.NoError(t, err) + + // This certificate is missing the pubkey section + certWithoutPubkey, err := nc.MarshalForHandshakes() + require.NoError(t, err) + + // Cert has no pubkey and no pubkey passed in must fail to validate + isNil, err := unmarshalCertificateV1(certWithoutPubkey, nil) + require.Error(t, err) + + // Cert has different pubkey than one passed in must fail + isNil, err = unmarshalCertificateV1(certWithPubkey, invalidPubkey) + require.Nil(t, isNil) + require.Error(t, err) + + // Cert has pubkey and no pubkey argument works ok + _, err = unmarshalCertificateV1(certWithPubkey, nil) + require.NoError(t, err) + + // Cert has no pubkey and valid, correctly signed pubkey passed in + nc2, err := unmarshalCertificateV1(certWithoutPubkey, pubKey) + require.NoError(t, err) + + assert.Equal(t, pubKey, nc2.PublicKey()) +} + func TestCertificateV1_PublicKeyPem(t *testing.T) { t.Parallel() before := time.Now().Add(time.Second * -60).Round(time.Second) @@ -100,12 +156,18 @@ AAAAAAAAAAAAAAAAAAAAAAA= -----END NEBULA P256 PUBLIC KEY----- `) + + pubP256KeyPemCA := []byte(`-----BEGIN NEBULA ECDSA P256 PUBLIC KEY----- +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAA= +-----END NEBULA ECDSA P256 PUBLIC KEY----- +`) pubP256Key, _, _, err := UnmarshalPublicKeyFromPEM(pubP256KeyPem) require.NoError(t, err) nc.details.curve = Curve_P256 nc.details.publicKey = pubP256Key assert.Equal(t, Curve_P256, nc.Curve()) - assert.Equal(t, string(nc.MarshalPublicKeyPEM()), string(pubP256KeyPem)) + assert.Equal(t, string(nc.MarshalPublicKeyPEM()), string(pubP256KeyPemCA)) assert.True(t, nc.IsCA()) nc.details.isCA = false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/cert/cert_v2.go new/nebula-1.10.2/cert/cert_v2.go --- old/nebula-1.10.0/cert/cert_v2.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/cert/cert_v2.go 2026-01-21 18:42:34.000000000 +0100 @@ -592,7 +592,13 @@ // Maybe grab the public key var rawPublicKey cryptobyte.String if len(publicKey) > 0 { - rawPublicKey = publicKey + // If a public key is passed in, then the handshake certificate must + // not have a public key present + if input.PeekASN1Tag(TagCertPublicKey) { + return nil, ErrCertPubkeyPresent + } + rawPublicKey = make(cryptobyte.String, len(publicKey)) + copy(rawPublicKey, publicKey) } else if !input.ReadOptionalASN1(&rawPublicKey, nil, TagCertPublicKey) { return nil, ErrBadFormat } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/cert/cert_v2_test.go new/nebula-1.10.2/cert/cert_v2_test.go --- old/nebula-1.10.0/cert/cert_v2_test.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/cert/cert_v2_test.go 2026-01-21 18:42:34.000000000 +0100 @@ -76,6 +76,58 @@ assert.Equal(t, nc.Groups(), nc2.Groups()) } +func TestCertificateV2_Unmarshal(t *testing.T) { + t.Parallel() + before := time.Now().Add(time.Second * -60).Round(time.Second) + after := time.Now().Add(time.Second * 60).Round(time.Second) + pubKey := []byte("1234567890abcedfghij1234567890ab") + + nc := certificateV2{ + details: detailsV2{ + name: "testing", + networks: []netip.Prefix{ + mustParsePrefixUnmapped("10.1.1.2/16"), + mustParsePrefixUnmapped("10.1.1.1/24"), + }, + unsafeNetworks: []netip.Prefix{ + mustParsePrefixUnmapped("9.1.1.3/16"), + mustParsePrefixUnmapped("9.1.1.2/24"), + }, + groups: []string{"test-group1", "test-group2", "test-group3"}, + notBefore: before, + notAfter: after, + isCA: false, + issuer: "1234567890abcdef1234567890abcdef", + }, + signature: []byte("1234567890abcdef1234567890abcdef"), + publicKey: pubKey, + } + + db, err := nc.details.Marshal() + require.NoError(t, err) + nc.rawDetails = db + + certWithPubkey, err := nc.Marshal() + require.NoError(t, err) + //t.Log("Cert size:", len(b)) + certWithoutPubkey, err := nc.MarshalForHandshakes() + require.NoError(t, err) + + // Cert must not have a pubkey if one is passed in as an argument + _, err = unmarshalCertificateV2(certWithPubkey, pubKey, Curve_CURVE25519) + require.ErrorIs(t, err, ErrCertPubkeyPresent) + + // Certs must have pubkeys + _, err = unmarshalCertificateV2(certWithoutPubkey, nil, Curve_CURVE25519) + require.ErrorIs(t, err, ErrBadFormat) + + // Ensure proper unmarshal if a pubkey is passed in + nc2, err := unmarshalCertificateV2(certWithoutPubkey, pubKey, Curve_CURVE25519) + require.NoError(t, err) + + assert.Equal(t, nc.PublicKey(), nc2.PublicKey()) +} + func TestCertificateV2_PublicKeyPem(t *testing.T) { t.Parallel() before := time.Now().Add(time.Second * -60).Round(time.Second) @@ -114,12 +166,19 @@ AAAAAAAAAAAAAAAAAAAAAAA= -----END NEBULA P256 PUBLIC KEY----- `) + + pubP256KeyPemCA := []byte(`-----BEGIN NEBULA ECDSA P256 PUBLIC KEY----- +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAA= +-----END NEBULA ECDSA P256 PUBLIC KEY----- +`) + pubP256Key, _, _, err := UnmarshalPublicKeyFromPEM(pubP256KeyPem) require.NoError(t, err) nc.curve = Curve_P256 nc.publicKey = pubP256Key assert.Equal(t, Curve_P256, nc.Curve()) - assert.Equal(t, string(nc.MarshalPublicKeyPEM()), string(pubP256KeyPem)) + assert.Equal(t, string(nc.MarshalPublicKeyPEM()), string(pubP256KeyPemCA)) assert.True(t, nc.IsCA()) nc.details.isCA = false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/cert/crypto_test.go new/nebula-1.10.2/cert/crypto_test.go --- old/nebula-1.10.0/cert/crypto_test.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/cert/crypto_test.go 2026-01-21 18:42:34.000000000 +0100 @@ -79,7 +79,7 @@ assert.Nil(t, k) assert.Equal(t, rest, invalidPem) - // Fail due to ivalid PEM format, because + // Fail due to invalid PEM format, because // it's missing the requisite pre-encapsulation boundary. curve, k, rest, err = DecryptAndUnmarshalSigningPrivateKey(passphrase, rest) require.EqualError(t, err, "input did not contain a valid PEM encoded block") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/cert/errors.go new/nebula-1.10.2/cert/errors.go --- old/nebula-1.10.0/cert/errors.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/cert/errors.go 2026-01-21 18:42:34.000000000 +0100 @@ -21,6 +21,7 @@ ErrPrivateKeyEncrypted = errors.New("private key must be decrypted") ErrCaNotFound = errors.New("could not find ca for the certificate") ErrUnknownVersion = errors.New("certificate version unrecognized") + ErrCertPubkeyPresent = errors.New("certificate has unexpected pubkey present") ErrInvalidPEMBlock = errors.New("input did not contain a valid PEM encoded block") ErrInvalidPEMCertificateBanner = errors.New("bytes did not contain a proper certificate banner") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/cert/pem.go new/nebula-1.10.2/cert/pem.go --- old/nebula-1.10.0/cert/pem.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/cert/pem.go 2026-01-21 18:42:34.000000000 +0100 @@ -86,7 +86,7 @@ case Curve_CURVE25519: return pem.EncodeToMemory(&pem.Block{Type: Ed25519PublicKeyBanner, Bytes: b}) case Curve_P256: - return pem.EncodeToMemory(&pem.Block{Type: P256PublicKeyBanner, Bytes: b}) + return pem.EncodeToMemory(&pem.Block{Type: ECDSAP256PublicKeyBanner, Bytes: b}) default: return nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/cert/pem_test.go new/nebula-1.10.2/cert/pem_test.go --- old/nebula-1.10.0/cert/pem_test.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/cert/pem_test.go 2026-01-21 18:42:34.000000000 +0100 @@ -44,7 +44,7 @@ assert.Equal(t, rest, invalidPem) require.EqualError(t, err, "bytes did not contain a proper certificate banner") - // Fail due to ivalid PEM format, because + // Fail due to invalid PEM format, because // it's missing the requisite pre-encapsulation boundary. cert, rest, err = UnmarshalCertificateFromPEM(rest) assert.Nil(t, cert) @@ -106,7 +106,7 @@ assert.Equal(t, rest, invalidPem) require.EqualError(t, err, "bytes did not contain a proper Ed25519/ECDSA private key banner") - // Fail due to ivalid PEM format, because + // Fail due to invalid PEM format, because // it's missing the requisite pre-encapsulation boundary. k, rest, curve, err = UnmarshalSigningPrivateKeyFromPEM(rest) assert.Nil(t, k) @@ -168,7 +168,7 @@ assert.Equal(t, rest, invalidPem) require.EqualError(t, err, "bytes did not contain a proper private key banner") - // Fail due to ivalid PEM format, because + // Fail due to invalid PEM format, because // it's missing the requisite pre-encapsulation boundary. k, rest, curve, err = UnmarshalPrivateKeyFromPEM(rest) assert.Nil(t, k) @@ -221,7 +221,7 @@ require.EqualError(t, err, "bytes did not contain a proper public key banner") assert.Equal(t, rest, invalidPem) - // Fail due to ivalid PEM format, because + // Fail due to invalid PEM format, because // it's missing the requisite pre-encapsulation boundary. k, rest, curve, err = UnmarshalPublicKeyFromPEM(rest) assert.Nil(t, k) @@ -299,7 +299,7 @@ require.EqualError(t, err, "bytes did not contain a proper public key banner") assert.Equal(t, rest, invalidPem) - // Fail due to ivalid PEM format, because + // Fail due to invalid PEM format, because // it's missing the requisite pre-encapsulation boundary. k, rest, curve, err = UnmarshalPublicKeyFromPEM(rest) assert.Nil(t, k) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/cmd/nebula-cert/ca_test.go new/nebula-1.10.2/cmd/nebula-cert/ca_test.go --- old/nebula-1.10.0/cmd/nebula-cert/ca_test.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/cmd/nebula-cert/ca_test.go 2026-01-21 18:42:34.000000000 +0100 @@ -200,7 +200,7 @@ assert.Empty(t, b) assert.Len(t, lKey, 64) - // test when reading passsword results in an error + // test when reading password results in an error os.Remove(keyF.Name()) os.Remove(crtF.Name()) ob.Reset() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/e2e/helpers_test.go new/nebula-1.10.2/e2e/helpers_test.go --- old/nebula-1.10.0/e2e/helpers_test.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/e2e/helpers_test.go 2026-01-21 18:42:34.000000000 +0100 @@ -304,7 +304,7 @@ assertUdpPacket(t, []byte("Hello from A"), aPacket, vpnIpA, vpnIpB, 90, 80) } -func assertHostInfoPair(t *testing.T, addrA, addrB netip.AddrPort, vpnNetsA, vpnNetsB []netip.Prefix, controlA, controlB *nebula.Control) { +func assertHostInfoPair(t testing.TB, addrA, addrB netip.AddrPort, vpnNetsA, vpnNetsB []netip.Prefix, controlA, controlB *nebula.Control) { // Get both host infos //TODO: CERT-V2 we may want to loop over each vpnAddr and assert all the things hBinA := controlA.GetHostInfoByVpnAddr(vpnNetsB[0].Addr(), false) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/examples/config.yml new/nebula-1.10.2/examples/config.yml --- old/nebula-1.10.0/examples/config.yml 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/examples/config.yml 2026-01-21 18:42:34.000000000 +0100 @@ -144,6 +144,10 @@ # valid values: always, never, private # This setting is reloadable. #send_recv_error: always + # Similar to send_recv_error, this option lets you configure if you want to accept "recv_error" packets from remote hosts. + # valid values: always, never, private + # This setting is reloadable. + #accept_recv_error: always # The so_sock option is a Linux-specific feature that allows all outgoing Nebula packets to be tagged with a specific identifier. # This tagging enables IP rule-based filtering. For example, it supports 0.0.0.0/0 unsafe_routes, # allowing for more precise routing decisions based on the packet tags. Default is 0 meaning no mark is set. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/go.mod new/nebula-1.10.2/go.mod --- old/nebula-1.10.0/go.mod 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/go.mod 2026-01-21 18:42:34.000000000 +0100 @@ -12,27 +12,27 @@ github.com/gogo/protobuf v1.3.2 github.com/google/gopacket v1.1.19 github.com/kardianos/service v1.2.4 - github.com/miekg/dns v1.1.68 + github.com/miekg/dns v1.1.70 github.com/miekg/pkcs11 v1.1.2-0.20231115102856-9078ad6b9d4b github.com/nbrownus/go-metrics-prometheus v0.0.0-20210712211119-974a6260965f github.com/prometheus/client_golang v1.23.2 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 - github.com/sirupsen/logrus v1.9.3 + github.com/sirupsen/logrus v1.9.4 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 github.com/stretchr/testify v1.11.1 github.com/vishvananda/netlink v1.3.1 go.yaml.in/yaml/v3 v3.0.4 - golang.org/x/crypto v0.45.0 + golang.org/x/crypto v0.47.0 golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 - golang.org/x/net v0.47.0 - golang.org/x/sync v0.18.0 - golang.org/x/sys v0.38.0 - golang.org/x/term v0.37.0 + golang.org/x/net v0.49.0 + golang.org/x/sync v0.19.0 + golang.org/x/sys v0.40.0 + golang.org/x/term v0.39.0 golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 golang.zx2c4.com/wireguard v0.0.0-20230325221338-052af4a8072b golang.zx2c4.com/wireguard/windows v0.5.3 - google.golang.org/protobuf v1.36.10 + google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v3 v3.0.1 gvisor.dev/gvisor v0.0.0-20240423190808-9d7a357edefe ) @@ -49,7 +49,7 @@ github.com/prometheus/procfs v0.16.1 // indirect github.com/vishvananda/netns v0.0.5 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/mod v0.24.0 // indirect + golang.org/x/mod v0.31.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.33.0 // indirect + golang.org/x/tools v0.40.0 // indirect ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/go.sum new/nebula-1.10.2/go.sum --- old/nebula-1.10.0/go.sum 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/go.sum 2026-01-21 18:42:34.000000000 +0100 @@ -83,8 +83,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA= -github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps= +github.com/miekg/dns v1.1.70 h1:DZ4u2AV35VJxdD9Fo9fIWm119BsQL5cZU1cQ9s0LkqA= +github.com/miekg/dns v1.1.70/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= github.com/miekg/pkcs11 v1.1.2-0.20231115102856-9078ad6b9d4b h1:J/AzCvg5z0Hn1rqZUJjpbzALUmkKX0Zwbc/i4fw7Sfk= github.com/miekg/pkcs11 v1.1.2-0.20231115102856-9078ad6b9d4b/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -131,8 +131,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw= @@ -162,16 +162,16 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q= -golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4= +golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= +golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/exp v0.0.0-20230725093048-515e97ebf090 h1:Di6/M8l0O2lCLc6VVRWhgCiApHV8MnQurBnFSHsQtNY= golang.org/x/exp v0.0.0-20230725093048-515e97ebf090/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -182,8 +182,8 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -191,8 +191,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -206,14 +206,13 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -224,8 +223,8 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= -golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -244,8 +243,8 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/handshake_ix.go new/nebula-1.10.2/handshake_ix.go --- old/nebula-1.10.0/handshake_ix.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/handshake_ix.go 2026-01-21 18:42:34.000000000 +0100 @@ -1,6 +1,7 @@ package nebula import ( + "bytes" "net/netip" "time" @@ -166,6 +167,13 @@ return } + if !bytes.Equal(remoteCert.Certificate.PublicKey(), ci.H.PeerStatic()) { + f.l.WithField("from", via). + WithField("handshake", m{"stage": 1, "style": "ix_psk0"}). + WithField("cert", remoteCert).Info("public key mismatch between certificate and handshake") + return + } + if remoteCert.Certificate.Version() != ci.myCert.Version() { // We started off using the wrong certificate version, lets see if we can match the version that was sent to us myCertOtherVersion := cs.getCertificate(remoteCert.Certificate.Version()) @@ -535,6 +543,12 @@ e.Info("Invalid certificate from host") return true } + if !bytes.Equal(remoteCert.Certificate.PublicKey(), ci.H.PeerStatic()) { + f.l.WithField("from", via). + WithField("handshake", m{"stage": 2, "style": "ix_psk0"}). + WithField("cert", remoteCert).Info("public key mismatch between certificate and handshake") + return true + } if len(remoteCert.Certificate.Networks()) == 0 { f.l.WithError(err).WithField("from", via). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/interface.go new/nebula-1.10.2/interface.go --- old/nebula-1.10.0/interface.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/interface.go 2026-01-21 18:42:34.000000000 +0100 @@ -77,7 +77,8 @@ reQueryEvery atomic.Uint32 reQueryWait atomic.Int64 - sendRecvErrorConfig sendRecvErrorConfig + sendRecvErrorConfig recvErrorConfig + acceptRecvErrorConfig recvErrorConfig // rebindCount is used to decide if an active tunnel should trigger a punch notification through a lighthouse rebindCount int8 @@ -110,34 +111,34 @@ GetCertState() *CertState } -type sendRecvErrorConfig uint8 +type recvErrorConfig uint8 const ( - sendRecvErrorAlways sendRecvErrorConfig = iota - sendRecvErrorNever - sendRecvErrorPrivate + recvErrorAlways recvErrorConfig = iota + recvErrorNever + recvErrorPrivate ) -func (s sendRecvErrorConfig) ShouldSendRecvError(endpoint netip.AddrPort) bool { +func (s recvErrorConfig) ShouldRecvError(endpoint netip.AddrPort) bool { switch s { - case sendRecvErrorPrivate: + case recvErrorPrivate: return endpoint.Addr().IsPrivate() - case sendRecvErrorAlways: + case recvErrorAlways: return true - case sendRecvErrorNever: + case recvErrorNever: return false default: - panic(fmt.Errorf("invalid sendRecvErrorConfig value: %d", s)) + panic(fmt.Errorf("invalid recvErrorConfig value: %d", s)) } } -func (s sendRecvErrorConfig) String() string { +func (s recvErrorConfig) String() string { switch s { - case sendRecvErrorAlways: + case recvErrorAlways: return "always" - case sendRecvErrorNever: + case recvErrorNever: return "never" - case sendRecvErrorPrivate: + case recvErrorPrivate: return "private" default: return fmt.Sprintf("invalid(%d)", s) @@ -312,6 +313,7 @@ func (f *Interface) RegisterConfigChangeCallbacks(c *config.C) { c.RegisterReloadCallback(f.reloadFirewall) c.RegisterReloadCallback(f.reloadSendRecvError) + c.RegisterReloadCallback(f.reloadAcceptRecvError) c.RegisterReloadCallback(f.reloadDisconnectInvalid) c.RegisterReloadCallback(f.reloadMisc) @@ -375,16 +377,16 @@ switch stringValue { case "always": - f.sendRecvErrorConfig = sendRecvErrorAlways + f.sendRecvErrorConfig = recvErrorAlways case "never": - f.sendRecvErrorConfig = sendRecvErrorNever + f.sendRecvErrorConfig = recvErrorNever case "private": - f.sendRecvErrorConfig = sendRecvErrorPrivate + f.sendRecvErrorConfig = recvErrorPrivate default: if c.GetBool("listen.send_recv_error", true) { - f.sendRecvErrorConfig = sendRecvErrorAlways + f.sendRecvErrorConfig = recvErrorAlways } else { - f.sendRecvErrorConfig = sendRecvErrorNever + f.sendRecvErrorConfig = recvErrorNever } } @@ -393,6 +395,30 @@ } } +func (f *Interface) reloadAcceptRecvError(c *config.C) { + if c.InitialLoad() || c.HasChanged("listen.accept_recv_error") { + stringValue := c.GetString("listen.accept_recv_error", "always") + + switch stringValue { + case "always": + f.acceptRecvErrorConfig = recvErrorAlways + case "never": + f.acceptRecvErrorConfig = recvErrorNever + case "private": + f.acceptRecvErrorConfig = recvErrorPrivate + default: + if c.GetBool("listen.accept_recv_error", true) { + f.acceptRecvErrorConfig = recvErrorAlways + } else { + f.acceptRecvErrorConfig = recvErrorNever + } + } + + f.l.WithField("acceptRecvError", f.acceptRecvErrorConfig.String()). + Info("Loaded accept_recv_error config") + } +} + func (f *Interface) reloadMisc(c *config.C) { if c.HasChanged("counters.try_promote") { n := c.GetUint32("counters.try_promote", defaultPromoteEvery) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/main.go new/nebula-1.10.2/main.go --- old/nebula-1.10.0/main.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/main.go 2026-01-21 18:42:34.000000000 +0100 @@ -265,6 +265,7 @@ ifce.RegisterConfigChangeCallbacks(c) ifce.reloadDisconnectInvalid(c) ifce.reloadSendRecvError(c) + ifce.reloadAcceptRecvError(c) handshakeManager.f = ifce go handshakeManager.Run(ctx) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/noiseutil/boring.go new/nebula-1.10.2/noiseutil/boring.go --- old/nebula-1.10.0/noiseutil/boring.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/noiseutil/boring.go 2026-01-21 18:42:34.000000000 +0100 @@ -22,7 +22,7 @@ // NewGCMTLS is no longer exposed in go1.19+, so we need to link it in // See: https://github.com/golang/go/issues/56326 // -// NewGCMTLS is the internal method used with boringcrypto that provices a +// NewGCMTLS is the internal method used with boringcrypto that provides a // validated mode of AES-GCM which enforces the nonce is strictly // monotonically increasing. This is the TLS 1.2 specification for nonce // generation (which also matches the method used by the Noise Protocol) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/outside.go new/nebula-1.10.2/outside.go --- old/nebula-1.10.0/outside.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/outside.go 2026-01-21 18:42:34.000000000 +0100 @@ -516,7 +516,7 @@ } func (f *Interface) maybeSendRecvError(endpoint netip.AddrPort, index uint32) { - if f.sendRecvErrorConfig.ShouldSendRecvError(endpoint) { + if f.sendRecvErrorConfig.ShouldRecvError(endpoint) { f.sendRecvError(endpoint, index) } } @@ -534,6 +534,13 @@ } func (f *Interface) handleRecvError(addr netip.AddrPort, h *header.H) { + if !f.acceptRecvErrorConfig.ShouldRecvError(addr) { + f.l.WithField("index", h.RemoteIndex). + WithField("udpAddr", addr). + Debug("Recv error received, ignoring") + return + } + if f.l.Level >= logrus.DebugLevel { f.l.WithField("index", h.RemoteIndex). WithField("udpAddr", addr). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/overlay/tun_linux.go new/nebula-1.10.2/overlay/tun_linux.go --- old/nebula-1.10.0/overlay/tun_linux.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/overlay/tun_linux.go 2026-01-21 18:42:34.000000000 +0100 @@ -10,6 +10,7 @@ "net/netip" "os" "strings" + "sync" "sync/atomic" "time" "unsafe" @@ -40,6 +41,11 @@ useSystemRoutes bool useSystemRoutesBufferSize int + // These are routes learned from `tun.use_system_route_table` + // stored here to make it easier to restore them after a reload + routesFromSystem map[netip.Prefix]routing.Gateways + routesFromSystemLock sync.Mutex + l *logrus.Logger } @@ -131,6 +137,7 @@ TXQueueLen: c.GetInt("tun.tx_queue", 500), useSystemRoutes: c.GetBool("tun.use_system_route_table", false), useSystemRoutesBufferSize: c.GetInt("tun.use_system_route_table_buffer_size", 0), + routesFromSystem: map[netip.Prefix]routing.Gateways{}, l: l, } @@ -164,6 +171,13 @@ return err } + // Bring along any routes learned from the system route table on reload + t.routesFromSystemLock.Lock() + for dst, gw := range t.routesFromSystem { + routeTree.Insert(dst, gw) + } + t.routesFromSystemLock.Unlock() + oldDefaultMTU := t.DefaultMTU oldMaxMTU := t.MaxMTU newDefaultMTU := c.GetInt("tun.mtu", DefaultMTU) @@ -673,14 +687,18 @@ newTree := t.routeTree.Load().Clone() + t.routesFromSystemLock.Lock() if r.Type == unix.RTM_NEWROUTE { t.l.WithField("destination", dst).WithField("via", gateways).Info("Adding route") + t.routesFromSystem[dst] = gateways newTree.Insert(dst, gateways) } else { t.l.WithField("destination", dst).WithField("via", gateways).Info("Removing route") + delete(t.routesFromSystem, dst) newTree.Delete(dst) } + t.routesFromSystemLock.Unlock() t.routeTree.Store(newTree) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/routing/gateway.go new/nebula-1.10.2/routing/gateway.go --- old/nebula-1.10.0/routing/gateway.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/routing/gateway.go 2026-01-21 18:42:34.000000000 +0100 @@ -6,7 +6,7 @@ ) const ( - // Sentinal value + // Sentinel value BucketNotCalculated = -1 ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/udp/udp_generic.go new/nebula-1.10.2/udp/udp_generic.go --- old/nebula-1.10.0/udp/udp_generic.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/udp/udp_generic.go 2026-01-21 18:42:34.000000000 +0100 @@ -10,9 +10,11 @@ import ( "context" + "errors" "fmt" "net" "net/netip" + "time" "github.com/sirupsen/logrus" "github.com/slackhq/nebula/config" @@ -74,12 +76,22 @@ func (u *GenericConn) ListenOut(r EncReader) { buffer := make([]byte, MTU) + var lastRecvErr time.Time + for { // Just read one packet at a time n, rua, err := u.ReadFromUDPAddrPort(buffer) if err != nil { - u.l.WithError(err).Debug("udp socket is closed, exiting read loop") - return + if errors.Is(err, net.ErrClosed) { + u.l.WithError(err).Debug("udp socket is closed, exiting read loop") + return + } + // Dampen unexpected message warns to once per minute + if lastRecvErr.IsZero() || time.Since(lastRecvErr) > time.Minute { + lastRecvErr = time.Now() + u.l.WithError(err).Warn("unexpected udp socket receive error") + } + continue } r(netip.AddrPortFrom(rua.Addr().Unmap(), rua.Port()), buffer[:n]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nebula-1.10.0/udp/udp_rio_windows.go new/nebula-1.10.2/udp/udp_rio_windows.go --- old/nebula-1.10.0/udp/udp_rio_windows.go 2025-12-04 20:42:31.000000000 +0100 +++ new/nebula-1.10.2/udp/udp_rio_windows.go 2026-01-21 18:42:34.000000000 +0100 @@ -14,6 +14,7 @@ "sync" "sync/atomic" "syscall" + "time" "unsafe" "github.com/sirupsen/logrus" @@ -66,7 +67,7 @@ u := &RIOConn{l: l} - err := u.bind(&windows.SockaddrInet6{Addr: addr.As16(), Port: port}) + err := u.bind(l, &windows.SockaddrInet6{Addr: addr.As16(), Port: port}) if err != nil { return nil, fmt.Errorf("bind: %w", err) } @@ -82,11 +83,11 @@ return u, nil } -func (u *RIOConn) bind(sa windows.Sockaddr) error { +func (u *RIOConn) bind(l *logrus.Logger, sa windows.Sockaddr) error { var err error u.sock, err = winrio.Socket(windows.AF_INET6, windows.SOCK_DGRAM, windows.IPPROTO_UDP) if err != nil { - return err + return fmt.Errorf("winrio.Socket error: %w", err) } // Enable v4 for this socket @@ -100,35 +101,40 @@ size := uint32(unsafe.Sizeof(flag)) err = syscall.WSAIoctl(syscall.Handle(u.sock), syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0) if err != nil { - return err + // This is a best-effort to prevent errors from being returned by the udp recv operation. + // Quietly log a failure and continue. + l.WithError(err).Debug("failed to set UDP_CONNRESET ioctl") } + ret = 0 flag = 0 size = uint32(unsafe.Sizeof(flag)) SIO_UDP_NETRESET := uint32(syscall.IOC_IN | syscall.IOC_VENDOR | 15) err = syscall.WSAIoctl(syscall.Handle(u.sock), SIO_UDP_NETRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0) if err != nil { - return err + // This is a best-effort to prevent errors from being returned by the udp recv operation. + // Quietly log a failure and continue. + l.WithError(err).Debug("failed to set UDP_NETRESET ioctl") } err = u.rx.Open() if err != nil { - return err + return fmt.Errorf("error rx.Open(): %w", err) } err = u.tx.Open() if err != nil { - return err + return fmt.Errorf("error tx.Open(): %w", err) } u.rq, err = winrio.CreateRequestQueue(u.sock, packetsPerRing, 1, packetsPerRing, 1, u.rx.cq, u.tx.cq, 0) if err != nil { - return err + return fmt.Errorf("error CreateRequestQueue: %w", err) } err = windows.Bind(u.sock, sa) if err != nil { - return err + return fmt.Errorf("error windows.Bind(): %w", err) } return nil @@ -137,15 +143,22 @@ func (u *RIOConn) ListenOut(r EncReader) { buffer := make([]byte, MTU) + var lastRecvErr time.Time + for { // Just read one packet at a time n, rua, err := u.receive(buffer) + if err != nil { if errors.Is(err, net.ErrClosed) { u.l.WithError(err).Debug("udp socket is closed, exiting read loop") return } - u.l.WithError(err).Error("unexpected udp socket receive error") + // Dampen unexpected message warns to once per minute + if lastRecvErr.IsZero() || time.Since(lastRecvErr) > time.Minute { + lastRecvErr = time.Now() + u.l.WithError(err).Warn("unexpected udp socket receive error") + } continue } ++++++ vendor.tar.zst ++++++ ++++ 8524 lines of diff (skipped)
