diff --git a/hack/test-port-forwarding.pl b/hack/test-port-forwarding.pl index 269b10a8e4c..4c586dbf442 100755 --- a/hack/test-port-forwarding.pl +++ b/hack/test-port-forwarding.pl @@ -303,16 +303,19 @@ sub JoinHostPort { ignore: true - guestIP: 0.0.0.0 + guestIPMustBeZero: false guestPortRange: [3010, 3019] hostPortRange: [2010, 2019] ignore: true - guestIP: 0.0.0.0 + guestIPMustBeZero: false guestPortRange: [3000, 3029] hostPortRange: [2000, 2029] # The following rule is completely shadowed by the previous one and has no effect - guestIP: 0.0.0.0 + guestIPMustBeZero: false guestPortRange: [3020, 3029] hostPortRange: [2020, 2029] ignore: true @@ -323,7 +326,7 @@ sub JoinHostPort { # Blocking 127.0.0.2 cannot block forwarding from 0.0.0.0 # forward: 0.0.0.0 3002 → 127.0.0.1 2002 - # Blocking 0.0.0.0 will block forwarding from any interface + # Blocking 0.0.0.0 will block forwarding from any interface because guestIPMustBeZero is false # ignore: 0.0.0.0 3010 # ignore: 127.0.0.1 3011 @@ -344,14 +347,41 @@ sub JoinHostPort { # forward: :: 3032 → ipv4 2032 # forward: ::1 3033 → ipv4 2033 -- guestPortRange: [300, 309] +- guestPortRange: [300, 304] - # forward: 127.0.0.1 300 → 127.0.0.1 300 + # forward: 127.0.0.1 300 → 127.0.0.1 300 + # forward: 0.0.0.0 301 → 127.0.0.1 301 + # forward: :: 302 → 127.0.0.1 302 + # forward: ::1 303 → 127.0.0.1 303 + # ignore: 192.168.5.15 304 → 127.0.0.1 304 -- guestPortRange: [310, 319] +- guestPortRange: [305, 309] + guestIPMustBeZero: false + + # forward: 127.0.0.1 325 → 127.0.0.1 325 + # forward: 0.0.0.0 326 → 127.0.0.1 326 + # forward: :: 327 → 127.0.0.1 327 + # forward: ::1 328 → 127.0.0.1 328 + # ignore: 192.168.5.15 329 → 127.0.0.1 329 + +- guestPortRange: [310, 314] + hostIP: 0.0.0.0 + + # forward: 127.0.0.1 310 → 0.0.0.0 310 + # forward: 0.0.0.0 311 → 0.0.0.0 311 + # forward: :: 312 → 0.0.0.0 312 + # forward: ::1 313 → 0.0.0.0 313 + # ignore: 192.168.5.15 314 → 0.0.0.0 314 + +- guestPortRange: [315, 319] + guestIPMustBeZero: false hostIP: 0.0.0.0 - # forward: 127.0.0.1 310 → 0.0.0.0 310 + # forward: 127.0.0.1 315 → 0.0.0.0 315 + # forward: 0.0.0.0 316 → 0.0.0.0 316 + # forward: :: 317 → 0.0.0.0 317 + # forward: ::1 318 → 0.0.0.0 318 + # ignore: 192.168.5.15 319 → 0.0.0.0 319 # Things we can't test: # - Accessing a forward from a different interface (e.g. connect to ipv4 to connect to 0.0.0.0) @@ -382,6 +412,7 @@ sub JoinHostPort { # forward: ::1 4025 → ipv4 4025 - guestIP: "0.0.0.0" + guestIPMustBeZero: false guestPortRange: [4030, 4039] hostIP: "ipv4" @@ -396,6 +427,7 @@ sub JoinHostPort { guestPortRange: [4040, 4049] - guestIP: "0.0.0.0" + guestIPMustBeZero: false guestPortRange: [4040, 4049] ignore: true @@ -414,4 +446,21 @@ sub JoinHostPort { - guestPort: 5000 hostSocket: port5000.sock - # forward: 127.0.0.1 5000 → sockDir/port5000.sock + # forward: 127.0.0.1 5000 → sockDir/port5000.sock + +- guestPort: 5001 + hostSocket: port5001.sock + + # ignore: 192.168.5.15 5001 → sockDir/port5001.sock + +- guestPort: 5002 + guestIPMustBeZero: false + hostSocket: port5002.sock + + # forward: 127.0.0.1 5002 → sockDir/port5002.sock + +- guestPort: 5003 + guestIPMustBeZero: false + hostSocket: port5003.sock + + # ignore: 192.168.5.15 5003 → sockDir/port5003.sock diff --git a/pkg/hostagent/port.go b/pkg/hostagent/port.go index cf792386f87..1186a397e42 100644 --- a/pkg/hostagent/port.go +++ b/pkg/hostagent/port.go @@ -69,7 +69,7 @@ func (pf *portForwarder) forwardingAddresses(guest *api.IPPort) (hostAddr, guest case guestIP.IsUnspecified(): case guestIP.Equal(rule.GuestIP): case guestIP.Equal(net.IPv6loopback) && rule.GuestIP.Equal(IPv4loopback1): - case rule.GuestIP.IsUnspecified() && !rule.GuestIPMustBeZero: + case rule.GuestIP.IsUnspecified() && !*rule.GuestIPMustBeZero: // When GuestIPMustBeZero is true, then 0.0.0.0 must be an exact match, which is already // handled above by the guest.IP.IsUnspecified() condition. default: diff --git a/pkg/limatype/lima_yaml.go b/pkg/limatype/lima_yaml.go index 0933e45e68e..360260caeb6 100644 --- a/pkg/limatype/lima_yaml.go +++ b/pkg/limatype/lima_yaml.go @@ -285,7 +285,7 @@ const ( ) type PortForward struct { - GuestIPMustBeZero bool `yaml:"guestIPMustBeZero,omitempty" json:"guestIPMustBeZero,omitempty"` + GuestIPMustBeZero *bool `yaml:"guestIPMustBeZero,omitempty" json:"guestIPMustBeZero,omitempty"` GuestIP net.IP `yaml:"guestIP,omitempty" json:"guestIP,omitempty"` GuestPort int `yaml:"guestPort,omitempty" json:"guestPort,omitempty"` GuestPortRange [2]int `yaml:"guestPortRange,omitempty" json:"guestPortRange,omitempty"` diff --git a/pkg/limayaml/defaults.go b/pkg/limayaml/defaults.go index 1f617dbd490..fc138addaf2 100644 --- a/pkg/limayaml/defaults.go +++ b/pkg/limayaml/defaults.go @@ -882,12 +882,15 @@ func FillPortForwardDefaults(rule *limatype.PortForward, instDir string, user li rule.Proto = limatype.ProtoAny } if rule.GuestIP == nil { - if rule.GuestIPMustBeZero { + if rule.GuestIPMustBeZero != nil && *rule.GuestIPMustBeZero { rule.GuestIP = net.IPv4zero } else { rule.GuestIP = IPv4loopback1 } } + if rule.GuestIPMustBeZero == nil { + rule.GuestIPMustBeZero = ptr.Of(rule.GuestIP.Equal(net.IPv4zero)) + } if rule.HostIP == nil { rule.HostIP = IPv4loopback1 } diff --git a/pkg/limayaml/defaults_test.go b/pkg/limayaml/defaults_test.go index 55227992d71..b52d407fbb2 100644 --- a/pkg/limayaml/defaults_test.go +++ b/pkg/limayaml/defaults_test.go @@ -124,12 +124,13 @@ func TestFillDefault(t *testing.T) { } defaultPortForward := limatype.PortForward{ - GuestIP: IPv4loopback1, - GuestPortRange: [2]int{1, 65535}, - HostIP: IPv4loopback1, - HostPortRange: [2]int{1, 65535}, - Proto: limatype.ProtoAny, - Reverse: false, + GuestIP: IPv4loopback1, + GuestIPMustBeZero: ptr.Of(false), + GuestPortRange: [2]int{1, 65535}, + HostIP: IPv4loopback1, + HostPortRange: [2]int{1, 65535}, + Proto: limatype.ProtoAny, + Reverse: false, } // ------------------------------------------------------------------------------------ @@ -386,13 +387,14 @@ func TestFillDefault(t *testing.T) { net.ParseIP("1.1.1.1"), }, PortForwards: []limatype.PortForward{{ - GuestIP: IPv4loopback1, - GuestPort: 80, - GuestPortRange: [2]int{80, 80}, - HostIP: IPv4loopback1, - HostPort: 80, - HostPortRange: [2]int{80, 80}, - Proto: limatype.ProtoTCP, + GuestIP: IPv4loopback1, + GuestIPMustBeZero: ptr.Of(false), + GuestPort: 80, + GuestPortRange: [2]int{80, 80}, + HostIP: IPv4loopback1, + HostPort: 80, + HostPortRange: [2]int{80, 80}, + Proto: limatype.ProtoTCP, }}, CopyToHost: []limatype.CopyToHost{{}}, Env: map[string]string{ @@ -599,13 +601,14 @@ func TestFillDefault(t *testing.T) { net.ParseIP("2.2.2.2"), }, PortForwards: []limatype.PortForward{{ - GuestIP: IPv4loopback1, - GuestPort: 88, - GuestPortRange: [2]int{88, 88}, - HostIP: IPv4loopback1, - HostPort: 8080, - HostPortRange: [2]int{8080, 8080}, - Proto: limatype.ProtoTCP, + GuestIP: IPv4loopback1, + GuestIPMustBeZero: ptr.Of(false), + GuestPort: 88, + GuestPortRange: [2]int{88, 88}, + HostIP: IPv4loopback1, + HostPort: 8080, + HostPortRange: [2]int{8080, 8080}, + Proto: limatype.ProtoTCP, }}, CopyToHost: []limatype.CopyToHost{{}}, Env: map[string]string{ diff --git a/pkg/limayaml/validate.go b/pkg/limayaml/validate.go index e13844e7fff..f823803bc08 100644 --- a/pkg/limayaml/validate.go +++ b/pkg/limayaml/validate.go @@ -285,7 +285,7 @@ func Validate(y *limatype.LimaYAML, warn bool) error { } for i, rule := range y.PortForwards { field := fmt.Sprintf("portForwards[%d]", i) - if rule.GuestIPMustBeZero && !rule.GuestIP.Equal(net.IPv4zero) { + if *rule.GuestIPMustBeZero && !rule.GuestIP.Equal(net.IPv4zero) { errs = errors.Join(errs, fmt.Errorf("field `%s.guestIPMustBeZero` can only be true when field `%s.guestIP` is 0.0.0.0", field, field)) } if rule.GuestPort != 0 { diff --git a/pkg/portfwd/forward.go b/pkg/portfwd/forward.go index e442cc354a5..003fca40884 100644 --- a/pkg/portfwd/forward.go +++ b/pkg/portfwd/forward.go @@ -83,9 +83,9 @@ func (fw *Forwarder) forwardingAddresses(guest *api.IPPort) (hostAddr, guestAddr case guestIP.IsUnspecified(): case guestIP.Equal(rule.GuestIP): case guestIP.Equal(net.IPv6loopback) && rule.GuestIP.Equal(IPv4loopback1): - case rule.GuestIP.IsUnspecified() && !rule.GuestIPMustBeZero: + case rule.GuestIP.IsUnspecified() && !*rule.GuestIPMustBeZero: // When GuestIPMustBeZero is true, then 0.0.0.0 must be an exact match, which is already - // handled above by the guest.IP.IsUnspecified() condition. + // handled above by the guestIP.IsUnspecified() condition. default: continue } diff --git a/templates/default.yaml b/templates/default.yaml index 0e28c09db76..fcbf7cd4d71 100644 --- a/templates/default.yaml +++ b/templates/default.yaml @@ -491,9 +491,9 @@ networks: # ignore: true # don't forward these ports (guestPortRange, in this case 1-65535) # # - guestPort: 7443 -# guestIP: "0.0.0.0" # Will match *any* interface -# guestIPMustBeZero: true # Restrict matching to 0.0.0.0 binds only -# hostIP: "0.0.0.0" # Forwards to 0.0.0.0, exposing it externally +# guestIP: "0.0.0.0" # Will match *any* interface +# guestIPMustBeZero: false # 0.0.0.0 matches any bound interface, not just 0.0.0.0 itself +# hostIP: "0.0.0.0" # Forwards to 0.0.0.0, exposing it externally # # - guestSocket: "/run/user/{{.UID}}/my.sock" # hostSocket: mysocket