Skip to content

Commit 81d830b

Browse files
committed
go.mod: experimental integration of gomodjail (library sandbox)
https://github.com/AkihiroSuda/gomodjail gomodjail imposes syscall restrictions on a specific set of Go modules (excepts ones that use unsafe pointers, reflections, etc.), so as to mitigate their potential vulnerabilities and supply chain attack vectors. Usage: ``` gomodjail run --go-mod=./go.mod -- nerdctl run hello-world ``` or ``` gomodjail pack --go-mod=./go.mod /usr/local/bin/nerdctl ./nerdctl.gomodjail run hello-world ``` Hint: use `git diff --word-diff` for reviewing the changes in this commit Signed-off-by: Akihiro Suda <[email protected]>
1 parent fb3b8c1 commit 81d830b

File tree

14 files changed

+127
-46
lines changed

14 files changed

+127
-46
lines changed

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# artifacts
22
/nerdctl
33
_output
4+
*.gomodjail
45

56
# golangci-lint
67
/build

.github/workflows/workflow-test.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ jobs:
197197
test-integration-rootless:
198198
needs: build-dependencies
199199
timeout-minutes: 40
200-
name: "${{ matrix.target }} | ${{ matrix.containerd }} | ${{ matrix.rootlesskit }} | ${{ matrix.ubuntu }}"
200+
name: "${{ matrix.target }} | ${{ matrix.containerd }} | ${{ matrix.rootlesskit }} | ${{ matrix.ubuntu }} || ${{ matrix.nerdctl }}"
201201
runs-on: "${{ matrix.runner }}"
202202
strategy:
203203
fail-fast: false
@@ -209,30 +209,47 @@ jobs:
209209
target: rootless
210210
runner: "ubuntu-22.04"
211211
arch: amd64
212+
nerdctl: ""
213+
comment: ""
212214
- ubuntu: 24.04
213215
containerd: v2.0.5
214216
rootlesskit: v2.3.4
215217
target: rootless
216218
arch: amd64
217219
runner: "ubuntu-24.04"
220+
nerdctl: ""
221+
comment: ""
218222
- ubuntu: 24.04
219223
containerd: v2.0.5
220224
rootlesskit: v2.3.4
221225
target: rootless
222226
arch: arm64
223227
runner: "ubuntu-24.04-arm"
228+
nerdctl: ""
229+
comment: ""
224230
- ubuntu: 24.04
225231
containerd: v2.0.5
226232
rootlesskit: v2.3.4
227233
target: rootless-port-slirp4netns
228234
arch: amd64
229235
runner: "ubuntu-24.04"
236+
nerdctl: ""
237+
comment: ""
238+
- ubuntu: 24.04
239+
containerd: v2.0.5
240+
rootlesskit: v2.3.4
241+
target: rootless
242+
arch: amd64
243+
runner: "ubuntu-24.04"
244+
nerdctl: "nerdctl.gomodjail"
245+
comment: "Flaky, not a blocker for merging PRs"
230246
env:
231247
CONTAINERD_VERSION: "${{ matrix.containerd }}"
232248
ARCH: "${{ matrix.arch }}"
233249
UBUNTU_VERSION: "${{ matrix.ubuntu }}"
234250
ROOTLESSKIT_VERSION: "${{ matrix.rootlesskit }}"
235251
TEST_TARGET: "test-integration-${{ matrix.target }}"
252+
NERDCTL: "${{ matrix.nerdctl }}"
236253
steps:
237254
- name: "Set up AppArmor"
238255
if: matrix.ubuntu == '24.04'
@@ -279,9 +296,10 @@ jobs:
279296
fi
280297
echo "WORKAROUND_ISSUE_622=${WORKAROUND_ISSUE_622}" >> "$GITHUB_ENV"
281298
- name: "Test (network driver=slirp4netns, port driver=builtin)"
282-
run: docker run -t --rm --privileged -e WORKAROUND_ISSUE_622=${WORKAROUND_ISSUE_622} ${TEST_TARGET} /test-integration-rootless.sh ./hack/test-integration.sh -test.only-flaky=false
299+
run: docker run -t --rm --privileged -e WORKAROUND_ISSUE_622=${WORKAROUND_ISSUE_622} -e NERDCTL=${NERDCTL} ${TEST_TARGET} /test-integration-rootless.sh ./hack/test-integration.sh -test.only-flaky=false
283300
- name: "Test (network driver=slirp4netns, port driver=builtin) (flaky)"
284-
run: docker run -t --rm --privileged -e WORKAROUND_ISSUE_622=${WORKAROUND_ISSUE_622} ${TEST_TARGET} /test-integration-rootless.sh ./hack/test-integration.sh -test.only-flaky=true
301+
if: matrix.nerdctl != 'nerdctl.gomodjail'
302+
run: docker run -t --rm --privileged -e WORKAROUND_ISSUE_622=${WORKAROUND_ISSUE_622} -e NERDCTL=${NERDCTL} ${TEST_TARGET} /test-integration-rootless.sh ./hack/test-integration.sh -test.only-flaky=true
285303

