mirror of
https://github.com/YunoHost/dynette.git
synced 2024-09-03 20:06:17 +02:00
Refactor the madness
This commit is contained in:
parent
dfd8c0a412
commit
ab8e0423fc
4 changed files with 91 additions and 106 deletions
|
@ -1,15 +1,12 @@
|
||||||
YunoHost DynDNS Server
|
YunoHost DynDNS Server
|
||||||
======================
|
======================
|
||||||
|
|
||||||
|
|
||||||
**Note: Tested on Debian wheezy and YunoHost 2.4 (should work on Ubuntu)**
|
|
||||||
|
|
||||||
Setup quickly
|
Setup quickly
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
You can use the dynette_ynh package for YunoHost
|
You can use the dynette_ynh package for YunoHost
|
||||||
https://github.com/YunoHost-Apps/dynette_ynh
|
https://github.com/YunoHost-Apps/dynette_ynh
|
||||||
|
|
||||||
|
|
||||||
Web subscribe server deployment
|
Web subscribe server deployment
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
{
|
{
|
||||||
"database_url": "postgres://{{ db_user }}:{{ db_password }}@localhost/{{ db_name }}",
|
"database_url" : "postgres://{{ db_user }}:{{ db_password }}@localhost/{{ db_name }}",
|
||||||
"domains" : [ {{ subdomains }} ],
|
"dyndns_domains" : [ {{ subdomains }} ],
|
||||||
"subs_url" : [ https://{{ dynette_domain }} ],
|
"base_url" : "https://{{ dynette_domain }}",
|
||||||
"ns0" : {{ ns0 }},
|
"ns0" : "{{ ns0 }}",
|
||||||
"ns1" : {{ ns1 }},
|
"ns1" : "{{ ns1 }}",
|
||||||
"rname" : {{ rname }},
|
"rname" : "{{ rname }}",
|
||||||
"master_key" : {{ master_key }}
|
"master_key" : "{{ master_key }}",
|
||||||
|
"allowed_operations": {
|
||||||
|
"." : ["A", "AAAA", "TXT", "MX", "CAA"],
|
||||||
|
"*." : ["A", "AAAA"],
|
||||||
|
"pubsub." : ["A", "AAAA", "CNAME"],
|
||||||
|
"muc." : ["A", "AAAA", "CNAME"],
|
||||||
|
"vjud." : ["A", "AAAA", "CNAME"],
|
||||||
|
"xmpp-upload." : ["A", "AAAA", "CNAME"],
|
||||||
|
"_xmpp-client._tcp." : ["SRV"],
|
||||||
|
"_xmpp-server._tcp." : ["SRV"],
|
||||||
|
"mail._domainkey." : ["TXT"],
|
||||||
|
"_dmarc." : ["TXT"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
164
dynette.cron.py
164
dynette.cron.py
|
@ -1,48 +1,26 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python3
|
||||||
|
|
||||||
### Configuration ###
|
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
with open('config.json') as config_file:
|
|
||||||
config = json.load(config_file)
|
|
||||||
|
|
||||||
postgresql_dsn = "dbname=dynette user=dynette password=myPassword"
|
|
||||||
conf_file = '/etc/bind/named.conf.local' # Include this filename in '/etc/bind/named.conf'
|
|
||||||
zone_dir = '/var/lib/bind/' # Do not forget the trailing '/'
|
|
||||||
subs_urls = config_file["subs_urls"] # 127.0.0.1 if you install subscribe server locally
|
|
||||||
ns0 = config_file["ns0"] # Name servers
|
|
||||||
ns1 = config_file["ns1"]
|
|
||||||
rname = config_file["rname"] # Responsible person (https://tools.ietf.org/html/rfc1035#section-3.3.13)
|
|
||||||
master_key = config_file["master_key"]
|
|
||||||
|
|
||||||
allowed_operations = {
|
|
||||||
'.' : ['A', 'AAAA', 'TXT', 'MX', 'CAA'],
|
|
||||||
'*.' : ['A', 'AAAA'],
|
|
||||||
'pubsub.' : ['A', 'AAAA', 'CNAME'],
|
|
||||||
'muc.' : ['A', 'AAAA', 'CNAME'],
|
|
||||||
'vjud.' : ['A', 'AAAA', 'CNAME'],
|
|
||||||
'xmpp-upload.' : ['A', 'AAAA', 'CNAME'],
|
|
||||||
'_xmpp-client._tcp.' : ['SRV'],
|
|
||||||
'_xmpp-server._tcp.' : ['SRV'],
|
|
||||||
'mail._domainkey.' : ['TXT'],
|
|
||||||
'_dmarc.' : ['TXT']
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
### Script ###
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import psycopg2
|
import psycopg2
|
||||||
from urllib import urlopen
|
from urllib import urlopen
|
||||||
|
import json
|
||||||
|
|
||||||
|
with open('config.json') as config_file:
|
||||||
|
config = json.load(config_file)
|
||||||
|
|
||||||
|
conf_file = '/etc/bind/named.conf.local' # Include this filename in '/etc/bind/named.conf'
|
||||||
|
zone_dir = '/var/lib/bind/' # Do not forget the trailing '/'
|
||||||
|
database = config_file["dabase_url"]
|
||||||
|
base_url = config_file["base_url"]
|
||||||
|
ns0 = config_file["ns0"]
|
||||||
|
ns1 = config_file["ns1"]
|
||||||
|
rname = config_file["rname"] # Responsible person (https://tools.ietf.org/html/rfc1035#section-3.3.13)
|
||||||
|
master_key = config_file["master_key"]
|
||||||
|
dyndns_domains = config_file['dyndns_domains']
|
||||||
|
allowed_operations = config_files["allowed_operations"]
|
||||||
|
|
||||||
# Bind configuration
|
with psycopg2.connect(database) as postgresql_connection:
|
||||||
lines = ['// Generated by Dynette CRON']
|
|
||||||
|
|
||||||
with psycopg2.connect(postgresql_dsn) as postgresql_connection:
|
|
||||||
with postgresql_connection.cursor() as psql:
|
with postgresql_connection.cursor() as psql:
|
||||||
# look in the job queue if we have tasks to handle
|
# look in the job queue if we have tasks to handle
|
||||||
need_rewrite = False
|
need_rewrite = False
|
||||||
|
@ -69,70 +47,68 @@ with psycopg2.connect(postgresql_dsn) as postgresql_connection:
|
||||||
# job could be added just after we read them all
|
# job could be added just after we read them all
|
||||||
psql.execute("DELETE FROM jobqueues;")
|
psql.execute("DELETE FROM jobqueues;")
|
||||||
|
|
||||||
# Loop through Dynette servers
|
# Init zone for dyndns domains that don't already exists
|
||||||
for url in subs_urls:
|
for domain in dyndns_domains:
|
||||||
|
if os.path.exists(zone_dir + domain +'.db'):
|
||||||
|
continue
|
||||||
|
|
||||||
lines.extend([
|
db_lines = f"""
|
||||||
'key dynette. {',
|
$ORIGIN .
|
||||||
' algorithm hmac-md5;',
|
$TTL 10 ; 10 seconds
|
||||||
' secret "'+ master_key +'";',
|
{domain}. IN SOA {ns0}. {rname}. (
|
||||||
'};',
|
18 ; serial
|
||||||
])
|
10800 ; refresh (3 hours)
|
||||||
|
3600 ; retry (1 hour)
|
||||||
|
604800 ; expire (1 week)
|
||||||
|
10 ; minimum (10 seconds)
|
||||||
|
|
||||||
# Get available DynDNS domains
|
$TTL 3600 ; 1 hour
|
||||||
domains = json.loads(str(urlopen(url +'/domains').read()))
|
NS {ns0}.
|
||||||
for domain in domains:
|
NS {ns1}.
|
||||||
|
|
||||||
# Create zone database if not present
|
$ORIGIN {domain}.
|
||||||
if not os.path.exists(zone_dir + domain +'.db'):
|
"""
|
||||||
db_lines = [
|
with open(zone_dir + domain +'.db', 'w') as zone:
|
||||||
'$ORIGIN .',
|
zone.write(db_lines)
|
||||||
'$TTL 10 ; 10 seconds',
|
|
||||||
domain+'. IN SOA '+ ns0 +'. '+ rname +'. (',
|
|
||||||
' 18 ; serial',
|
|
||||||
' 10800 ; refresh (3 hours)',
|
|
||||||
' 3600 ; retry (1 hour)',
|
|
||||||
' 604800 ; expire (1 week)',
|
|
||||||
' 10 ; minimum (10 seconds)',
|
|
||||||
' )',
|
|
||||||
'$TTL 3600 ; 1 hour',
|
|
||||||
' NS '+ ns0 +'.',
|
|
||||||
' NS '+ ns1 +'.',
|
|
||||||
'',
|
|
||||||
'$ORIGIN '+ domain +'.',
|
|
||||||
]
|
|
||||||
with open(zone_dir + domain +'.db', 'w') as zone:
|
|
||||||
for line in db_lines:
|
|
||||||
zone.write(line + '\n')
|
|
||||||
|
|
||||||
lines.extend([
|
# Update /etc/bind/named.conf.local
|
||||||
'zone "'+ domain +'" {',
|
# that provide permissions for all regirested subdomains on allowed zone file elements
|
||||||
' type master;',
|
# and registers the key for bind9, later used to authenticate nsupdate from the clients
|
||||||
' file "'+ zone_dir + domain +'.db"; ',
|
lines = ['// Generated by Dynette CRON']
|
||||||
' update-policy {',
|
lines.append(f"""
|
||||||
' grant dynette. wildcard *.'+ domain +'. ANY;',
|
key dynette. {
|
||||||
])
|
algorithm hmac-md5;
|
||||||
|
secret "{master_key}";
|
||||||
|
};
|
||||||
|
""")
|
||||||
|
for domain in dyndns_domains:
|
||||||
|
lines.append(f"""
|
||||||
|
zone "{domain}" {
|
||||||
|
type master;
|
||||||
|
file {zone_dir}{domain}.db;
|
||||||
|
update-policy {
|
||||||
|
grant dynette. wildcard *.{domain}. ANY;""")
|
||||||
|
|
||||||
# Get registered sub-domains
|
# Get registered sub-domains
|
||||||
result = json.loads(str(urlopen(url +'/all/'+ domain).read()))
|
registered_subdomains = json.loads(str(urlopen(base_url +'/all/'+ domain).read()))
|
||||||
for entry in result:
|
for entry in registered_subdomains:
|
||||||
for subd, type in allowed_operations.items():
|
for subd, types in allowed_operations.items():
|
||||||
if subd == '.': subd = ''
|
if subd == '.':
|
||||||
lines.append(' grant '+ entry['subdomain'] +'. name '+ subd + entry['subdomain'] +'. ' + ' '.join(type) +';')
|
subd = ''
|
||||||
|
all_types = ' '.join(types)
|
||||||
|
lines.append(f" grant {entry['subdomain']}. name {subd}{entry['subdomain']}. {all_types};")
|
||||||
|
|
||||||
lines.extend([
|
lines.append(f"""
|
||||||
' };',
|
};
|
||||||
'};'
|
};""")
|
||||||
'',
|
|
||||||
])
|
|
||||||
|
|
||||||
for entry in result:
|
for entry in registered_subdomains:
|
||||||
lines.extend([
|
lines.append(f"""
|
||||||
'key '+ entry['subdomain'] +'. {',
|
key {entry['subdomain']}. {
|
||||||
' algorithm ' + entry['key_algo'] + ';',
|
algorithm {entry['key_algo']};
|
||||||
' secret "'+ entry['public_key'] +'";',
|
secret {entry['public_key']};
|
||||||
'};',
|
};
|
||||||
])
|
"""
|
||||||
|
|
||||||
# update bind9 zone
|
# update bind9 zone
|
||||||
if need_rewrite:
|
if need_rewrite:
|
||||||
|
|
|
@ -21,7 +21,7 @@ rescue => err
|
||||||
end
|
end
|
||||||
|
|
||||||
DataMapper.setup(:default, ENV['DATABASE_URL'] || config['database_url'])
|
DataMapper.setup(:default, ENV['DATABASE_URL'] || config['database_url'])
|
||||||
DOMAINS = config['domains']
|
DOMAINS = config['dyndns_domains']
|
||||||
ALLOWED_IP = ["127.0.0.1"]
|
ALLOWED_IP = ["127.0.0.1"]
|
||||||
|
|
||||||
###############
|
###############
|
||||||
|
|
Loading…
Add table
Reference in a new issue