diff options
Diffstat (limited to 'test/test_go_isolation.py')
-rw-r--r-- | test/test_go_isolation.py | 207 |
1 files changed, 163 insertions, 44 deletions
diff --git a/test/test_go_isolation.py b/test/test_go_isolation.py index ee5ddf47..7884274d 100644 --- a/test/test_go_isolation.py +++ b/test/test_go_isolation.py @@ -1,4 +1,5 @@ -import os +import pwd +import grp import json import unittest from unit.applications.lang.go import TestApplicationGo @@ -18,20 +19,25 @@ class TestGoIsolation(TestApplicationGo): return unit if not complete_check else unit.complete() + def unpriv_creds(self): + nobody_uid = pwd.getpwnam('nobody').pw_uid + + try: + nogroup_gid = grp.getgrnam('nogroup').gr_gid + nogroup = 'nogroup' + except: + nogroup_gid = grp.getgrnam('nobody').gr_gid + nogroup = 'nobody' + + return (nobody_uid, nogroup_gid, nogroup) + def isolation_key(self, key): return key in self.available['features']['isolation'].keys() - def conf_isolation(self, isolation): - self.assertIn( - 'success', - self.conf(isolation, 'applications/ns_inspect/isolation'), - 'configure isolation', - ) - def test_isolation_values(self): self.load('ns_inspect') - obj = self.isolation.parsejson(self.get()['body']) + obj = self.getjson()['body'] for ns, ns_value in self.available['features']['isolation'].items(): if ns.upper() in obj['NS']: @@ -39,44 +45,155 @@ class TestGoIsolation(TestApplicationGo): obj['NS'][ns.upper()], ns_value, '%s match' % ns ) - def test_isolation_user(self): + def test_isolation_unpriv_user(self): if not self.isolation_key('unprivileged_userns_clone'): print('unprivileged clone is not available') raise unittest.SkipTest() + if self.is_su: + print('privileged tests, skip this') + raise unittest.SkipTest() + self.load('ns_inspect') - obj = self.isolation.parsejson(self.get()['body']) + obj = self.getjson()['body'] - self.assertTrue(obj['UID'] != 0, 'uid not zero') - self.assertTrue(obj['GID'] != 0, 'gid not zero') - self.assertEqual(obj['UID'], os.getuid(), 'uid match') - self.assertEqual(obj['GID'], os.getgid(), 'gid match') + self.assertEqual(obj['UID'], self.uid, 'uid match') + self.assertEqual(obj['GID'], self.gid, 'gid match') - self.conf_isolation({"namespaces": {"credential": True}}) + self.load('ns_inspect', isolation={'namespaces': {'credential': True}}) - obj = self.isolation.parsejson(self.get()['body']) + obj = self.getjson()['body'] - # default uid and gid maps current user to nobody - self.assertEqual(obj['UID'], 65534, 'uid nobody') - self.assertEqual(obj['GID'], 65534, 'gid nobody') + nobody_uid, nogroup_gid, nogroup = self.unpriv_creds() - self.conf_isolation( - { - "namespaces": {"credential": True}, - "uidmap": [ - {"container": 1000, "host": os.geteuid(), "size": 1} - ], - "gidmap": [ - {"container": 1000, "host": os.getegid(), "size": 1} + # unprivileged unit map itself to nobody in the container by default + self.assertEqual(obj['UID'], nobody_uid, 'uid of nobody') + self.assertEqual(obj['GID'], nogroup_gid, 'gid of %s' % nogroup) + + self.load( + 'ns_inspect', + user='root', + isolation={'namespaces': {'credential': True}}, + ) + + obj = self.getjson()['body'] + + self.assertEqual(obj['UID'], 0, 'uid match user=root') + self.assertEqual(obj['GID'], 0, 'gid match user=root') + + self.load( + 'ns_inspect', + user='root', + group=nogroup, + isolation={'namespaces': {'credential': True}}, + ) + + obj = self.getjson()['body'] + + self.assertEqual(obj['UID'], 0, 'uid match user=root group=nogroup') + self.assertEqual( + obj['GID'], nogroup_gid, 'gid match user=root group=nogroup' + ) + + self.load( + 'ns_inspect', + user='root', + group='root', + isolation={ + 'namespaces': {'credential': True}, + 'uidmap': [{'container': 0, 'host': self.uid, 'size': 1}], + 'gidmap': [{'container': 0, 'host': self.gid, 'size': 1}], + }, + ) + + obj = self.getjson()['body'] + + self.assertEqual(obj['UID'], 0, 'uid match uidmap') + self.assertEqual(obj['GID'], 0, 'gid match gidmap') + + def test_isolation_priv_user(self): + if not self.is_su: + print('unprivileged tests, skip this') + raise unittest.SkipTest() + + self.load('ns_inspect') + + nobody_uid, nogroup_gid, nogroup = self.unpriv_creds() + + obj = self.getjson()['body'] + + self.assertEqual(obj['UID'], nobody_uid, 'uid match') + self.assertEqual(obj['GID'], nogroup_gid, 'gid match') + + self.load('ns_inspect', isolation={'namespaces': {'credential': True}}) + + obj = self.getjson()['body'] + + # privileged unit map app creds in the container by default + self.assertEqual(obj['UID'], nobody_uid, 'uid nobody') + self.assertEqual(obj['GID'], nogroup_gid, 'gid nobody') + + self.load( + 'ns_inspect', + user='root', + isolation={'namespaces': {'credential': True}}, + ) + + obj = self.getjson()['body'] + + self.assertEqual(obj['UID'], 0, 'uid nobody user=root') + self.assertEqual(obj['GID'], 0, 'gid nobody user=root') + + self.load( + 'ns_inspect', + user='root', + group=nogroup, + isolation={'namespaces': {'credential': True}}, + ) + + obj = self.getjson()['body'] + + self.assertEqual(obj['UID'], 0, 'uid match user=root group=nogroup') + self.assertEqual( + obj['GID'], nogroup_gid, 'gid match user=root group=nogroup' + ) + + self.load( + 'ns_inspect', + user='root', + group='root', + isolation={ + 'namespaces': {'credential': True}, + 'uidmap': [{'container': 0, 'host': 0, 'size': 1}], + 'gidmap': [{'container': 0, 'host': 0, 'size': 1}], + }, + ) + + obj = self.getjson()['body'] + + self.assertEqual(obj['UID'], 0, 'uid match uidmap user=root') + self.assertEqual(obj['GID'], 0, 'gid match gidmap user=root') + + # map 65535 uids + self.load( + 'ns_inspect', + user='nobody', + isolation={ + 'namespaces': {'credential': True}, + 'uidmap': [ + {'container': 0, 'host': 0, 'size': nobody_uid + 1} ], - } + }, ) - obj = self.isolation.parsejson(self.get()['body']) + obj = self.getjson()['body'] - # default uid and gid maps current user to root - self.assertEqual(obj['UID'], 1000, 'uid root') - self.assertEqual(obj['GID'], 1000, 'gid root') + self.assertEqual( + obj['UID'], nobody_uid, 'uid match uidmap user=nobody' + ) + self.assertEqual( + obj['GID'], nogroup_gid, 'gid match uidmap user=nobody' + ) def test_isolation_mnt(self): if not self.isolation_key('mnt'): @@ -87,12 +204,12 @@ class TestGoIsolation(TestApplicationGo): print('unprivileged clone is not available') raise unittest.SkipTest() - self.load('ns_inspect') - self.conf_isolation( - {"namespaces": {"mount": True, "credential": True}} + self.load( + 'ns_inspect', + isolation={'namespaces': {'mount': True, 'credential': True}}, ) - obj = self.isolation.parsejson(self.get()['body']) + obj = self.getjson()['body'] # all but user and mnt allns = list(self.available['features']['isolation'].keys()) @@ -119,14 +236,16 @@ class TestGoIsolation(TestApplicationGo): print('pid namespace is not supported') raise unittest.SkipTest() - if not self.isolation_key('unprivileged_userns_clone'): - print('unprivileged clone is not available') + if not (self.is_su or self.isolation_key('unprivileged_userns_clone')): + print('requires root or unprivileged_userns_clone') raise unittest.SkipTest() - self.load('ns_inspect') - self.conf_isolation({"namespaces": {"pid": True, "credential": True}}) + self.load( + 'ns_inspect', + isolation={'namespaces': {'pid': True, 'credential': True}}, + ) - obj = self.isolation.parsejson(self.get()['body']) + obj = self.getjson()['body'] self.assertEqual(obj['PID'], 1, 'pid of container is 1') @@ -150,9 +269,9 @@ class TestGoIsolation(TestApplicationGo): else: namespaces[ns] = False - self.conf_isolation({"namespaces": namespaces}) + self.load('ns_inspect', isolation={'namespaces': namespaces}) - obj = self.isolation.parsejson(self.get()['body']) + obj = self.getjson()['body'] for ns in allns: if ns.upper() in obj['NS']: |