From 1ba751993cfd8388787e109988023beeabcc957b Mon Sep 17 00:00:00 2001 From: Alain Saint-Sever Date: Sun, 12 Jan 2020 15:59:18 +0100 Subject: [PATCH] Add unload and remove profile command Signed-off-by: Alain Saint-Sever --- README.md | 1 + apparmor/apparmor.go | 26 ++++++++++++++++++++++++++ main.go | 22 ++++++++++++++++------ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 73daa8e..428b290 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ Flags: -d enable debug logging (default: false) -profile-dir directory for saving the profiles (default: /etc/apparmor.d/containers) + -u unload and remove profile (default: false) Commands: diff --git a/apparmor/apparmor.go b/apparmor/apparmor.go index b28844d..6e19463 100644 --- a/apparmor/apparmor.go +++ b/apparmor/apparmor.go @@ -107,3 +107,29 @@ func (profile *ProfileConfig) Install(dir string) error { } return nil } + +// Uninstall unloads the profile with `apparmor_parser` +// then removes it from given directory +func (profile *ProfileConfig) Uninstall(dir string) error { + // Make sure the path exists + if err := os.MkdirAll(dir, 0755); err != nil { + return err + } + + cmd := exec.Command("/sbin/apparmor_parser", "-R", profile.Name) + // to use the parser directly we have to make sure we are in the correct + // dir with the profile + cmd.Dir = dir + + output, err := cmd.CombinedOutput() + if err != nil { + return fmt.Errorf("Unloading apparmor profile %s failed: %v (%s)", profile.Name, err, output) + } + + // Last thing: remove profile file + if err := os.Remove(filepath.Join(dir, profile.Name)); err != nil { + return err + } + + return nil +} diff --git a/main.go b/main.go index 59f6479..371a9d4 100644 --- a/main.go +++ b/main.go @@ -18,7 +18,7 @@ import ( var ( apparmorProfileDir string - debug bool + debug, uninstall bool ) func main() { @@ -35,6 +35,7 @@ func main() { p.FlagSet = flag.NewFlagSet("global", flag.ExitOnError) p.FlagSet.StringVar(&apparmorProfileDir, "profile-dir", "/etc/apparmor.d/containers", "directory for saving the profiles") p.FlagSet.BoolVar(&debug, "d", false, "enable debug logging") + p.FlagSet.BoolVar(&uninstall, "u", false, "unload and remove profile") // Set the before function. p.Before = func(ctx context.Context) error { @@ -75,12 +76,21 @@ func main() { profile.Name = fmt.Sprintf("docker-%s", profile.Name) } - // install the profile - if err := profile.Install(apparmorProfileDir); err != nil { - logrus.Fatalf("Installing profile %s failed: %v", profile.Name, err) - } + if !uninstall { + // install the profile + if err := profile.Install(apparmorProfileDir); err != nil { + logrus.Fatalf("Installing profile %s failed: %v", profile.Name, err) + } + + fmt.Printf("Profile installed successfully you can now run the profile with\n`docker run --security-opt=\"apparmor:%s\"`\n", profile.Name) + } else { + // uninstall the profile (ie unload and remove) + if err := profile.Uninstall(apparmorProfileDir); err != nil { + logrus.Fatalf("Uninstalling profile %s failed: %v", profile.Name, err) + } - fmt.Printf("Profile installed successfully you can now run the profile with\n`docker run --security-opt=\"apparmor:%s\"`\n", profile.Name) + fmt.Printf("Profile %s uninstalled successfully\n", profile.Name) + } return nil }