1 package specconv
2
3 import (
4 "os"
5 "path/filepath"
6 "strings"
7
8 "github.com/opencontainers/runc/libcontainer/cgroups"
9 "github.com/opencontainers/runtime-spec/specs-go"
10 )
11
12
13
14 func Example() *specs.Spec {
15 spec := &specs.Spec{
16 Version: specs.Version,
17 Root: &specs.Root{
18 Path: "rootfs",
19 Readonly: true,
20 },
21 Process: &specs.Process{
22 Terminal: true,
23 User: specs.User{},
24 Args: []string{
25 "sh",
26 },
27 Env: []string{
28 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
29 "TERM=xterm",
30 },
31 Cwd: "/",
32 NoNewPrivileges: true,
33 Capabilities: &specs.LinuxCapabilities{
34 Bounding: []string{
35 "CAP_AUDIT_WRITE",
36 "CAP_KILL",
37 "CAP_NET_BIND_SERVICE",
38 },
39 Permitted: []string{
40 "CAP_AUDIT_WRITE",
41 "CAP_KILL",
42 "CAP_NET_BIND_SERVICE",
43 },
44 Ambient: []string{
45 "CAP_AUDIT_WRITE",
46 "CAP_KILL",
47 "CAP_NET_BIND_SERVICE",
48 },
49 Effective: []string{
50 "CAP_AUDIT_WRITE",
51 "CAP_KILL",
52 "CAP_NET_BIND_SERVICE",
53 },
54 },
55 Rlimits: []specs.POSIXRlimit{
56 {
57 Type: "RLIMIT_NOFILE",
58 Hard: uint64(1024),
59 Soft: uint64(1024),
60 },
61 },
62 },
63 Hostname: "runc",
64 Mounts: []specs.Mount{
65 {
66 Destination: "/proc",
67 Type: "proc",
68 Source: "proc",
69 Options: nil,
70 },
71 {
72 Destination: "/dev",
73 Type: "tmpfs",
74 Source: "tmpfs",
75 Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"},
76 },
77 {
78 Destination: "/dev/pts",
79 Type: "devpts",
80 Source: "devpts",
81 Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"},
82 },
83 {
84 Destination: "/dev/shm",
85 Type: "tmpfs",
86 Source: "shm",
87 Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"},
88 },
89 {
90 Destination: "/dev/mqueue",
91 Type: "mqueue",
92 Source: "mqueue",
93 Options: []string{"nosuid", "noexec", "nodev"},
94 },
95 {
96 Destination: "/sys",
97 Type: "sysfs",
98 Source: "sysfs",
99 Options: []string{"nosuid", "noexec", "nodev", "ro"},
100 },
101 {
102 Destination: "/sys/fs/cgroup",
103 Type: "cgroup",
104 Source: "cgroup",
105 Options: []string{"nosuid", "noexec", "nodev", "relatime", "ro"},
106 },
107 },
108 Linux: &specs.Linux{
109 MaskedPaths: []string{
110 "/proc/acpi",
111 "/proc/asound",
112 "/proc/kcore",
113 "/proc/keys",
114 "/proc/latency_stats",
115 "/proc/timer_list",
116 "/proc/timer_stats",
117 "/proc/sched_debug",
118 "/sys/firmware",
119 "/proc/scsi",
120 },
121 ReadonlyPaths: []string{
122 "/proc/bus",
123 "/proc/fs",
124 "/proc/irq",
125 "/proc/sys",
126 "/proc/sysrq-trigger",
127 },
128 Resources: &specs.LinuxResources{
129 Devices: []specs.LinuxDeviceCgroup{
130 {
131 Allow: false,
132 Access: "rwm",
133 },
134 },
135 },
136 Namespaces: []specs.LinuxNamespace{
137 {
138 Type: specs.PIDNamespace,
139 },
140 {
141 Type: specs.NetworkNamespace,
142 },
143 {
144 Type: specs.IPCNamespace,
145 },
146 {
147 Type: specs.UTSNamespace,
148 },
149 {
150 Type: specs.MountNamespace,
151 },
152 },
153 },
154 }
155 if cgroups.IsCgroup2UnifiedMode() {
156 spec.Linux.Namespaces = append(spec.Linux.Namespaces, specs.LinuxNamespace{
157 Type: specs.CgroupNamespace,
158 })
159 }
160 return spec
161 }
162
163
164
165
166 func ToRootless(spec *specs.Spec) {
167 var namespaces []specs.LinuxNamespace
168
169
170 for _, ns := range spec.Linux.Namespaces {
171 switch ns.Type {
172 case specs.NetworkNamespace, specs.UserNamespace:
173
174 default:
175 namespaces = append(namespaces, ns)
176 }
177 }
178
179 namespaces = append(namespaces, specs.LinuxNamespace{
180 Type: specs.UserNamespace,
181 })
182 spec.Linux.Namespaces = namespaces
183
184
185 spec.Linux.UIDMappings = []specs.LinuxIDMapping{{
186 HostID: uint32(os.Geteuid()),
187 ContainerID: 0,
188 Size: 1,
189 }}
190 spec.Linux.GIDMappings = []specs.LinuxIDMapping{{
191 HostID: uint32(os.Getegid()),
192 ContainerID: 0,
193 Size: 1,
194 }}
195
196
197 var mounts []specs.Mount
198 for _, mount := range spec.Mounts {
199
200 if filepath.Clean(mount.Destination) == "/sys" {
201 mounts = append(mounts, specs.Mount{
202 Source: "/sys",
203 Destination: "/sys",
204 Type: "none",
205 Options: []string{"rbind", "nosuid", "noexec", "nodev", "ro"},
206 })
207 continue
208 }
209
210
211 var options []string
212 for _, option := range mount.Options {
213 if !strings.HasPrefix(option, "gid=") && !strings.HasPrefix(option, "uid=") {
214 options = append(options, option)
215 }
216 }
217
218 mount.Options = options
219 mounts = append(mounts, mount)
220 }
221 spec.Mounts = mounts
222
223
224 spec.Linux.Resources = nil
225 }
226
View as plain text