Create an iptablesNetwork containing all the info needed to
set up per-network iptables rules, give it methods to do
create the rules, and use it instead of per-rule-type calls
from driver.createNetwork().
Signed-off-by: Rob Murray <rob.murray@docker.com>
Doesn't look like it would ever have worked, but:
- init the dbus connection to avoid a segv
- include the chain name when creating the rule
- remove the test rule if it's created
Signed-off-by: Rob Murray <rob.murray@docker.com>
Firewalld runs in the host netns. So, tests running in
their own netns can't check firewalld's iptables rules.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Commit 9a6e96f ("Before sending ARPs/NAs, check the bridge is ready")
introduced a check that, if a container's veth is connected to a bridge,
the port is forwarding before sending unsolicited ARP/NA messages to
advertise the container's MAC/IP addresses.
It waited for up-to 200ms, but it seems that's not always enough.
If the port isn't forwarding, the ARP/NA messages will be silently
dropped. But, if it comes up within two seconds, one or both of the
resends will succeed.
So - keep the wait for 200ms but, if anything goes wrong with checking
the bridge port's state, or it's not forwarding after that time, just
log an info/warning level message and continue.
Signed-off-by: Rob Murray <rob.murray@docker.com>
When a macvlan's parent interface is down it's not possible
to send NA messages. So, ignore the error.
Signed-off-by: Rob Murray <rob.murray@docker.com>
For kernels that don't have CONFIG_IP_NF_RAW, if the env
var DOCKER_INSECURE_NO_IPTABLES_RAW is set to "1", don't
try to create raw rules.
This means direct routing to published ports is possible
from other hosts on the local network, even if the port
is published to a loopback address.
Signed-off-by: Rob Murray <rob.murray@docker.com>
If the userland-proxy is running, packets from one bridge network
addressed to the host port are not DNAT'd - so that docker-proxy
can pick them up, and therefore the packet bypasses the network
isolation rules.
Without the userland-proxy, there's no way for a packet from one
bridge network to bypass the network isolation rules. So, in this
case, DNAT is not skipped - and that at-least allows packets
originating from the network that published the port to access
the host port.
Commit 0546d90 improved support for routed mode networks (allowing
nat-mode networks access to containers in routed-mode networks, as
well as just remote access).
That commit changed the "SKIP DNAT" logic, making sure DNAT was
skipped for a routed-mode network if the userland-proxy was enabled
(so, containers in routed mode networks could access ports published
by other networks).
But, it still skipped DNAT for a routed mode network if the userland
proxy was disabled - packets from the routed mode network aimed at
any other network would be dropped by the network isolation rules
anyway, and containers in a routed mode network don't need access to
ports published from that network (because, by definition, there
can't be any).
However, network isolation rules can be worked-around with a rule
in the DOCKER-USER chain, but the SKIP DNAT rule is harder to deal
with.
So, for routed-mode, only skip DNAT if the userland-proxy is
enabled (just like nat-mode networks).
Signed-off-by: Rob Murray <rob.murray@docker.com>
These chains were added in commit 76417bf ("Don't use ipset"), but
not included in the list of chains that get flushed and deleted
on daemon startup.
Signed-off-by: Rob Murray <rob.murray@docker.com>
libnetwork/drivers/remote/driver_test.go:29:2: naked return in func `decodeToMap` with 3 lines of code (nakedret)
return
^
libnetwork/ipams/remote/remote_test.go:23:2: naked return in func `decodeToMap` with 3 lines of code (nakedret)
return
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
libnetwork/types/types.go:330:2: naked return in func `ParseCIDR` with 6 lines of code (nakedret)
return
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
libnetwork/osl/namespace_linux.go:324:2: naked return in func `DisableARPForVIP` with 28 lines of code (nakedret)
return
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
libnetwork/drivers/overlay/encryption.go:370:2: naked return in func `programSA` with 64 lines of code (nakedret)
return
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
libnetwork/cmd/networkdb-test/dbclient/ndbClient.go:251:5: naked return in func `checkTable` with 42 lines of code (nakedret)
return
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Re-implement the Build function using the new implementation from
libnetwork/internal/resolvconf.
BuildKit is the only consumer of the Build function currently, and we
should consider either moving the internal package out of internal, or
to provide a more customized variant of Build that fits BuildKit's
needs (i.e., only patch content, but not write to a file).
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The new resolvconf implementation in libnetwork/internal/resolvconf
uses a different order for "search" and puts it after the resolvers.
While this changes the checksum of the file, and thus would be potentially
detected as "user modified", we no longer use this function ourselves,
and BuildKit (which uses this function) only consumes the Content field,
and discards the Hash; https://github.com/moby/buildkit/blob/v0.20.0/executor/oci/resolvconf.go#L99-L103
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
The tests were depending on the implementation ignoring invalid
nameservers, as these should always be an IP-address, not a hostname.
Update the tests to use correct values, instead of codifying the
bad behavior.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
A jump to DOCKER-INGRESS chain is only created when Swarm needs
it. That's always after jumps to DOCKER-USER and DOCKER-FORWARD
have been inserted at the top of the FORWARD chain. The
DOCKER-INGRESS rule needs to be between those two other jumps.
Placing the jump to DOCKER-INGRESS at the top of the DOCKER-FORWARD
chain puts it in the right place, without needing to shuffle any
other rules around when it's added.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Commit 0546d90 introduced the use of ipset to reduce the number
of rules that need to be processed per-packet, and make the code
a bit simpler.
But, docker's used on embedded kernels compiled without support
for ipset, so the change is too disruptive.
Replace the two ipset rules with a new chain that writes out the
rule's actions long-hand. So ..
This rule:
-A FORWARD -m set --match-set docker-ext-bridges-v4 dst \
-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Is transformed into a per-bridge rule in new chain DOCKER-CT:
-A DOCKER-FORWARD -j DOCKER-CT
-A DOCKER-CT -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A DOCKER-CT -o bridge1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
And:
-A FORWARD -m set --match-set docker-ext-bridges-v4 dst -j DOCKER
Is transformed into a per-bridge rule in new chain DOCKER-BRIDGE:
-A DOCKER-FORWARD -j DOCKER-BRIDGE
-A DOCKER-BRIDGE -o docker0 -j DOCKER
-A DOCKER-BRIDGE -o bridge1 -j DOCKER
Signed-off-by: Rob Murray <rob.murray@docker.com>
Creating a swarm network from a config-only network failed
because the new EnableIPv4 wasn't validated/propagated
correctly.
So:
- Always initialise EnableIPv4 to true, including for a config
only network, and on load from the store.
- Treat enableIPv4=true as the no-overridden state when checking
params for a config-from network.
- Propagate settings from the config 'Network' objects attributes
to its generic options, because the network driver only sees
generic options.
- This was happening already for Network.internal, after the
config-only network options were processed. Move that to
'applyConfigurationTo'.
- Add enableIPv4/enableIpv6 - enableIPv6 will normaly be present
anyway. But, for a network created pre-28.x and restored from
the store, there was no entry for 'netlabel.EnableIpv4'.
- Extend TestSwarmScopedNetFromConfig to start a service and
check it's ok.
Signed-off-by: Rob Murray <rob.murray@docker.com>
For swarm networks, Controller.NewNetwork is called to validate
network config ... nothing gets created, but ManagerRedirectError
is returned if the config is ok - then swarm does its own thing.
So, for a --config-from network, merge config before checking
whether it'll have IPv4 enabled.
Signed-off-by: Rob Murray <rob.murray@docker.com>
With ip6tables enabled (by default), the daemon should start on a
host with IPv6 disabled - then error if IPv6 network creation is
attempted.
That regressed in commit 255fff4 - so, only try to set up network
isolation rules for a network if it's IPv6-enabled.
Signed-off-by: Rob Murray <rob.murray@docker.com>
In 28.0.0, Docker appended to the FORWARD chain - breaking other
applications that had appended their own rules that needed to execute
after Docker's rules.
Move most of Docker's rules out of the filter-FORWARD chain into a
new DOCKER-FORWARD chain, so that Docker can append to DOCKER-FORWARD
without affecting the order of rules in the FORWARD chain.
After daemon startup inserts jumps to DOCKER-USER and DOCKER-FORWARD,
the bridge driver will not touch the FORWARD chain again. DOCKER-INGRESS
is still added to the FORWARD chain, if used, as it was in 27.x and
earlier.
Signed-off-by: Rob Murray <rob.murray@docker.com>
On i386, Linux doesn't provide direct socket syscall but instead
multiplexes them through the socketcall syscall (see `man 2 socketcall`).
This commit fixes compilation for i386 by wrapping the offending syscall
in a new function that uses the socketcall syscall on i386, and
the `setsockopt` syscall on other archs.
Signed-off-by: Albin Kerouanton <albinker@gmail.com>
The `ErrPortAlreadyAllocated` error was introduced in ffd68badc0,
and at the time used as sentinel error in the bridge driver. It was later
integrated into libnetwork ([libnetwork@672ced7]), and brought back when
libnetwork was integrated in v1.7.0; 272f8cd4bc
After libnetwork was integrated, the error was unused as sentinel error,
except for locally inside the package as part of a test;
git rev-parse --verify HEAD
496bc46c88
git grep '\.ErrPortAlreadyAllocated'
Which is still the case Today;
git describe --tags --match="v[0-9]*" HEAD
v28.0.0
git rev-parse --verify HEAD
af898abe44
git grep '\.ErrPortAlreadyAllocated'
Same for the `ErrAllPortsAllocated` (added in 739d124480)
and `ErrUnknownProtocol` (added in 303ed3c830)
errors, which were never used as sentinel errors, and still aren't;
git grep '\.ErrAllPortsAllocated'
git grep '\.ErrUnknownProtocol'
vendor/github.com/moby/buildkit/client/llb/source.go: if errors.Is(err, gitutil.ErrUnknownProtocol) {
This patch;
- un-exports these errors as they are not used as sentinel errors
- strips down the `ErrPortAlreadyAllocated`, removing the methods that
were added, but never used.
- removes the `newErrPortAlreadyAllocated` constructor
- renames `ErrPortAlreadyAllocated` to `alreadyAllocatedErr` to follow
go conventions.
[libnetwork@672ced7]: c0474b6438
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
New iptables rules were added by:
- commit 27adcd5 (libnet/d/bridge: port mappings: drop direct-access
when gw_mode=nat)
- commit d216084 (libnet/d/bridge: drop remote connections to port
mapped on lo)
But they're added even when iptables=false or ip6tables=false in daemon
config.
So, group those rules with the other per-port rules, behind a config
check.
Signed-off-by: Rob Murray <rob.murray@docker.com>
In the bridge network driver, filterPortMappedOnLoopback and
filterDirectAccess each set up some per-port iptables rules - but
they're not called by setPerPortIptables.
So, make sure they're called when firewalld is reloaded.
Signed-off-by: Rob Murray <rob.murray@docker.com>
Adding a `default` statement so that disabling the "default-signifies-exhaustive"
linter option will make it show up.
libnetwork/networkdb/delegate.go:49:2: missing cases in switch of type networkdb.NodeEvent_Type: networkdb.NodeEventTypeInvalid (exhaustive)
switch nEvent.Type {
^
libnetwork/networkdb/delegate.go:223:2: missing cases in switch of type networkdb.TableEvent_Type: networkdb.TableEventTypeInvalid (exhaustive)
switch tEvent.Type {
^
libnetwork/networkdb/nodemgmt.go:51:2: missing cases in switch of type networkdb.nodeState: networkdb.nodeNotFound (exhaustive)
switch newState {
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
These need revisiting, similar to similar code in libnetwork/drivers/bridge.
There was already a TODO in place for this, so ignoring these for now.
libnetwork/endpoint.go:148:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
ib, _ := json.Marshal(epMap["ep_iface"])
^
libnetwork/endpoint.go:151:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
jb, _ := json.Marshal(epMap["joinInfo"])
^
libnetwork/endpoint.go:154:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
tb, _ := json.Marshal(epMap["exposed_ports"])
^
libnetwork/endpoint.go:159:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
cb, _ := json.Marshal(epMap["sandbox"])
^
libnetwork/endpoint.go:237:12: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
sal, _ := json.Marshal(epMap["svcAliases"])
^
libnetwork/endpoint.go:242:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
pc, _ := json.Marshal(epMap["ingressPorts"])
^
libnetwork/endpoint.go:247:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
ma, _ := json.Marshal(epMap["myAliases"])
^
libnetwork/endpoint.go:252:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
dn, _ := json.Marshal(epMap["dnsNames"])
^
libnetwork/endpoint_info.go:123:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
rb, _ := json.Marshal(epMap["routes"])
^
libnetwork/endpoint_info.go:490:12: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
tb, _ := json.Marshal(v)
^
libnetwork/network.go:161:11: Error return value of `encoding/json.Marshal` is not checked: unsafe type `interface{}` found (errchkjson)
b, _ := json.Marshal(v)
^
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>