Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix connect to host and prevent disconnect from host for host network #17476

Merged
merged 1 commit into from Nov 10, 2015

Conversation

coolljt0725
Copy link
Contributor

There are two commits in this PR.
The first one is to fix connect to host. If a container start with default network(bridge) or none
it can't be connect to host as desired. but if disconnect the container from bridge or none, you can
connect to host, but this will cause some problem.

$ docker run -ti --rm --name container1 busybox
$ docker network disconnect bridge container1
$ docker network connect host container1

we able to connect to host after the container disconnect from bridge
but actually, the container still use its own network namespace, docker inspect still show its own private sandbox the container use and ifconfig in the container still the information of its own private network namespace.
From what I understand the container has private network namespace cannot connect to other network namespace, https://github.com/docker/docker/blob/master/daemon/container_unix.go#L742 is supposed to do thar but may not go there because container.NetworkSettings.Networks could be nil ,correct me if I'm wrong :) @mavenugo

The second commit is to prevent from disconnecting from host for a container start with --net=host. if a container with --net=host disconnect from host, it still in the host network namespace, but able to connect to other network, and cause some problem.


$ docker run -ti --rm --net=host --name container1 busybox
$ docker network disconnect host container1
$ docker network connect bridge container1
Error response from daemon: failed to set gateway while updating gateway: network is unreachable

though connect to bridge failed, but it has create a eth0 network interface on my host

eth0: flags=4163  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0
        inet6 fe80::42:acff:fe11:2  prefixlen 64  scopeid 0x20
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 8  bytes 648 (648.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10  bytes 732 (732.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

and docker inspect show the endpoint information

"Networks": {
            "bridge": {
                "EndpointID": "ddc8cd9e738f9255fc3288c82d77adf6d226ed1ec0e1c8000935b0269e39080a",
                "Gateway": "",
                "IPAddress": "172.17.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "MacAddress": "02:42:ac:11:00:02"
            }
        }

So I think we should prevent user from disconnect from host
ping @tiborvass

@tiborvass
Copy link
Contributor

Ping @mavenugo @mrjana

@@ -728,7 +728,9 @@ func (container *Container) updateNetworkSettings(n libnetwork.Network) error {
if container.NetworkSettings == nil {
container.NetworkSettings = &network.Settings{Networks: make(map[string]*network.EndpointSettings)}
}

if !container.hostConfig.NetworkMode.IsHost() && runconfig.NetworkMode(n.Type()).IsHost() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not be needing this extra check. The check for IsPrivate() should disallow connecting to host. Are you able to connect to host after the container is started on a private network?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrjana yes, I able to connect to host if I disconnect the container with private network from bridge

docker run -d --name c1 busybox top
docker network disconnect bridge c1
docker network connect host c1
docker inspect c1
  ....
"Networks": {
            "host": {
                "EndpointID": "6b09beacac0470bed008ee62c55f4161701c64d5a7ccaddd8a155eb0c779bf5f",
                "Gateway": "",
                "IPAddress": "",
                "IPPrefixLen": 0,
                "IPv6Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "MacAddress": ""
            }
        }

because if we disconnect it from bridge, the "NetworkSettings" is nil and the check below for IsPrivate() has no chance to run

@mrjana
Copy link
Contributor

mrjana commented Nov 4, 2015

@coolljt0725 I am ok with the design. But had a comment on the code changes. Can you please clarify?

When you try to connect a container to host, which is already connected to a private network, container.NetworkSettings.Networks cannot be nil

@mrjana
Copy link
Contributor

mrjana commented Nov 4, 2015

@coolljt0725 Also it needs a rebase

@coolljt0725
Copy link
Contributor Author

rebased

@thaJeztah
Copy link
Member

@mrjana @tiborvass is this a 1.9.1 fix?

@mrjana
Copy link
Contributor

mrjana commented Nov 5, 2015

@thaJeztah Yes

@mrjana
Copy link
Contributor

mrjana commented Nov 5, 2015

LGTM

@cpuguy83
Copy link
Member

cpuguy83 commented Nov 5, 2015

Moving to code review since it's got @mrjana's blessing.

@thaJeztah thaJeztah added this to the 1.9.1 milestone Nov 6, 2015
@@ -720,6 +720,10 @@ func (daemon *Daemon) updateNetworkSettings(container *Container, n libnetwork.N
container.NetworkSettings = &network.Settings{Networks: make(map[string]*network.EndpointSettings)}
}

if !container.hostConfig.NetworkMode.IsHost() && runconfig.NetworkMode(n.Type()).IsHost() {
return runconfig.ErrConflictSharedNetwork
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come this is ErrConflictSharedNetwork and the other one is ErrConflictHostNetwork when they are both host?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to prevent user from connecting to host and the other is prevent user from disconnecting from host

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But shouldn't these both be ErrConflictHostNetwork?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both be ErrConflictHostNetwork is also make sense, just need to modify the description of ErrConflictHostNetwork, I'll update

@coolljt0725
Copy link
Contributor Author

@cpuguy83 updated

@coolljt0725
Copy link
Contributor Author

@cpuguy83 updated

@cpuguy83
Copy link
Member

cpuguy83 commented Nov 9, 2015

LGTM

Container has private network namespace can not to connect to host
and container with host network can not be disconnected from host.

Signed-off-by: Lei Jitang <leijitang@huawei.com>
@calavera
Copy link
Contributor

calavera commented Nov 9, 2015

LGTM.

Unfortunately, this won't merge cleanly in the 1.9 release branch. @tiborvass should we open a new PR against that branch with a similar fix?

@calavera
Copy link
Contributor

It looks like this is okay for the release, no merged conflicts.

Merging!

calavera added a commit that referenced this pull request Nov 10, 2015
Fix connect to host and prevent disconnect from host for host network
@calavera calavera merged commit 470fc94 into moby:master Nov 10, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants