def _start_child(nonetns): # Create socket pair to communicate (s0, s1) = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM, 0) # Spawn a child that will run in a loop pid = os.fork() if pid: s1.close() return (s0, pid) # FIXME: clean up signal handers, atexit functions, etc. try: # pragma: no cover # coverage doesn't seem to understand fork s0.close() srv = nemu.protocol.Server(s1, s1) if not nonetns: # create new name space unshare.unshare(unshare.CLONE_NEWNET) # Enable packet forwarding execute([SYSCTL_PATH, '-w', 'net.ipv4.ip_forward=1']) execute([SYSCTL_PATH, '-w', 'net.ipv6.conf.default.forwarding=1']) srv.run() except BaseException, e: s = "Slave node aborting: %s\n" % str(e) sep = "=" * 70 + "\n" sys.stderr.write(s + sep) traceback.print_exc(file=sys.stdout) sys.stderr.write(sep) try: # try to pass the error to parent, if possible s1.send("500 " + s) except: pass os._exit(1)
def spawn_netns(): # prefer unshare module try: import unshare unshare.unshare(unshare.CLONE_NEWNET) return True except: pass # sledgehammer style: # - call ourselves prefixed by 'unshare -n' if found # - pass extra --no-netns parameter to avoid another recursion try: import shutil unshare = shutil.which("unshare") if unshare is None: return False sys.argv.append("--no-netns") os.execv(unshare, [unshare, "-n", sys.executable] + sys.argv) except: pass return False
def mnt_namespace(args): if (os.path.isdir(args.root_path)): shutil.rmtree(args.root_path) os.mkdir(args.root_path) os.system("tar -xzf ubuntu-rootfs.tar.gz -C " + args.root_path + " 2>/dev/null") os.system("cp mem loop " + args.root_path + "/home") os.system("chmod 766 " + args.root_path + "/home/loop") os.system("chmod 766 " + args.root_path + "/home/mem") unshare.unshare(unshare.CLONE_NEWNS)
def namespace_magic(): import unshare uid = os.getuid() gid = os.getgid() unshare.unshare(unshare.CLONE_NEWUSER | unshare.CLONE_NEWNS) with open('/proc/self/uid_map', 'w') as f: f.write(f'0 {uid} 1') # with open('/proc/self/gid_map', 'w') as f: # f.write(f'0 {gid} 1') os.system('id')
def _test(self, rules_file, queue): # Import the firewall rules in a detached network namespace unshare(CLONE_NEWNET) proc = subprocess.Popen(rules_file, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = proc.communicate() if proc.returncode: queue.put((False, err.strip())) else: queue.put((True, None))
def run(container_id, commands, environment=None): """ run commands in a container that has already been created :param container_id: container id :param commands: list of commands to execute :param environment: dictionary of key-value pairs """ if environment is None: environment = {} if not os.path.exists(fs.get_path_to_container(container_id)): console.error("Container does not exist") return pid = os.fork() if pid == 0: # container process console.log('Pocket starting with process-id: %d' % os.getpid()) cgroups.Cgroup(container_id).add(os.getpid()) os.chroot(fs.get_path_to_container(container_id)) os.chdir('/') unshare.unshare(unshare.CLONE_NEWUTS | unshare.CLONE_NEWNS | unshare.CLONE_NEWPID) pid2 = os.fork() if pid2 == 0: fs.mount("/proc", "/proc", "proc") os.system(f'/bin/hostname {container_id}') # execute the commands for command in commands: console.log(f'{container_id}: executing - {command}') os.execve( command.split(" ")[0], command.split(" "), environment) else: os.waitpid(pid2, 0) else: _, status = os.waitpid(pid, 0) fs.unmount(os.path.join(fs.get_path_to_container(container_id), "proc")) console.log(f'Pocket pid: {pid} exited with status {status}')
def child(self, pipe): try: unshare.unshare(unshare.CLONE_NEWNS | unshare.CLONE_NEWUTS | unshare.CLONE_NEWIPC | unshare.CLONE_NEWNET) pipe.send(1) #WAIT FOR PARENT CREATE CONTROLLER pipe.recv() subprocess.check_call(['ifconfig', self.guest_eth, self.guest_ip, 'netmask', self.netmask, 'up']) subprocess.check_call(['route', 'add', 'default', 'gw', self.host_ip]) subprocess.check_call(['ifconfig', 'lo', '127.0.0.1/8', 'up']) subprocess.check_call(['iptables', '-t', 'filter', '-F']) subprocess.check_call(['iptables', '-t', 'nat', '-F']) subprocess.check_call(['iptables', '-A', 'INPUT', '-i', 'lo', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-A', 'INPUT', '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-A', 'INPUT', '-m', 'state', '--state', 'INVALID', '-j', 'DROP']) subprocess.check_call(['iptables', '-P', 'INPUT', 'DROP']) subprocess.check_call(['iptables', '-A', 'OUTPUT', '-o', 'lo', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-A', 'OUTPUT', '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-A', 'OUTPUT', '-m', 'state', '--state', 'INVALID', '-j', 'DROP']) subprocess.check_call(['iptables', '-A', 'OUTPUT', '-m', 'owner', '--uid-owner', 'root', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-A', 'OUTPUT', '-m', 'owner', '--uid-owner', '_apt', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-P', 'OUTPUT', 'DROP']) subprocess.check_call(['iptables', '-P', 'FORWARD', 'DROP']) subprocess.check_call(['iptables', '-t', 'nat', '-P', 'PREROUTING', 'ACCEPT']) subprocess.check_call(['iptables', '-t', 'nat', '-P', 'POSTROUTING', 'ACCEPT']) subprocess.check_call(['iptables', '-t', 'nat', '-P', 'OUTPUT', 'ACCEPT']) pipe.close() runargs = [ 'runner', '--root', self.root, '--pivot', '--work-dir', '/', '--env=simple', '--ns-ipc', '--ns-uts', '--ns-pid', '--ns-mount', '--mount-proc', '--cap', 'safe' ] runargs += [ '--control-host', self.host_ip, '--control-port', str(self.control_port), '--cgroup', '/', '--cgroup-memory', str(self.cgroup_memory), '--max-realtime', str(self.real_time) ] if self.search: runargs += [ '--search' ] if self.debug: runargs += [ '--debug', self.debug ] runargs += self.runner_args runargs += self.args os.execvp('runner', runargs) except: raise finally: pipe.close()
def child(self, pipe): try: unshare.unshare(unshare.CLONE_NEWNS | unshare.CLONE_NEWUTS | unshare.CLONE_NEWIPC | unshare.CLONE_NEWNET) pipe.send(1) #WAIT FOR PARENT CREATE CONTROLLER pipe.recv() subprocess.check_call(['ifconfig', self.guest_eth, self.guest_ip, 'netmask', self.netmask, 'up']) subprocess.check_call(['route', 'add', 'default', 'gw', self.host_ip]) subprocess.check_call(['ifconfig', 'lo', '127.0.0.1/8', 'up']) subprocess.check_call(['iptables', '-t', 'filter', '-F']) subprocess.check_call(['iptables', '-t', 'nat', '-F']) subprocess.check_call(['iptables', '-A', 'INPUT', '-i', 'lo', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-A', 'INPUT', '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-A', 'INPUT', '-m', 'state', '--state', 'INVALID', '-j', 'DROP']) subprocess.check_call(['iptables', '-P', 'INPUT', 'DROP']) subprocess.check_call(['iptables', '-A', 'OUTPUT', '-o', 'lo', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-A', 'OUTPUT', '-m', 'state', '--state', 'ESTABLISHED,RELATED', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-A', 'OUTPUT', '-m', 'state', '--state', 'INVALID', '-j', 'DROP']) subprocess.check_call(['iptables', '-A', 'OUTPUT', '-m', 'owner', '--uid-owner', 'root', '-j', 'ACCEPT']) subprocess.check_call(['iptables', '-P', 'OUTPUT', 'DROP']) subprocess.check_call(['iptables', '-P', 'FORWARD', 'DROP']) subprocess.check_call(['iptables', '-t', 'nat', '-P', 'PREROUTING', 'ACCEPT']) subprocess.check_call(['iptables', '-t', 'nat', '-P', 'POSTROUTING', 'ACCEPT']) subprocess.check_call(['iptables', '-t', 'nat', '-P', 'OUTPUT', 'ACCEPT']) pipe.close() runargs = [ 'runner', '--root', self.root, '--pivot', '--work-dir', '/', '--env=simple', '--ns-ipc', '--ns-uts', '--ns-pid', '--ns-mount', '--mount-proc', '--cap', 'safe' ] runargs += [ '--control-host', self.host_ip, '--control-port', str(self.control_port), '--cgroup', '/', '--cgroup-memory', str(self.cgroup_memory), '--max-realtime', str(self.real_time) ] if self.search: runargs += [ '--search' ] if self.debug: runargs += [ '--debug', self.debug ] runargs += self.runner_args runargs += self.args os.execvp('runner', runargs) except: raise finally: pipe.close()
def namespaced_action(): global MOUNT_DIRS unshare.unshare(unshare_flags) os.environ['SANDBOX'] = 'true' def chroot_action(): debug("chowning dirs for %s: %r" % (user, shadow_dirs)) for d in shadow_dirs: subprocess.check_call(['chown', user, d]) debug("bringing up `lo` network interface") subprocess.check_call(['ifconfig', 'lo', 'up']) if init_expr: debug("running init command: %r (as root)" % (init_expr,)) subprocess.check_call(['bash','-c', init_expr]) def user_action(): debug("running command: %r (as user %s)" % (cmd, user)) if cmd == DEFAULT_CMD: print >> sys.stderr, """try:\nexport PS1='\\n<container> \u@\h \w \$ '\n""" subprocess.check_call(cmd) return selective_chroot.execute_as_user(user_action, user=user) ret, MOUNT_DIRS = selective_chroot.chroot(base=chroot_base, shadow_dirs=shadow_dirs, action=chroot_action) return ret
def run(): i = 2 string_cmd = "" while i < len(sys.argv): string_cmd = string_cmd + str(sys.argv[i]) + " " i += 1 print("running " + string_cmd) os.chroot("/ubuntu_xenial_1604") os.chdir("/") os.system("mount -t proc proc /proc") unshare(131072) unshare(1073741824) unshare(67108864) os.system(str(string_cmd))
def uts_namespace(args): unshare.unshare(unshare.CLONE_NEWUTS) os.system("hostname " + args.hostname)
def main(): parser = argparse.ArgumentParser(description='Run nft tests') parser.add_argument('filenames', nargs='*', metavar='path/to/file.t', help='Run only these tests') parser.add_argument('-d', '--debug', action='store_true', dest='debug', help='enable debugging mode') parser.add_argument('-e', '--need-fix', action='store_true', dest='need_fix_line', help='run rules that need a fix') parser.add_argument('-f', '--force-family', action='store_true', dest='force_all_family', help='keep testing all families on error') parser.add_argument('-H', '--host', action='store_true', help='run tests against installed libnftables.so.1') parser.add_argument('-j', '--enable-json', action='store_true', dest='enable_json', help='test JSON functionality as well') parser.add_argument('-l', '--library', default=None, help='path to libntables.so.1, overrides --host') parser.add_argument('-s', '--schema', action='store_true', dest='enable_schema', help='verify json input/output against schema') parser.add_argument('-v', '--version', action='version', version='1.0', help='Print the version information') args = parser.parse_args() global debug_option, need_fix_option, enable_json_option, enable_json_schema debug_option = args.debug need_fix_option = args.need_fix_line force_all_family_option = args.force_all_family enable_json_option = args.enable_json enable_json_schema = args.enable_schema specific_file = False signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) if os.getuid() != 0: print("You need to be root to run this, sorry") return # Change working directory to repository root os.chdir(TESTS_PATH + "/../..") try: import unshare unshare.unshare(unshare.CLONE_NEWNET) except: print_warning("cannot run in own namespace, connectivity might break") check_lib_path = True if args.library is None: if args.host: args.library = 'libnftables.so.1' check_lib_path = False else: args.library = 'src/.libs/libnftables.so.1' if check_lib_path and not os.path.exists(args.library): print("The nftables library at '%s' does not exist. " "You need to build the project." % args.library) return if args.enable_schema and not args.enable_json: print_error("Option --schema requires option --json") return global nftables nftables = Nftables(sofile=args.library) test_files = files_ok = run_total = 0 tests = passed = warnings = errors = 0 global log_file try: log_file = open(LOGFILE, 'w') print_info("Log will be available at %s" % LOGFILE) except IOError: print_error("Cannot open log file %s" % LOGFILE) return file_list = [] if args.filenames: file_list = args.filenames if len(args.filenames) == 1: specific_file = True else: for directory in TESTS_DIRECTORY: path = os.path.join(TESTS_PATH, directory) for root, dirs, files in os.walk(path): for f in files: if f.endswith(".t"): file_list.append(os.path.join(directory, f)) for filename in file_list: result = run_test_file(filename, force_all_family_option, specific_file) file_tests = result[0] file_passed = result[1] file_warnings = result[2] file_errors = result[3] file_unit_run = result[4] test_files += 1 if file_warnings == 0 and file_tests == file_passed: files_ok += 1 if file_tests: tests += file_tests passed += file_passed errors += file_errors warnings += file_warnings if force_all_family_option: run_total += file_unit_run if test_files == 0: print("No test files to run") else: if not specific_file: if force_all_family_option: print("%d test files, %d files passed, %d unit tests, " % (test_files, files_ok, tests)) print("%d total executed, %d error, %d warning" % (run_total, errors, warnings)) else: print("%d test files, %d files passed, %d unit tests, " % (test_files, files_ok, tests)) print("%d error, %d warning" % (errors, warnings))
def test(v): flags = 0 kwpath = {} for a in v: if len(a) == 1: flags |= a[0] else: kwpath[a[0]] = a[1] for k in kwpath: if os.path.exists(kwpath[k]) and unshare.get_nstype(kwpath[k]) != None: unshare.unbind(kwpath[k], kw_ns[k]) open(kwpath[k], "w").close() r, w = os.pipe() r = os.fdopen(r) w = os.fdopen(w, 'w') pid = os.fork() if pid != 0: w.close() ns1 = pickle.load(r) ns2 = dict([(k, os.stat("/proc/self/ns/%s" % (k)).st_ino) for k in os.listdir("/proc/self/ns")]) pid, status = os.waitpid(pid, 0) if status != 0: print "%x %s failed" % (flags, kwpath) raise (Exception) else: for k in ns1: if k == 'pid': continue def getpath(): if k in kwpath: return kwpath[k] if k == 'mnt' and 'mount' in kwpath: return kwpath['mount'] if k == 'pid_for_children' and 'pid' in kwpath: return kwpath['pid'] return None def getflags(): if k in kw_ns: return kw_ns[k] if k == 'mnt': return kw_ns['mount'] if k == 'pid_for_children': return kw_ns['pid'] raise Exception(k) path = getpath() def error(msg): raise Exception("%s \n %s \n %s \n%x %s" % (msg, ns1, ns2, flags, kwpath)) if path != None: if ns1[k] != os.stat(path).st_ino: error("Wrong namespace saved in %s %d" % (path, os.stat(path).st_ino)) if ns1[k] == ns2[k]: raise Exception("%s %s %s" % (k, ns1, ns2)) elif getflags() & flags == 0: if ns1[k] != ns2[k]: error("Namespaces not equal %s" % (k)) else: if ns1[k] == ns2[k]: error("Namespaces equal %s" % (k)) else: r.close() try: unshare.unshare(flags, **kwpath) ns = dict([(k, os.stat("/proc/self/ns/%s" % (k)).st_ino) for k in os.listdir("/proc/self/ns")]) pickle.dump(ns, w) w.close() os._exit(0) except Exception, e: print >> sys.stderr, e os._exit(1)
UID = os.getuid() GID = os.getgid() tmpdir = tempfile.TemporaryDirectory(prefix='clean-shell-') tmp_path = Path(tmpdir.name) # Check if it is allowed for normal users: unpriv_path = Path('/proc/sys/kernel/unprivileged_userns_clone') if unpriv_path.exists() and unpriv_path.read_text()[0] == '0': print( "Must enable user namespace clone: sudo bash -c 'echo 1 > /proc/sys/kernel/unprivileged_userns_clone'" ) exit(1) #print('phase 1') unshare.unshare(unshare.CLONE_NEWNS | unshare.CLONE_NEWUSER) open("/proc/self/setgroups", "w").write('deny') open("/proc/self/uid_map", 'w').write('0 %s 1' % UID) open("/proc/self/gid_map", 'w').write('0 %s 1' % GID) #print('uid:', os.getuid()) # Rebind all files for dest in FILES: dest = os.path.expanduser(dest) is_dir = dest.endswith('/') dest = Path(dest) basename = dest.name # if dir, pathlib.Path removes trailing slash # Take values from ~/.clean-shell/ if (local_path / basename).exists():
def pid_namespace(args): unshare.unshare(unshare.CLONE_NEWPID)
def main(): parser = argparse.ArgumentParser(description='Run iptables tests') parser.add_argument('filename', nargs='*', metavar='path/to/file.t', help='Run only this test') parser.add_argument('-H', '--host', action='store_true', help='Run tests against installed binaries') parser.add_argument('-l', '--legacy', action='store_true', help='Test iptables-legacy') parser.add_argument('-m', '--missing', action='store_true', help='Check for missing tests') parser.add_argument('-n', '--nftables', action='store_true', help='Test iptables-over-nftables') parser.add_argument('-N', '--netns', action='store_true', help='Test netnamespace path') args = parser.parse_args() # # show list of missing test files # if args.missing: show_missing() return global EXECUTEABLE EXECUTEABLE = "xtables-legacy-multi" if args.nftables: EXECUTEABLE = "xtables-nft-multi" if os.getuid() != 0: print("You need to be root to run this, sorry") return if not args.host: os.putenv("XTABLES_LIBDIR", os.path.abspath(EXTENSIONS_PATH)) os.putenv( "PATH", "%s/iptables:%s" % (os.path.abspath(os.path.curdir), os.getenv("PATH"))) test_files = 0 tests = 0 passed = 0 # setup global var log file global log_file try: log_file = open(LOGFILE, 'w') except IOError: print("Couldn't open log file %s" % LOGFILE) return if args.filename: file_list = args.filename else: file_list = [ os.path.join(EXTENSIONS_PATH, i) for i in os.listdir(EXTENSIONS_PATH) if i.endswith('.t') ] file_list.sort() if not args.netns: try: import unshare unshare.unshare(unshare.CLONE_NEWNET) except: print("Cannot run in own namespace, connectivity might break") for filename in file_list: file_tests, file_passed = run_test_file(filename, args.netns) if file_tests: tests += file_tests passed += file_passed test_files += 1 print("%d test files, %d unit tests, %d passed" % (test_files, tests, passed))
r.close() try: unshare.unshare(flags, **kwpath) ns = dict([(k, os.stat("/proc/self/ns/%s" % (k)).st_ino) for k in os.listdir("/proc/self/ns")]) pickle.dump(ns, w) w.close() os._exit(0) except Exception, e: print >> sys.stderr, e os._exit(1) if __name__ == '__main__': args = list([(n, os.path.join(sys.argv[1], n)) for n in kw_ns] + [(n, ) for n in flag_ns]) if len(sys.argv) >= 3: N = int(sys.argv[2]) else: N = len(args) unshare.unshare(unshare.CLONE_NEWNS) # Isolate test from systemd for n in range(1, N + 1): combinations = list(itertools.combinations(args, n)) print "n=%d/N=%d (%d combinations)" % (n, N, len(combinations)) for v in combinations: try: test(v) except: print "test(%s) failed" % (str(v)) raise
def unshare (): import unshare as u u.unshare (u.CLONE_NEWNS) subprocess.check_call (['mount', '--make-rprivate', '/'])
def net_namespace(args): unshare.unshare(unshare.CLONE_NEWNET) os.system("ip link add name eth1 type veth peer name veth1") os.system("ip link set dev veth1 netns ") os.system("ifconfig eth1 " + args.ip_addr)