Enhance the user experience by enabling authentication to Netbird using Single Sign-On (SSO) with any Identity Provider (IDP) provider. Current client offers this capability through the Device Authorization Flow, however, is not widely supported by many IDPs, and even some that do support it do not provide a complete verification URL.
To address these challenges, this pull request enable Authorization Code Flow with Proof Key for Code Exchange (PKCE) for client logins, which is a more widely adopted and secure approach to facilitate SSO with various IDP providers.
EBPF proxy between TURN (relay) and WireGuard to reduce number of used ports used by the NetBird agent.
- Separate the wg configuration from the proxy logic
- In case if eBPF type proxy has only one single proxy instance
- In case if the eBPF is not supported fallback to the original proxy Implementation
Between the signature of eBPF type proxy and original proxy has
differences so this is why the factory structure exists
* use ipset for iptables
* Update unit-tests for iptables
* Remove debug code
* Update dependencies
* Create separate sets for dPort and sPort rules
* Fix iptables tests
* Fix 0.0.0.0 processing in iptables with ipset
* Optimize rules with All groups
* Use IP sets in ACLs (nftables implementation)
* Fix squash rule when we receive optimized rules list from management
* Add DNS list argument for mobile client
* Write testable code
Many places are checked the wgInterface != nil condition.
It is doing it just because to avoid the real wgInterface creation for tests.
Instead of this involve a wgInterface interface what is moc-able.
* Refactor the DNS server internal code structure
With the fake resolver has been involved several
if-else statement and generated some unused
variables to distinguish the listener and fake
resolver solutions at running time. With this
commit the fake resolver and listener based
solution has been moved into two separated
structure. Name of this layer is the 'service'.
With this modification the unit test looks
simpler and open the option to add new logic for
the permanent DNS service usage for mobile
systems.
* Remove is running check in test
We can not ensure the state well so remove this
check. The test will fail if the server is not
running well.
* ACL firewall manager fix/improvement
Fix issue with rule squashing, it contained issue when calculated
total amount of IPs in the Peer map (doesn't included offline peers).
That why squashing not worked.
Also this commit changes the rules apply behaviour. Instead policy:
1. Apply all rules from network map
2. Remove all previous applied rules
We do:
1. Apply only new rules
2. Remove outdated rules
Why first variant was implemented: because when you have drop policy
it is important in which order order you rules are and you need totally
clean previous state to apply the new. But in the release we didn't
include drop policy so we can do this improvement.
* Print log message about processed ACL rules
Reduce the peer status notifications
When receive new network map invoke multiple notifications for
every single peers. It cause high cpu usage We handle the in a
batch the peer notification in update network map.
- Remove the unnecessary UpdatePeerFQDN calls in addNewPeer
- Fix notification in RemovePeer function
- Involve FinishPeerListModifications logic
Works only with userspace implementation:
1. Configure host to solve DNS requests via a fake DSN server address in the Netbird network.
2. Add to firewall catch rule for these DNS requests.
3. Resolve these DNS requests and respond by writing directly to wireguard device.
Prevent peer updates if the status is not changing from disconnected to connected and vice versa.
Fixed route score calculation, added tests and changed the log message
fixed installer /usr/local/bin creation
* Extend protocol and firewall manager to handle old management
* Send correct empty firewall rules list when delete peer
* Add extra tests for firewall manager and uspfilter
* Work with inconsistent state
* Review note
* Update comment
Add new feature to notify the user when new client route has arrived.
Refactor the initial route handling. I move every route logic into the route
manager package.
* Add notification management for client rules
* Export the route notification for Android
* Compare the notification based on network range instead of id.
in some cases an IDP device flow expiration time might be shorter than 90s
we should check if the cancel context was set before using it
We will need a follow-up to identify and document the IDP with lower defaults.
fixes#890
Adds functionality to support Identity Provider (IdP) managers
that do not support a complete verification URI in the
device authentication flow.
In cases where the verification_uri_complete field is empty,
the user will be prompted with their user_code,
and the verification_uri field will be used as a fallback
This PR brings support of a shared port between stun (ICE agent) and
the kernel WireGuard
It implements a single port mode for execution with kernel WireGuard
interface using a raw socket listener.
BPF filters ensure that only STUN packets hit the NetBird userspace app
Removed a lot of the proxy logic and direct mode exchange.
Now we are doing an extra hole punch to the remote WireGuard
port for best-effort cases and support to old client's direct mode.
This PR adds supports for the WireGuard userspace implementation
using Bind interface from wireguard-go.
The newly introduced ICEBind struct implements Bind with UDPMux-based
structs from pion/ice to handle hole punching using ICE.
The core implementation was taken from StdBind of wireguard-go.
The result is a single WireGuard port that is used for host and server reflexive candidates.
Relay candidates are still handled separately and will be integrated in the following PRs.
ICEBind checks the incoming packets for being STUN or WireGuard ones
and routes them to UDPMux (to handle hole punching) or to WireGuard respectively.
Refactored updateServerStates and calculateState
added some checks to ensure we are not sending connecting on context canceled
removed some state updates from the RunClient function
Some IDP requires different scope requests and
issue access tokens for different purposes
This change allow for remote configurable scopes
and the use of ID token
On Android, because of the hard SELinux policies can not list the
interfaces of the ICE package. Without it can not generate a host type
candidate. In this pull request, the list of interfaces comes via the Java
interface.
Check SSO support by calling the internal.GetDeviceAuthorizationFlowInfo
Rename LoginSaveConfigIfSSOSupported to SaveConfigIfSSOSupported
Receive device name as input for setup-key login
have a default android name when no context value is provided
log non parsed errors from management registration calls
Fix the status indication in the client service. The status of the
management server and the signal server was incorrect if the network
connection was broken. Basically the status update was not used by
the management and signal library.
Before defining if we will use direct or proxy connection we will exchange a
message with the other peer if the modes match we keep the decision
from the shouldUseProxy function otherwise we skip using direct connection.
Added a feature support message to the signal protocol
The peer login expiration ACL check introduced in #714
filters out peers that are expired and agents receive a network map
without that expired peers.
However, the agents should see those peers in status "Disconnected".
This PR extends the Agent <-> Management protocol
by introducing a new field OfflinePeers
that contain expired peers. Agents keep track of those and display
then just in the Status response.
The ConnStatus is a custom type based on iota
like an enum. The problem was nowhere used to the
benefits of this implementation. All ConnStatus
instances has been compared with strings. I
suppose the reason to do it to avoid a circle
dependency. In this commit the separated status
package has been moved to peer package.
Remove unused, exported functions from engine
Code cleaning in the config.go of the client. This change keep the
logic in original state. The name of the exported function was not
covered well the internal workflow. Without read the comment was not
understandable what is the difference between the GetConfig and
ReadConfig. By the way both of them doing write operation.
Small code cleaning in the iface package. These changes necessary to
get a clean code in case if we involve more platforms. The OS related
functions has been distributed into separate files and it has been
mixed with not OS related logic. The goal is to get a clear picture
of the layer between WireGuard and business logic.
* Disable upstream DNS resolver after several tries and fails
* Add tests for upstream fails
* Use an extra flag to disable domains in DNS upstreams
* Fix hashing IPs of nameservers for updates.
avoid sending admin or management URLs on service start
as it doesn't have an input
Parse management and admin URL when needed
Pass empty admin url on commands to prevent default overwrite
Adding --external-ip-map and --dns-resolver-address to up command and shorthand option to global flags.
Refactor get and read config functions with new ConfigInput type.
updated cobra package to latest release.
This PR adds system activity tracking.
The management service records events like
add/remove peer, group, rule, route, etc.
The activity events are stored in the SQLite event store
and can be queried by the HTTP API.
If peer is deleted in the console,
we set its state as needs login
On Down command we clean any previous state errors
this prevents need for daemon restart
Removed state error wrapping when engine exits, log is enough
Use stdout and stderr log path only if on Linux and attempt to create the path
Update status system with FQDN fields and
status command to display the domain names of remote and local peers
Set some DNS logs to tracing
update readme file
Added host configurators for Linux, Windows, and macOS.
The host configurator will update the peer system configuration
directing DNS queries according to its capabilities.
Some Linux distributions don't support split (match) DNS or custom ports,
and that will be reported to our management system in another PR
Due to peer reconnects when restarting the Management service,
there are lots of SaveStore operations to update peer status.
Store.SavePeerStatus stores peer status separately and the
FileStore implementation stores it in memory.
Added DNS update protocol message
Added sync to clients
Update nameserver API with new fields
Added default NS groups
Added new dns-name flag for the management service append to peer DNS label
If the gateway address would be nil which is
the case on macOS, we return the preferredSrc
added tests for getExistingRIBRouteGateway function
update log message
* Seticon only when status changes
This prevents a memory leak with the systray lib
when setting the icon every 2 seconds causes a large memory consumption
see https://github.com/getlantern/systray/issues/135
* Use fork with permanent fix
* Add additional check for needed kernel modules
* Check if wireguard and tun modules are loaded
If modules are loaded return true, otherwise attempt to load them
* fix state check
* Add module function tests
* Add test execution in container
* run client package tests on docker
* add package comment to new file
* force entrypoint
* add --privileged flag
* clean only if tables where created
* run from within the directories
Handle routes updates from management
Manage routing firewall rules
Manage peer RIB table
Add get peer and get notification channel from the status recorder
Update interface peers allowed IPs
Added additional common blacklisted interfaces
Updated the signal protocol to pass the peer port and netbird version
Co-authored-by: braginini <bangvalo@gmail.com>
Support Generic OAuth 2.0 Device Authorization Grant
as per RFC specification https://www.rfc-editor.org/rfc/rfc8628.
The previous version supported only Auth0 as an IDP backend.
This implementation enables the Interactive SSO Login feature
for any IDP compatible with the specification, e.g., Keycloak.
This PR fixes a race condition that happens
when agents connect to a Signal stream, multiple
times within a short amount of time. Common on
slow and unstable internet connections.
Every time an agent establishes a new connection
to Signal, Signal creates a Stream and writes an entry
to the registry of connected peers storing the stream.
Every time an agent disconnects, Signal removes the
stream from the registry.
Due to unstable connections, the agent could detect
a broken connection, and attempt to reconnect to Signal.
Signal will override the stream, but it might detect
the old broken connection later, causing peer deregistration.
It will deregister the peer leaving the client thinking
it is still connected, rejecting any messages.
All the existing agents by default connect to port 33073 of the
Management service. This value is also stored in the local config.
All the agents won't switch to the new port 443
unless explicitly specified in the config.
We want the transition to be smooth for our users, therefore
this PR adds logic to check whether the old port 33073 can be
changed to 443 and updates the config automatically.
This PR is a part of an effort to use standard ports (443 or 80) that are usually allowed by default in most of the environments.
Right now Management Service runs the Let'sEncrypt manager on port 443, HTTP API server on port 33071,
and a gRPC server on port 33073. There are three separate listeners.
This PR combines these listeners into one.
With this change, the HTTP and gRPC server runs on either 443 with TLS or 80 without TLS
by default (no --port specified).
Let's Encrypt manager always runs on port 443 if enabled.
The backward compatibility server runs on port 33073 (with TLS or without).
HTTP port 33071 is obsolete and not used anymore.
Newly installed agents will connect to port 443 by default instead of port 33073 if not specified otherwise.
When building client without CGO, user.Lookup
attempts to get user from /etc/passwd
Which doesn't have the user as MacOS uses
opendirectoryd as user directory
This PR fixes issues with the terminal when
running netbird ssh to a remote agent.
Every session looks up a user and loads its
profile. If no user is found, the connection is rejected.
The default user is root.
The Management client will try reconnecting in case.
of network issues or non-permanent errors.
If the device was off-boarded, then the client will stop retrying.
This PR adds support for SSH access through the NetBird network
without managing SSH skeys.
NetBird client app has an embedded SSH server (Linux/Mac only)
and a netbird ssh command.
Before this change, NetBird Agent wasn't handling
peer interface configuration changes dynamically.
Also, remote peer configuration changes have
not been applied (e.g. AllowedIPs changed).
Not a very common cause, but still it should be handled.
Now, Agent reacts to PeerConfig changes sent from the
management service and restarts remote connections
if AllowedIps have been changed.
The peer IP allocation logic was allocating sequential peer IP from the 100.64.0.0/10
address block.
Each account is created with a random subnet from 100.64.0.0/10.
The total amount of potential subnets is 64.
The new logic allocates random peer IP
from the account subnet.
This gives us flexibility to add support for
multi subnet accounts without overlapping IPs.
* GetClientID method and increase interval on slow_down err
* Reuse existing authentication flow if is not expired
Created a new struct to hold additional info
about the flow
If there is a waiting sso running, we cancel its context
* Run the up command on a goroutine
* Use time.Until
* Use proper ctx and consistently use goroutine for up/down
* Fix UP calls when state is idle
When we want to login we can call server.Login
It already checks the login status of the peer
* Remove unused status
* Defer close daemon client conn
Co-authored-by: braginini <bangvalo@gmail.com>
Send Desktop UI client version as user-agent to daemon
This is sent on every login request to the management
Parse the GRPC context on the system package and
retrieves the user-agent
Management receives the new UIVersion field and
store in the Peer's system meta
Updated windows installer package generation with
launch UI after install
remove older version
remove wiretrustee
added install and uninstall scripts
Updated brew cask:
run installer script to start daemon
Daemon conflicts with wiretrustee on brew
Removed migrate check on non-root commands like status
CLI CMD is now going to stdout
Added MacOS icons, plist, and cask template file
Adjusted goreleaser with the new name for all builds
Added Icon and update windows-ui build to include it and avoid console
migrated Docker builds to new namespace netbirdio
UI and CLI Clients are now able to use SSO login by default
we will check if the management has configured or supports SSO providers
daemon will handle fetching and waiting for an access token
Oauth package was moved to internal to avoid one extra package at this stage
Secrets were removed from OAuth
CLI clients have less and better output
2 new status were introduced, NeedsLogin and FailedLogin for better messaging
With NeedsLogin we no longer have endless login attempts
The management will validate the JWT as it does in the API
and will register the Peer to the user's account.
New fields were added to grpc messages in management
and client daemon and its clients were updated
Peer has one new field, UserID,
that will hold the id of the user that registered it
JWT middleware CheckJWT got a splitter
and renamed to support validation for non HTTP requests
Added test for adding new Peer with UserID
Lots of tests update because of a new field
Agent systray UI has been extended with
a setting window that allows configuring
management URL, admin URL and
supports pre-shared key.
While for the Netbird managed version
the Settings are not necessary, it helps
to properly configure the self-hosted version.
Add method for rotating access token with refresh tokens
This will be useful for catching expired sessions and
offboarding users
Also added functions to handle secrets. They have to be revisited
as some tests didn't run on CI as they waited some user input, like password
Updates test workflows with serial execution to avoid collision
of ports and resource names.
Also, used -exec sudo flag for UNIX tests and removed not-needed
limits configuration on Linux and added a 5 minutes timeout.
Updated the multi-peer tests in the client/internal/engine_test.go
to provide proper validation when creating or starting
a peer engine instance fails.
As some operations of the tests running on windows
are slow, we will experiment with disabling the Defender before
restoring cache and checkout a repository, then we reenable
it to run the tests.
disabled extra logs for windows interface
When stopping engine, all peer conns have to be closed
and for each peer WireGuard iface is called
to remove WireGuard peer.
This operation happens in a goroutine causing
Engine to remove the whole WireGuard interface before.
Therefore consequent calls to RemovePeer are unsuccessful.
This fix just adds a small delay before removing interface.
* Call start services function for tests
when testing CMDs we were using some global
variables which got replaced by parallel test
Now we will call a single function independently
for each test
When one of the peers has a static public host IP
or both peers are in the same local network
we establish a direct Wireguard connection
bypassing proxy usage.
This helps reduce FD usage and improves
performance.
* Create temp file before saving data
On the event of full disk, we may encounter the case where the
destination file get replaced by an empty file as the
ioutil.WriteFile truncates the destination before write.
* Close the tempFile instance before moving it
* Blacklist Wireguard interfaces for ICE checks
* test: WIP mocking the grpc server for testing the sending of the client information
* WIP: Test_SystemMetaDataFromClient with mocks, todo:
* fix: failing meta data test
* test: add system meta expectation in management client test
* fix: removing deprecated register function, replacing with new one
* fix: removing deprecated register function from mockclient interface impl
* fix: fixing interface declaration
* chore: remove unused commented code
Co-authored-by: braginini <bangvalo@gmail.com>
* moved wiretrustee version from main to system.info
* added wiretrustee version for all supported platforms
* typo corrected
* refactor: use single WiretrusteeVersion() func to get version of the client
Co-authored-by: braginini <bangvalo@gmail.com>
* update interface tests and configuration messages
* little debug
* little debug on both errors
* print all devs
* list of devices
* debug func
* handle interface close
* debug socks
* debug socks
* if ports match
* use random assigned ports
* remove unused const
* close management client connection when stopping engine
* GracefulStop when management clients are closed
* enable workflows on PRs too
* remove iface_test debug code
* get account id from access token claim
* use GetOrCreateAccountByUser and add test
* correct account id claim
* remove unused account
* Idp manager interface
* auth0 idp manager
* use if instead of switch case
* remove unnecessary lock
* NewAuth0Manager
* move idpmanager to its own package
* update metadata when accountId is not supplied
* update tests with idpmanager field
* format
* new idp manager and config support
* validate if we fetch the interface before converting to string
* split getJWTToken
* improve tests
* proper json fields and handle defer body close
* fix ci lint notes
* documentation and proper defer position
* UpdateUserAppMetadata tests
* update documentation
* ManagerCredentials interface
* Marshal and Unmarshal functions
* fix tests
* ManagerHelper and ManagerHTTPClient
* further tests with mocking
* rename package and custom http client
* sync local packages
* remove idp suffix
* feature: support new management service protocol
* chore: add more logging to track networkmap serial
* refactor: organize peer update code in engine
* chore: fix lint issues
* refactor: extract Signal client interface
* test: add signal client mock
* refactor: introduce Management Service client interface
* chore: place management and signal clients mocks to respective packages
* test: add Serial test to the engine
* fix: lint issues
* test: unit tests for a networkMapUpdate
* test: unit tests Sync update
* script to generate syso files
* test wireguard-windows driver package
* set int log
* add windows test
* add windows test
* verbose bash
* use cd
* move checkout
* exit 0
* removed tty flag
* artifact path
* fix tags and add cache
* fix cache
* fix cache
* test dir
* restore artifacts in the root
* try dll file
* try dll file
* copy dll
* typo in copy dll
* compile test
* checkout first
* updated cicd
* fix add address issue and gen GUID
* psexec typo
* accept eula
* mod tidy before tests
* regular test exec and verbose test with psexec
* test all
* return WGInterface Interface
* use WgIfaceName and timeout after 30 seconds
* different ports and validate connect 2 peers
* Use time.After for timeout and close interface
* Use time.After for testing connect peers
* WG Interface struct
* Update engine and parse address
* refactor Linux create and assignAddress
* NewWGIface and configuration methods
* Update proxy with interface methods
* update up command test
* resolve lint warnings
* remove psexec test
* close copied files
* add goos before build
* run tests on mac,windows and linux
* cache by testing os
* run on push
* fix indentation
* adjust test timeouts
* remove parallel flag
* mod tidy before test
* ignore syso files
* removed functions and renamed vars
* different IPs for connect peers test
* Generate syso with DLL
* Single Close method
* use port from test constant
* test: remove wireguard interfaces after finishing engine test
* use load_wgnt_from_rsrc
Co-authored-by: braginini <bangvalo@gmail.com>
* feature: introduce NetworkMap to the management protocol with a Serial ID
* test: add Management Sync method protocol test
* test: add Management Sync method NetworkMap field check [FAILING]
* test: add Management Sync method NetworkMap field check [FAILING]
* feature: fill NetworkMap property to when Deleting peer
* feature: fill NetworkMap in the Sync protocol
* test: code review mentions - GeneratePrivateKey() in the test
* fix: wiretrustee client use wireguard GeneratePrivateKey() instead of GenerateKey()
* test: add NetworkMap test
* fix: management_proto test remove store.json on test finish
* fix: too many open files caused by agent not being closed after unsuccessful attempts to start a peer connection (happens when no network available)
* fix: minor refactor to consider signal status
* refactor: move goroutine that runs Signal Client Receive to the engine for better control
* chore: fix comments typo
* test: fix golint
* chore: comments update
* chore: consider connection state=READY in signal and management clients
* chore: fix typos
* test: fix signal ping-pong test
* chore: add wait condition to signal client
* refactor: add stream status to the Signal client
* refactor: defer mutex unlock
* move setup-key to root command
* up will check login and start service
* update tests to reflect new UP capabilities
* display client IP
* removed unused argument
* install service if not installed
* update post-install and add pre remove script
* improve log messages
* handle service status failures and install service when needed
* removing unused files
* update documentation and description
* add version command
* update service lib version
* using lib constant for not installed services
* match version from goreleaser
* fix: graceful shutdown
* stop only if service is running
* add logs initialization to service controller commands
Co-authored-by: braginini <bangvalo@gmail.com>
* feature: add logging to a file
* refactor: move InitLog to util lib
* docs: update signal and management docs
* chore: update docker compose
* set --log-file to console
* chore: comment out log volume in docker compose
Co-authored-by: mlsmaycon <mlsmaycon@gmail.com>
* windows installer
* unpack function in local dir
* working-directory client
* using env var plugin
* test tag and publishing
* getting version from tag
* using version number
* remove unnecessary commands and add description
* using long version outputs
* uncomment docker steps
* feature: update STUNs and TURNs in engine
* fix: setup TURN credentials request only when refresh enabled
* feature: update TURNs and STUNs in teh client app on Management update
* chore: disable peer reflexive candidates in ICE
* chore: relocate management.json
* chore: make TURN secret and pwd plain text in config
* abstract peer channel
* remove wip code
* refactor NewServer with Peer updates channel
* feature: add TURN credentials manager
* hmac logic
* example test function
* test: add TimeBasedAuthSecretsManager_GenerateCredentials test
* test: make tests for now with hardcoded secret
* test: add TimeBasedAuthSecretsManager_SetupRefresh test
* test: add TimeBasedAuthSecretsManager_SetupRefresh test
* test: add TimeBasedAuthSecretsManager_CancelRefresh test
* feature: extract TURNConfig to the management config
* feature: return hash based TURN credentials only on initial sync
* feature: make TURN time based secret credentials optional
Co-authored-by: mlsmaycon <mlsmaycon@gmail.com>
* feature: replace RegisterPeer with Login method that does both - registration and login
* test: add management login test
* feature: add WiretrusteeConfig to the Login response to configure peer global config
* feature: add client peer login support
* fix: missing parts
* chore: update go deps
* feature: support Management Service gRPC endpoints [CLIENT]
* feature: finalize client sync with management
* fix: management store peer key lower case restore
* fix: management returns peer ip without a mask
* refactor: remove cmd pkg
* fix: invalid tun interface name on mac
* fix: timeout when calling management client
* fix: tests and lint errors
* fix: golang-test workflow
* fix: client service tests
* fix: iface build
* feature: detect management scheme on startup
* chore: better logs for management
* fix: goreleaser
* fix: lint errors
* fix: signal TLS
* fix: direct Wireguard connection
* chore: verbose logging on direct connection