portmap: Apply the DNAT hairpin to the whole subnet

The DNAT hairpin rule only allow the container itself to access the
ports it is exposing thru the host IP. Other containers in the same
subnet might also want to access this service via the host IP, so
apply this rule to the whole subnet instead of just for the container.

This is particularly useful with setups using a reverse proxy for
https. With such a setup connections between containers (for ex.
oauth2) have to downgrade to http, or need complex dns setup to make
use of the internal IP of the reverse proxy. On the other hand going
thru the host IP is easy as that is probably what the service name
already resolve to.

Signed-off-by: Alban Bedel <albeu@free.fr>
--
v2: Fixed the tests
v3: Updated iptables rules documentation in README.md
v4: Fixed the network addresses in README.md to match iptables output
This commit is contained in:
Alban Bedel
2020-03-31 23:29:25 +02:00
parent a78853f29f
commit 5e0fbd8374
4 changed files with 48 additions and 41 deletions

View File

@ -60,9 +60,9 @@ type PortMapConf struct {
// These are fields parsed out of the config or the environment;
// included here for convenience
ContainerID string `json:"-"`
ContIPv4 net.IP `json:"-"`
ContIPv6 net.IP `json:"-"`
ContainerID string `json:"-"`
ContIPv4 net.IPNet `json:"-"`
ContIPv6 net.IPNet `json:"-"`
}
// The default mark bit to signal that masquerading is required
@ -85,13 +85,13 @@ func cmdAdd(args *skel.CmdArgs) error {
netConf.ContainerID = args.ContainerID
if netConf.ContIPv4 != nil {
if netConf.ContIPv4.IP != nil {
if err := forwardPorts(netConf, netConf.ContIPv4); err != nil {
return err
}
}
if netConf.ContIPv6 != nil {
if netConf.ContIPv6.IP != nil {
if err := forwardPorts(netConf, netConf.ContIPv6); err != nil {
return err
}
@ -138,13 +138,13 @@ func cmdCheck(args *skel.CmdArgs) error {
conf.ContainerID = args.ContainerID
if conf.ContIPv4 != nil {
if conf.ContIPv4.IP != nil {
if err := checkPorts(conf, conf.ContIPv4); err != nil {
return err
}
}
if conf.ContIPv6 != nil {
if conf.ContIPv6.IP != nil {
if err := checkPorts(conf, conf.ContIPv6); err != nil {
return err
}
@ -205,9 +205,9 @@ func parseConfig(stdin []byte, ifName string) (*PortMapConf, *current.Result, er
if conf.PrevResult != nil {
for _, ip := range result.IPs {
if ip.Version == "6" && conf.ContIPv6 != nil {
if ip.Version == "6" && conf.ContIPv6.IP != nil {
continue
} else if ip.Version == "4" && conf.ContIPv4 != nil {
} else if ip.Version == "4" && conf.ContIPv4.IP != nil {
continue
}
@ -223,9 +223,9 @@ func parseConfig(stdin []byte, ifName string) (*PortMapConf, *current.Result, er
}
switch ip.Version {
case "6":
conf.ContIPv6 = ip.Address.IP
conf.ContIPv6 = ip.Address
case "4":
conf.ContIPv4 = ip.Address.IP
conf.ContIPv4 = ip.Address
}
}
}