From ba5bedf3754ebce326e77bd8a0ca3ff4b7895703 Mon Sep 17 00:00:00 2001 From: lasith-kg Date: Thu, 23 Nov 2023 02:12:46 +0000 Subject: [PATCH] (feat): Allow trusted actions + warnings --- cmd/ebs-bootstrap.go | 13 +++++++++++ configs/ubuntu.yml | 2 +- internal/action/action.go | 2 +- internal/config/config.go | 20 ++++++++--------- internal/config/modifier.go | 2 +- internal/service/owner.go | 44 +++++++++++++++++++++++++------------ 6 files changed, 56 insertions(+), 27 deletions(-) diff --git a/cmd/ebs-bootstrap.go b/cmd/ebs-bootstrap.go index 9ec1c9e..65149dc 100644 --- a/cmd/ebs-bootstrap.go +++ b/cmd/ebs-bootstrap.go @@ -22,6 +22,9 @@ func main() { uos := service.NewUnixOwnerService() ans := service.NewAwsNitroNVMeService() + // Warnings + warnings(uos) + // Config + Flags c, f, err := config.Parse(os.Args) checkError(err) @@ -67,3 +70,13 @@ func checkError(err error) { log.Fatal(err) } } + +func warnings(us service.OwnerService) { + cu, err := us.GetCurrentUser() + if err != nil { + return + } + if cu.Uid != 0 { + log.Println("🚧 Not running as root user. Operations that query and modify block devices will likely be restricted") + } +} diff --git a/configs/ubuntu.yml b/configs/ubuntu.yml index cbe8919..5303b44 100644 --- a/configs/ubuntu.yml +++ b/configs/ubuntu.yml @@ -8,4 +8,4 @@ devices: mountOptions: defaults group: ubuntu user: ubuntu - permissions: 644 \ No newline at end of file + permissions: 644 diff --git a/internal/action/action.go b/internal/action/action.go index efb41cc..246d973 100644 --- a/internal/action/action.go +++ b/internal/action/action.go @@ -63,7 +63,7 @@ func (ae *ActionExecutor) ExecuteAction(action Action) error { // Special handling for trusted actions when device is under // healthcheck mode if action.IsTrusted() { - if ae.config.GetSkipTrustedActions() { + if !ae.config.GetAllowTrustedActions() { log.Printf("🙅 Skipped trusted action. %s", action.Refuse()) return nil } diff --git a/internal/config/config.go b/internal/config/config.go index 2a1634e..c044190 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -39,9 +39,9 @@ func ParseMode(s string) (Mode, error) { } type Flag struct { - Config string - Mode string - SkipTrustedActions bool + Config string + Mode string + AllowTrustedActions bool } type Device struct { @@ -56,13 +56,13 @@ type Device struct { } type Defaults struct { - Mode Mode `yaml:"mode"` - SkipTrustedActions bool `yaml:"skipTrustedActions"` + Mode Mode `yaml:"mode"` + AllowTrustedActions bool `yaml:"allowTrustedActions"` } type Overrides struct { - Mode Mode `yaml:"mode"` - SkipTrustedActions bool `yaml:"skipTrustedActions"` + Mode Mode `yaml:"mode"` + AllowTrustedActions bool `yaml:"allowTrustedActions"` } type Config struct { @@ -111,7 +111,7 @@ func parseFlags(program string, args []string) (*Flag, error) { // to supply the configuration file flags.StringVar(&flag.Config, "config", "/etc/ebs-bootstrap/config.yml", "path to config file") flags.StringVar(&flag.Mode, "mode", "", "override for mode") - flags.BoolVar(&flag.SkipTrustedActions, "skip-trusted-actions", false, "skip trusted actions") + flags.BoolVar(&flag.AllowTrustedActions, "allow-trusted-actions", false, "allow trusted actions to run in healthcheck mode") // Actually parse the flag err := flags.Parse(args) @@ -139,6 +139,6 @@ func (c *Config) GetMode(name string) (Mode, error) { return Empty, fmt.Errorf("🔴 %s: Ensure that you have provided a supported mode locally or globally", name) } -func (c *Config) GetSkipTrustedActions() bool { - return c.Overrides.SkipTrustedActions || c.Defaults.SkipTrustedActions +func (c *Config) GetAllowTrustedActions() bool { + return c.Overrides.AllowTrustedActions || c.Defaults.AllowTrustedActions } diff --git a/internal/config/modifier.go b/internal/config/modifier.go index c9f9461..f9ebfb0 100644 --- a/internal/config/modifier.go +++ b/internal/config/modifier.go @@ -47,7 +47,7 @@ func (om *OverridesModifier) Modify(c *Config) error { return err } c.Overrides.Mode = mode - c.Overrides.SkipTrustedActions = om.flag.SkipTrustedActions + c.Overrides.AllowTrustedActions = om.flag.AllowTrustedActions return nil } diff --git a/internal/service/owner.go b/internal/service/owner.go index d57c7cf..706f170 100644 --- a/internal/service/owner.go +++ b/internal/service/owner.go @@ -9,6 +9,7 @@ import ( ) type OwnerService interface { + GetCurrentUser() (*model.User, error) GetUser(owner string) (*model.User, error) GetGroup(owner string) (*model.Group, error) } @@ -19,47 +20,62 @@ func NewUnixOwnerService() *UnixOwnerService { return &UnixOwnerService{} } -func (s *UnixOwnerService) GetUser(owner string) (*model.User, error) { +func (uos *UnixOwnerService) GetCurrentUser() (*model.User, error) { + u, err := user.Current() + if err != nil { + return nil, fmt.Errorf("🔴 Failed to get current user") + } + uid, err := strconv.Atoi(u.Uid) + if err != nil { + return nil, fmt.Errorf("🔴 Failed to cast user (id) to integer") + } + return &model.User{ + Name: u.Name, + Uid: uid, + }, nil +} + +func (uos *UnixOwnerService) GetUser(us string) (*model.User, error) { var u *user.User - if _, err := strconv.Atoi(owner); err != nil { + if _, err := strconv.Atoi(us); err != nil { // If not a valid integer, try to look up by username - u, err = user.Lookup(owner) + u, err = user.Lookup(us) if err != nil { - return nil, fmt.Errorf("🔴 Owner (name) %s does not exist", owner) + return nil, fmt.Errorf("🔴 User (name) %s does not exist", us) } } else { - u, err = user.LookupId(owner) + u, err = user.LookupId(us) if err != nil { - return nil, fmt.Errorf("🔴 Owner (id) %s does not exist", owner) + return nil, fmt.Errorf("🔴 User (id) %s does not exist", us) } } uid, err := strconv.Atoi(u.Uid) if err != nil { - return nil, fmt.Errorf("🔴 Failed to cast owner id to integer") + return nil, fmt.Errorf("🔴 Failed to cast user (id) to integer") } return &model.User{Name: u.Username, Uid: uid}, nil } -func (s *UnixOwnerService) GetGroup(group string) (*model.Group, error) { +func (uos *UnixOwnerService) GetGroup(grp string) (*model.Group, error) { var g *user.Group - if _, err := strconv.Atoi(group); err != nil { + if _, err := strconv.Atoi(grp); err != nil { // If not a valid integer, try to look up by group name - g, err = user.LookupGroup(group) + g, err = user.LookupGroup(grp) if err != nil { - return nil, fmt.Errorf("🔴 Group (name) %s does not exist", group) + return nil, fmt.Errorf("🔴 Group (name) %s does not exist", grp) } } else { - g, err = user.LookupGroupId(group) + g, err = user.LookupGroupId(grp) if err != nil { - return nil, fmt.Errorf("🔴 Group (id) %s does not exist", group) + return nil, fmt.Errorf("🔴 Group (id) %s does not exist", grp) } } gid, err := strconv.Atoi(g.Gid) if err != nil { - return nil, fmt.Errorf("🔴 Failed to cast group id to integer") + return nil, fmt.Errorf("🔴 Failed to cast group (id) to integer") } return &model.Group{Name: g.Name, Gid: gid}, nil