mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-12-15 16:30:55 +01:00
vmauth ip filters (refactoring) (#4059)
Added ip filters (allow_list and deny_list) for enterprise-version of vmauth (#3491) --------- Signed-off-by: Alexander Marshalov <_@marshalov.org>
This commit is contained in:
parent
624e13a1d6
commit
f5981c1447
@ -289,11 +289,11 @@ func initAuthConfig() {
|
|||||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1240
|
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1240
|
||||||
sighupCh := procutil.NewSighupChan()
|
sighupCh := procutil.NewSighupChan()
|
||||||
|
|
||||||
m, err := readAuthConfig(*authConfigPath)
|
err := loadAuthConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("cannot load auth config from `-auth.config=%s`: %s", *authConfigPath, err)
|
logger.Fatalf("cannot load auth config from `-auth.config=%s`: %s", *authConfigPath, err)
|
||||||
}
|
}
|
||||||
authConfig.Store(m)
|
|
||||||
stopCh = make(chan struct{})
|
stopCh = make(chan struct{})
|
||||||
authConfigWG.Add(1)
|
authConfigWG.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
@ -324,44 +324,60 @@ func authConfigReloader(sighupCh <-chan os.Signal) {
|
|||||||
procutil.SelfSIGHUP()
|
procutil.SelfSIGHUP()
|
||||||
case <-sighupCh:
|
case <-sighupCh:
|
||||||
logger.Infof("SIGHUP received; loading -auth.config=%q", *authConfigPath)
|
logger.Infof("SIGHUP received; loading -auth.config=%q", *authConfigPath)
|
||||||
m, err := readAuthConfig(*authConfigPath)
|
err := loadAuthConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("failed to load -auth.config=%q; using the last successfully loaded config; error: %s", *authConfigPath, err)
|
logger.Errorf("failed to load -auth.config=%q; using the last successfully loaded config; error: %s", *authConfigPath, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
authConfig.Store(m)
|
|
||||||
logger.Infof("Successfully reloaded -auth.config=%q", *authConfigPath)
|
logger.Infof("Successfully reloaded -auth.config=%q", *authConfigPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var authConfig atomic.Value
|
var authConfig atomic.Pointer[AuthConfig]
|
||||||
|
var authUsers atomic.Pointer[map[string]*UserInfo]
|
||||||
var authConfigWG sync.WaitGroup
|
var authConfigWG sync.WaitGroup
|
||||||
var stopCh chan struct{}
|
var stopCh chan struct{}
|
||||||
|
|
||||||
func readAuthConfig(path string) (map[string]*UserInfo, error) {
|
func loadAuthConfig() error {
|
||||||
|
ac, err := readAuthConfig(*authConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to load `-auth.config=%q`: %s", *authConfigPath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m, err := parseAuthConfigUsers(ac)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse users from `-auth.config=%q`: %s", *authConfigPath, err)
|
||||||
|
}
|
||||||
|
logger.Infof("Loaded information about %d users from %q", len(m), *authConfigPath)
|
||||||
|
|
||||||
|
authConfig.Store(ac)
|
||||||
|
authUsers.Store(&m)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readAuthConfig(path string) (*AuthConfig, error) {
|
||||||
data, err := fs.ReadFileOrHTTP(path)
|
data, err := fs.ReadFileOrHTTP(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
m, err := parseAuthConfig(data)
|
return parseAuthConfig(data)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot parse %q: %w", path, err)
|
|
||||||
}
|
|
||||||
logger.Infof("Loaded information about %d users from %q", len(m), path)
|
|
||||||
return m, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseAuthConfig(data []byte) (map[string]*UserInfo, error) {
|
func parseAuthConfig(data []byte) (*AuthConfig, error) {
|
||||||
var err error
|
data, err := envtemplate.ReplaceBytes(data)
|
||||||
data, err = envtemplate.ReplaceBytes(data)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot expand environment vars: %w", err)
|
return nil, fmt.Errorf("cannot expand environment vars: %w", err)
|
||||||
}
|
}
|
||||||
var ac AuthConfig
|
var ac AuthConfig
|
||||||
if err := yaml.UnmarshalStrict(data, &ac); err != nil {
|
if err = yaml.UnmarshalStrict(data, &ac); err != nil {
|
||||||
return nil, fmt.Errorf("cannot unmarshal AuthConfig data: %w", err)
|
return nil, fmt.Errorf("cannot unmarshal AuthConfig data: %w", err)
|
||||||
}
|
}
|
||||||
|
return &ac, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseAuthConfigUsers(ac *AuthConfig) (map[string]*UserInfo, error) {
|
||||||
uis := ac.Users
|
uis := ac.Users
|
||||||
if len(uis) == 0 {
|
if len(uis) == 0 {
|
||||||
return nil, fmt.Errorf("`users` section cannot be empty in AuthConfig")
|
return nil, fmt.Errorf("`users` section cannot be empty in AuthConfig")
|
||||||
|
@ -13,7 +13,11 @@ import (
|
|||||||
func TestParseAuthConfigFailure(t *testing.T) {
|
func TestParseAuthConfigFailure(t *testing.T) {
|
||||||
f := func(s string) {
|
f := func(s string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
_, err := parseAuthConfig([]byte(s))
|
ac, err := parseAuthConfig([]byte(s))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = parseAuthConfigUsers(ac)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expecting non-nil error")
|
t.Fatalf("expecting non-nil error")
|
||||||
}
|
}
|
||||||
@ -202,7 +206,11 @@ users:
|
|||||||
func TestParseAuthConfigSuccess(t *testing.T) {
|
func TestParseAuthConfigSuccess(t *testing.T) {
|
||||||
f := func(s string, expectedAuthConfig map[string]*UserInfo) {
|
f := func(s string, expectedAuthConfig map[string]*UserInfo) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
m, err := parseAuthConfig([]byte(s))
|
ac, err := parseAuthConfig([]byte(s))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
m, err := parseAuthConfigUsers(ac)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool {
|
|||||||
authToken = strings.Replace(authToken, "Token", "Bearer", 1)
|
authToken = strings.Replace(authToken, "Token", "Bearer", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
ac := authConfig.Load().(map[string]*UserInfo)
|
ac := *authUsers.Load()
|
||||||
ui := ac[authToken]
|
ui := ac[authToken]
|
||||||
if ui == nil {
|
if ui == nil {
|
||||||
invalidAuthTokenRequests.Inc()
|
invalidAuthTokenRequests.Inc()
|
||||||
|
Loading…
Reference in New Issue
Block a user