Merge pull request #1754 from master3395/v2.5.5-dev

V2.5.5 dev
This commit is contained in:
Master3395
2026-04-07 18:55:21 +02:00
committed by GitHub
5 changed files with 88 additions and 27 deletions

View File

@@ -396,8 +396,9 @@ class ApacheVhost:
logging.writeToFile(str(msg))
@staticmethod
def perHostVirtualConfOLS(vhFile, administratorEmail):
# General Configurations tab
def perHostVirtualConfOLS(vhFile, administratorEmail, documentRoot=None):
# General Configurations tab. Child domains use vhRoot=master path in olsChildMainConf, so docRoot
# must be the real document root (not $VH_ROOT/public_html) for content and ACME HTTP-01.
try:
confFile = open(vhFile, "w+")
virtualHostName = vhFile.split('/')[6]
@@ -405,6 +406,13 @@ class ApacheVhost:
currentConf = vhostConfs.OLSLBConf
currentConf = currentConf.replace('{adminEmails}', administratorEmail)
currentConf = currentConf.replace('{domain}', virtualHostName)
if documentRoot:
root = documentRoot.rstrip('/')
currentConf = currentConf.replace('{olsDocRoot}', root)
currentConf = currentConf.replace('{olsAcmeChallengeRoot}', root + '/.well-known/acme-challenge')
else:
currentConf = currentConf.replace('{olsDocRoot}', '$VH_ROOT/public_html')
currentConf = currentConf.replace('{olsAcmeChallengeRoot}', '$VH_ROOT/public_html/.well-known/acme-challenge')
confFile.write(currentConf)
confFile.close()

View File

@@ -326,7 +326,9 @@ class DNS:
# auth=1)
# record.save()
DNS.createDNSRecord(zone, "_dmarc." + topLevelDomain, "TXT", "v=DMARC1; p=none;", 0, 3600)
# Apex DMARC: do not auto-add p=none here — use one TXT at _dmarc.<apex> in Cloudflare/DNS
# to avoid conflicting duplicate DMARC records (invalid per RFC 7489).
# DNS.createDNSRecord(zone, "_dmarc." + topLevelDomain, "TXT", "v=DMARC1; p=none;", 0, 3600)
# record = Records(domainOwner=zone,
# domain_id=zone.id,
@@ -489,7 +491,9 @@ class DNS:
# auth=1)
# record.save()
DNS.createDNSRecord(zone, "_dmarc." + topLevelDomain, "TXT", "v=DMARC1; p=none;", 0, 3600)
# Apex DMARC: do not auto-add p=none here — use one TXT at _dmarc.<apex> in Cloudflare/DNS
# to avoid conflicting duplicate DMARC records (invalid per RFC 7489).
# DNS.createDNSRecord(zone, "_dmarc." + topLevelDomain, "TXT", "v=DMARC1; p=none;", 0, 3600)
# record = Records(domainOwner=zone,
# domain_id=zone.id,
@@ -585,7 +589,9 @@ class DNS:
# auth=1)
# record.save()
DNS.createDNSRecord(zone, "_dmarc." + actualSubDomain, "TXT", "v=DMARC1; p=none;", 0, 3600)
# Do not auto-create subdomain _dmarc: one organizational policy at _dmarc.<apex> is enough for
# typical setups; avoids dozens of p=none records and Cloudflare clutter.
# DNS.createDNSRecord(zone, "_dmarc." + actualSubDomain, "TXT", "v=DMARC1; p=none;", 0, 3600)
# record = Records(domainOwner=zone,
# domain_id=zone.id,
@@ -889,7 +895,7 @@ class DNS:
for zone in sorted(zones, key=lambda v: v['name']):
zone = zone['id']
DNS.createDNSRecordCloudFlare(cf, zone, name, type, value, ttl, priority)
DNS.createDNSRecordCloudFlare(cf, zone, name, type, value, priority, ttl)
except CloudFlare.exceptions.CloudFlareAPIError as e:
logging.CyberCPLogFileWriter.writeToFile(str(e))
@@ -985,12 +991,25 @@ class DNS:
# Get all DNS records for this zone
try:
dns_records = cf.zones.dns_records.get(zone_id)
# For subdomains, only delete records that match this subdomain (name can be "status" or "status.newstargeted.com")
# For subdomains, delete the FQDN and any deeper names (mail.sub, www.sub, _dmarc.sub, etc.)
if is_subdomain:
subdomain_label = domainName.split('.')[0]
base_fqdn = domainName.rstrip('.').lower()
zone_fqdn = (zone_name or '').rstrip('.').lower()
def record_to_fqdn(record_name):
n = (record_name or '').rstrip('.').lower()
if not zone_fqdn:
return n
if n == zone_fqdn or n.endswith('.' + zone_fqdn):
return n
return ('%s.%s' % (n, zone_fqdn)).rstrip('.')
def record_matches(r):
n = (r.get('name') or '').rstrip('.')
return n == domainName or n == subdomain_label
fqdn = record_to_fqdn(r.get('name') or '')
if fqdn == base_fqdn:
return True
return fqdn.endswith('.' + base_fqdn)
to_delete = [r for r in dns_records if record_matches(r)]
else:
to_delete = list(dns_records)

View File

