init.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package lxc
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "net"
  7. "os"
  8. "strings"
  9. "syscall"
  10. "github.com/dotcloud/docker/daemon/execdriver"
  11. "github.com/dotcloud/docker/pkg/netlink"
  12. "github.com/dotcloud/docker/pkg/user"
  13. "github.com/syndtr/gocapability/capability"
  14. )
  15. // Clear environment pollution introduced by lxc-start
  16. func setupEnv(args *execdriver.InitArgs) error {
  17. // Get env
  18. var env []string
  19. content, err := ioutil.ReadFile(".dockerenv")
  20. if err != nil {
  21. return fmt.Errorf("Unable to load environment variables: %v", err)
  22. }
  23. if err := json.Unmarshal(content, &env); err != nil {
  24. return fmt.Errorf("Unable to unmarshal environment variables: %v", err)
  25. }
  26. // Propagate the plugin-specific container env variable
  27. env = append(env, "container="+os.Getenv("container"))
  28. args.Env = env
  29. os.Clearenv()
  30. for _, kv := range args.Env {
  31. parts := strings.SplitN(kv, "=", 2)
  32. if len(parts) == 1 {
  33. parts = append(parts, "")
  34. }
  35. os.Setenv(parts[0], parts[1])
  36. }
  37. return nil
  38. }
  39. func setupHostname(args *execdriver.InitArgs) error {
  40. hostname := getEnv(args, "HOSTNAME")
  41. if hostname == "" {
  42. return nil
  43. }
  44. return setHostname(hostname)
  45. }
  46. // Setup networking
  47. func setupNetworking(args *execdriver.InitArgs) error {
  48. if args.Ip != "" {
  49. // eth0
  50. iface, err := net.InterfaceByName("eth0")
  51. if err != nil {
  52. return fmt.Errorf("Unable to set up networking: %v", err)
  53. }
  54. ip, ipNet, err := net.ParseCIDR(args.Ip)
  55. if err != nil {
  56. return fmt.Errorf("Unable to set up networking: %v", err)
  57. }
  58. if err := netlink.NetworkLinkAddIp(iface, ip, ipNet); err != nil {
  59. return fmt.Errorf("Unable to set up networking: %v", err)
  60. }
  61. if err := netlink.NetworkSetMTU(iface, args.Mtu); err != nil {
  62. return fmt.Errorf("Unable to set MTU: %v", err)
  63. }
  64. if err := netlink.NetworkLinkUp(iface); err != nil {
  65. return fmt.Errorf("Unable to set up networking: %v", err)
  66. }
  67. // loopback
  68. iface, err = net.InterfaceByName("lo")
  69. if err != nil {
  70. return fmt.Errorf("Unable to set up networking: %v", err)
  71. }
  72. if err := netlink.NetworkLinkUp(iface); err != nil {
  73. return fmt.Errorf("Unable to set up networking: %v", err)
  74. }
  75. }
  76. if args.Gateway != "" {
  77. gw := net.ParseIP(args.Gateway)
  78. if gw == nil {
  79. return fmt.Errorf("Unable to set up networking, %s is not a valid gateway IP", args.Gateway)
  80. }
  81. if err := netlink.AddDefaultGw(gw); err != nil {
  82. return fmt.Errorf("Unable to set up networking: %v", err)
  83. }
  84. }
  85. return nil
  86. }
  87. // Setup working directory
  88. func setupWorkingDirectory(args *execdriver.InitArgs) error {
  89. if args.WorkDir == "" {
  90. return nil
  91. }
  92. if err := syscall.Chdir(args.WorkDir); err != nil {
  93. return fmt.Errorf("Unable to change dir to %v: %v", args.WorkDir, err)
  94. }
  95. return nil
  96. }
  97. // Takes care of dropping privileges to the desired user
  98. func changeUser(args *execdriver.InitArgs) error {
  99. uid, gid, suppGids, err := user.GetUserGroupSupplementary(
  100. args.User,
  101. syscall.Getuid(), syscall.Getgid(),
  102. )
  103. if err != nil {
  104. return err
  105. }
  106. if err := syscall.Setgroups(suppGids); err != nil {
  107. return fmt.Errorf("Setgroups failed: %v", err)
  108. }
  109. if err := syscall.Setgid(gid); err != nil {
  110. return fmt.Errorf("Setgid failed: %v", err)
  111. }
  112. if err := syscall.Setuid(uid); err != nil {
  113. return fmt.Errorf("Setuid failed: %v", err)
  114. }
  115. return nil
  116. }
  117. func setupCapabilities(args *execdriver.InitArgs) error {
  118. if args.Privileged {
  119. return nil
  120. }
  121. drop := []capability.Cap{
  122. capability.CAP_SETPCAP,
  123. capability.CAP_SYS_MODULE,
  124. capability.CAP_SYS_RAWIO,
  125. capability.CAP_SYS_PACCT,
  126. capability.CAP_SYS_ADMIN,
  127. capability.CAP_SYS_NICE,
  128. capability.CAP_SYS_RESOURCE,
  129. capability.CAP_SYS_TIME,
  130. capability.CAP_SYS_TTY_CONFIG,
  131. capability.CAP_AUDIT_WRITE,
  132. capability.CAP_AUDIT_CONTROL,
  133. capability.CAP_MAC_OVERRIDE,
  134. capability.CAP_MAC_ADMIN,
  135. capability.CAP_NET_ADMIN,
  136. capability.CAP_SYSLOG,
  137. }
  138. c, err := capability.NewPid(os.Getpid())
  139. if err != nil {
  140. return err
  141. }
  142. c.Unset(capability.CAPS|capability.BOUNDS, drop...)
  143. if err := c.Apply(capability.CAPS | capability.BOUNDS); err != nil {
  144. return err
  145. }
  146. return nil
  147. }
  148. func getEnv(args *execdriver.InitArgs, key string) string {
  149. for _, kv := range args.Env {
  150. parts := strings.SplitN(kv, "=", 2)
  151. if parts[0] == key && len(parts) == 2 {
  152. return parts[1]
  153. }
  154. }
  155. return ""
  156. }