Skip to content

Commit

Permalink
Implement dns ux socket uid/gid setting via new listener.dns_sock_[gu…
Browse files Browse the repository at this point in the history
…]id kws

Defaults to 953 to accomodate pdns-auth container USER.
  • Loading branch information
cvaroqui committed May 31, 2023
1 parent 59fd7dd commit db3c47d
Showing 1 changed file with 86 additions and 89 deletions.
175 changes: 86 additions & 89 deletions opensvc/daemon/dns.py
Expand Up @@ -2,15 +2,17 @@
Listener Thread
"""
import errno
import os
import sys
import socket
import logging
import threading
import shutil
import grp
import json
import logging
import os
import pwd
import re
import select
import socket
import shutil
import sys
import threading
import time

import foreign.six as six
Expand All @@ -30,6 +32,14 @@
else:
MAKEFILE_KWARGS = {"buffering": None}

def record(qtype, qname, content, ttl=60):
return {
"qname": qname,
"qtype": qtype,
"content": content,
"ttl": ttl,
}

class Dns(shared.OsvcThread):
name = "dns"
sock_tmo = 1.0
Expand Down Expand Up @@ -59,6 +69,11 @@ def run(self):

self.log.info("listening on %s", Env.paths.dnsuxsock)

sock_uid = self.get_uid()
sock_gid = self.get_gid()
os.chown(Env.paths.dnsuxsock, sock_uid, sock_gid)
self.log.info("chown %s:%s %s", sock_uid, sock_gid, Env.paths.dnsuxsock)

self.zone = "%s." % self.cluster_name.strip(".")
self.suffix = ".%s" % self.zone
self.suffix_len = len(self.suffix)
Expand Down Expand Up @@ -94,6 +109,32 @@ def run(self):
self.sock.close()
self.exit()

def get_gid(self):
s = shared.NODE.oget("listener", "dns_sock_gid")
try:
return int(s)
except ValueError:
return
try:
info = grp.getgrnam(s)
return info[2]
except KeyError:
return

def get_uid(self):
s = shared.NODE.oget("listener", "dns_sock_uid")
try:
return int(s)
except ValueError:
pass
else:
return
try:
info = pwd.getpwnam(s)
return info[2]
except KeyError:
return

def wait_monitor(self):
while True:
nmon_status = self.node_data.get(["monitor", "status"], default="init")
Expand Down Expand Up @@ -235,8 +276,23 @@ def router(self, data):
def action_initialize(self, parameters):
return True

def action_getAllDomainMetadata(self, parameters):
if parameters.get("name") != self.zone:
return {}
return {
"ALLOW-AXFR-FROM": ["0.0.0.0/0", "AUTO-NS"],
}

def action_getAllDomains(self, parameters):
return [
{
"zone": self.zone,
},
]

def action_getDomainMetadata(self, parameters):
"""
Example request:
{
"method": "getDomainMetadata",
"parameters": {
Expand All @@ -245,6 +301,8 @@ def action_getDomainMetadata(self, parameters):
}
}
"""
if parameters.get("name") != self.zone:
return []
kind = parameters.get("kind")
if kind == "ALLOW-AXFR-FROM":
return ["0.0.0.0/0", "AUTO-NS"]
Expand Down Expand Up @@ -285,9 +343,8 @@ def action_lookup(self, parameters):
self.aaaa_record(parameters) + \
self.srv_record(parameters) + \
self.txt_record(parameters) + \
self.cname_record(parameters)

return self._action_list(qname)
self.cname_record(parameters) + \
self.soa_record(parameters)
return []

def action_list(self, parameters):
Expand All @@ -300,59 +357,39 @@ def lookup_pattern(self, suffix):
if not qname.endswith(suffix):
continue
for content in contents:
data.append({
"qtype": "A",
"qname": qname,
"content": content,
"ttl": 60
})
data.append(record("A", qname, content))
return data

def _action_list(self, suffix):
"""
Empty suffix is what "dns dump" uses.
"""
data = []
if suffix:
data += self.soa_record({"qname": suffix})
if len(data) == 0:
return data
# don't include NS record in dump, as those depend on suffix
data += self.zone_ns_records(suffix)
else:
data += self.zone_ns_records(self.zone)
if suffix == "":
suffix = self.zone
elif suffix != self.zone:
return []

data += self.soa_record({"qname": suffix})
data += self.zone_ns_records(suffix)

for qname, contents in self.a_records().items():
if suffix and not qname.endswith(suffix):
continue
for content in contents:
qtype = "AAAA" if ":" in content else "A"
data.append({
"qtype": qtype,
"qname": qname,
"content": content,
"ttl": 60
})
data.append(record(qtype, qname, content))
for qname, contents in self.srv_records().items():
if suffix and not qname.endswith(suffix):
continue
for content in contents:
data.append({
"qtype": "SRV",
"qname": qname,
"content": content,
"ttl": 60
})
data.append(record("SRV", qname, content))
for qname, contents in self.ptr_records().items():
if suffix and not qname.endswith(suffix):
continue
for content in contents:
qtype = "PTR6" if ":" in qname else "PTR"
data.append({
"qtype": "PTR",
"qname": qname,
"content": content,
"ttl": 60
})
data.append(record(qtype, qname, content))
return data

def remove_suffix(self, qname):
Expand All @@ -375,13 +412,8 @@ def ns_record(self, parameters):
def zone_ns_records(self, zonename):
data = []
for i, dns in enumerate(shared.NODE.dns):
dns = "ns%d.%s" % (i, zonename)
data.append({
"qtype": "NS",
"qname": zonename,
"content": dns,
"ttl": 3600
})
content = "ns%d.%s" % (i, zonename)
data.append(record("NS", zonename, content, ttl=3600))
return data

def soa_records(self):
Expand All @@ -405,17 +437,7 @@ def soa_record(self, parameters):
return []
elif qname != self.zone:
return []

data = [
{
"qtype": "SOA",
"qname": qname,
"content": self.soa_content,
"ttl": 60,
"domain_id": -1
}
]
return data
return [record("SOA", qname, self.soa_content)]

def cname_record(self, parameters):
return []
Expand All @@ -427,52 +449,27 @@ def srv_record(self, parameters):
qname = parameters.get("qname").lower()
if not qname.endswith(self.suffix):
return []
return [{
"qtype": "SRV",
"qname": qname,
"content": content,
"ttl": 60
} for content in self.srv_records().get(qname, [])]
return [record("SRV", qname, content) for content in self.srv_records().get(qname, [])]

def ptr_record(self, parameters):
qname = parameters.get("qname").lower()
return [{
"qtype": "PTR",
"qname": qname,
"content": name,
"ttl": 60
} for name in self.ptr_records().get(qname, []) if "." in name]
return [record("PTR", qname, name) for name in self.ptr_records().get(qname, []) if "." in name]

def ptr6_record(self, parameters):
qname = parameters.get("qname").lower()
return [{
"qtype": "PTR6",
"qname": qname,
"content": name,
"ttl": 60
} for name in self.ptr_records().get(qname, []) if ":" in name]
return [record("PTR6", qname, name) for name in self.ptr_records().get(qname, []) if ":" in name]

def a_record(self, parameters):
qname = parameters.get("qname").lower()
if not qname.endswith(self.suffix):
return []
return [{
"qtype": "A",
"qname": qname,
"content": addr,
"ttl": 60
} for addr in self.a_records().get(qname, []) if "." in addr]
return [record("A", qname, addr) for addr in self.a_records().get(qname, []) if "." in addr]

def aaaa_record(self, parameters):
qname = parameters.get("qname").lower()
if not qname.endswith(self.suffix):
return []
return [{
"qtype": "AAAA",
"qname": qname,
"content": addr,
"ttl": 60
} for addr in self.a_records().get(qname, []) if ":" in addr]
return [record("AAAA", qname, addr) for addr in self.a_records().get(qname, []) if ":" in addr]

def ptr_records(self):
data = self.get_cache("ptr")
Expand Down

0 comments on commit db3c47d

Please sign in to comment.