dyndns

Check-in [cd0b3be596]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Drop root privs after we get the DNS server socket
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | master | trunk
Files: files | file ages | folders
SHA3-256:cd0b3be596fb5e51d62455c5ef1e7d7df8c24285e25157e62421940e0f69f82c
User & Date: vandys 2018-07-05 16:57:56
Context
2018-07-05
16:57
Drop root privs after we get the DNS server socket Leaf check-in: cd0b3be596 user: vandys tags: master, trunk
16:48
Clean up "fossil extra". Snapshot of dnslib for our use. check-in: 773c4f126c user: vandys tags: master, trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to server.py.

19
20
21
22
23
24
25



26
27
28
29
30
31
32
...
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
...
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
231
232
233
234
235
236
237
































238
239
240
241
242
243
244
245

# Port for UDP dynamic DNS requests/updates
PORT = 5053

# Our dynamic DNS server state
dyn_server = None




# Dotted domain name helper
class DomainName(str):
    def __getattr__(self, item):
	return DomainName(item + '.' + self)

class DynDNS(object):
    def __init__(self, dom):
................................................................................

	# Formatted answer
	# sys.stderr.write("reply: %r\n" % (reply,))
	resp = (host, reply.pack())
	return resp

    def serve_dns(self):
	sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	sock.bind(('', 53))

	ignored = 0
	while True:
	    buf,who = sock.recvfrom(8192)
	    try:
		tup = self.dns_response(buf)
	    except:
		ignored += 1
		continue
	    if tup is None:
		ignored += 1
................................................................................
	    # DNS typically receives a *lot* of junk
	    if ignored:
		sys.stderr.write("(%d previously ignored)\n" % (ignored,))
		ignored = 0

	    sys.stderr.write("Query %s %s %s\n" %
		(who, host, time.asctime()))
	    sock.sendto(res, who)

def load_accounts():
    global accounts, touched

    f = open("etc/accounts", "r")
    st = os.fstat(f.fileno())
    if (touched is not None) and (touched >= st.st_mtime):
................................................................................
	if len(tup) != 2:
	    continue
	newa[tup[0]] = tup[1]
    accounts = newa
    f.close()

def serve_dyn():
    global used, hosts, accounts

    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('', PORT))
    while True:

	# Next request
	buf,who = sock.recvfrom(8192)
	sys.stderr.write("Update %s %s: %s\n" % (who, time.asctime(), buf))

	# Decode
	try:
	    # Decode outer wrapper
	    outer = json.loads(buf)
	    req = outer["req"]
	    sig = str(outer["sig"])
................................................................................
def usage():
    sys.stderr.write("Usage is: %s <domain>\n" % (sys.argv[0],))
    sys.exit(1)

if __name__ == '__main__':
    if len(sys.argv) != 2:
	usage()

































    print "Starting dynamic DNS server..."
    t = threading.Thread(target=serve_dyn)
    t.start()

    print "Starting nameserver..."
    dyn_server = DynDNS(sys.argv[1])
    dyn_server.serve_dns()







>
>
>







 







|
<
>


|







 







|







 







|

<
<



|
|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>








19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135
...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
...
163
164
165
166
167
168
169
170
171


172
173
174
175
176
177
178
179
180
181
182
183
...
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

# Port for UDP dynamic DNS requests/updates
PORT = 5053

# Our dynamic DNS server state
dyn_server = None

# Our two sockets
reqsock = dnssock = None

# Dotted domain name helper
class DomainName(str):
    def __getattr__(self, item):
	return DomainName(item + '.' + self)

class DynDNS(object):
    def __init__(self, dom):
................................................................................

	# Formatted answer
	# sys.stderr.write("reply: %r\n" % (reply,))
	resp = (host, reply.pack())
	return resp

    def serve_dns(self):
	global dnssock


	ignored = 0
	while True:
	    buf,who = dnssock.recvfrom(8192)
	    try:
		tup = self.dns_response(buf)
	    except:
		ignored += 1
		continue
	    if tup is None:
		ignored += 1
................................................................................
	    # DNS typically receives a *lot* of junk
	    if ignored:
		sys.stderr.write("(%d previously ignored)\n" % (ignored,))
		ignored = 0

	    sys.stderr.write("Query %s %s %s\n" %
		(who, host, time.asctime()))
	    dnssock.sendto(res, who)

def load_accounts():
    global accounts, touched

    f = open("etc/accounts", "r")
    st = os.fstat(f.fileno())
    if (touched is not None) and (touched >= st.st_mtime):
................................................................................
	if len(tup) != 2:
	    continue
	newa[tup[0]] = tup[1]
    accounts = newa
    f.close()

def serve_dyn():
    global used, hosts, accounts, reqsock



    while True:

	# Next request
	buf,who = reqsock.recvfrom(8192)
	sys.stderr.write("Receive %s %s: %s\n" % (who, time.asctime(), buf))

	# Decode
	try:
	    # Decode outer wrapper
	    outer = json.loads(buf)
	    req = outer["req"]
	    sig = str(outer["sig"])
................................................................................
def usage():
    sys.stderr.write("Usage is: %s <domain>\n" % (sys.argv[0],))
    sys.exit(1)

if __name__ == '__main__':
    if len(sys.argv) != 2:
	usage()

    # DNS service socket
    dnssock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    dnssock.bind(('', 53))

    # Request socket
    reqsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    reqsock.bind(('', PORT))

    # Drop privs
    # (This assumes we're running *as* root, i.e., not setuid, but
    #  actual uid == 0)
    try:
	os.setgroups([])
    except:
	pass
    try:
	os.setegid(65534)
    except:
	pass
    try:
	os.setgid(65534)
    except:
	pass
    try:
	os.seteuid(65534)
    except:
	pass
    try:
	os.setuid(65534)
    except:
	pass

    print "Starting dynamic DNS server..."
    t = threading.Thread(target=serve_dyn)
    t.start()

    print "Starting nameserver..."
    dyn_server = DynDNS(sys.argv[1])
    dyn_server.serve_dns()