Files
CyberPanel/plogical/dnsUtilities.py

638 lines
25 KiB
Python
Raw Normal View History

2019-12-10 23:04:24 +05:00
#!/usr/local/CyberCP/bin/python
2018-06-01 02:08:21 +05:00
import os,sys
sys.path.append('/usr/local/CyberCP')
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
2019-07-18 14:08:00 +05:00
try:
django.setup()
except:
pass
2019-12-15 13:30:40 +05:00
from plogical import CyberCPLogFileWriter as logging
2017-10-24 19:16:36 +05:00
import subprocess
2018-06-01 02:08:21 +05:00
import shlex
2019-07-18 14:08:00 +05:00
try:
from dns.models import Domains,Records
from manageServices.models import PDNSStatus, SlaveServers
except:
pass
2020-02-08 23:09:18 +05:00
import CloudFlare
2020-02-14 00:26:51 +05:00
from plogical.processUtilities import ProcessUtilities
2017-10-24 19:16:36 +05:00
class DNS:
nsd_base = "/etc/nsd/nsd.conf"
zones_base_dir = "/usr/local/lsws/conf/zones/"
create_zone_dir = "/usr/local/lsws/conf/zones"
2019-08-22 14:07:46 +05:00
defaultNameServersPath = '/home/cyberpanel/defaultNameservers'
2020-02-08 23:09:18 +05:00
CFPath = '/home/cyberpanel/CloudFlare'
2017-10-24 19:16:36 +05:00
2018-06-01 02:08:21 +05:00
## DNS Functions
2017-10-24 19:16:36 +05:00
2020-02-14 00:26:51 +05:00
def loadCFKeys(self):
cfFile = '%s%s' % (DNS.CFPath, self.admin.userName)
data = open(cfFile, 'r').readlines()
self.email = data[0].rstrip('\n')
self.key = data[1].rstrip('\n')
self.status = data[2].rstrip('\n')
def cfTemplate(self, zoneDomain, admin, enableCheck = None):
try:
self.admin = admin
## Get zone
self.loadCFKeys()
if enableCheck == None:
pass
else:
if self.status == 'Enable':
pass
else:
return 0, 'Sync not enabled.'
cf = CloudFlare.CloudFlare(email=self.email, token=self.key)
try:
params = {'name': zoneDomain, 'per_page': 50}
zones = cf.zones.get(params=params)
for zone in sorted(zones, key=lambda v: v['name']):
zone = zone['id']
domain = Domains.objects.get(name=zoneDomain)
records = Records.objects.filter(domain_id=domain.id)
for record in records:
DNS.createDNSRecordCloudFlare(cf, zone, record.name, record.type, record.content, record.prio,
record.ttl)
return 1, None
except CloudFlare.exceptions.CloudFlareAPIError as e:
logging.CyberCPLogFileWriter.writeToFile(str(e))
except Exception as e:
logging.CyberCPLogFileWriter.writeToFile(str(e))
try:
zone_info = cf.zones.post(data={'jump_start': False, 'name': zoneDomain})
zone = zone_info['id']
domain = Domains.objects.get(name=zoneDomain)
records = Records.objects.filter(domain_id=domain.id)
for record in records:
DNS.createDNSRecordCloudFlare(cf, zone, record.name, record.type, record.content, record.prio,
record.ttl)
return 1, None
except CloudFlare.exceptions.CloudFlareAPIError as e:
return 0, str(e)
except Exception as e:
return 0, str(e)
except BaseException as msg:
return 0, str(e)
2017-10-24 19:16:36 +05:00
@staticmethod
2018-06-01 02:08:21 +05:00
def dnsTemplate(domain, admin):
2017-10-24 19:16:36 +05:00
try:
2018-06-01 02:08:21 +05:00
ipFile = "/etc/cyberpanel/machineIP"
f = open(ipFile)
ipData = f.read()
ipAddress = ipData.split('\n', 1)[0]
import tldextract
extractDomain = tldextract.extract(domain)
topLevelDomain = extractDomain.domain + '.' + extractDomain.suffix
subDomain = extractDomain.subdomain
if len(subDomain) == 0:
if Domains.objects.filter(name=topLevelDomain).count() == 0:
2019-02-04 01:03:18 +05:00
try:
pdns = PDNSStatus.objects.get(pk=1)
if pdns.type == 'MASTER':
zone = Domains(admin=admin, name=topLevelDomain, type="MASTER")
2019-06-27 13:07:47 +05:00
zone.save()
for items in SlaveServers.objects.all():
record = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="NS",
content=items.slaveServer,
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
2019-02-04 01:03:18 +05:00
else:
zone = Domains(admin=admin, name=topLevelDomain, type="NATIVE")
except:
zone = Domains(admin=admin, name=topLevelDomain, type="NATIVE")
2018-06-01 02:08:21 +05:00
zone.save()
2019-06-27 13:07:47 +05:00
if zone.type == 'NATIVE':
2019-08-22 14:07:46 +05:00
if os.path.exists(DNS.defaultNameServersPath):
defaultNS = open(DNS.defaultNameServersPath, 'r').readlines()
2019-06-27 13:07:47 +05:00
2019-08-22 14:07:46 +05:00
for items in defaultNS:
2020-01-31 18:00:39 +05:00
if len(items) > 5:
record = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="NS",
content=items.rstrip('\n'),
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
2019-08-22 14:07:46 +05:00
else:
record = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="NS",
content='ns1.%s' % (topLevelDomain),
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
record = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="NS",
content='ns2.%s' % (topLevelDomain),
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
2019-06-26 03:57:16 +05:00
2018-06-01 02:08:21 +05:00
content = "ns1." + topLevelDomain + " hostmaster." + topLevelDomain + " 1 10800 3600 604800 3600"
soaRecord = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="SOA",
content=content,
ttl=3600,
prio=0,
disabled=0,
auth=1)
soaRecord.save()
## Main A record.
record = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="A",
content=ipAddress,
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
# CNAME Records.
cNameValue = "www." + topLevelDomain
record = Records(domainOwner=zone,
domain_id=zone.id,
name=cNameValue,
type="CNAME",
content=topLevelDomain,
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
cNameValue = "ftp." + topLevelDomain
record = Records(domainOwner=zone,
domain_id=zone.id,
name=cNameValue,
type="CNAME",
content=topLevelDomain,
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
## MX Record.
mxValue = "mail." + topLevelDomain
record = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="MX",
content=mxValue,
ttl=3600,
prio="10",
disabled=0,
auth=1)
record.save()
record = Records(domainOwner=zone,
domain_id=zone.id,
name=mxValue,
type="A",
content=ipAddress,
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
## TXT Records for mail
record = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="TXT",
content="v=spf1 a mx ip4:" + ipAddress + " ~all",
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
record = Records(domainOwner=zone,
domain_id=zone.id,
name="_dmarc." + topLevelDomain,
type="TXT",
content="v=DMARC1; p=none",
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
record = Records(domainOwner=zone,
domain_id=zone.id,
name="_domainkey." + topLevelDomain,
type="TXT",
content="t=y; o=~;",
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
2017-10-24 19:16:36 +05:00
else:
2018-06-01 02:08:21 +05:00
if Domains.objects.filter(name=topLevelDomain).count() == 0:
2019-02-04 01:03:18 +05:00
try:
pdns = PDNSStatus.objects.get(pk=1)
if pdns.type == 'MASTER':
zone = Domains(admin=admin, name=topLevelDomain, type="MASTER")
else:
zone = Domains(admin=admin, name=topLevelDomain, type="NATIVE")
except:
zone = Domains(admin=admin, name=topLevelDomain, type="NATIVE")
2018-06-01 02:08:21 +05:00
content = "ns1." + topLevelDomain + " hostmaster." + topLevelDomain + " 1 10800 3600 604800 3600"
soaRecord = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="SOA",
content=content,
ttl=3600,
prio=0,
disabled=0,
auth=1)
soaRecord.save()
## Main A record.
record = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="A",
content=ipAddress,
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
# CNAME Records.
cNameValue = "www." + topLevelDomain
record = Records(domainOwner=zone,
domain_id=zone.id,
name=cNameValue,
type="CNAME",
content=topLevelDomain,
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
cNameValue = "ftp." + topLevelDomain
record = Records(domainOwner=zone,
domain_id=zone.id,
name=cNameValue,
type="CNAME",
content=topLevelDomain,
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
## MX Record.
mxValue = "mail." + topLevelDomain
record = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="MX",
content=mxValue,
ttl=3600,
prio="10",
disabled=0,
auth=1)
record.save()
record = Records(domainOwner=zone,
domain_id=zone.id,
name=mxValue,
type="A",
content=ipAddress,
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
2018-06-11 21:04:55 +05:00
## TXT Records for mail
record = Records(domainOwner=zone,
domain_id=zone.id,
name=topLevelDomain,
type="TXT",
content="v=spf1 a mx ip4:" + ipAddress + " ~all",
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
record = Records(domainOwner=zone,
domain_id=zone.id,
name="_dmarc." + topLevelDomain,
type="TXT",
content="v=DMARC1; p=none",
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
record = Records(domainOwner=zone,
domain_id=zone.id,
name="_domainkey." + topLevelDomain,
type="TXT",
content="t=y; o=~;",
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
2018-06-01 02:08:21 +05:00
## Creating sub-domain level record.
zone = Domains.objects.get(name=topLevelDomain)
actualSubDomain = subDomain + "." + topLevelDomain
## Main A record.
DNS.createDNSRecord(zone, actualSubDomain, "A", ipAddress, 0, 3600)
# CNAME Records.
cNameValue = "www." + actualSubDomain
DNS.createDNSRecord(zone, cNameValue, "CNAME", actualSubDomain, 0, 3600)
2017-10-24 19:16:36 +05:00
2018-12-13 04:23:08 +05:00
if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu:
command = 'sudo systemctl restart pdns'
ProcessUtilities.executioner(command)
2020-02-14 00:26:51 +05:00
dns = DNS()
dns.cfTemplate(domain, admin)
2019-12-10 15:09:10 +05:00
except BaseException as msg:
2018-06-01 02:08:21 +05:00
logging.CyberCPLogFileWriter.writeToFile(
"We had errors while creating DNS records for: " + domain + ". Error message: " + str(msg))
2017-10-24 19:16:36 +05:00
@staticmethod
2018-06-01 02:08:21 +05:00
def createDKIMRecords(domain):
2017-10-24 19:16:36 +05:00
try:
2018-06-01 02:08:21 +05:00
import tldextract
2017-10-24 19:16:36 +05:00
2018-06-01 02:08:21 +05:00
extractDomain = tldextract.extract(domain)
topLevelDomain = extractDomain.domain + '.' + extractDomain.suffix
2017-10-24 19:16:36 +05:00
2018-06-01 02:08:21 +05:00
zone = Domains.objects.get(name=topLevelDomain)
2017-10-24 19:16:36 +05:00
2018-06-01 02:08:21 +05:00
path = "/etc/opendkim/keys/" + topLevelDomain + "/default.txt"
2020-01-30 17:58:56 +05:00
command = "cat " + path
2019-12-15 13:30:40 +05:00
output = subprocess.check_output(shlex.split(command)).decode("utf-8")
2018-11-07 22:50:14 +05:00
leftIndex = output.index('(') + 2
rightIndex = output.rindex(')') - 1
2017-10-24 19:16:36 +05:00
2018-06-01 02:08:21 +05:00
record = Records(domainOwner=zone,
domain_id=zone.id,
name="default._domainkey." + topLevelDomain,
type="TXT",
2018-11-07 22:50:14 +05:00
content=output[leftIndex:rightIndex],
2018-06-01 02:08:21 +05:00
ttl=3600,
prio=0,
disabled=0,
auth=1)
record.save()
2017-10-24 19:16:36 +05:00
2018-12-13 04:23:08 +05:00
if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu:
2020-01-30 17:58:56 +05:00
command = ' systemctl restart pdns'
ProcessUtiities.executioner(command)
2018-12-13 04:23:08 +05:00
2019-12-10 15:09:10 +05:00
except BaseException as msg:
2018-06-01 02:08:21 +05:00
logging.CyberCPLogFileWriter.writeToFile(
2018-06-11 21:04:55 +05:00
"We had errors while creating DKIM record for: " + domain + ". Error message: " + str(msg))
2017-10-24 19:16:36 +05:00
2018-06-05 00:53:45 +05:00
@staticmethod
def getZoneObject(virtualHostName):
try:
return Domains.objects.get(name=virtualHostName)
except:
return 0
2020-02-10 12:00:16 +05:00
@staticmethod
def createDNSRecordCloudFlare(cf, zone, name, type, value, priority, ttl):
2020-02-12 14:44:38 +05:00
try:
2020-02-12 21:29:50 +05:00
if value.find('DKIM')> -1:
value = value.replace('\n\t', '')
value = value.replace('"', '')
2020-02-12 14:44:38 +05:00
dns_record = {'name': name, 'type': type, 'content': value, 'ttl': ttl, 'priority': priority}
r = cf.zones.dns_records.post(zone, data=dns_record)
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
2020-02-10 12:00:16 +05:00
2017-10-24 19:16:36 +05:00
@staticmethod
2018-06-01 02:08:21 +05:00
def createDNSRecord(zone, name, type, value, priority, ttl):
2018-06-11 21:04:55 +05:00
try:
2019-06-27 13:07:47 +05:00
if zone.type == 'MASTER':
getSOA = Records.objects.get(domainOwner=zone, type='SOA')
soaContent = getSOA.content.split(' ')
soaContent[2] = str(int(soaContent[2]) + 1)
getSOA.content = " ".join(soaContent)
getSOA.save()
2018-06-11 21:04:55 +05:00
if type == 'NS':
if Records.objects.filter(name=name, type=type, content=value).count() == 0:
record = Records(domainOwner=zone,
domain_id=zone.id,
name=name,
type=type,
content=value,
ttl=ttl,
prio=priority,
disabled=0,
auth=1)
record.save()
2018-12-13 04:23:08 +05:00
if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu:
command = 'sudo systemctl restart pdns'
ProcessUtilities.executioner(command)
2018-06-11 21:04:55 +05:00
return
2018-06-05 00:53:45 +05:00
2018-11-06 00:19:58 +05:00
if type == 'TXT':
if Records.objects.filter(name=name, type=type, content=value).count() == 0:
record = Records(domainOwner=zone,
domain_id=zone.id,
name=name,
type=type,
content=value,
ttl=ttl,
prio=priority,
disabled=0,
auth=1)
record.save()
2018-12-13 04:23:08 +05:00
if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu:
command = 'sudo systemctl restart pdns'
ProcessUtilities.executioner(command)
2018-11-06 00:19:58 +05:00
return
2018-06-27 00:16:50 +05:00
if type == 'MX':
record = Records(domainOwner=zone,
domain_id=zone.id,
name=name,
type=type,
content=value,
ttl=ttl,
prio=priority,
disabled=0,
auth=1)
record.save()
2018-12-13 04:23:08 +05:00
if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu:
command = 'sudo systemctl restart pdns'
ProcessUtilities.executioner(command)
2018-11-06 00:19:58 +05:00
return
2018-06-27 00:16:50 +05:00
2018-06-11 21:04:55 +05:00
if Records.objects.filter(name=name, type=type).count() == 0:
2018-06-05 00:53:45 +05:00
record = Records(domainOwner=zone,
domain_id=zone.id,
name=name,
type=type,
content=value,
ttl=ttl,
prio=priority,
disabled=0,
auth=1)
record.save()
2018-12-13 04:23:08 +05:00
if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu:
command = 'sudo systemctl restart pdns'
ProcessUtilities.executioner(command)
2019-12-10 15:09:10 +05:00
except BaseException as msg:
2018-06-11 21:04:55 +05:00
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [createDNSRecord]")
2017-10-24 19:16:36 +05:00
@staticmethod
2018-06-01 02:08:21 +05:00
def deleteDNSZone(virtualHostName):
2017-10-24 19:16:36 +05:00
try:
2018-06-01 02:08:21 +05:00
delZone = Domains.objects.get(name=virtualHostName)
delZone.delete()
except:
## There does not exist a zone for this domain.
2018-06-05 00:53:45 +05:00
pass
@staticmethod
def createDNSZone(virtualHostName, admin):
try:
zone = Domains(admin=admin, name=virtualHostName, type="NATIVE")
zone.save()
except:
## There does not exist a zone for this domain.
pass
@staticmethod
def getDNSRecords(virtualHostName):
try:
zone = Domains.objects.get(name=virtualHostName)
zone.save()
return zone.records_set.all()
except:
## There does not exist a zone for this domain.
pass
@staticmethod
def getDNSZones():
try:
return Domains.objects.all()
except:
pass
@staticmethod
def deleteDNSRecord(recordID):
try:
delRecord = Records.objects.get(id=recordID)
delRecord.delete()
except:
## There does not exist a zone for this domain.
pass