286304
test-integration-docker-compatibility:
287305
timeout-minutes: 40

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# artifacts
22
/nerdctl
33
_output
4+
*.gomodjail
45

56
# golangci-lint
67
/build

Dockerfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ ARG CONTAINERD_FUSE_OVERLAYFS_VERSION=v2.1.2@BINARY
3939
ARG TINI_VERSION=v0.19.0@BINARY
4040
# Extra deps: Debug
4141
ARG BUILDG_VERSION=v0.5.2@BINARY
42+
# Extra deps: gomodjail
43+
ARG GOMODJAIL_VERSION=v0.1.1@756b1b9636c6de78984cbad1a974d930e2f0e851
4244

4345
# Test deps
4446
# Currently, the Docker Official Images and the test deps are not pinned by the hash
@@ -231,6 +233,13 @@ RUN ROOTLESSKIT_VERSION=${ROOTLESSKIT_VERSION/@BINARY}; \
231233
tar xzf "${fname}" -C /out/bin && \
232234
rm -f "${fname}" /out/bin/rootlesskit-docker-proxy && \
233235
echo "- RootlessKit: ${ROOTLESSKIT_VERSION}" >> /out/share/doc/nerdctl-full/README.md
236+
ARG GOMODJAIL_VERSION
237+
RUN git clone https://github.com/AkihiroSuda/gomodjail.git /go/src/github.com/AkihiroSuda/gomodjail && \
238+
cd /go/src/github.com/AkihiroSuda/gomodjail && \
239+
git-checkout-tag-with-hash.sh "${GOMODJAIL_VERSION}" && \
240+
make STATIC=1 && \
241+
cp -a _output/bin/gomodjail /out/bin/ && \
242+
echo "- gomodjail: ${GOMODJAIL_VERSION}" >> /out/share/doc/nerdctl-full/README.md
234243

235244
RUN echo "" >> /out/share/doc/nerdctl-full/README.md && \
236245
echo "## License" >> /out/share/doc/nerdctl-full/README.md && \
@@ -245,6 +254,8 @@ COPY . /go/src/github.com/containerd/nerdctl
245254
RUN { echo "# nerdctl (full distribution)"; echo "- nerdctl: $(cd /go/src/github.com/containerd/nerdctl && git describe --tags)"; cat /out/share/doc/nerdctl-full/README.md; } > /out/share/doc/nerdctl-full/README.md.new; mv /out/share/doc/nerdctl-full/README.md.new /out/share/doc/nerdctl-full/README.md
246255
WORKDIR /go/src/github.com/containerd/nerdctl
247256
RUN BINDIR=/out/bin make binaries install
257+
RUN /out/bin/gomodjail pack --go-mod=/go/src/github.com/containerd/nerdctl/go.mod /out/bin/nerdctl && \
258+
cp -a nerdctl.gomodjail /out/bin/
248259
COPY README.md /out/share/doc/nerdctl/
249260
COPY docs /out/share/doc/nerdctl/docs
250261
RUN (cd /out && find ! -type d | sort | xargs sha256sum > /tmp/SHA256SUMS ) && \

Dockerfile.d/test-integration-rootless.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# limitations under the License.
1616

