Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/mobyPublic

Commit2faf258

Browse files
authored
Merge pull request#51616 from akerouanton/fix-51591
libnet/pms/nat: don't bind IPv6 ports if not supported by port driver
2 parents9a84135 +310aa92 commit2faf258

File tree

4 files changed

+81
-33
lines changed

4 files changed

+81
-33
lines changed

‎daemon/libnetwork/drivers/bridge/port_mapping_linux_test.go‎

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ func TestAddPortMappings(t *testing.T) {
220220
enableProxybool
221221
hairpinbool
222222
busyPortIPv4int
223-
rootlessbool
223+
newPDCfunc() nat.PortDriverClient
224224
hostAddrs []string
225225
noProxy6To4bool
226226

@@ -667,14 +667,29 @@ func TestAddPortMappings(t *testing.T) {
667667
{PortBinding: types.PortBinding{Proto:types.TCP,Port:80}},
668668
},
669669
enableProxy:true,
670-
rootless:true,
670+
newPDC:func() nat.PortDriverClient {returnnewMockPortDriverClient(true) },
671671
expPBs: []types.PortBinding{
672672
{Proto:types.TCP,IP:ctrIP4.IP,Port:22,HostIP:net.IPv4zero,HostPort:firstEphemPort},
673673
{Proto:types.TCP,IP:ctrIP6.IP,Port:22,HostIP:net.IPv6zero,HostPort:firstEphemPort},
674674
{Proto:types.TCP,IP:ctrIP4.IP,Port:80,HostIP:net.IPv4zero,HostPort:firstEphemPort+1},
675675
{Proto:types.TCP,IP:ctrIP6.IP,Port:80,HostIP:net.IPv6zero,HostPort:firstEphemPort+1},
676676
},
677677
},
678+
{
679+
name:"rootless, ipv6 not supported",
680+
epAddrV4:ctrIP4,
681+
epAddrV6:ctrIP6,
682+
cfg: []portmapperapi.PortBindingReq{
683+
{PortBinding: types.PortBinding{Proto:types.TCP,Port:22}},
684+
{PortBinding: types.PortBinding{Proto:types.TCP,Port:80}},
685+
},
686+
enableProxy:true,
687+
newPDC:func() nat.PortDriverClient {returnnewMockPortDriverClient(false) },
688+
expPBs: []types.PortBinding{
689+
{Proto:types.TCP,IP:ctrIP4.IP,Port:22,HostIP:net.IPv4zero,HostPort:firstEphemPort},
690+
{Proto:types.TCP,IP:ctrIP4.IP,Port:80,HostIP:net.IPv4zero,HostPort:firstEphemPort+1},
691+
},
692+
},
678693
{
679694
name:"rootless without proxy",
680695
epAddrV4:ctrIP4,
@@ -683,8 +698,8 @@ func TestAddPortMappings(t *testing.T) {
683698
{PortBinding: types.PortBinding{Proto:types.TCP,Port:22}},
684699
{PortBinding: types.PortBinding{Proto:types.TCP,Port:80}},
685700
},
686-
rootless:true,
687-
hairpin:true,
701+
newPDC:func() nat.PortDriverClient {returnnewMockPortDriverClient(true) },
702+
hairpin:true,
688703
expPBs: []types.PortBinding{
689704
{Proto:types.TCP,IP:ctrIP4.IP,Port:22,HostIP:net.IPv4zero,HostPort:firstEphemPort},
690705
{Proto:types.TCP,IP:ctrIP6.IP,Port:22,HostIP:net.IPv6zero,HostPort:firstEphemPort},
@@ -745,8 +760,8 @@ func TestAddPortMappings(t *testing.T) {
745760
}
746761

747762
varpdc nat.PortDriverClient
748-
iftc.rootless {
749-
pdc=newMockPortDriverClient()
763+
iftc.newPDC!=nil {
764+
pdc=tc.newPDC()
750765
}
751766

752767
pms:=&drvregistry.PortMappers{}
@@ -780,7 +795,7 @@ func TestAddPortMappings(t *testing.T) {
780795
n.firewallerNetwork=fwn
781796

782797
expChildIP:=func(hostIP net.IP) net.IP {
783-
if!tc.rootless {
798+
ifpdc==nil {
784799
returnhostIP
785800
}
786801
ifhostIP.To4()==nil {
@@ -938,16 +953,21 @@ func (p mockPortDriverPort) String() string {
938953

939954
typemockPortDriverClientstruct {
940955
openPortsmap[mockPortDriverPort]bool
956+
supportV6bool
941957
}
942958

943-
funcnewMockPortDriverClient()*mockPortDriverClient {
959+
funcnewMockPortDriverClient(supportV6bool)*mockPortDriverClient {
944960
return&mockPortDriverClient{
945961
openPorts:map[mockPortDriverPort]bool{},
962+
supportV6:supportV6,
946963
}
947964
}
948965

949-
func (c*mockPortDriverClient)ChildHostIP(hostIP netip.Addr) netip.Addr {
966+
func (c*mockPortDriverClient)ChildHostIP(protostring,hostIP netip.Addr) netip.Addr {
950967
ifhostIP.Is6() {
968+
if!c.supportV6 {
969+
return netip.Addr{}
970+
}
951971
returnnetip.IPv6Loopback()
952972
}
953973
returnnetip.MustParseAddr("127.0.0.1")

‎daemon/libnetwork/internal/rlkclient/rootlesskit_client_linux.go‎

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,38 @@ func NewPortDriverClient(ctx context.Context) (*PortDriverClient, error) {
7575
returnpdc,nil
7676
}
7777

78+
// proto normalizes the protocol to match what the rootlesskit API expects.
79+
func (c*PortDriverClient)proto(protostring,hostIP netip.Addr)string {
80+
// proto is like "tcp", but we need to convert it to "tcp4" or "tcp6" explicitly
81+
// for libnetwork >= 20201216
82+
//
83+
// See https://github.com/moby/libnetwork/pull/2604/files#diff-8fa48beed55dd033bf8e4f8c40b31cf69d0b2cc5d4bb53cde8594670ea6c938aR20
84+
// See also https://github.com/rootless-containers/rootlesskit/issues/231
85+
apiProto:=proto
86+
if!strings.HasSuffix(apiProto,"4")&&!strings.HasSuffix(apiProto,"6") {
87+
ifhostIP.Is6() {
88+
apiProto+="6"
89+
}else {
90+
apiProto+="4"
91+
}
92+
}
93+
returnapiProto
94+
}
95+
7896
// ChildHostIP returns the address that must be used in the child network
7997
// namespace in place of hostIP, a host IP address. In particular, port
8098
// mappings from host IP addresses, and DNAT rules, must use this child
81-
// address in place of the real host address.
82-
func (c*PortDriverClient)ChildHostIP(hostIP netip.Addr) netip.Addr {
99+
// address in place of the real host address. It may return an invalid
100+
// netip.Addr if the proto and IP family aren't supported.
101+
func (c*PortDriverClient)ChildHostIP(protostring,hostIP netip.Addr) netip.Addr {
83102
ifc==nil {
84103
returnhostIP
85104
}
105+
if_,ok:=c.protos[c.proto(proto,hostIP)];!ok {
106+
// This happens when apiProto="tcp6", portDriverName="slirp4netns",
107+
// because "slirp4netns" port driver does not support listening on IPv6 yet.
108+
return netip.Addr{}
109+
}
86110
ifc.childIP.IsValid() {
87111
returnc.childIP
88112
}
@@ -117,20 +141,8 @@ func (c *PortDriverClient) AddPort(
117141
ifc==nil {
118142
returnfunc()error {returnnil },nil
119143
}
120-
// proto is like "tcp", but we need to convert it to "tcp4" or "tcp6" explicitly
121-
// for libnetwork >= 20201216
122-
//
123-
// See https://github.com/moby/libnetwork/pull/2604/files#diff-8fa48beed55dd033bf8e4f8c40b31cf69d0b2cc5d4bb53cde8594670ea6c938aR20
124-
// See also https://github.com/rootless-containers/rootlesskit/issues/231
125-
apiProto:=proto
126-
if!strings.HasSuffix(apiProto,"4")&&!strings.HasSuffix(apiProto,"6") {
127-
ifhostIP.Is6() {
128-
apiProto+="6"
129-
}else {
130-
apiProto+="4"
131-
}
132-
}
133144

145+
apiProto:=c.proto(proto,hostIP)
134146
if_,ok:=c.protos[apiProto];!ok {
135147
// This happens when apiProto="tcp6", portDriverName="slirp4netns",
136148
// because "slirp4netns" port driver does not support listening on IPv6 yet.

‎daemon/libnetwork/portmapper/proxy_linux.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ func StartProxy(pb types.PortBinding,
135135
returnnil
136136
}
137137
stopped.Store(true)
138+
log.G(context.Background()).WithField("pb",pb).Debug("Stopping userland proxy")
138139
iferr:=cmd.Process.Signal(os.Interrupt);err!=nil {
139140
returnerr
140141
}

‎daemon/libnetwork/portmappers/nat/mapper_linux.go‎

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,21 @@ import (
66
"fmt"
77
"net"
88
"net/netip"
9+
"slices"
910
"strconv"
1011

1112
"github.com/containerd/log"
1213
"github.com/moby/moby/v2/daemon/libnetwork/internal/rlkclient"
1314
"github.com/moby/moby/v2/daemon/libnetwork/portallocator"
1415
"github.com/moby/moby/v2/daemon/libnetwork/portmapperapi"
1516
"github.com/moby/moby/v2/daemon/libnetwork/types"
17+
"github.com/moby/moby/v2/internal/sliceutil"
1618
)
1719

1820
constdriverName="nat"
1921

2022
typePortDriverClientinterface {
21-
ChildHostIP(hostIP netip.Addr) netip.Addr
23+
ChildHostIP(protostring,hostIP netip.Addr) netip.Addr
2224
AddPort(ctx context.Context,protostring,hostIP,childIP netip.Addr,hostPortint) (func()error,error)
2325
}
2426

@@ -73,12 +75,18 @@ func (pm PortMapper) MapPorts(ctx context.Context, cfg []portmapperapi.PortBindi
7375
}
7476
}()
7577

76-
addrs:=make([]net.IP,0,len(cfg))
77-
fori:=rangecfg {
78-
cfg[i]=setChildHostIP(pm.pdc,cfg[i])
79-
addrs=append(addrs,cfg[i].ChildHostIP)
78+
fori:=len(cfg)-1;i>=0;i-- {
79+
varsupportedbool
80+
ifcfg[i],supported=setChildHostIP(pm.pdc,cfg[i]);!supported {
81+
cfg=slices.Delete(cfg,i,i+1)
82+
continue
83+
}
8084
}
8185

86+
addrs:=sliceutil.Map(cfg,func(req portmapperapi.PortBindingReq) net.IP {
87+
returnreq.ChildHostIP
88+
})
89+
8290
pa:=portallocator.NewOSAllocator()
8391
allocatedPort,socks,err:=pa.RequestPortsInRange(addrs,proto,int(hostPort),int(hostPortEnd))
8492
iferr!=nil {
@@ -127,14 +135,21 @@ func (pm PortMapper) UnmapPorts(ctx context.Context, pbs []portmapperapi.PortBin
127135
returnerrors.Join(errs...)
128136
}
129137

130-
funcsetChildHostIP(pdcPortDriverClient,req portmapperapi.PortBindingReq) portmapperapi.PortBindingReq {
138+
// setChildHostIP returns a modified PortBindingReq that contains the IP
139+
// address that should be used for port allocation, firewall rules, etc. It
140+
// returns false when the PortBindingReq isn't supported by the PortDriverClient.
141+
funcsetChildHostIP(pdcPortDriverClient,req portmapperapi.PortBindingReq) (portmapperapi.PortBindingReq,bool) {
131142
ifpdc==nil {
132143
req.ChildHostIP=req.HostIP
133-
returnreq
144+
returnreq,true
134145
}
135146
hip,_:=netip.AddrFromSlice(req.HostIP)
136-
req.ChildHostIP=pdc.ChildHostIP(hip.Unmap()).AsSlice()
137-
returnreq
147+
chip:=pdc.ChildHostIP(req.Proto.String(),hip.Unmap())
148+
if!chip.IsValid() {
149+
returnreq,false
150+
}
151+
req.ChildHostIP=chip.AsSlice()
152+
returnreq,true
138153
}
139154

140155
// configPortDriver passes the port binding's details to rootlesskit, and updates the

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp