diff --git a/confluent_server/confluent/config/attributes.py b/confluent_server/confluent/config/attributes.py index 6c730f40..24f343dc 100644 --- a/confluent_server/confluent/config/attributes.py +++ b/confluent_server/confluent/config/attributes.py @@ -110,6 +110,9 @@ node = { 'crypted.selfapikey': { 'description': ('Crypt of api key for self api requests by node'), }, + 'trusted.subnets': { + 'description': 'Remote subnets in CIDR notation that should be considered as trusted as local networks' + } 'deployment.encryptboot': { 'description': ('Specify a strategy for encrypting the volume. Support ' 'for this setting is currently only enabled for ' diff --git a/confluent_server/confluent/credserver.py b/confluent_server/confluent/credserver.py index 546882b9..3fd50446 100644 --- a/confluent_server/confluent/credserver.py +++ b/confluent_server/confluent/credserver.py @@ -41,58 +41,19 @@ libc = ctypes.CDLL(ctypes.util.find_library('c')) # 6, len, hmac - hmac of crypted key using shared secret for long-haul support # 128, len, len, key - sealed key -_semitrusted = [] -def read_authnets(cfgpath): - global _semitrusted - with open(cfgpath, 'r') as cfgin: - _semitrusted = [] - for line in cfgin.readlines(): - line = line.split('#', 1)[0].strip() - if '/' not in line: - continue - subnet, prefix = line.split('/') - prefix = int(prefix) - _semitrusted.append((subnet, prefix)) - - -def watch_trusted(): - cfgpath = '/etc/confluent/auth_nets' - if isinstance(cfgpath, bytes): - bcfgpath = cfgpath - else: - bcfgpath = cfgpath.encode('utf8') - while True: - watcher = libc.inotify_init1(os.O_NONBLOCK) - if not os.path.exists(cfgpath): - with open(cfgpath, 'w') as cfgout: - cfgout.write( - '# This is a list of networks in addition to local\n' - '# networks to allow grant of initial deployment token,\n' - '# when a node has deployment API armed\n') - try: - read_authnets(cfgpath) - except Exception: - eventlet.sleep(15) - continue - if libc.inotify_add_watch(watcher, bcfgpath, 0xcc2) <= -1: - eventlet.sleep(15) - continue - select.select((watcher,), (), (), 86400) - try: - os.read(watcher, 1024) - except Exception: - pass - os.close(watcher) - - - -def address_is_somewhat_trusted(address): - for authnet in _semitrusted: - if netutil.ip_on_same_subnet(address, authnet[0], authnet[1]): - return True +def address_is_somewhat_trusted(address, nodename, cfm): if netutil.address_is_local(address): return True + authnets = cfm.get_node_attributes(nodename, 'trusted.subnets') + authnets = authnets.get(nodename, {}).get('trusted.subnets', {}).get('value', None) + if authnets: + for authnet in authnets.split(','): + for anet in authnet.split(): + na, plen = anet.split('/') + plen = int(plen) + if netutil.ip_on_same_subnet(address, no, plen): + return True return False class CredServer(object): @@ -119,7 +80,7 @@ class CredServer(object): elif tlv[1]: client.recv(tlv[1]) if not hmackey: - if not address_is_somewhat_trusted(peer[0]): + if not address_is_somewhat_trusted(peer[0], nodename, self.cfm): client.close() return apimats = self.cfm.get_node_attributes(nodename, diff --git a/confluent_server/confluent/sockapi.py b/confluent_server/confluent/sockapi.py index d7cd0736..341f1973 100644 --- a/confluent_server/confluent/sockapi.py +++ b/confluent_server/confluent/sockapi.py @@ -496,7 +496,6 @@ class SockApi(object): self.start_remoteapi() else: eventlet.spawn_n(self.watch_for_cert) - eventlet.spawn_n(credserver.watch_trusted) eventlet.spawn_n(self.watch_resolv) self.unixdomainserver = eventlet.spawn(_unixdomainhandler)