1717
set -eux -o pipefail
18+
: "${NERDCTL:=}"
1819
if [[ "$(id -u)" = "0" ]]; then
1920
# Ensure securityfs is mounted for apparmor to work
2021
if ! mountpoint -q /sys/kernel/security; then
@@ -32,7 +33,7 @@ if [[ "$(id -u)" = "0" ]]; then
3233

3334
# Switch to the rootless user via SSH
3435
systemctl start ssh
35-
exec ssh -o StrictHostKeyChecking=no rootless@localhost "$0" "$@"
36+
exec ssh -o StrictHostKeyChecking=no rootless@localhost NERDCTL="$NERDCTL" "$0" "$@"
3637
else
3738
containerd-rootless-setuptool.sh install
3839
if grep -q "options use-vc" /etc/resolv.conf; then
@@ -63,5 +64,5 @@ EOF
6364
# Once ssh-ed, we lost the Dockerfile working dir, so, get back in the nerdctl checkout
6465
cd /go/src/github.com/containerd/nerdctl
6566
# We also lose the PATH (and SendEnv=PATH would require sshd config changes)
66-
exec env PATH="/usr/local/go/bin:$PATH" "$@"
67+
exec env PATH="/usr/local/go/bin:$PATH" NERDCTL="$NERDCTL" "$@"
6768
fi

cmd/nerdctl/builder/builder_builder_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@ CMD ["echo", "nerdctl-test-builder-prune"]`, testutil.CommonImage)
133133
{
134134
Description: "Debug",
135135
// `nerdctl builder debug` is currently incompatible with `docker buildx debug`.
136-
Require: require.All(require.Not(nerdtest.Docker)),
136+
// FIXME: fails with gomodjail: "timed out to access cache storage. other debug session is running?"
137+
Require: require.All(require.Not(nerdtest.Docker), require.Not(nerdtest.Gomodjail)),
137138
NoParallel: true,
138139
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
139140
dockerfile := fmt.Sprintf(`FROM %s

cmd/nerdctl/container/container_restart_linux_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"gotest.tools/v3/assert"
2727

2828
"github.com/containerd/nerdctl/mod/tigron/expect"
29+
"github.com/containerd/nerdctl/mod/tigron/require"
2930
"github.com/containerd/nerdctl/mod/tigron/test"
3031

