mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-31 03:51:29 +02:00
get OIDC configuration from proxy flags/env
This commit is contained in:
@@ -41,13 +41,17 @@ When using ACME, the proxy server will store generated certificates in the speci
|
||||
NetBird Proxy deployment configuration is via flags or environment variables, with flags taking precedence over the environment.
|
||||
The following deployment configuration is available:
|
||||
|
||||
| Flag | Env | Purpose | Default |
|
||||
|---------------|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------|
|
||||
| `-debug` | `NB_PROXY_DEBUG_LOGS` | Enable debug logging | `false` |
|
||||
| `-mgmt` | `NB_PROXY_MANAGEMENT_ADDRESS` | The address of the management server for the proxy to get configuration from. | `"https://api.netbird.io:443"` |
|
||||
| `-addr` | `NB_PROXY_ADDRESS` | The address that the reverse proxy will listen on. | `":443` |
|
||||
| `-url` | `NB_PROXY_URL` | The URL that the proxy will be reached at (where endpoints will be CNAMEd to). If unset, this will fall back to the proxy address. | `""` |
|
||||
| `-cert-dir` | `NB_PROXY_CERTIFICATE_DIRECTORY` | The location that certficates are stored in. | `"./certs"` |
|
||||
| `-acme-certs` | `NB_PROXY_ACME_CERTIFICATES` | Whether to use ACME to generate certificates. | `false` |
|
||||
| `-acme-addr` | `NB_PROXY_ACME_ADDRESS` | The HTTP address the proxy will listen on to respond to HTTP-01 ACME challenges | `":80"` |
|
||||
| `-acme-dir` | `NB_PROXY_ACME_DIRECTORY` | The directory URL of the ACME server to be used | `"https://acme-v02.api.letsencrypt.org/directory"` |
|
||||
| Flag | Env | Purpose | Default |
|
||||
|------------------|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------|
|
||||
| `-debug` | `NB_PROXY_DEBUG_LOGS` | Enable debug logging | `false` |
|
||||
| `-mgmt` | `NB_PROXY_MANAGEMENT_ADDRESS` | The address of the management server for the proxy to get configuration from. | `"https://api.netbird.io:443"` |
|
||||
| `-addr` | `NB_PROXY_ADDRESS` | The address that the reverse proxy will listen on. | `":443` |
|
||||
| `-url` | `NB_PROXY_URL` | The URL that the proxy will be reached at (where endpoints will be CNAMEd to). If unset, this will fall back to the proxy address. | `"proxy.netbird.io"` |
|
||||
| `-cert-dir` | `NB_PROXY_CERTIFICATE_DIRECTORY` | The location that certficates are stored in. | `"./certs"` |
|
||||
| `-acme-certs` | `NB_PROXY_ACME_CERTIFICATES` | Whether to use ACME to generate certificates. | `false` |
|
||||
| `-acme-addr` | `NB_PROXY_ACME_ADDRESS` | The HTTP address the proxy will listen on to respond to HTTP-01 ACME challenges | `":80"` |
|
||||
| `-acme-dir` | `NB_PROXY_ACME_DIRECTORY` | The directory URL of the ACME server to be used | `"https://acme-v02.api.letsencrypt.org/directory"` |
|
||||
| `-oidc-id` | `NB_PROXY_OIDC_CLIENT_ID` | The OAuth2 Client ID for OIDC User Authentication | `"netbird-proxy"` |
|
||||
| `-oidc-secret` | `NB_PROXY_OIDC_CLIENT_SECRET` | The OAuth2 Client Secret for OIDC User Authentication | `""` |
|
||||
| `-oidc-endpoint` | `NB_PROXY_OIDC_ENDPOINT` | The OAuth2 provider endpoint for OIDC User Authentication | `"https://api.netbird.io/oauth2"` |
|
||||
| `-oidc-scopes` | `NB_PROXY_OIDC_SCOPES` | The OAuth2 scopes for OIDC User Authentication, comma separated | `"openid,profile,email"` |
|
||||
|
||||
@@ -49,19 +49,26 @@ func envStringOrDefault(key string, def string) string {
|
||||
|
||||
func main() {
|
||||
var (
|
||||
version, debug, acmeCerts bool
|
||||
mgmtAddr, addr, url, certDir, acmeAddr, acmeDir string
|
||||
version, debug bool
|
||||
mgmtAddr, addr, url, certDir string
|
||||
acmeCerts bool
|
||||
acmeAddr, acmeDir string
|
||||
oidcId, oidcSecret, oidcEndpoint, oidcScopes string
|
||||
)
|
||||
|
||||
flag.BoolVar(&version, "v", false, "Print version and exit")
|
||||
flag.BoolVar(&debug, "debug", envBoolOrDefault("NB_PROXY_DEBUG_LOGS", false), "Enable debug logs")
|
||||
flag.StringVar(&mgmtAddr, "mgmt", envStringOrDefault("NB_PROXY_MANAGEMENT_ADDRESS", DefaultManagementURL), "Management address to connect to.")
|
||||
flag.StringVar(&addr, "addr", envStringOrDefault("NB_PROXY_ADDRESS", ":443"), "Reverse proxy address to listen on.")
|
||||
flag.StringVar(&url, "url", envStringOrDefault("NB_PROXY_URL", ""), "The URL at which this proxy will be reached, where CNAME records for proxied endpoints will be directed.")
|
||||
flag.StringVar(&url, "url", envStringOrDefault("NB_PROXY_URL", "proxy.netbird.io"), "The URL at which this proxy will be reached, where CNAME records for proxied endpoints will be directed.")
|
||||
flag.StringVar(&certDir, "cert-dir", envStringOrDefault("NB_PROXY_CERTIFICATE_DIRECTORY", "./certs"), "Directory to store ")
|
||||
flag.BoolVar(&acmeCerts, "acme-certs", envBoolOrDefault("NB_PROXY_ACME_CERTIFICATES", false), "Generate ACME certificates using HTTP-01 challenges.")
|
||||
flag.StringVar(&acmeAddr, "acme-addr", envStringOrDefault("NB_PROXY_ACME_ADDRESS", ":80"), "HTTP address to listen on, used for ACME HTTP-01 certificate generation.")
|
||||
flag.StringVar(&acmeDir, "acme-dir", envStringOrDefault("NB_PROXY_ACME_DIRECTORY", acme.LetsEncryptURL), "URL of ACME challenge directory.")
|
||||
flag.StringVar(&oidcId, "oidc-id", envStringOrDefault("NB_PROXY_OIDC_CLIENT_ID", "netbird-proxy"), "The OAuth2 Client ID for OIDC User Authentication")
|
||||
flag.StringVar(&oidcSecret, "oidc-secret", envStringOrDefault("NB_PROXY_OIDC_CLIENT_SECRET", ""), "The OAuth2 Client Secret for OIDC User Authentication")
|
||||
flag.StringVar(&oidcEndpoint, "oidc-endpoint", envStringOrDefault("NB_PROXY_OIDC_ENDPOINT", ""), "The OIDC Endpoint for OIDC User Authentication")
|
||||
flag.StringVar(&oidcScopes, "oidc-scopes", envStringOrDefault("NB_PROXY_OIDC_SCOPES", "openid,profile,email"), "The OAuth2 scopes for OIDC User Authentication, comma separated")
|
||||
flag.Parse()
|
||||
|
||||
if version {
|
||||
@@ -89,6 +96,10 @@ func main() {
|
||||
GenerateACMECertificates: acmeCerts,
|
||||
ACMEChallengeAddress: acmeAddr,
|
||||
ACMEDirectory: acmeDir,
|
||||
OIDCClientId: oidcId,
|
||||
OIDCClientSecret: oidcSecret,
|
||||
OIDCEndpoint: oidcEndpoint,
|
||||
OIDCScopes: strings.Split(oidcScopes, ","),
|
||||
}
|
||||
|
||||
if err := srv.ListenAndServe(context.TODO(), addr); err != nil {
|
||||
|
||||
@@ -36,16 +36,16 @@ type oidcState struct {
|
||||
|
||||
// OIDC implements the Scheme interface for JWT/OIDC authentication
|
||||
type OIDC struct {
|
||||
id, accountId string
|
||||
verifier *oidc.IDTokenVerifier
|
||||
oauthConfig *oauth2.Config
|
||||
states map[string]*oidcState
|
||||
statesMux sync.RWMutex
|
||||
distributionGroups []string
|
||||
id, accountId, proxyURL string
|
||||
verifier *oidc.IDTokenVerifier
|
||||
oauthConfig *oauth2.Config
|
||||
states map[string]*oidcState
|
||||
statesMux sync.RWMutex
|
||||
distributionGroups []string
|
||||
}
|
||||
|
||||
// NewOIDC creates a new OIDC authentication scheme
|
||||
func NewOIDC(ctx context.Context, id, accountId string, cfg OIDCConfig) (*OIDC, error) {
|
||||
func NewOIDC(ctx context.Context, id, accountId, proxyURL string, cfg OIDCConfig) (*OIDC, error) {
|
||||
if cfg.OIDCProviderURL == "" || cfg.OIDCClientID == "" {
|
||||
return nil, fmt.Errorf("OIDC provider URL and client ID are required")
|
||||
}
|
||||
@@ -63,6 +63,7 @@ func NewOIDC(ctx context.Context, id, accountId string, cfg OIDCConfig) (*OIDC,
|
||||
o := &OIDC{
|
||||
id: id,
|
||||
accountId: accountId,
|
||||
proxyURL: proxyURL,
|
||||
verifier: provider.Verifier(&oidc.Config{
|
||||
ClientID: cfg.OIDCClientID,
|
||||
}),
|
||||
@@ -111,20 +112,11 @@ func (o *OIDC) Authenticate(r *http.Request) (string, string) {
|
||||
o.states[state] = &oidcState{OriginalURL: fmt.Sprintf("https://%s%s", r.Host, r.URL), CreatedAt: time.Now()}
|
||||
o.statesMux.Unlock()
|
||||
|
||||
// Construct the redirect URL as the currently requested URL with the defined callback path added.
|
||||
// The expectation is that the requested URL should reach back to the proxy and so the OAuth redirect
|
||||
// will end up back here to be handled by the middleware.
|
||||
redirectURL := &url.URL{
|
||||
Scheme: r.URL.Scheme,
|
||||
Host: r.Host,
|
||||
Path: callbackPath,
|
||||
}
|
||||
|
||||
return "", (&oauth2.Config{
|
||||
ClientID: o.oauthConfig.ClientID,
|
||||
ClientSecret: o.oauthConfig.ClientSecret,
|
||||
Endpoint: o.oauthConfig.Endpoint,
|
||||
RedirectURL: redirectURL.String(),
|
||||
RedirectURL: o.proxyURL + callbackPath,
|
||||
Scopes: o.oauthConfig.Scopes,
|
||||
}).AuthCodeURL(state)
|
||||
}
|
||||
|
||||
@@ -58,6 +58,10 @@ type Server struct {
|
||||
GenerateACMECertificates bool
|
||||
ACMEChallengeAddress string
|
||||
ACMEDirectory string
|
||||
OIDCClientId string
|
||||
OIDCClientSecret string
|
||||
OIDCEndpoint string
|
||||
OIDCScopes []string
|
||||
}
|
||||
|
||||
func (s *Server) ListenAndServe(ctx context.Context, addr string) (err error) {
|
||||
@@ -305,11 +309,11 @@ func (s *Server) updateMapping(ctx context.Context, mapping *proto.ProxyMapping)
|
||||
}
|
||||
if mapping.GetAuth().GetOidc() != nil {
|
||||
oidc := mapping.GetAuth().GetOidc()
|
||||
scheme, err := auth.NewOIDC(ctx, mapping.GetId(), mapping.GetAccountId(), auth.OIDCConfig{
|
||||
OIDCProviderURL: oidc.GetOidcProviderUrl(),
|
||||
OIDCClientID: oidc.GetOidcClientId(),
|
||||
OIDCClientSecret: oidc.GetOidcClientSecret(),
|
||||
OIDCScopes: oidc.GetOidcScopes(),
|
||||
scheme, err := auth.NewOIDC(ctx, mapping.GetId(), mapping.GetAccountId(), s.ProxyURL, auth.OIDCConfig{
|
||||
OIDCProviderURL: s.OIDCEndpoint,
|
||||
OIDCClientID: s.OIDCClientId,
|
||||
OIDCClientSecret: s.OIDCClientSecret,
|
||||
OIDCScopes: s.OIDCScopes,
|
||||
DistributionGroups: oidc.GetDistributionGroups(),
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user