mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
02fddffd51
With this capability set the container can e.g. change the ip address of his devices to that of another container on the docker0 bridge. In a quick test I was able to listen to a port on a different ip than the one docker assigned me, but was not able to hijack an open port redirection that another container had open. Maybe its possible with some more knowledge of networking though. Anyway, network setup is meant to be handled by docker, not the apps, so I believe denying this is generally in the spirit of docker, and it closes down potential security issues. Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
154 lines
3.6 KiB
Go
154 lines
3.6 KiB
Go
package lxc
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/dotcloud/docker/execdriver"
|
|
"github.com/dotcloud/docker/pkg/netlink"
|
|
"github.com/dotcloud/docker/utils"
|
|
"github.com/syndtr/gocapability/capability"
|
|
"net"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"syscall"
|
|
)
|
|
|
|
func setupHostname(args *execdriver.InitArgs) error {
|
|
hostname := getEnv(args, "HOSTNAME")
|
|
if hostname == "" {
|
|
return nil
|
|
}
|
|
return setHostname(hostname)
|
|
}
|
|
|
|
// Setup networking
|
|
func setupNetworking(args *execdriver.InitArgs) error {
|
|
if args.Ip != "" {
|
|
// eth0
|
|
iface, err := net.InterfaceByName("eth0")
|
|
if err != nil {
|
|
return fmt.Errorf("Unable to set up networking: %v", err)
|
|
}
|
|
ip, ipNet, err := net.ParseCIDR(args.Ip)
|
|
if err != nil {
|
|
return fmt.Errorf("Unable to set up networking: %v", err)
|
|
}
|
|
if err := netlink.NetworkLinkAddIp(iface, ip, ipNet); err != nil {
|
|
return fmt.Errorf("Unable to set up networking: %v", err)
|
|
}
|
|
if err := netlink.NetworkSetMTU(iface, args.Mtu); err != nil {
|
|
return fmt.Errorf("Unable to set MTU: %v", err)
|
|
}
|
|
if err := netlink.NetworkLinkUp(iface); err != nil {
|
|
return fmt.Errorf("Unable to set up networking: %v", err)
|
|
}
|
|
|
|
// loopback
|
|
iface, err = net.InterfaceByName("lo")
|
|
if err != nil {
|
|
return fmt.Errorf("Unable to set up networking: %v", err)
|
|
}
|
|
if err := netlink.NetworkLinkUp(iface); err != nil {
|
|
return fmt.Errorf("Unable to set up networking: %v", err)
|
|
}
|
|
}
|
|
if args.Gateway != "" {
|
|
gw := net.ParseIP(args.Gateway)
|
|
if gw == nil {
|
|
return fmt.Errorf("Unable to set up networking, %s is not a valid gateway IP", args.Gateway)
|
|
}
|
|
|
|
if err := netlink.AddDefaultGw(gw); err != nil {
|
|
return fmt.Errorf("Unable to set up networking: %v", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Setup working directory
|
|
func setupWorkingDirectory(args *execdriver.InitArgs) error {
|
|
if args.WorkDir == "" {
|
|
return nil
|
|
}
|
|
if err := syscall.Chdir(args.WorkDir); err != nil {
|
|
return fmt.Errorf("Unable to change dir to %v: %v", args.WorkDir, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Takes care of dropping privileges to the desired user
|
|
func changeUser(args *execdriver.InitArgs) error {
|
|
if args.User == "" {
|
|
return nil
|
|
}
|
|
userent, err := utils.UserLookup(args.User)
|
|
if err != nil {
|
|
return fmt.Errorf("Unable to find user %v: %v", args.User, err)
|
|
}
|
|
|
|
uid, err := strconv.Atoi(userent.Uid)
|
|
if err != nil {
|
|
return fmt.Errorf("Invalid uid: %v", userent.Uid)
|
|
}
|
|
gid, err := strconv.Atoi(userent.Gid)
|
|
if err != nil {
|
|
return fmt.Errorf("Invalid gid: %v", userent.Gid)
|
|
}
|
|
|
|
if err := syscall.Setgid(gid); err != nil {
|
|
return fmt.Errorf("setgid failed: %v", err)
|
|
}
|
|
if err := syscall.Setuid(uid); err != nil {
|
|
return fmt.Errorf("setuid failed: %v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func setupCapabilities(args *execdriver.InitArgs) error {
|
|
|
|
if args.Privileged {
|
|
return nil
|
|
}
|
|
|
|
drop := []capability.Cap{
|
|
capability.CAP_SETPCAP,
|
|
capability.CAP_SYS_MODULE,
|
|
capability.CAP_SYS_RAWIO,
|
|
capability.CAP_SYS_PACCT,
|
|
capability.CAP_SYS_ADMIN,
|
|
capability.CAP_SYS_NICE,
|
|
capability.CAP_SYS_RESOURCE,
|
|
capability.CAP_SYS_TIME,
|
|
capability.CAP_SYS_TTY_CONFIG,
|
|
capability.CAP_MKNOD,
|
|
capability.CAP_AUDIT_WRITE,
|
|
capability.CAP_AUDIT_CONTROL,
|
|
capability.CAP_MAC_OVERRIDE,
|
|
capability.CAP_MAC_ADMIN,
|
|
capability.CAP_NET_ADMIN,
|
|
}
|
|
|
|
c, err := capability.NewPid(os.Getpid())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
c.Unset(capability.CAPS|capability.BOUNDS, drop...)
|
|
|
|
if err := c.Apply(capability.CAPS | capability.BOUNDS); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func getEnv(args *execdriver.InitArgs, key string) string {
|
|
for _, kv := range args.Env {
|
|
parts := strings.SplitN(kv, "=", 2)
|
|
if parts[0] == key && len(parts) == 2 {
|
|
return parts[1]
|
|
}
|
|
}
|
|
return ""
|
|
}
|