setup.go 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package apparmor
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "os/exec"
  7. )
  8. const DefaultProfilePath = "/etc/apparmor.d/docker"
  9. const DefaultProfile = `
  10. # AppArmor profile from lxc for containers.
  11. @{HOME}=@{HOMEDIRS}/*/ /root/
  12. @{HOMEDIRS}=/home/
  13. #@{HOMEDIRS}+=
  14. @{multiarch}=*-linux-gnu*
  15. @{PROC}=/proc/
  16. profile docker-default flags=(attach_disconnected,mediate_deleted) {
  17. network,
  18. capability,
  19. file,
  20. umount,
  21. # ignore DENIED message on / remount
  22. deny mount options=(ro, remount) -> /,
  23. # allow tmpfs mounts everywhere
  24. mount fstype=tmpfs,
  25. # allow mqueue mounts everywhere
  26. mount fstype=mqueue,
  27. # allow fuse mounts everywhere
  28. mount fstype=fuse.*,
  29. # allow bind mount of /lib/init/fstab for lxcguest
  30. mount options=(rw, bind) /lib/init/fstab.lxc/ -> /lib/init/fstab/,
  31. # deny writes in /proc/sys/fs but allow binfmt_misc to be mounted
  32. mount fstype=binfmt_misc -> /proc/sys/fs/binfmt_misc/,
  33. deny @{PROC}/sys/fs/** wklx,
  34. # allow efivars to be mounted, writing to it will be blocked though
  35. mount fstype=efivarfs -> /sys/firmware/efi/efivars/,
  36. # block some other dangerous paths
  37. deny @{PROC}/sysrq-trigger rwklx,
  38. deny @{PROC}/mem rwklx,
  39. deny @{PROC}/kmem rwklx,
  40. deny @{PROC}/sys/kernel/[^s][^h][^m]* wklx,
  41. deny @{PROC}/sys/kernel/*/** wklx,
  42. # deny writes in /sys except for /sys/fs/cgroup, also allow
  43. # fusectl, securityfs and debugfs to be mounted there (read-only)
  44. mount fstype=fusectl -> /sys/fs/fuse/connections/,
  45. mount fstype=securityfs -> /sys/kernel/security/,
  46. mount fstype=debugfs -> /sys/kernel/debug/,
  47. deny mount fstype=debugfs -> /var/lib/ureadahead/debugfs/,
  48. mount fstype=proc -> /proc/,
  49. mount fstype=sysfs -> /sys/,
  50. deny /sys/[^f]*/** wklx,
  51. deny /sys/f[^s]*/** wklx,
  52. deny /sys/fs/[^c]*/** wklx,
  53. deny /sys/fs/c[^g]*/** wklx,
  54. deny /sys/fs/cg[^r]*/** wklx,
  55. deny /sys/firmware/efi/efivars/** rwklx,
  56. deny /sys/kernel/security/** rwklx,
  57. mount options=(move) /sys/fs/cgroup/cgmanager/ -> /sys/fs/cgroup/cgmanager.lower/,
  58. # the container may never be allowed to mount devpts. If it does, it
  59. # will remount the host's devpts. We could allow it to do it with
  60. # the newinstance option (but, right now, we don't).
  61. deny mount fstype=devpts,
  62. }
  63. `
  64. func InstallDefaultProfile() error {
  65. if !IsEnabled() {
  66. return nil
  67. }
  68. // If the profile already exists, let it be.
  69. if _, err := os.Stat(DefaultProfilePath); err == nil {
  70. return nil
  71. }
  72. if err := ioutil.WriteFile(DefaultProfilePath, []byte(DefaultProfile), 0644); err != nil {
  73. return err
  74. }
  75. output, err := exec.Command("/lib/init/apparmor-profile-load", "docker").CombinedOutput()
  76. if err != nil {
  77. return fmt.Errorf("Error loading docker profile: %s (%s)", err, output)
  78. }
  79. return nil
  80. }