How are containers secured with MACVLAN networks?
-
Containers cannot be connected both to an internal bridge and to the host network at the same time, according to https://devops.stackexchange.com/a/9884/35435 . However, this is what I need; I want a set of containers to be connected both to a Swarm overlay network for inter-container communication (or a different solution if necessary, like Weave), and also to the host's network, without NAT, to expose a service. Thus, for the container to expose its service, the only option I am aware of is to use a macvlan network.
Side note: using a Swarm service without the routing mesh (there will only be one container/service per host, and requests to that host should always be served by the container/service on that host) would work, except my understanding is that a published port will go through NAT. This is undesireable.
It appears that a container exposed through a macvlan network is completely exposed and cannot be firewalled off (I read that the macvlan network is independent of the host's network stack, somehow, and can't be firewalled by the host - if you have a source for this, please link it). It would be possible to limit the attack surface by using the smallest possible image, and be very careful about setting bind addresses for services on the container, but this doesn't replace a firewall.
So, assuming the preceding three paragraphs aren't drastically incorrect, what is the recommended way to securely expose a container on a macvlan network?
-
The referenced question deals with docker containers being attached to both a bridge and the host network at the same time.
However, to expose a service, you publish your service typically via dockers ingress rather than host most networking so this is rarely an issue.
i.e. the following compose fragment is legal:
services: my-api: image: foo networks: - overlay1 - bridge1 ports: - 9090:8080
Wheras this fragment is illegal:
services: my-api: image: foo # docker compose host mode networking. network_mode: host networks: - overlay1 - bridge1 - hostent ports: # docker swarm can publish a port on a host. This should work - target: 80 published: 8080 protocol: tcp mode: host
networks:
A different swarm compatible take on --net:host
Also can't be mixed with ingress networking.
hostnet:
external: true
name: host