mirror of
https://github.com/netbirdio/netbird.git
synced 2024-12-12 18:00:49 +01:00
5de4acf2fe
This PR aims to integrate Rosenpass with NetBird. It adds a manager for Rosenpass that starts a Rosenpass server and handles the managed peers. It uses the cunicu/go-rosenpass implementation. Rosenpass will then negotiate a pre-shared key every 2 minutes and apply it to the wireguard connection. The Feature can be enabled by setting a flag during the netbird up --enable-rosenpass command. If two peers are both support and have the Rosenpass feature enabled they will create a post-quantum secure connection. If one of the peers or both don't have this feature enabled or are running an older version that does not have this feature yet, the NetBird client will fall back to a plain Wireguard connection without pre-shared keys for those connections (keeping Rosenpass negotiation for the rest). Additionally, this PR includes an update of all Github Actions workflows to use go version 1.21.0 as this is a requirement for the integration. --------- Co-authored-by: braginini <bangvalo@gmail.com> Co-authored-by: Maycon Santos <mlsmaycon@gmail.com>
92 lines
2.4 KiB
Go
92 lines
2.4 KiB
Go
package client
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
|
|
"github.com/netbirdio/netbird/signal/proto"
|
|
"github.com/netbirdio/netbird/version"
|
|
|
|
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
|
)
|
|
|
|
// A set of tools to exchange connection details (Wireguard endpoints) with the remote peer.
|
|
|
|
// Status is the status of the client
|
|
type Status string
|
|
|
|
const StreamConnected Status = "Connected"
|
|
const StreamDisconnected Status = "Disconnected"
|
|
|
|
const (
|
|
// DirectCheck indicates support to direct mode checks
|
|
DirectCheck uint32 = 1
|
|
)
|
|
|
|
// FeaturesSupport register protocol supported features
|
|
type FeaturesSupport struct {
|
|
DirectCheck bool
|
|
}
|
|
|
|
type Client interface {
|
|
io.Closer
|
|
StreamConnected() bool
|
|
GetStatus() Status
|
|
Receive(msgHandler func(msg *proto.Message) error) error
|
|
Ready() bool
|
|
WaitStreamConnected()
|
|
SendToStream(msg *proto.EncryptedMessage) error
|
|
Send(msg *proto.Message) error
|
|
}
|
|
|
|
// UnMarshalCredential parses the credentials from the message and returns a Credential instance
|
|
func UnMarshalCredential(msg *proto.Message) (*Credential, error) {
|
|
|
|
credential := strings.Split(msg.GetBody().GetPayload(), ":")
|
|
if len(credential) != 2 {
|
|
return nil, fmt.Errorf("error parsing message body %s", msg.Body)
|
|
}
|
|
return &Credential{
|
|
UFrag: credential[0],
|
|
Pwd: credential[1],
|
|
}, nil
|
|
}
|
|
|
|
// MarshalCredential marshal a Credential instance and returns a Message object
|
|
func MarshalCredential(myKey wgtypes.Key, myPort int, remoteKey wgtypes.Key, credential *Credential, t proto.Body_Type,
|
|
rosenpassPubKey []byte, rosenpassAddr string) (*proto.Message, error) {
|
|
return &proto.Message{
|
|
Key: myKey.PublicKey().String(),
|
|
RemoteKey: remoteKey.String(),
|
|
Body: &proto.Body{
|
|
Type: t,
|
|
Payload: fmt.Sprintf("%s:%s", credential.UFrag, credential.Pwd),
|
|
WgListenPort: uint32(myPort),
|
|
NetBirdVersion: version.NetbirdVersion(),
|
|
RosenpassConfig: &proto.RosenpassConfig{
|
|
RosenpassPubKey: rosenpassPubKey,
|
|
RosenpassServerAddr: rosenpassAddr,
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// Credential is an instance of a GrpcClient's Credential
|
|
type Credential struct {
|
|
UFrag string
|
|
Pwd string
|
|
}
|
|
|
|
// ParseFeaturesSupported parses a slice of supported features into FeaturesSupport
|
|
func ParseFeaturesSupported(featuresMessage []uint32) FeaturesSupport {
|
|
var protoSupport FeaturesSupport
|
|
for _, feature := range featuresMessage {
|
|
if feature == DirectCheck {
|
|
protoSupport.DirectCheck = true
|
|
return protoSupport
|
|
}
|
|
}
|
|
return protoSupport
|
|
}
|