3132
"github.com/containerd/nerdctl/v2/pkg/testutil"
@@ -129,6 +130,8 @@ func TestRestartWithTime(t *testing.T) {
129130
func TestRestartWithSignal(t *testing.T) {
130131
testCase := nerdtest.Setup()
131132

133+
testCase.Require = require.Not(nerdtest.Gomodjail) // FIXME
134+
132135
testCase.Cleanup = func(data test.Data, helpers test.Helpers) {
133136
helpers.Anyhow("rm", "-f", data.Identifier())
134137
}

cmd/nerdctl/container/container_run_linux_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"gotest.tools/v3/assert"
3535

3636
"github.com/containerd/nerdctl/mod/tigron/expect"
37+
"github.com/containerd/nerdctl/mod/tigron/require"
3738
"github.com/containerd/nerdctl/mod/tigron/test"
3839

3940
"github.com/containerd/nerdctl/v2/cmd/nerdctl/helpers"
@@ -381,6 +382,7 @@ func TestRunTTY(t *testing.T) {
381382

382383
func TestRunSigProxy(t *testing.T) {
383384
testCase := nerdtest.Setup()
385+
testCase.Require = require.Not(nerdtest.Gomodjail) // FIXME
384386

385387
testCase.SubTests = []*test.Case{
386388
{

go.mod

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//gomodjail:confined
12
module github.com/containerd/nerdctl/v2
23

34
go 1.23.0
@@ -6,65 +7,65 @@ require (
67
github.com/Masterminds/semver/v3 v3.3.1
78
github.com/Microsoft/go-winio v0.6.2
89
github.com/Microsoft/hcsshim v0.12.9
9-
github.com/compose-spec/compose-go/v2 v2.6.1
10+
github.com/compose-spec/compose-go/v2 v2.6.1 //gomodjail:unconfined
1011
github.com/containerd/accelerated-container-image v1.3.0
11-
github.com/containerd/cgroups/v3 v3.0.5
12-
github.com/containerd/console v1.0.4
12+
github.com/containerd/cgroups/v3 v3.0.5 //gomodjail:unconfined
13+
github.com/containerd/console v1.0.4 //gomodjail:unconfined
1314
github.com/containerd/containerd/api v1.8.0
14-
github.com/containerd/containerd/v2 v2.0.5
15-
github.com/containerd/continuity v0.4.5
15+
github.com/containerd/containerd/v2 v2.0.5 //gomodjail:unconfined
16+
github.com/containerd/continuity v0.4.5 //gomodjail:unconfined
1617
github.com/containerd/errdefs v1.0.0
17-
github.com/containerd/fifo v1.1.0
18-
github.com/containerd/go-cni v1.1.12
19-
github.com/containerd/imgcrypt/v2 v2.0.1
18+
github.com/containerd/fifo v1.1.0 //gomodjail:unconfined
19+
github.com/containerd/go-cni v1.1.12 //gomodjail:unconfined
20+
github.com/containerd/imgcrypt/v2 v2.0.1 //gomodjail:unconfined
2021
github.com/containerd/log v0.1.0
2122
github.com/containerd/nerdctl/mod/tigron v0.0.0
22-
github.com/containerd/nydus-snapshotter v0.15.1
23-
github.com/containerd/platforms v1.0.0-rc.1
24-
github.com/containerd/stargz-snapshotter v0.16.3
25-
github.com/containerd/stargz-snapshotter/estargz v0.16.3
26-
github.com/containerd/stargz-snapshotter/ipfs v0.16.3
23+
github.com/containerd/nydus-snapshotter v0.15.1 //gomodjail:unconfined
24+
github.com/containerd/platforms v1.0.0-rc.1 //gomodjail:unconfined
25+
github.com/containerd/stargz-snapshotter v0.16.3 //gomodjail:unconfined
26+
github.com/containerd/stargz-snapshotter/estargz v0.16.3 //gomodjail:unconfined
27+
github.com/containerd/stargz-snapshotter/ipfs v0.16.3 //gomodjail:unconfined
2728
github.com/containerd/typeurl/v2 v2.2.3
28-
github.com/containernetworking/cni v1.3.0
29-
github.com/containernetworking/plugins v1.7.1
29+
github.com/containernetworking/cni v1.3.0 //gomodjail:unconfined
30+
github.com/containernetworking/plugins v1.7.1 //gomodjail:unconfined
3031
github.com/coreos/go-iptables v0.8.0
3132
github.com/coreos/go-systemd/v22 v22.5.0
32-
github.com/cyphar/filepath-securejoin v0.4.1
33+
github.com/cyphar/filepath-securejoin v0.4.1 //gomodjail:unconfined
3334
github.com/distribution/reference v0.6.0
34-
github.com/docker/cli v28.1.1+incompatible
35-
github.com/docker/docker v28.1.1+incompatible
35+
github.com/docker/cli v28.1.1+incompatible //gomodjail:unconfined
36+
github.com/docker/docker v28.1.1+incompatible //gomodjail:unconfined
3637
github.com/docker/go-connections v0.5.0
3738
github.com/docker/go-units v0.5.0
38-
github.com/fahedouch/go-logrotate v0.3.0
39-
github.com/fatih/color v1.18.0
39+
github.com/fahedouch/go-logrotate v0.3.0 //gomodjail:unconfined
40+
github.com/fatih/color v1.18.0 //gomodjail:unconfined
4041
github.com/fluent/fluent-logger-golang v1.9.0
4142
github.com/fsnotify/fsnotify v1.9.0
4243
github.com/go-viper/mapstructure/v2 v2.2.1
4344
github.com/ipfs/go-cid v0.5.0
4445
github.com/klauspost/compress v1.18.0
45-
github.com/mattn/go-isatty v0.0.20
46+
github.com/mattn/go-isatty v0.0.20 //gomodjail:unconfined
4647
github.com/moby/sys/mount v0.3.4
4748
github.com/moby/sys/signal v0.7.1
48-
github.com/moby/sys/userns v0.1.0
49-
github.com/moby/term v0.5.2
50-
github.com/muesli/cancelreader v0.2.2
49+
github.com/moby/sys/userns v0.1.0 //gomodjail:unconfined
50+
github.com/moby/term v0.5.2 //gomodjail:unconfined
51+
github.com/muesli/cancelreader v0.2.2 //gomodjail:unconfined
5152
github.com/opencontainers/go-digest v1.0.0
5253
github.com/opencontainers/image-spec v1.1.1
5354
github.com/opencontainers/runtime-spec v1.2.1
5455
github.com/pelletier/go-toml/v2 v2.2.4
55-
github.com/rootless-containers/bypass4netns v0.4.2
56-
github.com/rootless-containers/rootlesskit/v2 v2.3.4
57-
github.com/spf13/cobra v1.9.1
58-
github.com/spf13/pflag v1.0.6
59-
github.com/vishvananda/netlink v1.3.1-0.20250303224720-0e7078ed04c8
60-
github.com/vishvananda/netns v0.0.5
56+
github.com/rootless-containers/bypass4netns v0.4.2 //gomodjail:unconfined
57+
github.com/rootless-containers/rootlesskit/v2 v2.3.4 //gomodjail:unconfined
58+
github.com/spf13/cobra v1.9.1 //gomodjail:unconfined
59+
github.com/spf13/pflag v1.0.6 //gomodjail:unconfined
60+
github.com/vishvananda/netlink v1.3.1-0.20250303224720-0e7078ed04c8 //gomodjail:unconfined
61+
github.com/vishvananda/netns v0.0.5 //gomodjail:unconfined
6162
github.com/yuchanns/srslog v1.1.0
6263
go.uber.org/mock v0.5.2
6364
golang.org/x/crypto v0.37.0
6465
golang.org/x/net v0.39.0
65-
golang.org/x/sync v0.13.0
66-
golang.org/x/sys v0.32.0
67-
golang.org/x/term v0.31.0
66+
golang.org/x/sync v0.13.0 //gomodjail:unconfined
67+
golang.org/x/sys v0.32.0 //gomodjail:unconfined
68+
golang.org/x/term v0.31.0 //gomodjail:unconfined
6869
golang.org/x/text v0.24.0
6970
gopkg.in/yaml.v3 v3.0.1
7071
gotest.tools/v3 v3.5.2
@@ -105,6 +106,7 @@ require (
105106
github.com/moby/sys/mountinfo v0.7.2 // indirect
106107
github.com/moby/sys/sequential v0.6.0 // indirect
107108
github.com/moby/sys/symlink v0.3.0 // indirect
109+
//gomodjail:unconfined
108110
github.com/moby/sys/user v0.3.0 // indirect
109111
github.com/mr-tron/base58 v1.2.0 // indirect
110112
github.com/multiformats/go-base32 v0.1.0 // indirect
@@ -118,6 +120,7 @@ require (
118120
github.com/philhofer/fwd v1.1.3-0.20240612014219-fbbf4953d986 // indirect
119121
github.com/pkg/errors v0.9.1 // indirect
120122
github.com/sasha-s/go-deadlock v0.3.5 // indirect
123+
//gomodjail:unconfined
121124
github.com/sirupsen/logrus v1.9.3 // indirect
122125
github.com/smallstep/pkcs7 v0.1.1 // indirect
123126
github.com/spaolacci/murmur3 v1.1.0 // indirect
@@ -135,7 +138,9 @@ require (
135138
go.opentelemetry.io/otel/trace v1.31.0 // indirect
136139
golang.org/x/exp v0.0.0-20241108190413-2d47ceb2692f // indirect
137140
google.golang.org/genproto/googleapis/rpc v0.0.0-20250106144421-5f5ef82da422 // indirect
141+
//gomodjail:unconfined
138142
google.golang.org/grpc v1.69.4 // indirect
143+
//gomodjail:unconfined
139144
google.golang.org/protobuf v1.36.5 // indirect
140145
lukechampine.com/blake3 v1.3.0 // indirect
141146
)

mod/tigron/test/command.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ type GenericCommand struct {
110110
rawStdErr string
111111
}
112112

113+
func (gc *GenericCommand) Binary() string {
114+
return gc.cmd.Binary
115+
}
116+
113117
func (gc *GenericCommand) WithBinary(binary string) {
114118
gc.cmd.Binary = binary
115119
}

0 commit comments

Comments
 (0)