mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-12-16 05:19:43 +01:00
Compare commits
3 Commits
bbd0c4e136
...
a2f9cf99eb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2f9cf99eb | ||
|
|
ae020ece7b | ||
|
|
836a6e26a7 |
@@ -1020,6 +1020,22 @@ class FirewallManager:
|
||||
if owaspInstalled == 1 and comodoInstalled == 1:
|
||||
break
|
||||
|
||||
# Also check rules.conf for manual OWASP installations
|
||||
if owaspInstalled == 0:
|
||||
rulesConfPath = os.path.join(virtualHostUtilities.Server_root, "conf/modsec/rules.conf")
|
||||
if os.path.exists(rulesConfPath):
|
||||
try:
|
||||
command = "sudo cat " + rulesConfPath
|
||||
rulesConfig = ProcessUtilities.outputExecutioner(command).splitlines()
|
||||
for items in rulesConfig:
|
||||
# Check for OWASP includes in rules.conf (case-insensitive)
|
||||
if ('owasp' in items.lower() or 'crs-setup' in items.lower()) and \
|
||||
('include' in items.lower() or 'modsecurity_rules_file' in items.lower()):
|
||||
owaspInstalled = 1
|
||||
break
|
||||
except:
|
||||
pass
|
||||
|
||||
final_dic = {
|
||||
'modSecInstalled': 1,
|
||||
'owaspInstalled': owaspInstalled,
|
||||
|
||||
@@ -1366,7 +1366,8 @@ app.controller('modSecRulesPack', function ($scope, $http, $timeout, $window) {
|
||||
$scope.installationFailed = true;
|
||||
$scope.installationSuccess = false;
|
||||
|
||||
getOWASPAndComodoStatus(false);
|
||||
// Update toggle state immediately to reflect installation result
|
||||
getOWASPAndComodoStatus(true);
|
||||
|
||||
} else {
|
||||
$scope.modsecLoading = true;
|
||||
@@ -1379,6 +1380,9 @@ app.controller('modSecRulesPack', function ($scope, $http, $timeout, $window) {
|
||||
$scope.installationSuccess = true;
|
||||
|
||||
$scope.errorMessage = response.data.error_message;
|
||||
|
||||
// Update toggle to reflect failed installation (will show OFF)
|
||||
getOWASPAndComodoStatus(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -761,6 +761,8 @@ class ACLManager:
|
||||
else:
|
||||
if childDomain.master.admin.owner == admin.pk:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
except:
|
||||
domainName = Websites.objects.get(domain=domain)
|
||||
|
||||
@@ -582,6 +582,12 @@ InternalHosts refile:/etc/opendkim/TrustedHosts
|
||||
|
||||
postfixFilePath = "/etc/postfix/main.cf"
|
||||
|
||||
# Check if postfix main.cf exists before configuring
|
||||
if not os.path.exists(postfixFilePath):
|
||||
logging.CyberCPLogFileWriter.writeToFile(f"configureOpenDKIM: {postfixFilePath} not found, skipping postfix DKIM configuration")
|
||||
print("1,Postfix not installed")
|
||||
return
|
||||
|
||||
configData = """
|
||||
smtpd_milters = inet:127.0.0.1:8891
|
||||
non_smtpd_milters = $smtpd_milters
|
||||
|
||||
@@ -405,6 +405,7 @@ modsecurity_rules_file /usr/local/lsws/conf/modsec/rules.conf
|
||||
command = 'mkdir -p /usr/local/lsws/conf/modsec'
|
||||
result = subprocess.call(shlex.split(command))
|
||||
if result != 0:
|
||||
logging.CyberCPLogFileWriter.writeToFile("Failed to create modsec directory [setupOWASPRules]")
|
||||
return 0
|
||||
|
||||
if os.path.exists(pathToOWASFolderNew):
|
||||
@@ -420,30 +421,35 @@ modsecurity_rules_file /usr/local/lsws/conf/modsec/rules.conf
|
||||
result = subprocess.call(shlex.split(command))
|
||||
|
||||
if result != 0:
|
||||
logging.CyberCPLogFileWriter.writeToFile("Failed to download OWASP CRS from GitHub. Check internet connection. [setupOWASPRules]")
|
||||
return 0
|
||||
|
||||
command = "unzip -o /usr/local/lsws/conf/modsec/owasp.zip -d /usr/local/lsws/conf/modsec/"
|
||||
result = subprocess.call(shlex.split(command))
|
||||
|
||||
if result != 0:
|
||||
logging.CyberCPLogFileWriter.writeToFile("Failed to extract OWASP CRS zip file. Ensure unzip is installed. [setupOWASPRules]")
|
||||
return 0
|
||||
|
||||
command = 'mv /usr/local/lsws/conf/modsec/coreruleset-3.3.2 /usr/local/lsws/conf/modsec/owasp-modsecurity-crs-3.0-master'
|
||||
result = subprocess.call(shlex.split(command))
|
||||
|
||||
if result != 0:
|
||||
logging.CyberCPLogFileWriter.writeToFile("Failed to rename OWASP CRS directory. File may already exist. [setupOWASPRules]")
|
||||
return 0
|
||||
|
||||
command = 'mv %s/crs-setup.conf.example %s/crs-setup.conf' % (pathToOWASFolderNew, pathToOWASFolderNew)
|
||||
result = subprocess.call(shlex.split(command))
|
||||
|
||||
if result != 0:
|
||||
logging.CyberCPLogFileWriter.writeToFile("Failed to setup crs-setup.conf configuration file. [setupOWASPRules]")
|
||||
return 0
|
||||
|
||||
command = 'mv %s/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example %s/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf' % (pathToOWASFolderNew, pathToOWASFolderNew)
|
||||
result = subprocess.call(shlex.split(command))
|
||||
|
||||
if result != 0:
|
||||
logging.CyberCPLogFileWriter.writeToFile("Failed to setup REQUEST-900 exclusion rules. [setupOWASPRules]")
|
||||
return 0
|
||||
|
||||
command = 'mv %s/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example %s/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf' % (
|
||||
@@ -451,6 +457,7 @@ modsecurity_rules_file /usr/local/lsws/conf/modsec/rules.conf
|
||||
result = subprocess.call(shlex.split(command))
|
||||
|
||||
if result != 0:
|
||||
logging.CyberCPLogFileWriter.writeToFile("Failed to setup RESPONSE-999 exclusion rules. [setupOWASPRules]")
|
||||
return 0
|
||||
|
||||
content = """include {pathToOWASFolderNew}/crs-setup.conf
|
||||
|
||||
@@ -53,7 +53,16 @@ class virtualHostUtilities:
|
||||
redisConf = '/usr/local/lsws/conf/dvhost_redis.conf'
|
||||
vhostConfPath = '/usr/local/lsws/conf'
|
||||
|
||||
@staticmethod
|
||||
def emailServicesInstalled():
|
||||
"""
|
||||
Check if email services (Postfix/OpenDKIM) are installed and configured.
|
||||
Returns True if email services are available, False otherwise.
|
||||
|
||||
This checks for the marker file /home/cyberpanel/postfix which is created
|
||||
during email services installation.
|
||||
"""
|
||||
return os.path.exists('/home/cyberpanel/postfix')
|
||||
|
||||
@staticmethod
|
||||
def OnBoardingHostName(Domain, tempStatusPath, skipRDNSCheck):
|
||||
@@ -82,29 +91,33 @@ class virtualHostUtilities:
|
||||
except:
|
||||
CurrentHostName = ''
|
||||
|
||||
if skipRDNSCheck:
|
||||
pass
|
||||
else:
|
||||
if os.path.exists('/home/cyberpanel/postfix'):
|
||||
pass
|
||||
else:
|
||||
message = 'This server does not come with postfix installed. [404]'
|
||||
print(message)
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, message)
|
||||
logging.CyberCPLogFileWriter.writeToFile(message)
|
||||
return 0
|
||||
# Check if email services are installed
|
||||
# If not installed and rDNS check is required, log warning but continue
|
||||
# Email-specific operations will be skipped later
|
||||
emailServicesAvailable = virtualHostUtilities.emailServicesInstalled()
|
||||
|
||||
if not skipRDNSCheck and not emailServicesAvailable:
|
||||
message = 'Email services not installed. Hostname setup will continue without email configuration.'
|
||||
print(message)
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, message)
|
||||
logging.CyberCPLogFileWriter.writeToFile(message)
|
||||
|
||||
|
||||
####
|
||||
|
||||
# Get postfix hostname with error handling
|
||||
try:
|
||||
PostFixHostname = mailUtilities.FetchPostfixHostname()
|
||||
except Exception as e:
|
||||
message = f'Failed to fetch postfix hostname: {str(e)} [404]'
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, message)
|
||||
logging.CyberCPLogFileWriter.writeToFile(message)
|
||||
return 0
|
||||
# Get postfix hostname with error handling (only if email services are installed)
|
||||
PostFixHostname = None
|
||||
if emailServicesAvailable:
|
||||
try:
|
||||
PostFixHostname = mailUtilities.FetchPostfixHostname()
|
||||
except Exception as e:
|
||||
message = f'Failed to fetch postfix hostname: {str(e)}, continuing without email setup'
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, message)
|
||||
logging.CyberCPLogFileWriter.writeToFile(message)
|
||||
emailServicesAvailable = False # Disable email operations if we can't fetch postfix hostname
|
||||
else:
|
||||
# Set a default hostname when email services are not available
|
||||
PostFixHostname = Domain
|
||||
|
||||
# Get server IP with error handling
|
||||
try:
|
||||
@@ -391,51 +404,66 @@ class virtualHostUtilities:
|
||||
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Hostname SSL issued,50')
|
||||
|
||||
# Only setup mail server SSL if email services are installed
|
||||
if emailServicesAvailable:
|
||||
virtualHostUtilities.issueSSLForMailServer(Domain, path)
|
||||
|
||||
virtualHostUtilities.issueSSLForMailServer(Domain, path)
|
||||
try:
|
||||
with open(filePath, 'r') as f:
|
||||
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, f.read())
|
||||
|
||||
try:
|
||||
with open(filePath, 'r') as f:
|
||||
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, f.read())
|
||||
|
||||
# Safely extract SSL provider from issuer components
|
||||
issuer_components = x509.get_issuer().get_components()
|
||||
SSLProvider = 'Denial' # Default to Denial if we can't find the provider
|
||||
|
||||
# Look for the Organization (O) field in the issuer
|
||||
for component in issuer_components:
|
||||
if component[0] == b'O': # Organization field
|
||||
SSLProvider = component[1].decode('utf-8')
|
||||
break
|
||||
elif component[0] == b'CN' and SSLProvider == 'Denial': # Fallback to CN if O not found
|
||||
SSLProvider = component[1].decode('utf-8')
|
||||
except (FileNotFoundError, IndexError, OpenSSL.crypto.Error) as e:
|
||||
SSLProvider = 'Denial'
|
||||
logging.CyberCPLogFileWriter.writeToFile(f"Mail server SSL check error: {str(e)}")
|
||||
# Safely extract SSL provider from issuer components
|
||||
issuer_components = x509.get_issuer().get_components()
|
||||
SSLProvider = 'Denial' # Default to Denial if we can't find the provider
|
||||
|
||||
if SSLProvider == 'Denial':
|
||||
message = 'Failed to issue Mail server SSL, either its DNS record is not propagated or the domain is behind Cloudflare. [404]'
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, message)
|
||||
logging.CyberCPLogFileWriter.writeToFile(message)
|
||||
config['hostname'] = Domain
|
||||
config['onboarding'] = 3
|
||||
config['skipRDNSCheck'] = skipRDNSCheck
|
||||
admin.config = json.dumps(config)
|
||||
admin.save()
|
||||
return 0
|
||||
# Look for the Organization (O) field in the issuer
|
||||
for component in issuer_components:
|
||||
if component[0] == b'O': # Organization field
|
||||
SSLProvider = component[1].decode('utf-8')
|
||||
break
|
||||
elif component[0] == b'CN' and SSLProvider == 'Denial': # Fallback to CN if O not found
|
||||
SSLProvider = component[1].decode('utf-8')
|
||||
except (FileNotFoundError, IndexError, OpenSSL.crypto.Error) as e:
|
||||
SSLProvider = 'Denial'
|
||||
logging.CyberCPLogFileWriter.writeToFile(f"Mail server SSL check error: {str(e)}")
|
||||
|
||||
if SSLProvider == 'Denial':
|
||||
message = 'Failed to issue Mail server SSL, either its DNS record is not propagated or the domain is behind Cloudflare. [404]'
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, message)
|
||||
logging.CyberCPLogFileWriter.writeToFile(message)
|
||||
config['hostname'] = Domain
|
||||
config['onboarding'] = 3
|
||||
config['skipRDNSCheck'] = skipRDNSCheck
|
||||
admin.config = json.dumps(config)
|
||||
admin.save()
|
||||
return 0
|
||||
else:
|
||||
config['hostname'] = Domain
|
||||
config['onboarding'] = 1
|
||||
config['skipRDNSCheck'] = skipRDNSCheck
|
||||
admin.config = json.dumps(config)
|
||||
admin.save()
|
||||
# First update the postfix hash database, then restart services
|
||||
command = 'postmap -F hash:/etc/postfix/vmail_ssl.map && systemctl restart postfix && systemctl restart dovecot'
|
||||
ProcessUtilities.executioner(command, 'root', True)
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Completed. [200]')
|
||||
else:
|
||||
# Email services not installed, skip mail server SSL setup
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Email services not installed, skipping mail server SSL setup.')
|
||||
config['hostname'] = Domain
|
||||
config['onboarding'] = 1
|
||||
config['skipRDNSCheck'] = skipRDNSCheck
|
||||
admin.config = json.dumps(config)
|
||||
admin.save()
|
||||
# First update the postfix hash database, then restart services
|
||||
command = 'postmap -F hash:/etc/postfix/vmail_ssl.map && systemctl restart postfix && systemctl restart dovecot'
|
||||
ProcessUtilities.executioner(command, 'root', True)
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Completed. [200]')
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Hostname setup completed (without email configuration). [200]')
|
||||
|
||||
@staticmethod
|
||||
def setupAutoDiscover(mailDomain, tempStatusPath, virtualHostName, admin):
|
||||
# Check if email services are installed before proceeding
|
||||
if not virtualHostUtilities.emailServicesInstalled():
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Email services not installed, skipping mail domain setup.')
|
||||
logging.CyberCPLogFileWriter.writeToFile('setupAutoDiscover: Email services not installed, skipping.')
|
||||
return
|
||||
|
||||
if mailDomain:
|
||||
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Creating mail child domain..,80')
|
||||
@@ -479,6 +507,11 @@ local_name %s {
|
||||
|
||||
postFixPath = '/etc/postfix/main.cf'
|
||||
|
||||
# Check if main.cf exists before accessing it
|
||||
if not os.path.exists(postFixPath):
|
||||
logging.CyberCPLogFileWriter.writeToFile(f"setupAutoDiscover: {postFixPath} not found, skipping postfix TLS SNI configuration")
|
||||
return
|
||||
|
||||
postFixContent = open(postFixPath, 'r').read()
|
||||
|
||||
if postFixContent.find('tls_server_sni_maps') == -1:
|
||||
@@ -1108,6 +1141,17 @@ local_name %s {
|
||||
@staticmethod
|
||||
def issueSSLForMailServer(virtualHost, path):
|
||||
try:
|
||||
# Check if email services are installed before proceeding
|
||||
if not virtualHostUtilities.emailServicesInstalled():
|
||||
logging.CyberCPLogFileWriter.writeToFile("Email services not installed, skipping mail server SSL setup")
|
||||
print("1,Email services not installed")
|
||||
return 1, 'Email services not installed'
|
||||
|
||||
# Verify critical email directories exist
|
||||
if not os.path.exists('/etc/postfix'):
|
||||
logging.CyberCPLogFileWriter.writeToFile("/etc/postfix directory not found, skipping mail server SSL")
|
||||
print("1,Postfix directory not found")
|
||||
return 1, 'Postfix directory not found'
|
||||
|
||||
srcFullChain = '/etc/letsencrypt/live/' + virtualHost + '/fullchain.pem'
|
||||
srcPrivKey = '/etc/letsencrypt/live/' + virtualHost + '/privkey.pem'
|
||||
@@ -1183,6 +1227,12 @@ local_name %s {
|
||||
|
||||
filePath = "/etc/postfix/main.cf"
|
||||
|
||||
# Check if main.cf exists before trying to read it
|
||||
if not os.path.exists(filePath):
|
||||
logging.CyberCPLogFileWriter.writeToFile(f"{filePath} not found, skipping postfix hostname update")
|
||||
print("1,Postfix main.cf not found")
|
||||
return 1, 'Postfix main.cf not found'
|
||||
|
||||
data = open(filePath, 'r').readlines()
|
||||
|
||||
writeFile = open(filePath, 'w')
|
||||
|
||||
@@ -2519,11 +2519,12 @@ Require valid-user
|
||||
childDomains = []
|
||||
|
||||
for web in websites:
|
||||
for child in web.childdomains_set.filter(alais=0):
|
||||
if child.domain == f'mail.{web.domain}':
|
||||
pass
|
||||
else:
|
||||
childDomains.append(child)
|
||||
for child in web.childdomains_set.all():
|
||||
if child.alais == 0:
|
||||
if child.domain == f'mail.{web.domain}':
|
||||
pass
|
||||
else:
|
||||
childDomains.append(child)
|
||||
|
||||
pagination = self.getPagination(len(childDomains), recordsToShow)
|
||||
json_data = self.findChildsListJson(childDomains[finalPageNumber:endPageNumber])
|
||||
@@ -2533,6 +2534,8 @@ Require valid-user
|
||||
final_json = json.dumps(final_dic)
|
||||
return HttpResponse(final_json)
|
||||
except BaseException as msg:
|
||||
import traceback
|
||||
logging.CyberCPLogFileWriter.writeToFile(f"fetchChildDomainsMain error for userID {userID}: {str(msg)}\n{traceback.format_exc()}")
|
||||
dic = {'status': 1, 'listWebSiteStatus': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(dic)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
Reference in New Issue
Block a user