Signed-off-by: Darren Shepherd <darren@rancher.com>
| ... | ... |
@@ -337,6 +337,10 @@ func populateCommand(c *Container, env []string) error {
|
| 337 | 337 |
pid := &execdriver.Pid{}
|
| 338 | 338 |
pid.HostPid = c.hostConfig.PidMode.IsHost() |
| 339 | 339 |
|
| 340 |
+ uts := &execdriver.UTS{
|
|
| 341 |
+ HostUTS: c.hostConfig.UTSMode.IsHost(), |
|
| 342 |
+ } |
|
| 343 |
+ |
|
| 340 | 344 |
// Build lists of devices allowed and created within the container. |
| 341 | 345 |
var userSpecifiedDevices []*configs.Device |
| 342 | 346 |
for _, deviceMapping := range c.hostConfig.Devices {
|
| ... | ... |
@@ -412,6 +416,7 @@ func populateCommand(c *Container, env []string) error {
|
| 412 | 412 |
Network: en, |
| 413 | 413 |
Ipc: ipc, |
| 414 | 414 |
Pid: pid, |
| 415 |
+ UTS: uts, |
|
| 415 | 416 |
Resources: resources, |
| 416 | 417 |
AllowedDevices: allowedDevices, |
| 417 | 418 |
AutoCreatedDevices: autoCreatedDevices, |
| ... | ... |
@@ -86,6 +86,11 @@ type Pid struct {
|
| 86 | 86 |
HostPid bool `json:"host_pid"` |
| 87 | 87 |
} |
| 88 | 88 |
|
| 89 |
+// UTS settings of the container |
|
| 90 |
+type UTS struct {
|
|
| 91 |
+ HostUTS bool `json:"host_uts"` |
|
| 92 |
+} |
|
| 93 |
+ |
|
| 89 | 94 |
type NetworkInterface struct {
|
| 90 | 95 |
Gateway string `json:"gateway"` |
| 91 | 96 |
IPAddress string `json:"ip"` |
| ... | ... |
@@ -155,6 +160,7 @@ type Command struct {
|
| 155 | 155 |
Network *Network `json:"network"` |
| 156 | 156 |
Ipc *Ipc `json:"ipc"` |
| 157 | 157 |
Pid *Pid `json:"pid"` |
| 158 |
+ UTS *UTS `json:"uts"` |
|
| 158 | 159 |
Resources *Resources `json:"resources"` |
| 159 | 160 |
Mounts []Mount `json:"mounts"` |
| 160 | 161 |
AllowedDevices []*configs.Device `json:"allowed_devices"` |
| ... | ... |
@@ -29,6 +29,10 @@ func (d *driver) createContainer(c *execdriver.Command) (*configs.Config, error) |
| 29 | 29 |
return nil, err |
| 30 | 30 |
} |
| 31 | 31 |
|
| 32 |
+ if err := d.createUTS(container, c); err != nil {
|
|
| 33 |
+ return nil, err |
|
| 34 |
+ } |
|
| 35 |
+ |
|
| 32 | 36 |
if err := d.createNetwork(container, c); err != nil {
|
| 33 | 37 |
return nil, err |
| 34 | 38 |
} |
| ... | ... |
@@ -173,6 +177,16 @@ func (d *driver) createPid(container *configs.Config, c *execdriver.Command) err |
| 173 | 173 |
return nil |
| 174 | 174 |
} |
| 175 | 175 |
|
| 176 |
+func (d *driver) createUTS(container *configs.Config, c *execdriver.Command) error {
|
|
| 177 |
+ if c.UTS.HostUTS {
|
|
| 178 |
+ container.Namespaces.Remove(configs.NEWUTS) |
|
| 179 |
+ container.Hostname = "" |
|
| 180 |
+ return nil |
|
| 181 |
+ } |
|
| 182 |
+ |
|
| 183 |
+ return nil |
|
| 184 |
+} |
|
| 185 |
+ |
|
| 176 | 186 |
func (d *driver) setPrivileged(container *configs.Config) (err error) {
|
| 177 | 187 |
container.Capabilities = execdriver.GetAllCapabilities() |
| 178 | 188 |
container.Cgroups.AllowAllDevices = true |
| ... | ... |
@@ -42,6 +42,7 @@ docker-create - Create a new container |
| 42 | 42 |
[**-P**|**--publish-all**[=*false*]] |
| 43 | 43 |
[**-p**|**--publish**[=*[]*]] |
| 44 | 44 |
[**--pid**[=*[]*]] |
| 45 |
+[**--uts**[=*[]*]] |
|
| 45 | 46 |
[**--privileged**[=*false*]] |
| 46 | 47 |
[**--read-only**[=*false*]] |
| 47 | 48 |
[**--restart**[=*RESTART*]] |
| ... | ... |
@@ -193,6 +194,11 @@ This value should always larger than **-m**, so you should alway use this with * |
| 193 | 193 |
**host**: use the host's PID namespace inside the container. |
| 194 | 194 |
Note: the host mode gives the container full access to local PID and is therefore considered insecure. |
| 195 | 195 |
|
| 196 |
+**--uts**=host |
|
| 197 |
+ Set the UTS mode for the container |
|
| 198 |
+ **host**: use the host's UTS namespace inside the container. |
|
| 199 |
+ Note: the host mode gives the container access to changing the host's hostname and is therefore considered insecure. |
|
| 200 |
+ |
|
| 196 | 201 |
**--privileged**=*true*|*false* |
| 197 | 202 |
Give extended privileges to this container. The default is *false*. |
| 198 | 203 |
|
| ... | ... |
@@ -43,6 +43,7 @@ docker-run - Run a command in a new container |
| 43 | 43 |
[**-P**|**--publish-all**[=*false*]] |
| 44 | 44 |
[**-p**|**--publish**[=*[]*]] |
| 45 | 45 |
[**--pid**[=*[]*]] |
| 46 |
+[**--uts**[=*[]*]] |
|
| 46 | 47 |
[**--privileged**[=*false*]] |
| 47 | 48 |
[**--read-only**[=*false*]] |
| 48 | 49 |
[**--restart**[=*RESTART*]] |
| ... | ... |
@@ -323,6 +324,11 @@ ports and the exposed ports, use `docker port`. |
| 323 | 323 |
**host**: use the host's PID namespace inside the container. |
| 324 | 324 |
Note: the host mode gives the container full access to local PID and is therefore considered insecure. |
| 325 | 325 |
|
| 326 |
+**--uts**=host |
|
| 327 |
+ Set the UTS mode for the container |
|
| 328 |
+ **host**: use the host's UTS namespace inside the container. |
|
| 329 |
+ Note: the host mode gives the container access to changing the host's hostname and is therefore considered insecure. |
|
| 330 |
+ |
|
| 326 | 331 |
**--privileged**=*true*|*false* |
| 327 | 332 |
Give extended privileges to this container. The default is *false*. |
| 328 | 333 |
|
| ... | ... |
@@ -991,6 +991,8 @@ Creates a new container. |
| 991 | 991 |
--oom-kill-disable=false Whether to disable OOM Killer for the container or not |
| 992 | 992 |
-P, --publish-all=false Publish all exposed ports to random ports |
| 993 | 993 |
-p, --publish=[] Publish a container's port(s) to the host |
| 994 |
+ --pid="" PID namespace to use |
|
| 995 |
+ --uts="" UTS namespace to use |
|
| 994 | 996 |
--privileged=false Give extended privileges to this container |
| 995 | 997 |
--read-only=false Mount the container's root filesystem as read only |
| 996 | 998 |
--restart="no" Restart policy (no, on-failure[:max-retry], always) |
| ... | ... |
@@ -1958,6 +1960,7 @@ To remove an image using its digest: |
| 1958 | 1958 |
-P, --publish-all=false Publish all exposed ports to random ports |
| 1959 | 1959 |
-p, --publish=[] Publish a container's port(s) to the host |
| 1960 | 1960 |
--pid="" PID namespace to use |
| 1961 |
+ --uts="" UTS namespace to use |
|
| 1961 | 1962 |
--privileged=false Give extended privileges to this container |
| 1962 | 1963 |
--read-only=false Mount the container's root filesystem as read only |
| 1963 | 1964 |
--restart="no" Restart policy (no, on-failure[:max-retry], always) |
| ... | ... |
@@ -157,6 +157,7 @@ called a digest. As long as the input used to generate the image is unchanged, |
| 157 | 157 |
the digest value is predictable and referenceable. |
| 158 | 158 |
|
| 159 | 159 |
## PID settings (--pid) |
| 160 |
+ |
|
| 160 | 161 |
--pid="" : Set the PID (Process) Namespace mode for the container, |
| 161 | 162 |
'host': use the host's PID namespace inside the container |
| 162 | 163 |
|
| ... | ... |
@@ -177,6 +178,23 @@ within the container. |
| 177 | 177 |
This command would allow you to use `strace` inside the container on pid 1234 on |
| 178 | 178 |
the host. |
| 179 | 179 |
|
| 180 |
+## UTS settings (--uts) |
|
| 181 |
+ |
|
| 182 |
+ --uts="" : Set the UTS namespace mode for the container, |
|
| 183 |
+ 'host': use the host's UTS namespace inside the container |
|
| 184 |
+ |
|
| 185 |
+The UTS namespace is for setting the hostname and the domain that is visible |
|
| 186 |
+to running processes in that namespace. By default, all containers, including |
|
| 187 |
+those with `--net=host`, have their own UTS namespace. The `host` setting will |
|
| 188 |
+result in the container using the same UTS namespace as the host. |
|
| 189 |
+ |
|
| 190 |
+You may wish to share the UTS namespace with the host if you would like the |
|
| 191 |
+hostname of the container to change as the hostname of the host changes. A |
|
| 192 |
+more advanced use case would be changing the host's hostname from a container. |
|
| 193 |
+ |
|
| 194 |
+> **Note**: `--uts="host"` gives the container full access to change the |
|
| 195 |
+> hostname of the host and is therefore considered insecure. |
|
| 196 |
+ |
|
| 180 | 197 |
## IPC settings (--ipc) |
| 181 | 198 |
|
| 182 | 199 |
--ipc="" : Set the IPC mode for the container, |
| ... | ... |
@@ -2765,6 +2765,38 @@ func (s *DockerSuite) TestRunModePidHost(c *check.C) {
|
| 2765 | 2765 |
} |
| 2766 | 2766 |
} |
| 2767 | 2767 |
|
| 2768 |
+func (s *DockerSuite) TestRunModeUTSHost(c *check.C) {
|
|
| 2769 |
+ testRequires(c, NativeExecDriver, SameHostDaemon) |
|
| 2770 |
+ defer deleteAllContainers() |
|
| 2771 |
+ |
|
| 2772 |
+ hostUTS, err := os.Readlink("/proc/1/ns/uts")
|
|
| 2773 |
+ if err != nil {
|
|
| 2774 |
+ c.Fatal(err) |
|
| 2775 |
+ } |
|
| 2776 |
+ |
|
| 2777 |
+ cmd := exec.Command(dockerBinary, "run", "--uts=host", "busybox", "readlink", "/proc/self/ns/uts") |
|
| 2778 |
+ out2, _, err := runCommandWithOutput(cmd) |
|
| 2779 |
+ if err != nil {
|
|
| 2780 |
+ c.Fatal(err, out2) |
|
| 2781 |
+ } |
|
| 2782 |
+ |
|
| 2783 |
+ out2 = strings.Trim(out2, "\n") |
|
| 2784 |
+ if hostUTS != out2 {
|
|
| 2785 |
+ c.Fatalf("UTS different with --uts=host %s != %s\n", hostUTS, out2)
|
|
| 2786 |
+ } |
|
| 2787 |
+ |
|
| 2788 |
+ cmd = exec.Command(dockerBinary, "run", "busybox", "readlink", "/proc/self/ns/uts") |
|
| 2789 |
+ out2, _, err = runCommandWithOutput(cmd) |
|
| 2790 |
+ if err != nil {
|
|
| 2791 |
+ c.Fatal(err, out2) |
|
| 2792 |
+ } |
|
| 2793 |
+ |
|
| 2794 |
+ out2 = strings.Trim(out2, "\n") |
|
| 2795 |
+ if hostUTS == out2 {
|
|
| 2796 |
+ c.Fatalf("UTS should be different without --uts=host %s == %s\n", hostUTS, out2)
|
|
| 2797 |
+ } |
|
| 2798 |
+} |
|
| 2799 |
+ |
|
| 2768 | 2800 |
func (s *DockerSuite) TestRunTLSverify(c *check.C) {
|
| 2769 | 2801 |
cmd := exec.Command(dockerBinary, "ps") |
| 2770 | 2802 |
out, ec, err := runCommandWithOutput(cmd) |
| ... | ... |
@@ -76,6 +76,27 @@ func (n IpcMode) Container() string {
|
| 76 | 76 |
return "" |
| 77 | 77 |
} |
| 78 | 78 |
|
| 79 |
+type UTSMode string |
|
| 80 |
+ |
|
| 81 |
+// IsPrivate indicates whether container use it's private UTS namespace |
|
| 82 |
+func (n UTSMode) IsPrivate() bool {
|
|
| 83 |
+ return !(n.IsHost()) |
|
| 84 |
+} |
|
| 85 |
+ |
|
| 86 |
+func (n UTSMode) IsHost() bool {
|
|
| 87 |
+ return n == "host" |
|
| 88 |
+} |
|
| 89 |
+ |
|
| 90 |
+func (n UTSMode) Valid() bool {
|
|
| 91 |
+ parts := strings.Split(string(n), ":") |
|
| 92 |
+ switch mode := parts[0]; mode {
|
|
| 93 |
+ case "", "host": |
|
| 94 |
+ default: |
|
| 95 |
+ return false |
|
| 96 |
+ } |
|
| 97 |
+ return true |
|
| 98 |
+} |
|
| 99 |
+ |
|
| 79 | 100 |
type PidMode string |
| 80 | 101 |
|
| 81 | 102 |
// IsPrivate indicates whether container use it's private pid stack |
| ... | ... |
@@ -187,6 +208,7 @@ type HostConfig struct {
|
| 187 | 187 |
NetworkMode NetworkMode |
| 188 | 188 |
IpcMode IpcMode |
| 189 | 189 |
PidMode PidMode |
| 190 |
+ UTSMode UTSMode |
|
| 190 | 191 |
CapAdd []string |
| 191 | 192 |
CapDrop []string |
| 192 | 193 |
RestartPolicy RestartPolicy |
| ... | ... |
@@ -52,6 +52,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 52 | 52 |
flNetwork = cmd.Bool([]string{"#n", "#-networking"}, true, "Enable networking for this container")
|
| 53 | 53 |
flPrivileged = cmd.Bool([]string{"#privileged", "-privileged"}, false, "Give extended privileges to this container")
|
| 54 | 54 |
flPidMode = cmd.String([]string{"-pid"}, "", "PID namespace to use")
|
| 55 |
+ flUTSMode = cmd.String([]string{"-uts"}, "", "UTS namespace to use")
|
|
| 55 | 56 |
flPublishAll = cmd.Bool([]string{"P", "-publish-all"}, false, "Publish all exposed ports to random ports")
|
| 56 | 57 |
flStdin = cmd.Bool([]string{"i", "-interactive"}, false, "Keep STDIN open even if not attached")
|
| 57 | 58 |
flTty = cmd.Bool([]string{"t", "-tty"}, false, "Allocate a pseudo-TTY")
|
| ... | ... |
@@ -281,6 +282,11 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 281 | 281 |
return nil, nil, cmd, fmt.Errorf("--pid: invalid PID mode")
|
| 282 | 282 |
} |
| 283 | 283 |
|
| 284 |
+ utsMode := UTSMode(*flUTSMode) |
|
| 285 |
+ if !utsMode.Valid() {
|
|
| 286 |
+ return nil, nil, cmd, fmt.Errorf("--uts: invalid UTS mode")
|
|
| 287 |
+ } |
|
| 288 |
+ |
|
| 284 | 289 |
restartPolicy, err := ParseRestartPolicy(*flRestartPolicy) |
| 285 | 290 |
if err != nil {
|
| 286 | 291 |
return nil, nil, cmd, err |
| ... | ... |
@@ -337,6 +343,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*Config, *HostConfig, *flag.FlagSe |
| 337 | 337 |
NetworkMode: netMode, |
| 338 | 338 |
IpcMode: ipcMode, |
| 339 | 339 |
PidMode: pidMode, |
| 340 |
+ UTSMode: utsMode, |
|
| 340 | 341 |
Devices: deviceMappings, |
| 341 | 342 |
CapAdd: flCapAdd.GetAll(), |
| 342 | 343 |
CapDrop: flCapDrop.GetAll(), |