mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-13 16:14:40 +00:00
dnsmasq: add dnsmasq watcher; closes #5119
This commit is contained in:
parent
d7ade48769
commit
b7de99e08b
1
plist
1
plist
@ -738,6 +738,7 @@
|
||||
/usr/local/opnsense/scripts/OPNsense/Monit/setup.sh
|
||||
/usr/local/opnsense/scripts/auth/add_user.php
|
||||
/usr/local/opnsense/scripts/dhcp/cleanup_leases4.php
|
||||
/usr/local/opnsense/scripts/dhcp/dnsmasq_watcher.py
|
||||
/usr/local/opnsense/scripts/dhcp/get_leases.py
|
||||
/usr/local/opnsense/scripts/dhcp/prefixes.php
|
||||
/usr/local/opnsense/scripts/dhcp/unbound_watcher.py
|
||||
|
||||
@ -278,24 +278,18 @@ function _dnsmasq_dhcpleases_start()
|
||||
{
|
||||
global $config;
|
||||
|
||||
/* XXX this code is going away soon enough */
|
||||
$leases = '/var/dhcpd/var/db/dhcpd.leases';
|
||||
|
||||
if (isset($config['dnsmasq']['regdhcp']) && file_exists($leases)) {
|
||||
if (isset($config['dnsmasq']['regdhcp'])) {
|
||||
$domain = $config['system']['domain'];
|
||||
if (isset($config['dnsmasq']['regdhcpdomain'])) {
|
||||
$domain = $config['dnsmasq']['regdhcpdomain'];
|
||||
}
|
||||
mwexecf(
|
||||
'/usr/local/sbin/dhcpleases -l %s -d %s -p %s -h %s',
|
||||
[$leases, $domain, '/var/run/dnsmasq.pid', '/var/etc/dnsmasq-leases']
|
||||
);
|
||||
mwexecf('/usr/local/opnsense/scripts/dhcp/dnsmasq_watcher.py --domain %s', $domain);
|
||||
}
|
||||
}
|
||||
|
||||
function _dnsmasq_dhcpleases_stop()
|
||||
{
|
||||
killbypid('/var/run/dhcpleases.pid', 'TERM', true);
|
||||
killbypid('/var/run/dnsmasq_dhcpd.pid', 'TERM', true);
|
||||
}
|
||||
|
||||
function dnsmasq_hosts_generate()
|
||||
|
||||
126
src/opnsense/scripts/dhcp/dnsmasq_watcher.py
Executable file
126
src/opnsense/scripts/dhcp/dnsmasq_watcher.py
Executable file
@ -0,0 +1,126 @@
|
||||
#!/usr/local/bin/python3
|
||||
|
||||
"""
|
||||
Copyright (c) 2016-2020 Ad Schellevis <ad@opnsense.org>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
watch dhcp lease file and build include file for dnsmasq
|
||||
"""
|
||||
import ipaddress
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import argparse
|
||||
import syslog
|
||||
import signal
|
||||
from configparser import ConfigParser
|
||||
sys.path.insert(0, "/usr/local/opnsense/site-python")
|
||||
from daemonize import Daemonize
|
||||
import watchers.dhcpd
|
||||
|
||||
|
||||
def run_watcher(target_filename, default_domain, watch_file, service_pid):
|
||||
# cleanup interval (seconds)
|
||||
cleanup_interval = 60
|
||||
|
||||
# initiate lease watcher and setup cache
|
||||
dhcpdleases = watchers.dhcpd.DHCPDLease(watch_file)
|
||||
cached_leases = dict()
|
||||
|
||||
# start watching dhcp leases
|
||||
last_cleanup = time.time()
|
||||
|
||||
while True:
|
||||
for lease in dhcpdleases.watch():
|
||||
if 'ends' in lease and lease['ends'] > time.time() \
|
||||
and 'client-hostname' in lease and 'address' in lease and lease['client-hostname']:
|
||||
address = ipaddress.ip_address(lease['address'])
|
||||
lease['domain'] = default_domain
|
||||
cached_leases[lease['address']] = lease
|
||||
dhcpd_changed = True
|
||||
|
||||
if time.time() - last_cleanup > cleanup_interval:
|
||||
# cleanup every x seconds
|
||||
last_cleanup = time.time()
|
||||
addresses = list(cached_leases)
|
||||
for address in addresses:
|
||||
if cached_leases[address]['ends'] < time.time():
|
||||
syslog.syslog(
|
||||
syslog.LOG_NOTICE,
|
||||
"dhcpd expired %s @ %s" % (cached_leases[address]['client-hostname'], address)
|
||||
)
|
||||
del cached_leases[address]
|
||||
dhcpd_changed = True
|
||||
|
||||
if dhcpd_changed:
|
||||
with open(target_filename, 'w') as dnsmasq_conf:
|
||||
dnsmasq_conf.write('# dynamic entries from dhcpd.leases automatically entered\n')
|
||||
for address in cached_leases:
|
||||
dnsmasq_conf.write('%s %s.%s %s\n' % (
|
||||
address,
|
||||
cached_leases[address]['client-hostname'],
|
||||
cached_leases[address]['domain'],
|
||||
cached_leases[address]['client-hostname']
|
||||
))
|
||||
|
||||
pid = int(open(service_pid).read())
|
||||
os.kill(pid, signal.SIGHUP)
|
||||
|
||||
dhcpd_changed = False
|
||||
|
||||
# wait for next cycle
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--domain', help='default domain to use', default='local')
|
||||
parser.add_argument('--foreground', help='run in forground', default=False, action='store_true')
|
||||
parser.add_argument('--pid', help='pid file location', default='/var/run/dnsmasq_dhcpd.pid')
|
||||
parser.add_argument('--servicepid', help='dnsmasq pid file location', default='/var/run/dnsmasq.pid')
|
||||
parser.add_argument('--source', help='source leases file', default='/var/dhcpd/var/db/dhcpd.leases')
|
||||
parser.add_argument('--target', help='target config file', default='/var/etc/dnsmasq-leases')
|
||||
|
||||
inputargs = parser.parse_args()
|
||||
|
||||
syslog.openlog('dnsmasq', logoption=syslog.LOG_DAEMON, facility=syslog.LOG_LOCAL4)
|
||||
|
||||
if inputargs.foreground:
|
||||
run_watcher(
|
||||
target_filename=inputargs.target,
|
||||
default_domain=inputargs.domain,
|
||||
watch_file=inputargs.source,
|
||||
service_pid=inputargs.servicepid
|
||||
)
|
||||
else:
|
||||
syslog.syslog(syslog.LOG_NOTICE, 'daemonize dnsmasq dhcpd watcher.')
|
||||
cmd = lambda : run_watcher(
|
||||
target_filename=inputargs.target,
|
||||
default_domain=inputargs.domain,
|
||||
watch_file=inputargs.source,
|
||||
service_pid=inputargs.servicepid
|
||||
)
|
||||
daemon = Daemonize(app="dnsmasq_dhcpd", pid=inputargs.pid, action=cmd)
|
||||
daemon.start()
|
||||
Loading…
x
Reference in New Issue
Block a user