mirror of
https://github.com/google/nsjail.git
synced 2026-08-30 18:41:30 -07:00
* Introduces a dedicated, async worker thread that monitors SECCOMP_RET_USER_NOTIF events * Produces telemetry using protobufs to track resolved namespace paths, and network endpoints
439 lines
17 KiB
Protocol Buffer
439 lines
17 KiB
Protocol Buffer
syntax = "proto2";
|
|
|
|
package nsjail;
|
|
|
|
enum Mode {
|
|
LISTEN = 0; /* Listening on a TCP port */
|
|
ONCE = 1; /* Running the command once only */
|
|
RERUN = 2; /* Re-executing the command (forever) */
|
|
EXECVE = 3; /* Executing command w/o the supervisor */
|
|
}
|
|
/* Should be self explanatory */
|
|
enum LogLevel {
|
|
DEBUG = 0; /* Equivalent to the '-v' cmd-line option */
|
|
INFO = 1; /* Default level */
|
|
WARNING = 2; /* Equivalent to the '-q' cmd-line option */
|
|
ERROR = 3;
|
|
FATAL = 4;
|
|
}
|
|
message IdMap {
|
|
/* Empty string means "current uid/gid" */
|
|
optional string inside_id = 1 [default = ""];
|
|
optional string outside_id = 2 [default = ""];
|
|
/* See 'man user_namespaces' for the meaning of count */
|
|
optional uint32 count = 3 [default = 1];
|
|
/* Does this map use /usr/bin/new[u|g]idmap binary? */
|
|
optional bool use_newidmap = 4 [default = false];
|
|
}
|
|
message MountPt {
|
|
/* Can be skipped for filesystems like 'proc' */
|
|
optional string src = 1 [default = ""];
|
|
/* Should 'src' path be prefixed with this envar? */
|
|
optional string prefix_src_env = 2 [default = ""];
|
|
/* If specified, contains buffer that will be written to the dst file */
|
|
optional bytes src_content = 3 [default = ""];
|
|
/* Mount point inside jail */
|
|
required string dst = 4 [default = ""];
|
|
/* Should 'dst' path be prefixed with this envar? */
|
|
optional string prefix_dst_env = 5 [default = ""];
|
|
/* Can be empty for mount --bind mounts */
|
|
optional string fstype = 6 [default = ""];
|
|
/* E.g. size=5000000 for 'tmpfs' */
|
|
optional string options = 7 [default = ""];
|
|
/* Is it a 'mount --bind src dst' type of mount? */
|
|
optional bool is_bind = 8 [default = false];
|
|
/* Is it a R/W mount? */
|
|
optional bool rw = 9 [default = false];
|
|
/* Is it a directory? If not specified an internal
|
|
heuristics will be used to determine that */
|
|
optional bool is_dir = 10;
|
|
/* Should the sandboxing fail if we cannot mount this resource? */
|
|
optional bool mandatory = 11 [default = true];
|
|
/* Is it a symlink (instead of real mount point)? */
|
|
optional bool is_symlink = 12 [default = false];
|
|
/* Is it a nosuid mount */
|
|
optional bool nosuid = 13 [default = false];
|
|
/* Is it a nodev mount */
|
|
optional bool nodev = 14 [default = false];
|
|
/* Is it a noexec mount */
|
|
optional bool noexec = 15 [default = false];
|
|
}
|
|
enum RLimit {
|
|
VALUE = 0; /* Use the provided value */
|
|
SOFT = 1; /* Use the current soft rlimit */
|
|
HARD = 2; /* Use the current hard rlimit */
|
|
INF = 3; /* Use RLIM64_INFINITY */
|
|
}
|
|
message Exe {
|
|
/* Will be used both as execv's path and as argv[0] */
|
|
required string path = 1;
|
|
/* This will be argv[1] and so on.. */
|
|
repeated string arg = 2;
|
|
/* Override argv[0] */
|
|
optional string arg0 = 3;
|
|
/* Should execveat() be used to execute a file-descriptor instead? */
|
|
optional bool exec_fd = 4 [default = false];
|
|
}
|
|
message NsJailConfig {
|
|
/* Optional name and description for this config */
|
|
optional string name = 1 [default = ""];
|
|
repeated string description = 2;
|
|
|
|
/* Execution mode: see 'msg Mode' description for more */
|
|
optional Mode mode = 3 [default = ONCE];
|
|
/* Hostname inside jail */
|
|
optional string hostname = 4 [default = "NSJAIL"];
|
|
/* Initial current working directory for the binary */
|
|
optional string cwd = 5 [default = "/"];
|
|
|
|
/* Defines whether to use switch_root or pivot_root */
|
|
optional bool no_pivotroot = 6 [default = false];
|
|
|
|
/* TCP port to listen to. Valid with mode=LISTEN only */
|
|
optional uint32 port = 7 [default = 0];
|
|
/* Host to bind to for mode=LISTEN. Must be in IPv6 format */
|
|
optional string bindhost = 8 [default = "::"];
|
|
/* For mode=LISTEN, maximum number of connections across all IPs */
|
|
optional uint32 max_conns = 9 [default = 0];
|
|
/* For mode=LISTEN, maximum number of connections from a single IP */
|
|
optional uint32 max_conns_per_ip = 10 [default = 0];
|
|
|
|
/* Wall-time time limit for commands */
|
|
optional uint32 time_limit = 11 [default = 600];
|
|
/* Should nsjail go into background? */
|
|
optional bool daemon = 12 [default = false];
|
|
/* Maximum number of CPUs to use: 0 - no limit */
|
|
optional uint32 max_cpus = 13 [default = 0];
|
|
/* Niceness level of the jailed process */
|
|
optional int32 nice_level = 14 [default = 19];
|
|
|
|
/* FD to log to. */
|
|
optional int32 log_fd = 15;
|
|
/* File to save logs to. */
|
|
optional string log_file = 16;
|
|
/* Minimum log level displayed.
|
|
See 'msg LogLevel' description for more */
|
|
optional LogLevel log_level = 17;
|
|
|
|
/* Should the current environment variables be kept
|
|
when executing the binary */
|
|
optional bool keep_env = 18 [default = false];
|
|
/* EnvVars to be set before executing binaries. If the envar doesn't contain '='
|
|
(e.g. just the 'DISPLAY' string), the current envar value will be used */
|
|
repeated string envar = 19;
|
|
|
|
/* Should capabilities be preserved or dropped */
|
|
optional bool keep_caps = 20 [default = false];
|
|
/* Which capabilities should be preserved if keep_caps == false.
|
|
Format: "CAP_SYS_PTRACE" */
|
|
repeated string cap = 21;
|
|
/* Should nsjail close FD=0,1,2 before executing the process */
|
|
optional bool silent = 22 [default = false];
|
|
/* Should the child process have control over terminal?
|
|
Can be useful to allow /bin/sh to provide
|
|
job control / signals. Dangerous, can be used to put
|
|
characters into the controlling terminal back */
|
|
optional bool skip_setsid = 23 [default = false];
|
|
/* Redirect sdterr of the process to /dev/null instead of the socket or original TTY */
|
|
optional bool stderr_to_null = 24 [default = false];
|
|
/* Which FDs should be passed to the newly executed process
|
|
By default only FD=0,1,2 are passed */
|
|
repeated int32 pass_fd = 25;
|
|
/* Setting it to true will allow to have set-uid binaries
|
|
inside the jail */
|
|
optional bool disable_no_new_privs = 26 [default = false];
|
|
/* Set this to true to forward fatal signals to the child process instead
|
|
* of always using SIGKILL. */
|
|
optional bool forward_signals = 27 [default = false];
|
|
/* Disable rdtsc and rdtscp instructions. WARNING: To make it effective, you also need to
|
|
* forbid `prctl(PR_SET_TSC, PR_TSC_ENABLE, ...)` in seccomp rules! (x86 and x86_64 only).
|
|
* Dynamic binaries produced by GCC seem to rely on RDTSC, but static ones should work. */
|
|
optional bool disable_tsc = 28 [default = false];
|
|
/* OOM score adjustment for the sandbox (-1000 to 1000) */
|
|
optional int32 oom_score_adj = 29;
|
|
|
|
/* Various rlimits, the rlimit_as/rlimit_core/... are used only if
|
|
rlimit_as_type/rlimit_core_type/... are set to RLimit::VALUE */
|
|
optional uint64 rlimit_as = 30 [default = 4096]; /* In MiB */
|
|
optional RLimit rlimit_as_type = 31 [default = VALUE];
|
|
optional uint64 rlimit_core = 32 [default = 0]; /* In MiB */
|
|
optional RLimit rlimit_core_type = 33 [default = VALUE];
|
|
optional uint64 rlimit_cpu = 34 [default = 600]; /* In seconds */
|
|
optional RLimit rlimit_cpu_type = 35 [default = VALUE];
|
|
optional uint64 rlimit_fsize = 36 [default = 1]; /* In MiB */
|
|
optional RLimit rlimit_fsize_type = 37 [default = VALUE];
|
|
optional uint64 rlimit_nofile = 38 [default = 32];
|
|
optional RLimit rlimit_nofile_type = 39 [default = VALUE];
|
|
/* RLIMIT_NPROC is system-wide - tricky to use; use the soft limit value by
|
|
* default here */
|
|
optional uint64 rlimit_nproc = 40 [default = 1024];
|
|
optional RLimit rlimit_nproc_type = 41 [default = SOFT];
|
|
/* In MiB, use the soft limit value by default */
|
|
optional uint64 rlimit_stack = 42 [default = 8];
|
|
optional RLimit rlimit_stack_type = 43 [default = SOFT];
|
|
/* In KB, use the soft limit value by default */
|
|
optional uint64 rlimit_memlock = 44 [default = 64];
|
|
optional RLimit rlimit_memlock_type = 45 [default = SOFT];
|
|
optional uint64 rlimit_rtprio = 46 [default = 0];
|
|
optional RLimit rlimit_rtprio_type = 47 [default = SOFT];
|
|
optional uint64 rlimit_msgqueue = 48 [default = 1024]; /* In bytes */
|
|
optional RLimit rlimit_msgqueue_type = 49 [default = SOFT];
|
|
|
|
/* Disable all rlimits, default to limits set by parent */
|
|
optional bool disable_rl = 50 [default = false];
|
|
|
|
/* See 'man personality' for more */
|
|
optional bool persona_addr_compat_layout = 51 [default = false];
|
|
optional bool persona_mmap_page_zero = 52 [default = false];
|
|
optional bool persona_read_implies_exec = 53 [default = false];
|
|
optional bool persona_addr_limit_3gb = 54 [default = false];
|
|
optional bool persona_addr_no_randomize = 55 [default = false];
|
|
|
|
/* Which name-spaces should be used? */
|
|
optional bool clone_newnet = 56 [default = true];
|
|
optional bool clone_newuser = 57 [default = true];
|
|
optional bool clone_newns = 58 [default = true];
|
|
optional bool clone_newpid = 59 [default = true];
|
|
optional bool clone_newipc = 60 [default = true];
|
|
optional bool clone_newuts = 61 [default = true];
|
|
/* Disable for kernel versions < 4.6 as it's not supported there */
|
|
optional bool clone_newcgroup = 62 [default = true];
|
|
/* Supported with kernel versions >= 5.3 */
|
|
optional bool clone_newtime = 63 [default = false];
|
|
|
|
/* Mappings for UIDs and GIDs. See the description for 'msg IdMap'
|
|
for more */
|
|
repeated IdMap uidmap = 64;
|
|
repeated IdMap gidmap = 65;
|
|
|
|
/* Should /proc be mounted (R/O)? This can also be added in the 'mount'
|
|
section below */
|
|
optional bool mount_proc = 66 [default = false];
|
|
/* Mount points inside the jail. See the description for 'msg MountPt'
|
|
for more */
|
|
repeated MountPt mount = 67;
|
|
|
|
/* Kafel seccomp-bpf policy file or a string:
|
|
Homepage of the project: https://github.com/google/kafel */
|
|
optional string seccomp_policy_file = 68;
|
|
repeated string seccomp_string = 69;
|
|
/* Setting it to true makes audit write seccomp logs to dmesg */
|
|
optional bool seccomp_log = 70 [default = false];
|
|
|
|
/* Use SECCOMP_RET_USER_NOTIF and trace accessed files and network sockets */
|
|
optional bool seccomp_unotify = 99 [default = false];
|
|
/* File to write the seccomp_unotify report to */
|
|
optional string seccomp_unotify_report = 100;
|
|
|
|
/* If > 0, maximum cumulative size of RAM used inside any jail */
|
|
optional uint64 cgroup_mem_max = 71 [default = 0]; /* In bytes */
|
|
/* If > 0, maximum cumulative size of RAM + swap used inside any jail */
|
|
optional uint64 cgroup_mem_memsw_max = 72 [default = 0]; /* In bytes */
|
|
/* If >= 0, maximum cumulative size of swap used inside any jail */
|
|
optional int64 cgroup_mem_swap_max = 73 [default = -1]; /* In bytes */
|
|
/* Mount point for cgroups-memory in your system */
|
|
optional string cgroup_mem_mount = 74 [default = "/sys/fs/cgroup/memory"];
|
|
/* Writeable directory (for the nsjail user) under cgroup_mem_mount */
|
|
optional string cgroup_mem_parent = 75 [default = "NSJAIL"];
|
|
|
|
/* If > 0, maximum number of PIDs (threads/processes) inside jail */
|
|
optional uint64 cgroup_pids_max = 76 [default = 0];
|
|
/* Mount point for cgroups-pids in your system */
|
|
optional string cgroup_pids_mount = 77 [default = "/sys/fs/cgroup/pids"];
|
|
/* Writeable directory (for the nsjail user) under cgroup_pids_mount */
|
|
optional string cgroup_pids_parent = 78 [default = "NSJAIL"];
|
|
|
|
/* If > 0, Class identifier of network packets inside jail */
|
|
optional uint32 cgroup_net_cls_classid = 79 [default = 0];
|
|
/* Mount point for cgroups-net-cls in your system */
|
|
optional string cgroup_net_cls_mount = 80 [default = "/sys/fs/cgroup/net_cls"];
|
|
/* Writeable directory (for the nsjail user) under cgroup_net_mount */
|
|
optional string cgroup_net_cls_parent = 81 [default = "NSJAIL"];
|
|
|
|
/* If > 0, number of milliseconds of CPU time per second that jailed processes can use */
|
|
optional uint32 cgroup_cpu_ms_per_sec = 82 [default = 0];
|
|
/* Mount point for cgroups-cpu in your system */
|
|
optional string cgroup_cpu_mount = 83 [default = "/sys/fs/cgroup/cpu"];
|
|
/* Writeable directory (for the nsjail user) under cgroup_cpu_mount */
|
|
optional string cgroup_cpu_parent = 84 [default = "NSJAIL"];
|
|
|
|
/* Mount point for cgroup v2 in your system */
|
|
optional string cgroupv2_mount = 85 [default = "/sys/fs/cgroup"];
|
|
/* Use cgroup v2 */
|
|
optional bool use_cgroupv2 = 86 [default = false];
|
|
/* Check whether cgroupv2 is available, and use it if available. */
|
|
optional bool detect_cgroupv2 = 87 [default = false];
|
|
|
|
/* Should the 'lo' interface be brought up (active) inside this jail? */
|
|
optional bool iface_no_lo = 88 [default = false];
|
|
|
|
/* Put this interface inside the jail */
|
|
repeated string iface_own = 89;
|
|
|
|
/* Parameters for the cloned MACVLAN interface inside jail */
|
|
optional string macvlan_iface = 90; /* Interface to be cloned, eg 'eth0' */
|
|
optional string macvlan_vs_ip = 91 [default = "192.168.0.2"];
|
|
optional string macvlan_vs_nm = 92 [default = "255.255.255.0"];
|
|
optional string macvlan_vs_gw = 93 [default = "192.168.0.1"];
|
|
optional string macvlan_vs_ma = 94 [default = ""];
|
|
optional string macvlan_vs_mo = 95 [default = "private"];
|
|
|
|
message TrafficRule {
|
|
enum TrafficAction {
|
|
UNKNOWN_ACTION = 0;
|
|
DROP = 1; /* Block the traffic silently */
|
|
REJECT = 2; /* Block and send ICMP unreachable / TCP RST */
|
|
ALLOW = 3; /* Explicitly allow */
|
|
}
|
|
|
|
enum IpFamily {
|
|
IPV4 = 0;
|
|
IPV6 = 1;
|
|
}
|
|
|
|
enum Protocol {
|
|
UNKNOWN_PROTO = 0; /* No protocol filter */
|
|
TCP = 1;
|
|
UDP = 2;
|
|
ICMP = 3;
|
|
ICMPV6 = 4;
|
|
}
|
|
|
|
/* Match parameters (Selectors) */
|
|
optional string src_ip = 1; /* Source IP or CIDR */
|
|
optional string dst_ip = 2; /* Dest IP or CIDR */
|
|
optional string iif = 3; /* Input interface */
|
|
optional string oif = 4; /* Output interface */
|
|
optional Protocol proto = 5 [default = UNKNOWN_PROTO];
|
|
optional uint32 sport = 6; /* Source port */
|
|
optional uint32 dport = 7; /* Dest port */
|
|
optional uint32 sport_end = 8; /* For port ranges */
|
|
optional uint32 dport_end = 9; /* For port ranges */
|
|
|
|
/* Action parameters */
|
|
optional TrafficAction action = 10 [default = DROP];
|
|
|
|
/* Address family: IPV4 (default) or IPV6 */
|
|
optional IpFamily ip_family = 15 [default = IPV4];
|
|
}
|
|
repeated TrafficRule traffic_rule = 96;
|
|
|
|
message UserNet {
|
|
/* Backend to use */
|
|
enum Backend {
|
|
NSTUN = 0;
|
|
PASTA = 1;
|
|
}
|
|
optional Backend backend = 1 [default = NSTUN];
|
|
|
|
message Pasta {
|
|
/* Enable User-Mode NAT */
|
|
optional bool nat = 1 [default = true];
|
|
/* Enable TCP traffic forwarding */
|
|
optional bool enable_tcp = 2 [default = true];
|
|
/* Enable UDP traffic forwarding */
|
|
optional bool enable_udp = 3 [default = true];
|
|
/* Enable ICMP traffic forwarding */
|
|
optional bool enable_icmp = 4 [default = true];
|
|
|
|
/* IPv4 is enabled */
|
|
optional bool ip4_enabled = 5 [default = true];
|
|
/* IPv4 mask for the container */
|
|
optional string mask4 = 6 [default = "255.255.255.0"];
|
|
/* Enable IPv4 DHCP server in pasta */
|
|
optional bool enable_ip4_dhcp = 7 [default = false];
|
|
|
|
/* IPv6 enabled */
|
|
optional bool ip6_enabled = 8 [default = true];
|
|
/* IPv6 mask for the container */
|
|
optional string mask6 = 9 [default = "64"];
|
|
/* Enable IPv6 DHCP server in pasta */
|
|
optional bool enable_ip6_dhcp = 10 [default = false];
|
|
/* Enable IPv6 Router Advertisements in pasta */
|
|
optional bool enable_ip6_ra = 11 [default = false];
|
|
|
|
/* Announce DNS server to container via DHCP/NDP */
|
|
optional bool enable_dns = 12 [default = false];
|
|
/* Map IP address as seen from container to the host nameserver */
|
|
optional string dns_forward = 13 [default = ""];
|
|
/* Remap connections to the gateway address to the host */
|
|
optional bool map_gw = 14 [default = true];
|
|
|
|
/* Configure TCP port forwarding from host to namespace */
|
|
optional string tcp_map_in = 15 [default = "none"];
|
|
/* Configure UDP port forwarding from host to namespace */
|
|
optional string udp_map_in = 16 [default = "none"];
|
|
/* Configure TCP port forwarding from namespace to host */
|
|
optional string tcp_map_out = 17 [default = "none"];
|
|
/* Configure UDP port forwarding from namespace to host */
|
|
optional string udp_map_out = 18 [default = "none"];
|
|
}
|
|
optional Pasta pasta = 2;
|
|
|
|
message NstunRule {
|
|
enum Direction {
|
|
GUEST_TO_HOST = 0;
|
|
HOST_TO_GUEST = 1;
|
|
}
|
|
enum Action {
|
|
DROP = 0;
|
|
REJECT = 1;
|
|
ALLOW = 2;
|
|
REDIRECT = 3;
|
|
ENCAP_SOCKS5 = 4;
|
|
ENCAP_CONNECT = 5;
|
|
}
|
|
enum Protocol {
|
|
ANY = 0;
|
|
TCP = 1;
|
|
UDP = 2;
|
|
ICMP = 3;
|
|
}
|
|
optional Direction direction = 11 [default = GUEST_TO_HOST];
|
|
optional Action action = 1 [default = ALLOW];
|
|
optional Protocol proto = 2 [default = ANY];
|
|
|
|
/* Match source IP network in "x.x.x.x/yy" or "x.x.x.x" format */
|
|
optional string src_ip = 3;
|
|
/* Match source port range */
|
|
optional uint32 sport = 4;
|
|
optional uint32 sport_end = 5;
|
|
|
|
/* Match destination IP network */
|
|
optional string dst_ip = 6;
|
|
/* Match destination port range (also the listen port for HOST_TO_GUEST) */
|
|
optional uint32 dport = 7;
|
|
optional uint32 dport_end = 8;
|
|
|
|
/* Action parameters */
|
|
optional string redirect_ip = 9;
|
|
optional uint32 redirect_port = 10;
|
|
}
|
|
|
|
/* IPv4 backend firewall/NAT rules */
|
|
repeated NstunRule rule4 = 3;
|
|
/* IPv6 backend firewall/NAT rules */
|
|
repeated NstunRule rule6 = 12;
|
|
|
|
/* IP address for the container */
|
|
optional string ip4 = 4 [default = "10.255.255.2"];
|
|
/* Gateway address for the container */
|
|
optional string gw4 = 5 [default = "10.255.255.1"];
|
|
|
|
/* IPv6 address for the container */
|
|
optional string ip6 = 6 [default = "fc00::2"];
|
|
/* IPv6 gateway for the container */
|
|
optional string gw6 = 7 [default = "fc00::1"];
|
|
|
|
/* Name of the interface inside the namespace */
|
|
optional string ns_iface = 8 [default = "eth0"];
|
|
}
|
|
optional UserNet user_net = 97;
|
|
|
|
/* Binary path (with arguments) to be executed. If not specified here, it
|
|
can be specified with cmd-line as "-- /path/to/command arg1 arg2" */
|
|
optional Exe exec_bin = 98;
|
|
}
|
|
|
|
// vim: set noexpandtab ts=4 sw=4:
|