diff --git a/cmd/keeper/keeper.go b/cmd/keeper/keeper.go index d67de577b..70d5ab879 100644 --- a/cmd/keeper/keeper.go +++ b/cmd/keeper/keeper.go @@ -81,9 +81,11 @@ type config struct { pgListenAddress string pgPort string pgBinPath string + pgReplAuthMethod string pgReplUsername string pgReplPassword string pgReplPasswordFile string + pgSUAuthMethod string pgSUUsername string pgSUPassword string pgSUPasswordFile string @@ -112,9 +114,11 @@ func init() { cmdKeeper.PersistentFlags().StringVar(&cfg.pgListenAddress, "pg-listen-address", "localhost", "postgresql instance listening address") cmdKeeper.PersistentFlags().StringVar(&cfg.pgPort, "pg-port", "5432", "postgresql instance listening port") cmdKeeper.PersistentFlags().StringVar(&cfg.pgBinPath, "pg-bin-path", "", "absolute path to postgresql binaries. If empty they will be searched in the current PATH") + cmdKeeper.PersistentFlags().StringVar(&cfg.pgReplAuthMethod, "pg-repl-auth-method", "md5", "postgres replication user auth method. Required.") cmdKeeper.PersistentFlags().StringVar(&cfg.pgReplUsername, "pg-repl-username", "", "postgres replication user name. Required. It'll be created on db initialization. Must be the same for all keepers.") cmdKeeper.PersistentFlags().StringVar(&cfg.pgReplPassword, "pg-repl-password", "", "postgres replication user password. Only one of --pg-repl-password or --pg-repl-passwordfile must be provided. Must be the same for all keepers.") cmdKeeper.PersistentFlags().StringVar(&cfg.pgReplPasswordFile, "pg-repl-passwordfile", "", "postgres replication user password file. Only one of --pg-repl-password or --pg-repl-passwordfile must be provided. Must be the same for all keepers.") + cmdKeeper.PersistentFlags().StringVar(&cfg.pgSUAuthMethod, "pg-su-auth-method", "md5", "postgres superuser auth method. Required.") cmdKeeper.PersistentFlags().StringVar(&cfg.pgSUUsername, "pg-su-username", user, "postgres superuser user name. Used for keeper managed instance access and pg_rewind based synchronization. It'll be created on db initialization. Defaults to the name of the effective user running stolon-keeper. Must be the same for all keepers.") cmdKeeper.PersistentFlags().StringVar(&cfg.pgSUPassword, "pg-su-password", "", "postgres superuser password. Only one of --pg-su-password or --pg-su-passwordfile must be provided. Must be the same for all keepers.") cmdKeeper.PersistentFlags().StringVar(&cfg.pgSUPasswordFile, "pg-su-passwordfile", "", "postgres superuser password file. Only one of --pg-su-password or --pg-su-passwordfile must be provided. Must be the same for all keepers)") @@ -347,8 +351,10 @@ type PostgresKeeper struct { pgListenAddress string pgPort string pgBinPath string + pgReplAuthMethod string pgReplUsername string pgReplPassword string + pgSUAuthMethod string pgSUUsername string pgSUPassword string pgInitialSUUsername string @@ -404,8 +410,10 @@ func NewPostgresKeeper(cfg *config, stop chan bool, end chan error) (*PostgresKe pgListenAddress: cfg.pgListenAddress, pgPort: cfg.pgPort, pgBinPath: cfg.pgBinPath, + pgReplAuthMethod: cfg.pgReplAuthMethod, pgReplUsername: cfg.pgReplUsername, pgReplPassword: cfg.pgReplPassword, + pgSUAuthMethod: cfg.pgSUAuthMethod, pgSUUsername: cfg.pgSUUsername, pgSUPassword: cfg.pgSUPassword, pgInitialSUUsername: cfg.pgInitialSUUsername, @@ -659,7 +667,7 @@ func (p *PostgresKeeper) Start() { // TODO(sgotti) reconfigure the various configurations options // (RequestTimeout) after a changed cluster config - pgm := postgresql.NewManager(p.pgBinPath, p.dataDir, p.getLocalConnParams(), p.getLocalReplConnParams(), p.pgSUUsername, p.pgSUPassword, p.pgReplUsername, p.pgReplPassword, p.requestTimeout) + pgm := postgresql.NewManager(p.pgBinPath, p.dataDir, p.getLocalConnParams(), p.getLocalReplConnParams(), p.pgSUAuthMethod, p.pgSUUsername, p.pgSUPassword, p.pgReplAuthMethod, p.pgReplUsername, p.pgReplPassword, p.requestTimeout) p.pgm = pgm p.pgm.Stop(true) @@ -1579,6 +1587,7 @@ func main() { func keeper(cmd *cobra.Command, args []string) { var err error + validAuthMethods := map[string]bool{"md5": true,"password": true,"trust": true} switch cfg.logLevel { case "error": slog.SetLevel(zap.ErrorLevel) @@ -1610,6 +1619,12 @@ func keeper(cmd *cobra.Command, args []string) { die("cannot create data dir: %v", err) } + if cfg.pgReplAuthMethod == "" { + die("--pg-repl-auth-method is required") + } else if !validAuthMethods[cfg.pgReplAuthMethod] { + die("--pg-repl-auth-method must be one of: md5, password, trust") + } + if cfg.pgReplUsername == "" { die("--pg-repl-username is required") } @@ -1620,6 +1635,11 @@ func keeper(cmd *cobra.Command, args []string) { if cfg.pgReplPassword != "" && cfg.pgReplPasswordFile != "" { die("only one of --pg-repl-password or --pg-repl-passwordfile must be provided") } + if cfg.pgSUAuthMethod == "" { + die("--pg-su-auth-method is required") + } else if !validAuthMethods[cfg.pgSUAuthMethod] { + die("--pg-su-auth-method must be one of: md5, password, trust") + } if cfg.pgSUPassword == "" && cfg.pgSUPasswordFile == "" { die("one of --pg-su-password or --pg-su-passwordfile is required") } diff --git a/pkg/postgresql/postgresql.go b/pkg/postgresql/postgresql.go index 115df776d..dd7c1d0c7 100644 --- a/pkg/postgresql/postgresql.go +++ b/pkg/postgresql/postgresql.go @@ -51,8 +51,10 @@ type Manager struct { curHba []string localConnParams ConnParams replConnParams ConnParams + suAuthMethod string suUsername string suPassword string + replAuthMethod string replUsername string replPassword string requestTimeout time.Duration @@ -76,7 +78,7 @@ type InitConfig struct { DataChecksums bool } -func NewManager(pgBinPath string, dataDir string, localConnParams, replConnParams ConnParams, suUsername, suPassword, replUsername, replPassword string, requestTimeout time.Duration) *Manager { +func NewManager(pgBinPath string, dataDir string, localConnParams, replConnParams ConnParams, suAuthMethod, suUsername, suPassword, replAuthMethod, replUsername, replPassword string, requestTimeout time.Duration) *Manager { return &Manager{ pgBinPath: pgBinPath, dataDir: filepath.Join(dataDir, "postgres"), @@ -84,8 +86,10 @@ func NewManager(pgBinPath string, dataDir string, localConnParams, replConnParam curParameters: make(common.Parameters), replConnParams: replConnParams, localConnParams: localConnParams, + suAuthMethod: suAuthMethod, suUsername: suUsername, suPassword: suPassword, + replAuthMethod: replAuthMethod, replUsername: replUsername, replPassword: replPassword, requestTimeout: requestTimeout, @@ -630,19 +634,19 @@ func (p *Manager) writePgHba() error { // Minimal entries for local normal and replication connections needed by the stolon keeper // Matched local connections are for postgres database and suUsername user with md5 auth // Matched local replicaton connections are for replUsername user with md5 auth - f.WriteString(fmt.Sprintf("local postgres %s md5\n", p.suUsername)) - f.WriteString(fmt.Sprintf("local replication %s md5\n", p.replUsername)) + f.WriteString(fmt.Sprintf("local postgres %s %s\n", p.suUsername, p.suAuthMethod)) + f.WriteString(fmt.Sprintf("local replication %s %s\n", p.replUsername, p.replAuthMethod)) // By default accept all connections for the superuser suUsername with md5 auth // Used for pg_rewind resyncronization // TODO(sgotti) Configure this dynamically based on our followers provided by the clusterview - f.WriteString(fmt.Sprintf("host all %s %s md5\n", p.suUsername, "0.0.0.0/0")) - f.WriteString(fmt.Sprintf("host all %s %s md5\n", p.suUsername, "::0/0")) + f.WriteString(fmt.Sprintf("host all %s %s %s\n", p.suUsername, "0.0.0.0/0", p.suAuthMethod)) + f.WriteString(fmt.Sprintf("host all %s %s %s\n", p.suUsername, "::0/0", p.suAuthMethod)) // By default accept all replication connections for the replication user with md5 auth // TODO(sgotti) Configure this dynamically based on our followers provided by the clusterview - f.WriteString(fmt.Sprintf("host replication %s %s md5\n", p.replUsername, "0.0.0.0/0")) - f.WriteString(fmt.Sprintf("host replication %s %s md5\n", p.replUsername, "::0/0")) + f.WriteString(fmt.Sprintf("host replication %s %s %s\n", p.replUsername, "0.0.0.0/0", p.replAuthMethod)) + f.WriteString(fmt.Sprintf("host replication %s %s %s\n", p.replUsername, "::0/0", p.replAuthMethod)) if p.hba != nil { for _, e := range p.hba {