Update runc for devices changes

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2016-02-05 15:15:25 -08:00
parent c2c0458598
commit 3baae2d525
6 changed files with 285 additions and 493 deletions

299
README.md
View File

@ -78,303 +78,10 @@ PID USER COMMAND
### OCI Container JSON Format:
OCI container JSON format is based on OCI [specs](https://github.com/opencontainers/specs).
You can generate JSON files by using `runc spec`, it'll generate `config.json`
and `runtime.json`. It assumes that the file-system is found in a directory called
You can generate JSON files by using `runc spec`.
It assumes that the file-system is found in a directory called
`rootfs` and there is a user with uid and gid of `0` defined within that file-system.
Below are sample `config.json` and `runtime.json` configuration files. Note that it
could be outdated, please always create base JSON files by `runc spec`.
`config.json`:
```json
{
"version": "0.2.0",
"platform": {
"os": "linux",
"arch": "amd64"
},
"process": {
"terminal": true,
"user": {
"uid": 0,
"gid": 0,
"additionalGids": null
},
"args": [
"sh"
],
"env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"TERM=xterm"
],
"cwd": ""
},
"root": {
"path": "rootfs",
"readonly": true
},
"hostname": "shell",
"mounts": [
{
"name": "proc",
"path": "/proc"
},
{
"name": "dev",
"path": "/dev"
},
{
"name": "devpts",
"path": "/dev/pts"
},
{
"name": "shm",
"path": "/dev/shm"
},
{
"name": "mqueue",
"path": "/dev/mqueue"
},
{
"name": "sysfs",
"path": "/sys"
},
{
"name": "cgroup",
"path": "/sys/fs/cgroup"
}
],
"linux": {
"capabilities": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
]
}
}
```
`runtime.json`:
```json
{
"mounts": {
"cgroup": {
"type": "cgroup",
"source": "cgroup",
"options": [
"nosuid",
"noexec",
"nodev",
"relatime",
"ro"
]
},
"dev": {
"type": "tmpfs",
"source": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
},
"devpts": {
"type": "devpts",
"source": "devpts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620",
"gid=5"
]
},
"mqueue": {
"type": "mqueue",
"source": "mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
"proc": {
"type": "proc",
"source": "proc",
"options": null
},
"shm": {
"type": "tmpfs",
"source": "shm",
"options": [
"nosuid",
"noexec",
"nodev",
"mode=1777",
"size=65536k"
]
},
"sysfs": {
"type": "sysfs",
"source": "sysfs",
"options": [
"nosuid",
"noexec",
"nodev"
]
}
},
"hooks": {
"prestart": null,
"poststart": null,
"poststop": null
},
"linux": {
"uidMappings": null,
"gidMappings": null,
"rlimits": [
{
"type": "RLIMIT_NOFILE",
"hard": 1024,
"soft": 1024
}
],
"sysctl": null,
"resources": {
"disableOOMKiller": false,
"memory": {
"limit": 0,
"reservation": 0,
"swap": 0,
"kernel": 0,
"swappiness": -1
},
"cpu": {
"shares": 0,
"quota": 0,
"period": 0,
"realtimeRuntime": 0,
"realtimePeriod": 0,
"cpus": "",
"mems": ""
},
"pids": {
"limit": 0
},
"blockIO": {
"blkioWeight": 0,
"blkioLeafWeight": 0,
"blkioWeightDevice": null,
"blkioThrottleReadBpsDevice": null,
"blkioThrottleWriteBpsDevice": null,
"blkioThrottleReadIOPSDevice": null,
"blkioThrottleWriteIOPSDevice": null
},
"hugepageLimits": null,
"network": {
"classId": "",
"priorities": null
}
},
"cgroupsPath": "",
"namespaces": [
{
"type": "pid",
"path": ""
},
{
"type": "network",
"path": ""
},
{
"type": "ipc",
"path": ""
},
{
"type": "uts",
"path": ""
},
{
"type": "mount",
"path": ""
}
],
"devices": [
{
"path": "/dev/null",
"type": 99,
"major": 1,
"minor": 3,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
},
{
"path": "/dev/random",
"type": 99,
"major": 1,
"minor": 8,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
},
{
"path": "/dev/full",
"type": 99,
"major": 1,
"minor": 7,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
},
{
"path": "/dev/tty",
"type": 99,
"major": 5,
"minor": 0,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
},
{
"path": "/dev/zero",
"type": 99,
"major": 1,
"minor": 5,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
},
{
"path": "/dev/urandom",
"type": 99,
"major": 1,
"minor": 9,
"permissions": "rwm",
"fileMode": 438,
"uid": 0,
"gid": 0
}
],
"apparmorProfile": "",
"selinuxProcessLabel": "",
"seccomp": {
"defaultAction": "SCMP_ACT_ALLOW",
"architectures": null,
"syscalls": []
},
"rootfsPropagation": ""
}
}
```
### Examples:
#### Using a Docker image (requires version 1.3 or later)
@ -388,7 +95,7 @@ To test using Docker's `busybox` image follow these steps:
mkdir rootfs
tar -C rootfs -xf busybox.tar
```
* Create `config.json` and `runtime.json` by using `runc spec`.
* Create `config.json` by using `runc spec`.
* Execute `runc start` and you should be placed into a shell where you can run `ps`:
```
$ runc start

View File

@ -25,6 +25,19 @@ func (s *DevicesGroup) Apply(d *cgroupData) error {
}
func (s *DevicesGroup) Set(path string, cgroup *configs.Cgroup) error {
devices := cgroup.Resources.Devices
if len(devices) > 0 {
for _, dev := range devices {
file := "devices.deny"
if dev.Allow {
file = "devices.allow"
}
if err := writeFile(path, file, dev.CgroupString()); err != nil {
return err
}
}
return nil
}
if !cgroup.Resources.AllowAllDevices {
if err := writeFile(path, "devices.deny", "a"); err != nil {
return err

View File

@ -28,11 +28,14 @@ type Cgroup struct {
type Resources struct {
// If this is true allow access to any kind of device within the container. If false, allow access only to devices explicitly listed in the allowed_devices list.
AllowAllDevices bool `json:"allow_all_devices"`
// Deprecated
AllowAllDevices bool `json:"allow_all_devices,omitempty"`
// Deprecated
AllowedDevices []*Device `json:"allowed_devices,omitempty"`
// Deprecated
DeniedDevices []*Device `json:"denied_devices,omitempty"`
AllowedDevices []*Device `json:"allowed_devices"`
DeniedDevices []*Device `json:"denied_devices"`
Devices []*Device `json:"devices"`
// Memory limit (in bytes)
Memory int64 `json:"memory"`

View File

@ -35,16 +35,13 @@ type Device struct {
// Gid of the device.
Gid uint32 `json:"gid"`
// Write the file to the allowed list
Allow bool `json:"allow"`
}
func (d *Device) CgroupString() string {
var p string
if d.Permissions == "" {
p = "rwm" // empty permissions is invalid... causes a write invalid argument error upon saving to cgroups
} else {
p = d.Permissions
}
return fmt.Sprintf("%c %s:%s %s", d.Type, deviceNumberString(d.Major), deviceNumberString(d.Minor), p)
return fmt.Sprintf("%c %s:%s %s", d.Type, deviceNumberString(d.Major), deviceNumberString(d.Minor), d.Permissions)
}
func (d *Device) Mkdev() int {

388
spec.go
View File

@ -107,7 +107,14 @@ var specCommand = cli.Command{
"CAP_KILL",
"CAP_NET_BIND_SERVICE",
},
Resources: &specs.Resources{
Devices: []specs.DeviceCgroup{
{
Allow: false,
Access: sPtr("rwm"),
},
},
},
Namespaces: []specs.Namespace{
{
Type: "pid",
@ -125,7 +132,6 @@ var specCommand = cli.Command{
Type: "mount",
},
},
Rlimits: []specs.Rlimit{
{
Type: "RLIMIT_NOFILE",
@ -133,90 +139,6 @@ var specCommand = cli.Command{
Soft: uint64(1024),
},
},
Resources: &specs.Resources{
Devices: []specs.DeviceCgroup{
{
Allow: false,
Access: sPtr("rwm"),
},
{
Allow: true,
Type: rPtr('c'),
Major: iPtr(8),
Minor: iPtr(229),
Access: sPtr("rw"),
},
{
Allow: true,
Type: rPtr('b'),
Major: iPtr(8),
Minor: iPtr(0),
Access: sPtr("r"),
},
},
Memory: &specs.Memory{},
},
Devices: []specs.Device{
{
Type: 'c',
Path: "/dev/null",
Major: 1,
Minor: 3,
FileMode: fmPtr(0666),
UID: u32Ptr(0),
GID: u32Ptr(0),
},
{
Type: 'c',
Path: "/dev/random",
Major: 1,
Minor: 8,
FileMode: fmPtr(0666),
UID: u32Ptr(0),
GID: u32Ptr(0),
},
{
Type: 'c',
Path: "/dev/full",
Major: 1,
Minor: 7,
FileMode: fmPtr(0666),
UID: u32Ptr(0),
GID: u32Ptr(0),
},
{
Type: 'c',
Path: "/dev/tty",
Major: 5,
Minor: 0,
FileMode: fmPtr(0666),
UID: u32Ptr(0),
GID: u32Ptr(0),
},
{
Type: 'c',
Path: "/dev/zero",
Major: 1,
Minor: 5,
FileMode: fmPtr(0666),
UID: u32Ptr(0),
GID: u32Ptr(0),
},
{
Type: 'c',
Path: "/dev/urandom",
Major: 1,
Minor: 9,
FileMode: fmPtr(0666),
UID: u32Ptr(0),
GID: u32Ptr(0),
},
},
Seccomp: specs.Seccomp{
DefaultAction: "SCMP_ACT_ALLOW",
Syscalls: []specs.Syscall{},
},
},
}
@ -355,7 +277,7 @@ func createLibcontainerConfig(cgroupName string, spec *specs.LinuxSpec) (*config
}
config.Rlimits = append(config.Rlimits, rl)
}
c, err := createCgroupConfig(cgroupName, spec, config.Devices)
c, err := createCgroupConfig(cgroupName, spec)
if err != nil {
return nil, err
}
@ -403,7 +325,7 @@ func createLibcontainerMount(cwd string, m specs.Mount) *configs.Mount {
}
}
func createCgroupConfig(name string, spec *specs.LinuxSpec, devices []*configs.Device) (*configs.Cgroup, error) {
func createCgroupConfig(name string, spec *specs.LinuxSpec) (*configs.Cgroup, error) {
myCgroupPath, err := cgroups.GetThisCgroupDir("devices")
if err != nil {
return nil, err
@ -413,125 +335,219 @@ func createCgroupConfig(name string, spec *specs.LinuxSpec, devices []*configs.D
Parent: myCgroupPath,
Resources: &configs.Resources{},
}
c.Resources.AllowedDevices = append(devices, allowedDevices...)
c.Resources.AllowedDevices = allowedDevices
r := spec.Linux.Resources
if r != nil {
if r.Memory != nil {
if r.Memory.Limit != nil {
c.Resources.Memory = int64(*r.Memory.Limit)
}
if r.Memory.Reservation != nil {
c.Resources.MemoryReservation = int64(*r.Memory.Reservation)
}
if r.Memory.Swap != nil {
c.Resources.MemorySwap = int64(*r.Memory.Swap)
}
if r.Memory.Kernel != nil {
c.Resources.KernelMemory = int64(*r.Memory.Kernel)
}
if r.Memory.Swappiness != nil {
c.Resources.MemorySwappiness = int64(*r.Memory.Swappiness)
if r == nil {
return c, nil
}
for i, d := range spec.Linux.Resources.Devices {
var (
t = 'a'
major = int64(-1)
minor = int64(-1)
)
if d.Type != nil {
t = *d.Type
}
if d.Major != nil {
major = *d.Major
}
if d.Minor != nil {
minor = *d.Minor
}
if d.Access == nil || *d.Access == "" {
return nil, fmt.Errorf("device access at %d field canot be empty", i)
}
dd := &configs.Device{
Type: t,
Major: major,
Minor: minor,
Permissions: *d.Access,
Allow: d.Allow,
}
c.Resources.Devices = append(c.Resources.Devices, dd)
}
// append the default allowed devices to the end of the list
c.Resources.Devices = append(c.Resources.Devices, allowedDevices...)
if r.Memory != nil {
if r.Memory.Limit != nil {
c.Resources.Memory = int64(*r.Memory.Limit)
}
if r.Memory.Reservation != nil {
c.Resources.MemoryReservation = int64(*r.Memory.Reservation)
}
if r.Memory.Swap != nil {
c.Resources.MemorySwap = int64(*r.Memory.Swap)
}
if r.Memory.Kernel != nil {
c.Resources.KernelMemory = int64(*r.Memory.Kernel)
}
if r.Memory.Swappiness != nil {
c.Resources.MemorySwappiness = int64(*r.Memory.Swappiness)
}
}
if r.CPU != nil {
if r.CPU.Shares != nil {
c.Resources.CpuShares = int64(*r.CPU.Shares)
}
if r.CPU.Quota != nil {
c.Resources.CpuQuota = int64(*r.CPU.Quota)
}
if r.CPU.Period != nil {
c.Resources.CpuPeriod = int64(*r.CPU.Period)
}
if r.CPU.RealtimeRuntime != nil {
c.Resources.CpuRtRuntime = int64(*r.CPU.RealtimeRuntime)
}
if r.CPU.RealtimePeriod != nil {
c.Resources.CpuRtPeriod = int64(*r.CPU.RealtimePeriod)
}
if r.CPU.Cpus != nil {
c.Resources.CpusetCpus = *r.CPU.Cpus
}
if r.CPU.Mems != nil {
c.Resources.CpusetMems = *r.CPU.Mems
}
}
if r.Pids != nil {
c.Resources.PidsLimit = *r.Pids.Limit
}
if r.BlockIO != nil {
if r.BlockIO.Weight != nil {
c.Resources.BlkioWeight = *r.BlockIO.Weight
}
if r.BlockIO.LeafWeight != nil {
c.Resources.BlkioLeafWeight = *r.BlockIO.LeafWeight
}
if r.BlockIO.WeightDevice != nil {
for _, wd := range r.BlockIO.WeightDevice {
weightDevice := configs.NewWeightDevice(wd.Major, wd.Minor, *wd.Weight, *wd.LeafWeight)
c.Resources.BlkioWeightDevice = append(c.Resources.BlkioWeightDevice, weightDevice)
}
}
if r.CPU != nil {
if r.CPU.Shares != nil {
c.Resources.CpuShares = int64(*r.CPU.Shares)
}
if r.CPU.Quota != nil {
c.Resources.CpuQuota = int64(*r.CPU.Quota)
}
if r.CPU.Period != nil {
c.Resources.CpuPeriod = int64(*r.CPU.Period)
}
if r.CPU.RealtimeRuntime != nil {
c.Resources.CpuRtRuntime = int64(*r.CPU.RealtimeRuntime)
}
if r.CPU.RealtimePeriod != nil {
c.Resources.CpuRtPeriod = int64(*r.CPU.RealtimePeriod)
}
if r.CPU.Cpus != nil {
c.Resources.CpusetCpus = *r.CPU.Cpus
}
if r.CPU.Mems != nil {
c.Resources.CpusetMems = *r.CPU.Mems
if r.BlockIO.ThrottleReadBpsDevice != nil {
for _, td := range r.BlockIO.ThrottleReadBpsDevice {
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
c.Resources.BlkioThrottleReadBpsDevice = append(c.Resources.BlkioThrottleReadBpsDevice, throttleDevice)
}
}
if r.Pids != nil {
c.Resources.PidsLimit = *r.Pids.Limit
}
if r.BlockIO != nil {
if r.BlockIO.Weight != nil {
c.Resources.BlkioWeight = *r.BlockIO.Weight
}
if r.BlockIO.LeafWeight != nil {
c.Resources.BlkioLeafWeight = *r.BlockIO.LeafWeight
}
if r.BlockIO.WeightDevice != nil {
for _, wd := range r.BlockIO.WeightDevice {
weightDevice := configs.NewWeightDevice(wd.Major, wd.Minor, *wd.Weight, *wd.LeafWeight)
c.Resources.BlkioWeightDevice = append(c.Resources.BlkioWeightDevice, weightDevice)
}
}
if r.BlockIO.ThrottleReadBpsDevice != nil {
for _, td := range r.BlockIO.ThrottleReadBpsDevice {
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
c.Resources.BlkioThrottleReadBpsDevice = append(c.Resources.BlkioThrottleReadBpsDevice, throttleDevice)
}
}
if r.BlockIO.ThrottleWriteBpsDevice != nil {
for _, td := range r.BlockIO.ThrottleWriteBpsDevice {
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
c.Resources.BlkioThrottleWriteBpsDevice = append(c.Resources.BlkioThrottleWriteBpsDevice, throttleDevice)
}
}
if r.BlockIO.ThrottleReadIOPSDevice != nil {
for _, td := range r.BlockIO.ThrottleReadIOPSDevice {
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
c.Resources.BlkioThrottleReadIOPSDevice = append(c.Resources.BlkioThrottleReadIOPSDevice, throttleDevice)
}
}
if r.BlockIO.ThrottleWriteIOPSDevice != nil {
for _, td := range r.BlockIO.ThrottleWriteIOPSDevice {
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
c.Resources.BlkioThrottleWriteIOPSDevice = append(c.Resources.BlkioThrottleWriteIOPSDevice, throttleDevice)
}
if r.BlockIO.ThrottleWriteBpsDevice != nil {
for _, td := range r.BlockIO.ThrottleWriteBpsDevice {
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
c.Resources.BlkioThrottleWriteBpsDevice = append(c.Resources.BlkioThrottleWriteBpsDevice, throttleDevice)
}
}
for _, l := range r.HugepageLimits {
c.Resources.HugetlbLimit = append(c.Resources.HugetlbLimit, &configs.HugepageLimit{
Pagesize: *l.Pagesize,
Limit: *l.Limit,
if r.BlockIO.ThrottleReadIOPSDevice != nil {
for _, td := range r.BlockIO.ThrottleReadIOPSDevice {
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
c.Resources.BlkioThrottleReadIOPSDevice = append(c.Resources.BlkioThrottleReadIOPSDevice, throttleDevice)
}
}
if r.BlockIO.ThrottleWriteIOPSDevice != nil {
for _, td := range r.BlockIO.ThrottleWriteIOPSDevice {
throttleDevice := configs.NewThrottleDevice(td.Major, td.Minor, *td.Rate)
c.Resources.BlkioThrottleWriteIOPSDevice = append(c.Resources.BlkioThrottleWriteIOPSDevice, throttleDevice)
}
}
}
for _, l := range r.HugepageLimits {
c.Resources.HugetlbLimit = append(c.Resources.HugetlbLimit, &configs.HugepageLimit{
Pagesize: *l.Pagesize,
Limit: *l.Limit,
})
}
if r.DisableOOMKiller != nil {
c.Resources.OomKillDisable = *r.DisableOOMKiller
}
if r.Network != nil {
if r.Network.ClassID != nil {
c.Resources.NetClsClassid = string(*r.Network.ClassID)
}
for _, m := range r.Network.Priorities {
c.Resources.NetPrioIfpriomap = append(c.Resources.NetPrioIfpriomap, &configs.IfPrioMap{
Interface: m.Name,
Priority: int64(m.Priority),
})
}
if r.DisableOOMKiller != nil {
c.Resources.OomKillDisable = *r.DisableOOMKiller
}
if r.Network != nil {
if r.Network.ClassID != nil {
c.Resources.NetClsClassid = string(*r.Network.ClassID)
}
for _, m := range r.Network.Priorities {
c.Resources.NetPrioIfpriomap = append(c.Resources.NetPrioIfpriomap, &configs.IfPrioMap{
Interface: m.Name,
Priority: int64(m.Priority),
})
}
}
}
return c, nil
}
func createDevices(spec *specs.LinuxSpec, config *configs.Config) error {
// add whitelisted devices
config.Devices = []*configs.Device{
{
Type: 'c',
Path: "/dev/null",
Major: 1,
Minor: 3,
FileMode: 0666,
Uid: 0,
Gid: 0,
},
{
Type: 'c',
Path: "/dev/random",
Major: 1,
Minor: 8,
FileMode: 0666,
Uid: 0,
Gid: 0,
},
{
Type: 'c',
Path: "/dev/full",
Major: 1,
Minor: 7,
FileMode: 0666,
Uid: 0,
Gid: 0,
},
{
Type: 'c',
Path: "/dev/tty",
Major: 5,
Minor: 0,
FileMode: 0666,
Uid: 0,
Gid: 0,
},
{
Type: 'c',
Path: "/dev/zero",
Major: 1,
Minor: 5,
FileMode: 0666,
Uid: 0,
Gid: 0,
},
{
Type: 'c',
Path: "/dev/urandom",
Major: 1,
Minor: 9,
FileMode: 0666,
Uid: 0,
Gid: 0,
},
}
// merge in additional devices from the spec
for _, d := range spec.Linux.Devices {
var uid, gid uint32
if d.UID != nil {
uid = *d.UID
}
if d.GID != nil {
gid = *d.GID
}
device := &configs.Device{
Type: d.Type,
Path: d.Path,
Major: d.Major,
Minor: d.Minor,
FileMode: *d.FileMode,
Uid: *d.UID,
Gid: *d.GID,
Uid: uid,
Gid: gid,
}
config.Devices = append(config.Devices, device)
}

View File

@ -24,12 +24,62 @@ var allowedDevices = []*configs.Device{
Major: wildcard,
Minor: wildcard,
Permissions: "m",
Allow: true,
},
{
Type: 'b',
Major: wildcard,
Minor: wildcard,
Permissions: "m",
Allow: true,
},
{
Type: 'c',
Path: "/dev/null",
Major: 1,
Minor: 3,
Permissions: "rwm",
Allow: true,
},
{
Type: 'c',
Path: "/dev/random",
Major: 1,
Minor: 8,
Permissions: "rwm",
Allow: true,
},
{
Type: 'c',
Path: "/dev/full",
Major: 1,
Minor: 7,
Permissions: "rwm",
Allow: true,
},
{
Type: 'c',
Path: "/dev/tty",
Major: 5,
Minor: 0,
Permissions: "rwm",
Allow: true,
},
{
Type: 'c',
Path: "/dev/zero",
Major: 1,
Minor: 5,
Permissions: "rwm",
Allow: true,
},
{
Type: 'c',
Path: "/dev/urandom",
Major: 1,
Minor: 9,
Permissions: "rwm",
Allow: true,
},
{
Path: "/dev/console",
@ -37,6 +87,7 @@ var allowedDevices = []*configs.Device{
Major: 5,
Minor: 1,
Permissions: "rwm",
Allow: true,
},
{
Path: "/dev/tty0",
@ -44,6 +95,7 @@ var allowedDevices = []*configs.Device{
Major: 4,
Minor: 0,
Permissions: "rwm",
Allow: true,
},
{
Path: "/dev/tty1",
@ -51,6 +103,7 @@ var allowedDevices = []*configs.Device{
Major: 4,
Minor: 1,
Permissions: "rwm",
Allow: true,
},
// /dev/pts/ - pts namespaces are "coming soon"
{
@ -59,6 +112,7 @@ var allowedDevices = []*configs.Device{
Major: 136,
Minor: wildcard,
Permissions: "rwm",
Allow: true,
},
{
Path: "",
@ -66,6 +120,7 @@ var allowedDevices = []*configs.Device{
Major: 5,
Minor: 2,
Permissions: "rwm",
Allow: true,
},
// tuntap
{
@ -74,6 +129,7 @@ var allowedDevices = []*configs.Device{
Major: 10,
Minor: 200,
Permissions: "rwm",
Allow: true,
},
}