Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 55 additions & 6 deletions hack/test-port-forwarding.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand All @@ -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)
Expand Down Expand Up @@ -382,6 +412,7 @@ sub JoinHostPort {
# forward: ::1 4025 → ipv4 4025

- guestIP: "0.0.0.0"
guestIPMustBeZero: false
guestPortRange: [4030, 4039]
hostIP: "ipv4"

Expand All @@ -396,6 +427,7 @@ sub JoinHostPort {
guestPortRange: [4040, 4049]

- guestIP: "0.0.0.0"
guestIPMustBeZero: false
guestPortRange: [4040, 4049]
ignore: true

Expand All @@ -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
2 changes: 1 addition & 1 deletion pkg/hostagent/port.go
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion pkg/limatype/lima_yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down
5 changes: 4 additions & 1 deletion pkg/limayaml/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
43 changes: 23 additions & 20 deletions pkg/limayaml/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

// ------------------------------------------------------------------------------------
Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -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{
Expand Down
2 changes: 1 addition & 1 deletion pkg/limayaml/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions pkg/portfwd/forward.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
6 changes: 3 additions & 3 deletions templates/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading