Skip to content

Commit 6a44a97

Browse files
authored
Merge pull request #667 from rancher-sandbox/iptables-fix
iptables rule without an ip range applies to all interfaces
2 parents 5162b86 + aa23c52 commit 6a44a97

File tree

6 files changed

+47
-10
lines changed

6 files changed

+47
-10
lines changed

.cirrus.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ task:
3030
- cat /proc/cpuinfo
3131
install_deps_script:
3232
- apt-get update
33-
- apt-get install -y --no-install-recommends ca-certificates curl git golang openssh-client make netcat ovmf sudo qemu-system-x86 qemu-utils
33+
- apt-get install -y --no-install-recommends ca-certificates curl git golang jq openssh-client make netcat ovmf sudo qemu-system-x86 qemu-utils
3434
go_cache:
3535
fingerprint_script: uname -s ; cat go.sum
3636
folder: $GOPATH/pkg/mod

.github/workflows/test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ jobs:
121121
# QEMU: required by Lima itself
122122
# bash: required by test-example.sh (OS version of bash is too old)
123123
# coreutils: required by test-example.sh for the "timeout" command
124+
# These would need to be added to run the alpine.yaml config on the macOS runner:
125+
# curl: required by test-example.sh to download nerdctl for alpine
126+
# jq: required by test-example.sh to determine download URL for nerdctl
124127
run: |
125128
set -x
126129
# Github runners seem to symlink to python2.7 version of 2to3,

hack/test-example.sh

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,14 @@ if [[ -n ${CHECKS["mount-home"]} ]]; then
168168
fi
169169
fi
170170

171+
# Use GHCR to avoid hitting Docker Hub rate limit
172+
nginx_image="ghcr.io/stargz-containers/nginx:1.19-alpine-org"
173+
alpine_image="ghcr.io/containerd/alpine:3.14.0"
174+
171175
if [[ -n ${CHECKS["containerd-user"]} ]]; then
172176
INFO "Run a nginx container with port forwarding 127.0.0.1:8080"
173177
set -x
174178
limactl shell "$NAME" nerdctl info
175-
# Use GHCR to avoid hitting Docker Hub rate limit
176-
nginx_image="ghcr.io/stargz-containers/nginx:1.19-alpine-org"
177179
limactl shell "$NAME" nerdctl pull --quiet ${nginx_image}
178180
limactl shell "$NAME" nerdctl run -d --name nginx -p 127.0.0.1:8080:80 ${nginx_image}
179181

@@ -189,7 +191,6 @@ if [[ -n ${CHECKS["containerd-user"]} ]]; then
189191
mkdir -p "$hometmp"
190192
defer "rm -rf \"$hometmp\""
191193
set -x
192-
alpine_image="ghcr.io/containerd/alpine:3.14.0"
193194
limactl shell "$NAME" nerdctl pull --quiet ${alpine_image}
194195
echo "random-content-${RANDOM}" >"$hometmp/random"
195196
expected="$(cat "$hometmp/random")"
@@ -219,6 +220,34 @@ if [[ -n ${CHECKS["port-forwards"]} ]]; then
219220
limactl shell "$NAME" sudo zypper in -y netcat-openbsd
220221
fi
221222
"${scriptdir}/test-port-forwarding.pl" "${NAME}"
223+
224+
if [[ -n ${CHECKS["containerd-user"]} || ${NAME} == "alpine" ]]; then
225+
INFO "Testing that 'nerdctl run' binds to 0.0.0.0 by default and is forwarded to the host"
226+
if [ "$(uname)" = "Darwin" ]; then
227+
# macOS runners seem to use `localhost` as the hostname, so the perl lookup just returns `127.0.0.1`
228+
hostip=$(system_profiler SPNetworkDataType -json | jq -r 'first(.SPNetworkDataType[] | select(.ip_address) | .ip_address) | first')
229+
else
230+
hostip=$(perl -MSocket -MSys::Hostname -E 'say inet_ntoa(scalar gethostbyname(hostname()))')
231+
fi
232+
if [ -n "${hostip}" ]; then
233+
sudo=""
234+
if [ "${NAME}" = "alpine" ]; then
235+
arch=$(limactl info | jq -r .defaultTemplate.arch)
236+
nerdctl=$(limactl info | jq -r ".defaultTemplate.containerd.archives[] | select(.arch==\"$arch\").location")
237+
curl -Lso nerdctl-full.tgz "${nerdctl}"
238+
limactl shell "$NAME" sudo apk add containerd
239+
limactl shell "$NAME" sudo rc-service containerd start
240+
limactl shell "$NAME" sudo tar xzf "${PWD}/nerdctl-full.tgz" -C /usr/local
241+
rm nerdctl-full.tgz
242+
sudo="sudo"
243+
fi
244+
limactl shell "$NAME" $sudo nerdctl info
245+
limactl shell "$NAME" $sudo nerdctl pull --quiet ${nginx_image}
246+
limactl shell "$NAME" $sudo nerdctl run -d --name nginx -p 8888:80 ${nginx_image}
247+
248+
timeout 3m bash -euxc "until curl -f --retry 30 --retry-connrefused http://${hostip}:8888; do sleep 3; done"
249+
fi
250+
fi
222251
set +x
223252
fi
224253

hack/test-port-forwarding.pl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,3 +310,10 @@ sub JoinHostPort {
310310
# forward: :: 4041 → 127.0.0.1 4041
311311
# ignore: 127.0.0.1 4043 → 127.0.0.1 4043
312312
# ignore: 192.168.5.15 4044 → 127.0.0.1 4044
313+
314+
# This rule exist to test `nerdctl run` binding to 0.0.0.0 by default,
315+
# and making sure it gets forwarded to the external host IP.
316+
# The actual test code is in test-example.sh in the "port-forwarding" block.
317+
- guestIPMustBeZero: true
318+
guestPort: 8888
319+
hostIP: 0.0.0.0

pkg/guestagent/iptables/iptables.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,10 @@ func parsePortsFromRules(rules []string) ([]Entry, error) {
7575
istcp = true
7676
}
7777

78-
// if the IP is blank the port forwarding the portforwarding,
79-
// which gets information from this, will skip it. When no IP
80-
// is present localhost will work.
78+
// When no IP is present the rule applies to all interfaces.
8179
ip := found[1]
8280
if ip == "" {
83-
ip = "127.0.0.1"
81+
ip = "0.0.0.0"
8482
}
8583
ent := Entry{
8684
IP: net.ParseIP(ip),

pkg/guestagent/iptables/iptables_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ func TestParsePortsFromRules(t *testing.T) {
8484
t.Fatalf("expected 2 ports parsed from iptables but parsed %d", l)
8585
}
8686

87-
if res[0].IP.String() != "127.0.0.1" || res[0].Port != 8082 || res[0].TCP != true {
88-
t.Errorf("expected port 8082 on IP 127.0.0.1 with TCP true but go port %d on IP %s with TCP %t", res[0].Port, res[0].IP.String(), res[0].TCP)
87+
if res[0].IP.String() != "0.0.0.0" || res[0].Port != 8082 || res[0].TCP != true {
88+
t.Errorf("expected port 8082 on IP 0.0.0.0 with TCP true but got port %d on IP %s with TCP %t", res[0].Port, res[0].IP.String(), res[0].TCP)
8989
}
9090
if res[1].IP.String() != "127.0.0.1" || res[1].Port != 8081 || res[1].TCP != true {
9191
t.Errorf("expected port 8081 on IP 127.0.0.1 with TCP true but go port %d on IP %s with TCP %t", res[1].Port, res[1].IP.String(), res[1].TCP)

0 commit comments

Comments
 (0)