@@ -343,7 +343,7 @@ retryTimeout 0
respBuffer 0
}
"""
OLSLBConf = """docRoot $VH_ROOT/public_html
OLSLBConf = """docRoot {olsDocRoot}
vhDomain $VH_NAME
vhAliases www.$VH_NAME
adminEmails {adminEmails}
@@ -371,7 +371,7 @@ accesslog $VH_ROOT/logs/$VH_NAME.access_log {
}
context /.well-known/acme-challenge {
location $VH_ROOT/public_html/.well-known/acme-challenge
location {olsAcmeChallengeRoot}
allowBrowse 1
rewrite {

View File

@@ -1843,11 +1843,7 @@ local_name %s {
raise BaseException(retValues[1])
## Now restart litespeed after initial configurations are done
if LimitsCheck:
website = ChildDomains(master=master, domain=virtualHostName, path=path, phpSelection=phpVersion,
ssl=ssl, alais=alias)
website.save()
## ChildDomains row is saved only after SSL/Apache succeed (avoids orphan DB rows on failure)
if ssl == 1:
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Creating SSL..,50')
@@ -1883,7 +1879,7 @@ local_name %s {
if result[0] == 0:
raise BaseException(result[1])
else:
ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, master.adminEmail)
ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, master.adminEmail, path)
installUtilities.installUtilities.reStartLiteSpeed()
php = PHPManager.getPHPString(phpVersion)
@@ -1900,10 +1896,20 @@ local_name %s {
if dkimCheck == 1:
DNS.createDKIMRecords(virtualHostName)
if LimitsCheck:
website = ChildDomains(master=master, domain=virtualHostName, path=path, phpSelection=phpVersion,
ssl=ssl, alais=alias)
website.save()
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Domain successfully created. [200]')
return 1, "None"
except BaseException as msg:
try:
if ChildDomains.objects.filter(domain=virtualHostName).exists():
ChildDomains.objects.filter(domain=virtualHostName).delete()
except BaseException:
pass
if ACLManager.FindIfChild() == 0:
numberOfWebsites = Websites.objects.count() + ChildDomains.objects.count()
vhost.deleteCoreConf(virtualHostName, numberOfWebsites)
@@ -1981,11 +1987,11 @@ local_name %s {
if child:
# Handle None values for child domains
admin_email = website.master.adminEmail if website.master.adminEmail else website.master.admin.email
ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, admin_email)
ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, admin_email, website.path)
else:
# Handle None values for main domains
admin_email = website.adminEmail if website.adminEmail else website.admin.email
ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, admin_email)
ApacheVhost.perHostVirtualConfOLS(completePathToConfigFile, admin_email, None)
if child:
# Handle None values for child domains
@@ -2423,9 +2429,14 @@ def main():
except:
aliasDomain = 0
virtualHostUtilities.createDomain(args.masterDomain, args.virtualHostName, args.phpVersion, args.path,
int(args.ssl), dkimCheck, openBasedir, args.websiteOwner, apache,
tempStatusPath, 1, aliasDomain)
ret = virtualHostUtilities.createDomain(args.masterDomain, args.virtualHostName, args.phpVersion, args.path,
int(args.ssl), dkimCheck, openBasedir, args.websiteOwner, apache,
tempStatusPath, 1, aliasDomain)
if ret[0] == 1:
print("1," + str(ret[1]))
sys.exit(0)
print("0," + str(ret[1]))
sys.exit(1)
elif args.function == "issueSSL":
virtualHostUtilities.issueSSL(args.virtualHostName, args.path, args.administratorEmail)
elif args.function == "issueSSLv2":

View File

@@ -2487,11 +2487,34 @@ Require valid-user
+ " --openBasedir " + str(data['openBasedir']) + ' --path ' + path + ' --websiteOwner ' \
+ admin.userName + ' --tempStatusPath ' + tempStatusPath + " --apache " + apacheBackend + f' --aliasDomain {str(alias)}'
ProcessUtilities.popenExecutioner(execPath)
time.sleep(2)
create_result = subprocess.run(execPath, shell=True, capture_output=True, text=True, timeout=1800)
st = ''
try:
if os.path.isfile(tempStatusPath):
with open(tempStatusPath, 'r', encoding='utf-8', errors='replace') as sf:
st = sf.read().strip()
except BaseException:
st = ''
out = (create_result.stdout or '').strip()
last_line = out.split('\n')[-1] if out else ''
cli_ok = last_line.startswith('1,')
cli_fail = last_line.startswith('0,')
status_ok = ('Domain successfully created.' in st and '[200]' in st)
status_fail = ('[404]' in st)
data_ret = {'status': 1, 'createWebSiteStatus': 1, 'error_message': "None",
'tempStatusPath': tempStatusPath}
if create_result.returncode == 0 and (cli_ok or status_ok) and not status_fail:
data_ret = {'status': 1, 'createWebSiteStatus': 1, 'error_message': "None",
'tempStatusPath': tempStatusPath}
else:
err_msg = 'Child domain creation failed.'
if cli_fail and len(last_line) > 2:
err_msg = last_line.split(',', 1)[1].strip() or err_msg
elif st:
err_msg = st.replace('. [404]', '').strip() or err_msg
elif create_result.stderr and create_result.stderr.strip():
err_msg = create_result.stderr.strip()[:500]
data_ret = {'status': 0, 'createWebSiteStatus': 0, 'error_message': err_msg[:2000],
'tempStatusPath': tempStatusPath}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)