Compare commits

...

4 Commits

Author SHA1 Message Date
pascal-fischer
24e19ae287 revert systemd changes (#1046) 2023-08-03 00:05:13 +02:00
Maycon Santos
74fde0ea2c Update setup key auto_groups description (#1042)
* Update setup key auto_groups description

* Update setup key auto_groups description
2023-08-02 17:50:00 +02:00
pascal-fischer
890e09b787 Keep confiured nameservers as fallback (#1036)
* keep existing nameserver as fallback when adding netbird resolver

* fix resolvconf

* fix imports
2023-08-01 17:45:44 +02:00
Bethuel Mmbaga
48098c994d Handle authentication errors in PKCE flow (#1039)
* handle authentication errors in PKCE flow

* remove shadowing and replace TokenEndpoint for PKCE config

---------

Co-authored-by: Maycon Santos <mlsmaycon@gmail.com>
2023-07-31 14:22:38 +02:00
7 changed files with 68 additions and 46 deletions

View File

@@ -25,6 +25,8 @@ var _ OAuthFlow = &PKCEAuthorizationFlow{}
const (
queryState = "state"
queryCode = "code"
queryError = "error"
queryErrorDesc = "error_description"
defaultPKCETimeoutSeconds = 300
)
@@ -141,9 +143,13 @@ func (p *PKCEAuthorizationFlow) startServer(tokenChan chan<- *oauth2.Token, errC
tokenValidatorFunc := func() (*oauth2.Token, error) {
query := req.URL.Query()
state := query.Get(queryState)
if authError := query.Get(queryError); authError != "" {
authErrorDesc := query.Get(queryErrorDesc)
return nil, fmt.Errorf("%s.%s", authError, authErrorDesc)
}
// Prevent timing attacks on state
if subtle.ConstantTimeCompare([]byte(p.state), []byte(state)) == 0 {
if state := query.Get(queryState); subtle.ConstantTimeCompare([]byte(p.state), []byte(state)) == 0 {
return nil, fmt.Errorf("invalid state")
}
@@ -161,12 +167,13 @@ func (p *PKCEAuthorizationFlow) startServer(tokenChan chan<- *oauth2.Token, errC
token, err := tokenValidatorFunc()
if err != nil {
errChan <- fmt.Errorf("PKCE authorization flow failed: %v", err)
renderPKCEFlowTmpl(w, err)
errChan <- fmt.Errorf("PKCE authorization flow failed: %v", err)
return
}
tokenChan <- token
renderPKCEFlowTmpl(w, nil)
tokenChan <- token
})
if err := server.ListenAndServe(); err != nil {

View File

@@ -15,7 +15,8 @@ const (
fileGeneratedResolvConfSearchBeginContent = "search "
fileGeneratedResolvConfContentFormat = fileGeneratedResolvConfContentHeader +
"\n# If needed you can restore the original file by copying back %s\n\nnameserver %s\n" +
fileGeneratedResolvConfSearchBeginContent + "%s\n"
fileGeneratedResolvConfSearchBeginContent + "%s\n\n" +
"%s\n"
)
const (
@@ -91,7 +92,12 @@ func (f *fileConfigurator) applyDNSConfig(config hostDNSConfig) error {
searchDomains += " " + dConf.domain
appendedDomains++
}
content := fmt.Sprintf(fileGeneratedResolvConfContentFormat, fileDefaultResolvConfBackupLocation, config.serverIP, searchDomains)
originalContent, err := os.ReadFile(fileDefaultResolvConfBackupLocation)
if err != nil {
log.Errorf("Could not read existing resolv.conf")
}
content := fmt.Sprintf(fileGeneratedResolvConfContentFormat, fileDefaultResolvConfBackupLocation, config.serverIP, searchDomains, string(originalContent))
err = writeDNSConfig(content, defaultResolvConfPath, f.originalPerms)
if err != nil {
err = f.restore()

View File

@@ -182,12 +182,11 @@ func (s *systemConfigurator) addDNSState(state, domains, dnsServer string, port
}
func (s *systemConfigurator) addDNSSetupForAll(dnsServer string, port int) error {
primaryServiceKey := s.getPrimaryService()
primaryServiceKey, existingNameserver := s.getPrimaryService()
if primaryServiceKey == "" {
return fmt.Errorf("couldn't find the primary service key")
}
err := s.addDNSSetup(getKeyWithInput(primaryServiceSetupKeyFormat, primaryServiceKey), dnsServer, port)
err := s.addDNSSetup(getKeyWithInput(primaryServiceSetupKeyFormat, primaryServiceKey), dnsServer, port, existingNameserver)
if err != nil {
return err
}
@@ -196,27 +195,32 @@ func (s *systemConfigurator) addDNSSetupForAll(dnsServer string, port int) error
return nil
}
func (s *systemConfigurator) getPrimaryService() string {
func (s *systemConfigurator) getPrimaryService() (string, string) {
line := buildCommandLine("show", globalIPv4State, "")
stdinCommands := wrapCommand(line)
b, err := runSystemConfigCommand(stdinCommands)
if err != nil {
log.Error("got error while sending the command: ", err)
return ""
return "", ""
}
scanner := bufio.NewScanner(bytes.NewReader(b))
primaryService := ""
router := ""
for scanner.Scan() {
text := scanner.Text()
if strings.Contains(text, "PrimaryService") {
return strings.TrimSpace(strings.Split(text, ":")[1])
primaryService = strings.TrimSpace(strings.Split(text, ":")[1])
}
if strings.Contains(text, "Router") {
router = strings.TrimSpace(strings.Split(text, ":")[1])
}
}
return ""
return primaryService, router
}
func (s *systemConfigurator) addDNSSetup(setupKey, dnsServer string, port int) error {
func (s *systemConfigurator) addDNSSetup(setupKey, dnsServer string, port int, existingDNSServer string) error {
lines := buildAddCommandLine(keySupplementalMatchDomainsNoSearch, digitSymbol+strconv.Itoa(0))
lines += buildAddCommandLine(keyServerAddresses, arraySymbol+dnsServer)
lines += buildAddCommandLine(keyServerAddresses, arraySymbol+dnsServer+" "+existingDNSServer)
lines += buildAddCommandLine(keyServerPort, digitSymbol+strconv.Itoa(port))
addDomainCommand := buildCreateStateWithOperation(setupKey, lines)
stdinCommands := wrapCommand(addDomainCommand)

View File

@@ -4,6 +4,7 @@ package dns
import (
"fmt"
"os"
"os/exec"
"strings"
@@ -59,7 +60,11 @@ func (r *resolvconf) applyDNSConfig(config hostDNSConfig) error {
appendedDomains++
}
content := fmt.Sprintf(fileGeneratedResolvConfContentFormat, fileDefaultResolvConfBackupLocation, config.serverIP, searchDomains)
originalContent, err := os.ReadFile(fileDefaultResolvConfBackupLocation)
if err != nil {
log.Errorf("Could not read existing resolv.conf")
}
content := fmt.Sprintf(fileGeneratedResolvConfContentFormat, fileDefaultResolvConfBackupLocation, config.serverIP, searchDomains, string(originalContent))
err = r.applyConfig(content)
if err != nil {

View File

@@ -371,24 +371,24 @@ func handlerFunc(gRPCHandler *grpc.Server, httpHandler http.Handler) http.Handle
}
func loadMgmtConfig(mgmtConfigPath string) (*server.Config, error) {
config := &server.Config{}
_, err := util.ReadJson(mgmtConfigPath, config)
loadedConfig := &server.Config{}
_, err := util.ReadJson(mgmtConfigPath, loadedConfig)
if err != nil {
return nil, err
}
if mgmtLetsencryptDomain != "" {
config.HttpConfig.LetsEncryptDomain = mgmtLetsencryptDomain
loadedConfig.HttpConfig.LetsEncryptDomain = mgmtLetsencryptDomain
}
if mgmtDataDir != "" {
config.Datadir = mgmtDataDir
loadedConfig.Datadir = mgmtDataDir
}
if certKey != "" && certFile != "" {
config.HttpConfig.CertFile = certFile
config.HttpConfig.CertKey = certKey
loadedConfig.HttpConfig.CertFile = certFile
loadedConfig.HttpConfig.CertKey = certKey
}
oidcEndpoint := config.HttpConfig.OIDCConfigEndpoint
oidcEndpoint := loadedConfig.HttpConfig.OIDCConfigEndpoint
if oidcEndpoint != "" {
// if OIDCConfigEndpoint is specified, we can load DeviceAuthEndpoint and TokenEndpoint automatically
log.Infof("loading OIDC configuration from the provided IDP configuration endpoint %s", oidcEndpoint)
@@ -399,45 +399,45 @@ func loadMgmtConfig(mgmtConfigPath string) (*server.Config, error) {
log.Infof("loaded OIDC configuration from the provided IDP configuration endpoint: %s", oidcEndpoint)
log.Infof("overriding HttpConfig.AuthIssuer with a new value %s, previously configured value: %s",
oidcConfig.Issuer, config.HttpConfig.AuthIssuer)
config.HttpConfig.AuthIssuer = oidcConfig.Issuer
oidcConfig.Issuer, loadedConfig.HttpConfig.AuthIssuer)
loadedConfig.HttpConfig.AuthIssuer = oidcConfig.Issuer
log.Infof("overriding HttpConfig.AuthKeysLocation (JWT certs) with a new value %s, previously configured value: %s",
oidcConfig.JwksURI, config.HttpConfig.AuthKeysLocation)
config.HttpConfig.AuthKeysLocation = oidcConfig.JwksURI
oidcConfig.JwksURI, loadedConfig.HttpConfig.AuthKeysLocation)
loadedConfig.HttpConfig.AuthKeysLocation = oidcConfig.JwksURI
if !(config.DeviceAuthorizationFlow == nil || strings.ToLower(config.DeviceAuthorizationFlow.Provider) == string(server.NONE)) {
if !(loadedConfig.DeviceAuthorizationFlow == nil || strings.ToLower(loadedConfig.DeviceAuthorizationFlow.Provider) == string(server.NONE)) {
log.Infof("overriding DeviceAuthorizationFlow.TokenEndpoint with a new value: %s, previously configured value: %s",
oidcConfig.TokenEndpoint, config.DeviceAuthorizationFlow.ProviderConfig.TokenEndpoint)
config.DeviceAuthorizationFlow.ProviderConfig.TokenEndpoint = oidcConfig.TokenEndpoint
oidcConfig.TokenEndpoint, loadedConfig.DeviceAuthorizationFlow.ProviderConfig.TokenEndpoint)
loadedConfig.DeviceAuthorizationFlow.ProviderConfig.TokenEndpoint = oidcConfig.TokenEndpoint
log.Infof("overriding DeviceAuthorizationFlow.DeviceAuthEndpoint with a new value: %s, previously configured value: %s",
oidcConfig.DeviceAuthEndpoint, config.DeviceAuthorizationFlow.ProviderConfig.DeviceAuthEndpoint)
config.DeviceAuthorizationFlow.ProviderConfig.DeviceAuthEndpoint = oidcConfig.DeviceAuthEndpoint
oidcConfig.DeviceAuthEndpoint, loadedConfig.DeviceAuthorizationFlow.ProviderConfig.DeviceAuthEndpoint)
loadedConfig.DeviceAuthorizationFlow.ProviderConfig.DeviceAuthEndpoint = oidcConfig.DeviceAuthEndpoint
u, err := url.Parse(oidcEndpoint)
if err != nil {
return nil, err
}
log.Infof("overriding DeviceAuthorizationFlow.ProviderConfig.Domain with a new value: %s, previously configured value: %s",
u.Host, config.DeviceAuthorizationFlow.ProviderConfig.Domain)
config.DeviceAuthorizationFlow.ProviderConfig.Domain = u.Host
u.Host, loadedConfig.DeviceAuthorizationFlow.ProviderConfig.Domain)
loadedConfig.DeviceAuthorizationFlow.ProviderConfig.Domain = u.Host
if config.DeviceAuthorizationFlow.ProviderConfig.Scope == "" {
config.DeviceAuthorizationFlow.ProviderConfig.Scope = server.DefaultDeviceAuthFlowScope
if loadedConfig.DeviceAuthorizationFlow.ProviderConfig.Scope == "" {
loadedConfig.DeviceAuthorizationFlow.ProviderConfig.Scope = server.DefaultDeviceAuthFlowScope
}
}
if config.PKCEAuthorizationFlow != nil {
if loadedConfig.PKCEAuthorizationFlow != nil {
log.Infof("overriding PKCEAuthorizationFlow.TokenEndpoint with a new value: %s, previously configured value: %s",
oidcConfig.TokenEndpoint, config.PKCEAuthorizationFlow.ProviderConfig.TokenEndpoint)
config.DeviceAuthorizationFlow.ProviderConfig.TokenEndpoint = oidcConfig.TokenEndpoint
oidcConfig.TokenEndpoint, loadedConfig.PKCEAuthorizationFlow.ProviderConfig.TokenEndpoint)
loadedConfig.PKCEAuthorizationFlow.ProviderConfig.TokenEndpoint = oidcConfig.TokenEndpoint
log.Infof("overriding PKCEAuthorizationFlow.AuthorizationEndpoint with a new value: %s, previously configured value: %s",
oidcConfig.AuthorizationEndpoint, config.PKCEAuthorizationFlow.ProviderConfig.AuthorizationEndpoint)
config.PKCEAuthorizationFlow.ProviderConfig.AuthorizationEndpoint = oidcConfig.AuthorizationEndpoint
oidcConfig.AuthorizationEndpoint, loadedConfig.PKCEAuthorizationFlow.ProviderConfig.AuthorizationEndpoint)
loadedConfig.PKCEAuthorizationFlow.ProviderConfig.AuthorizationEndpoint = oidcConfig.AuthorizationEndpoint
}
}
return config, err
return loadedConfig, err
}
// OIDCConfigResponse used for parsing OIDC config response

View File

@@ -327,7 +327,7 @@ components:
type: string
example: valid
auto_groups:
description: Setup key groups to auto-assign to peers registered with this key
description: List of group IDs to auto-assign to peers registered with this key
type: array
items:
type: string
@@ -375,7 +375,7 @@ components:
type: boolean
example: false
auto_groups:
description: Setup key groups to auto-assign to peers registered with this key
description: List of group IDs to auto-assign to peers registered with this key
type: array
items:
type: string

View File

@@ -681,7 +681,7 @@ type RuleRequest struct {
// SetupKey defines model for SetupKey.
type SetupKey struct {
// AutoGroups Setup key groups to auto-assign to peers registered with this key
// AutoGroups List of group IDs to auto-assign to peers registered with this key
AutoGroups []string `json:"auto_groups"`
// Expires Setup Key expiration date
@@ -723,7 +723,7 @@ type SetupKey struct {
// SetupKeyRequest defines model for SetupKeyRequest.
type SetupKeyRequest struct {
// AutoGroups Setup key groups to auto-assign to peers registered with this key
// AutoGroups List of group IDs to auto-assign to peers registered with this key
AutoGroups []string `json:"auto_groups"`
// ExpiresIn Expiration time in seconds