init repo
This commit is contained in:
commit
1472938a30
33
README.md
Normal file
33
README.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
t]
|
||||||
|
Description=Address Python Server
|
||||||
|
After=syslog.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=addressserver
|
||||||
|
Group=addressserver
|
||||||
|
WorkingDirectory=/home/addressserver/address_scanner
|
||||||
|
ExecStart=/usr/bin/python3 /home/addressserver/address_scanner/server.py
|
||||||
|
SyslogIdentifier=address_server
|
||||||
|
StandardOutput=syslog
|
||||||
|
StandardError=syslog
|
||||||
|
Restart=always
|
||||||
|
RestartSec=3
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
apt-get install python3-pip
|
||||||
|
pip3 install netifaces paho-mqtt
|
||||||
|
|
||||||
|
*/2 * * * * /usr/bin/python3 /root/scanner.py -i eth0 -4 192 -6 2a02 --host 192.168.25.221 --username mc8051 --password XXXXXXX -q
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
https://www.thomaschristlieb.de/ein-python-script-mit-systemd-als-daemon-systemd-tut-garnicht-weh/
|
||||||
|
https://stackoverflow.com/a/47370156
|
||||||
|
```
|
93
scanner.py
Normal file
93
scanner.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import netifaces
|
||||||
|
import optparse
|
||||||
|
import sys
|
||||||
|
import socket
|
||||||
|
import time
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
|
||||||
|
is_connected = False
|
||||||
|
|
||||||
|
def on_connect(client, userdata, flags, rc):
|
||||||
|
global is_connected
|
||||||
|
if(rc == 0):
|
||||||
|
is_connected = True
|
||||||
|
|
||||||
|
hostname = socket.gethostname()
|
||||||
|
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
|
||||||
|
parser.add_option('-i', '--interface', action="store", dest="interface", help="Network Interface", default="")
|
||||||
|
parser.add_option('-q', '--quite', action="store_true", dest="quite", help="No output")
|
||||||
|
parser.add_option('-4', '--match4', action="store", dest="match4", help="IPv4 MUST start with this argument", default="")
|
||||||
|
parser.add_option('-6', '--match6', action="store", dest="match6", help="IPv6 MUST start with this argument", default="")
|
||||||
|
parser.add_option('--host', action="store", dest="mqqt_host", help="MQTT Host", default="")
|
||||||
|
parser.add_option('--port', action="store", dest="mqqt_port", help="MQTT Port", default="1883")
|
||||||
|
parser.add_option('--username', action="store", dest="mqqt_user", help="MQTT Username (optional)", default="")
|
||||||
|
parser.add_option('--password', action="store", dest="mqqt_pass", help="MQTT Password (optional)", default="")
|
||||||
|
|
||||||
|
options, args = parser.parse_args()
|
||||||
|
|
||||||
|
client_enabled = not(not options.mqqt_host)
|
||||||
|
|
||||||
|
if client_enabled:
|
||||||
|
client = mqtt.Client()
|
||||||
|
client.connect(options.mqqt_host, int(options.mqqt_port), 60)
|
||||||
|
|
||||||
|
if options.mqqt_user and options.mqqt_pass:
|
||||||
|
client.username_pw_set(username=options.mqqt_user, password=options.mqqt_pass)
|
||||||
|
|
||||||
|
client.on_connect = on_connect
|
||||||
|
client.loop_start()
|
||||||
|
else:
|
||||||
|
print("Warning: no MQTT server defined")
|
||||||
|
|
||||||
|
if client_enabled:
|
||||||
|
timeout = 10
|
||||||
|
while (not is_connected) and (timeout > 0):
|
||||||
|
timeout -= 1
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
if timeout <= 0:
|
||||||
|
print("MQTT timeout")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
try:
|
||||||
|
addrs = netifaces.ifaddresses(options.interface)
|
||||||
|
except ValueError as ex:
|
||||||
|
print("Invalid interface " + options.interface)
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
if not options.quite:
|
||||||
|
print("Checking network interface " + options.interface + " on " + hostname)
|
||||||
|
|
||||||
|
if not options.match4 and not options.quite:
|
||||||
|
print("Warning: no IPv4-Match set")
|
||||||
|
|
||||||
|
if not options.match6 and not options.quite:
|
||||||
|
print("Warning: no IPv6-Match set")
|
||||||
|
|
||||||
|
|
||||||
|
ipv4 = ""
|
||||||
|
for addr in addrs[netifaces.AF_INET]:
|
||||||
|
if addr["addr"].startswith(options.match4):
|
||||||
|
ipv4 = addr["addr"]
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
ipv6 = ""
|
||||||
|
for addr in addrs[netifaces.AF_INET6]:
|
||||||
|
if addr["addr"].startswith(options.match6):
|
||||||
|
ipv6 = addr["addr"]
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
if not options.quite:
|
||||||
|
print("")
|
||||||
|
print("Found IPv4 " + ipv4 + " and IPv6 " + ipv6)
|
||||||
|
|
||||||
|
if client_enabled:
|
||||||
|
client.publish("network/" + hostname + "/hostname", hostname)
|
||||||
|
client.publish("network/" + hostname + "/ipv4", ipv4)
|
||||||
|
client.publish("network/" + hostname + "/ipv6", ipv6)
|
||||||
|
|
||||||
|
client.loop_stop()
|
420
server.py
Normal file
420
server.py
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
import schedule
|
||||||
|
import time
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import socket
|
||||||
|
import CloudFlare
|
||||||
|
import logging
|
||||||
|
import smtplib
|
||||||
|
import ssl
|
||||||
|
import io
|
||||||
|
|
||||||
|
logger = logging.getLogger('dns_updater')
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y:%H:%M:%S')
|
||||||
|
|
||||||
|
|
||||||
|
ch = logging.StreamHandler()
|
||||||
|
ch.setFormatter(formatter)
|
||||||
|
logger.addHandler(ch)
|
||||||
|
|
||||||
|
log_capture_string = io.StringIO()
|
||||||
|
ch2 = logging.StreamHandler(log_capture_string)
|
||||||
|
ch2.setFormatter(formatter)
|
||||||
|
logger.addHandler(ch2)
|
||||||
|
|
||||||
|
OPENWRT_PATH = "/cgi-bin/luci/"
|
||||||
|
INTERVAL = 60
|
||||||
|
userdata = dict()
|
||||||
|
mqtt_data = dict()
|
||||||
|
mail_data = dict()
|
||||||
|
openwrt = dict()
|
||||||
|
hosts = dict()
|
||||||
|
dns = dict()
|
||||||
|
firewall = dict()
|
||||||
|
|
||||||
|
def readFile():
|
||||||
|
with open("settings.json") as json_file:
|
||||||
|
global userdata
|
||||||
|
global hosts
|
||||||
|
global dns
|
||||||
|
global firewall
|
||||||
|
global mqtt_data
|
||||||
|
global mail_data
|
||||||
|
global openwrt
|
||||||
|
global OPENWRT_PATH
|
||||||
|
global INTERVAL
|
||||||
|
data = json.load(json_file)
|
||||||
|
|
||||||
|
userdata = {"apikey": data["apikey"], "username": data["user"]}
|
||||||
|
INTERVAL = data["interval"]
|
||||||
|
|
||||||
|
mqtt_data = data["mqtt"]
|
||||||
|
mail_data = data["mail"]
|
||||||
|
openwrt = data["openwrt"]
|
||||||
|
OPENWRT_PATH = "http://" + openwrt["host"] + OPENWRT_PATH
|
||||||
|
|
||||||
|
if "hosts" in data:
|
||||||
|
z = hosts.copy()
|
||||||
|
z.update(data["hosts"])
|
||||||
|
hosts = z
|
||||||
|
|
||||||
|
if "dns" in data:
|
||||||
|
z = dns.copy()
|
||||||
|
z.update(data["dns"])
|
||||||
|
dns = z
|
||||||
|
|
||||||
|
if "firewall" in data:
|
||||||
|
z = firewall.copy()
|
||||||
|
z.update(data["firewall"])
|
||||||
|
firewall = z
|
||||||
|
|
||||||
|
readFile()
|
||||||
|
|
||||||
|
def saveFile():
|
||||||
|
logger.info("Saving settings.json file...")
|
||||||
|
with open('settings.json', 'wt') as out:
|
||||||
|
global userdata
|
||||||
|
global hosts
|
||||||
|
global dns
|
||||||
|
global INTERVAL
|
||||||
|
obj = {
|
||||||
|
"apikey": userdata["apikey"],
|
||||||
|
"user": userdata["username"],
|
||||||
|
"interval": INTERVAL,
|
||||||
|
"dns": dns,
|
||||||
|
"hosts": hosts,
|
||||||
|
"firewall": firewall,
|
||||||
|
"mqtt": mqtt_data,
|
||||||
|
"openwrt": openwrt,
|
||||||
|
"mail": mail_data,
|
||||||
|
}
|
||||||
|
res = json.dump(obj, out, sort_keys=True, indent=4, separators=(',', ': '))
|
||||||
|
logger.info("File saved")
|
||||||
|
|
||||||
|
schedule.every(2).minutes.do(saveFile)
|
||||||
|
|
||||||
|
|
||||||
|
def getPublicIP():
|
||||||
|
r = requests.get("https://ipinfo.io/")
|
||||||
|
data = json.loads(r.text)
|
||||||
|
|
||||||
|
return data.get("ip")
|
||||||
|
|
||||||
|
def do_dns_update(cf, zone_name, zone_id, dns_name, ip_address, ip_address_type):
|
||||||
|
"""Cloudflare API code - example"""
|
||||||
|
logger.info("Update %s to %s" % (dns_name+"."+zone_name, ip_address))
|
||||||
|
|
||||||
|
try:
|
||||||
|
prefix = "" if dns_name == "@" else dns_name+"."
|
||||||
|
params = {'name':prefix+zone_name, 'match':'all', 'type':ip_address_type}
|
||||||
|
dns_records = cf.zones.dns_records.get(zone_id, params=params)
|
||||||
|
except CloudFlare.exceptions.CloudFlareAPIError as e:
|
||||||
|
logger.error('/zones/dns_records %s - %d %s - api call failed' % (dns_name, e, e))
|
||||||
|
|
||||||
|
updated = False
|
||||||
|
changed = False
|
||||||
|
|
||||||
|
# update the record - unless it's already correct
|
||||||
|
for dns_record in dns_records:
|
||||||
|
old_ip_address = dns_record['content']
|
||||||
|
old_ip_address_type = dns_record['type']
|
||||||
|
|
||||||
|
if ip_address_type not in ['A', 'AAAA']:
|
||||||
|
# we only deal with A / AAAA records
|
||||||
|
continue
|
||||||
|
|
||||||
|
if ip_address_type != old_ip_address_type:
|
||||||
|
# only update the correct address type (A or AAAA)
|
||||||
|
# we don't see this becuase of the search params above
|
||||||
|
logger.debug('IGNORED: %s %s ; wrong address family' % (dns_name, old_ip_address))
|
||||||
|
continue
|
||||||
|
|
||||||
|
if ip_address == old_ip_address:
|
||||||
|
logger.debug('UNCHANGED: %s %s' % (dns_name, ip_address))
|
||||||
|
updated = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Yes, we need to update this record - we know it's the same address type
|
||||||
|
|
||||||
|
dns_record_id = dns_record['id']
|
||||||
|
dns_record = {
|
||||||
|
'name':dns_name,
|
||||||
|
'type':ip_address_type,
|
||||||
|
'content':ip_address
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
dns_record = cf.zones.dns_records.put(zone_id, dns_record_id, data=dns_record)
|
||||||
|
changed = True
|
||||||
|
except CloudFlare.exceptions.CloudFlareAPIError as e:
|
||||||
|
logger.error('/zones.dns_records.put %s - %d %s - api call failed' % (dns_name, e, e))
|
||||||
|
logger.debug('UPDATED: %s %s -> %s' % (dns_name, old_ip_address, ip_address))
|
||||||
|
updated = True
|
||||||
|
|
||||||
|
if updated:
|
||||||
|
return changed
|
||||||
|
|
||||||
|
# no exsiting dns record to update - so create dns record
|
||||||
|
dns_record = {
|
||||||
|
'name':dns_name,
|
||||||
|
'type':ip_address_type,
|
||||||
|
'content':ip_address
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
dns_record = cf.zones.dns_records.post(zone_id, data=dns_record)
|
||||||
|
changed = True
|
||||||
|
except CloudFlare.exceptions.CloudFlareAPIError as e:
|
||||||
|
logger.error('/zones.dns_records.post %s - %d %s - api call failed' % (dns_name, e, e))
|
||||||
|
logger.debug('CREATED: %s %s' % (dns_name, ip_address))
|
||||||
|
return changed
|
||||||
|
|
||||||
|
|
||||||
|
if openwrt["enabled"] == True:
|
||||||
|
jar = requests.cookies.RequestsCookieJar()
|
||||||
|
fw_login = requests.get(OPENWRT_PATH + "/rpc/auth", cookies=jar, json={
|
||||||
|
"id": 1,
|
||||||
|
"method": "login",
|
||||||
|
"params": [
|
||||||
|
openwrt["username"],
|
||||||
|
openwrt["password"]
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
if "result" not in fw_login.json() or fw_login.json()["result"] is None:
|
||||||
|
exit("Incorrect OpenWrt Login")
|
||||||
|
|
||||||
|
o = urlparse(OPENWRT_PATH)
|
||||||
|
jar.set('sysauth', fw_login.json()["result"], domain=o.netloc, path=o.path)
|
||||||
|
|
||||||
|
def setFirewall(section, key, new_ipv6):
|
||||||
|
global jar
|
||||||
|
|
||||||
|
logger.info("Updating firewall " + section + "." + key + "=" + new_ipv6)
|
||||||
|
|
||||||
|
if not new_ipv6:
|
||||||
|
logger.debug("Empty IPv6... Skipping...")
|
||||||
|
return
|
||||||
|
|
||||||
|
r = requests.get(OPENWRT_PATH + "/rpc/uci", cookies=jar, json={
|
||||||
|
"id": 1,
|
||||||
|
"method": "get_all",
|
||||||
|
"params": [
|
||||||
|
"firewall",
|
||||||
|
section
|
||||||
|
]
|
||||||
|
})
|
||||||
|
data = r.json()
|
||||||
|
|
||||||
|
if not "result" in data or data["result"] is None:
|
||||||
|
logger.warning("Unknown firewall section %s... Skipping..." % (section))
|
||||||
|
return
|
||||||
|
|
||||||
|
result = data["result"]
|
||||||
|
|
||||||
|
if not "family" in result or result["family"] is None:
|
||||||
|
logger.debug("No family set in firewall section %s... Skipping..." % (section))
|
||||||
|
return
|
||||||
|
|
||||||
|
if not key in result or result[key] is None:
|
||||||
|
logger.debug("No %s set in firewall section %s... Skipping..." % (key, section))
|
||||||
|
return
|
||||||
|
|
||||||
|
if result["family"] != "ipv6":
|
||||||
|
logger.debuginfo("Section %s is no ipv6... Skipping..." % (section))
|
||||||
|
return
|
||||||
|
|
||||||
|
if result[key] == new_ipv6:
|
||||||
|
logger.debug("Section %s has same ipv6... Skipping..." % (section))
|
||||||
|
return
|
||||||
|
|
||||||
|
r = requests.get(OPENWRT_PATH + "/rpc/uci", cookies=jar, json={
|
||||||
|
"id": 1,
|
||||||
|
"method": "set",
|
||||||
|
"params": [
|
||||||
|
"firewall",
|
||||||
|
section,
|
||||||
|
key,
|
||||||
|
new_ipv6
|
||||||
|
]
|
||||||
|
})
|
||||||
|
logger.debug("updated = %s" % r.json()["result"])
|
||||||
|
return True
|
||||||
|
|
||||||
|
def commitFirewall():
|
||||||
|
global jar
|
||||||
|
r = requests.get(OPENWRT_PATH + "/rpc/uci", cookies=jar, json={
|
||||||
|
"id": 1,
|
||||||
|
"method": "commit",
|
||||||
|
"params": [
|
||||||
|
"firewall",
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
def updateFirewall():
|
||||||
|
global hosts
|
||||||
|
global dns
|
||||||
|
global firewall
|
||||||
|
global commitFirewall
|
||||||
|
global setFirewall
|
||||||
|
logger.info("Updating firewall")
|
||||||
|
changed = False
|
||||||
|
for section in firewall:
|
||||||
|
for key in firewall[section]:
|
||||||
|
value = firewall[section][key]
|
||||||
|
ipv6 = hosts.get(value, dict()).get("ipv6", "")
|
||||||
|
changed = setFirewall(section, key, ipv6)
|
||||||
|
if changed == True:
|
||||||
|
logger.info("Firewall set... Commiting...")
|
||||||
|
commitFirewall()
|
||||||
|
logger.info("Firewall commited")
|
||||||
|
else:
|
||||||
|
logger.info("Nothing changed. Skipping firewall commit...")
|
||||||
|
return changed
|
||||||
|
|
||||||
|
def updateDNS():
|
||||||
|
global hosts
|
||||||
|
global userdata
|
||||||
|
global dns
|
||||||
|
global getPublicIP
|
||||||
|
global do_dns_update
|
||||||
|
|
||||||
|
logger.info("Updating DNS")
|
||||||
|
|
||||||
|
|
||||||
|
cf = CloudFlare.CloudFlare(email=userdata["username"], token=userdata["apikey"])
|
||||||
|
|
||||||
|
PUBLIC = getPublicIP()
|
||||||
|
if not PUBLIC or PUBLIC is None:
|
||||||
|
logger.error("EMPTY PUBLIC IP?!")
|
||||||
|
return False
|
||||||
|
|
||||||
|
changed = False
|
||||||
|
|
||||||
|
for domain in dns:
|
||||||
|
params = {'name':domain}
|
||||||
|
zones = cf.zones.get(params=params)
|
||||||
|
|
||||||
|
zone = zones[0]
|
||||||
|
zone_name = zone['name']
|
||||||
|
zone_id = zone['id']
|
||||||
|
for subdomain in dns[domain]:
|
||||||
|
ipv4_host = dns[domain][subdomain].get("ipv4", "")
|
||||||
|
ipv6_host = dns[domain][subdomain].get("ipv6", "")
|
||||||
|
|
||||||
|
if ipv4_host.lower() == "public":
|
||||||
|
ipv4 = PUBLIC
|
||||||
|
else:
|
||||||
|
ipv4 = hosts.get(ipv4_host, dict()).get("ipv4", "")
|
||||||
|
|
||||||
|
ipv6 = hosts.get(ipv6_host, dict()).get("ipv6", "")
|
||||||
|
|
||||||
|
dns_records = []
|
||||||
|
|
||||||
|
if ipv4:
|
||||||
|
if do_dns_update(cf, zone_name, zone_id, subdomain, ipv4, "A"):
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
if ipv6:
|
||||||
|
if do_dns_update(cf, zone_name, zone_id, subdomain, ipv6, "AAAA"):
|
||||||
|
changed = True
|
||||||
|
return changed
|
||||||
|
|
||||||
|
def sendMail(mail_data, title, content):
|
||||||
|
logger.info("Sending mail to %s" % mail_data["receipent"])
|
||||||
|
# Create a secure SSL context
|
||||||
|
context = ssl.create_default_context()
|
||||||
|
|
||||||
|
# Try to log in to server and send email
|
||||||
|
try:
|
||||||
|
server = smtplib.SMTP(mail_data["host"], mail_data["port"])
|
||||||
|
server.ehlo() # Can be omitted
|
||||||
|
server.starttls(context=context) # Secure the connection
|
||||||
|
server.ehlo() # Can be omitted
|
||||||
|
server.login(mail_data["username"], mail_data["password"])
|
||||||
|
|
||||||
|
message = "From: " + mail_data["username"] + "\n"
|
||||||
|
message += "To: " + mail_data["receipent"] + "\n"
|
||||||
|
message += "Subject: "+title+"\n"
|
||||||
|
message += "\n"
|
||||||
|
message += content
|
||||||
|
|
||||||
|
server.sendmail(mail_data["username"], mail_data["receipent"], message)
|
||||||
|
logger.debug("Mail send")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(e)
|
||||||
|
finally:
|
||||||
|
server.quit()
|
||||||
|
|
||||||
|
def updateAll():
|
||||||
|
global updateDNS
|
||||||
|
global updateFirewall
|
||||||
|
global openwrt
|
||||||
|
global log_capture_string
|
||||||
|
global mail_data
|
||||||
|
|
||||||
|
log_capture_string.truncate(0)
|
||||||
|
log_capture_string.seek(0)
|
||||||
|
|
||||||
|
changed = False
|
||||||
|
|
||||||
|
if openwrt["enabled"] == True:
|
||||||
|
if updateFirewall():
|
||||||
|
changed = True
|
||||||
|
else:
|
||||||
|
logger.info("Firewall update is disabled")
|
||||||
|
|
||||||
|
if updateDNS():
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
if mail_data and "enabled" in mail_data and mail_data["enabled"] == True:
|
||||||
|
if changed == True:
|
||||||
|
sendMail(mail_data, "Info: DNS/Firewall Address Server", log_capture_string.getvalue())
|
||||||
|
else:
|
||||||
|
logger.debug("No email. nothing changed")
|
||||||
|
else:
|
||||||
|
logger.info("Email is disabled")
|
||||||
|
|
||||||
|
schedule.every(INTERVAL).seconds.do(updateAll)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def on_connect(client, userdata, flags, rc):
|
||||||
|
logger.debug("Connected with result code "+str(rc))
|
||||||
|
if rc != 0:
|
||||||
|
logger.error("ERROR: Please check MQTT Login")
|
||||||
|
client.subscribe("network/+/hostname")
|
||||||
|
client.subscribe("network/+/ipv4")
|
||||||
|
client.subscribe("network/+/ipv6")
|
||||||
|
|
||||||
|
def on_message(client, userdata, msg):
|
||||||
|
global hosts
|
||||||
|
pl = str((msg.payload).decode("utf-8")).lower()
|
||||||
|
logger.debug(msg.topic + ": " + pl)
|
||||||
|
|
||||||
|
if msg.topic.startswith("network/") and (msg.topic.endswith("/ipv4") or msg.topic.endswith("/ipv6")):
|
||||||
|
host = msg.topic.split("/")[1]
|
||||||
|
|
||||||
|
if not host in hosts:
|
||||||
|
hosts[host] = dict()
|
||||||
|
|
||||||
|
hosts[host]["ipv4" if msg.topic.endswith("/ipv4") else "ipv6"] = pl
|
||||||
|
|
||||||
|
client = mqtt.Client()
|
||||||
|
client.username_pw_set(username=mqtt_data["username"], password=mqtt_data["password"])
|
||||||
|
client.connect(mqtt_data["host"], mqtt_data["port"], 60)
|
||||||
|
client.on_connect = on_connect
|
||||||
|
client.on_message = on_message
|
||||||
|
|
||||||
|
client.loop_start()
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
schedule.run_pending()
|
||||||
|
time.sleep(1)
|
||||||
|
except KeyboardInterrupt as ex:
|
||||||
|
saveFile()
|
||||||
|
|
||||||
|
# https://htmlpreview.github.io/?https://raw.githubusercontent.com/openwrt/luci/master/documentation/api/modules/luci.model.uci.html#Cursor.get
|
||||||
|
# https://wiki.teltonika.lt/view/UCI_command_usage
|
69
settings.json.sample
Normal file
69
settings.json.sample
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"apikey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
|
||||||
|
"dns": {
|
||||||
|
"domain2.com": {
|
||||||
|
"@": {
|
||||||
|
"ipv4": "public",
|
||||||
|
"ipv6": "proxy"
|
||||||
|
},
|
||||||
|
"playing": {
|
||||||
|
"ipv6": "playground"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"domain2.com": {
|
||||||
|
"test": {
|
||||||
|
"ipv4": "public",
|
||||||
|
"ipv6": "proxy"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"firewall": {
|
||||||
|
"cf2bd": {
|
||||||
|
"dest_ip": "proxy"
|
||||||
|
},
|
||||||
|
"cfgbd": {
|
||||||
|
"dest_ip": "proxy"
|
||||||
|
},
|
||||||
|
"cfgd": {
|
||||||
|
"dest_ip": "plex"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hosts": {
|
||||||
|
"playground": {
|
||||||
|
"ipv4": "192.168.1.12",
|
||||||
|
"ipv6": "2a02:908::8b0b"
|
||||||
|
},
|
||||||
|
"plex": {
|
||||||
|
"ipv4": "192.168.1.11",
|
||||||
|
"ipv6": "2a02:908::d237"
|
||||||
|
},
|
||||||
|
"proxy": {
|
||||||
|
"ipv4": "192.168.1.10",
|
||||||
|
"ipv6": "2a02:908::9867"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"interval": 600,
|
||||||
|
"mail": {
|
||||||
|
"enabled": true,
|
||||||
|
"host": "mail.example.com",
|
||||||
|
"password": "",
|
||||||
|
"port": 587,
|
||||||
|
"receipent": "user@example.com",
|
||||||
|
"username": "dns-updater@example.com"
|
||||||
|
},
|
||||||
|
"mqtt": {
|
||||||
|
"_comment": "Please secure your MQTT server",
|
||||||
|
"host": "192.168.1.2",
|
||||||
|
"password": "",
|
||||||
|
"port": 1883,
|
||||||
|
"username": "mc8051"
|
||||||
|
},
|
||||||
|
"openwrt": {
|
||||||
|
"_comment": "Please install luci JSON rpc package",
|
||||||
|
"enabled": true,
|
||||||
|
"host": "192.168.1.1",
|
||||||
|
"password": "",
|
||||||
|
"username": "root"
|
||||||
|
},
|
||||||
|
"user": "user@example.com"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user