mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-12-22 16:29:45 +01:00
This commit is contained in:
9
.idea/workspace.xml
generated
9
.idea/workspace.xml
generated
@@ -6,6 +6,12 @@
|
|||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="5251c5c9-f2a1-41f2-bc76-10b517091df1" name="Changes" comment="">
|
<list default="true" id="5251c5c9-f2a1-41f2-bc76-10b517091df1" name="Changes" comment="">
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/loginSystem/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/loginSystem/views.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/plogical/adminPass.py" beforeDir="false" afterPath="$PROJECT_DIR$/plogical/adminPass.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/plogical/customACME.py" beforeDir="false" afterPath="$PROJECT_DIR$/plogical/customACME.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/plogical/sslUtilities.py" beforeDir="false" afterPath="$PROJECT_DIR$/plogical/sslUtilities.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/plogical/sslv2.py" beforeDir="false" afterPath="$PROJECT_DIR$/plogical/sslv2.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/websiteFunctions/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/websiteFunctions/views.py" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -48,7 +54,7 @@
|
|||||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager": "true",
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"SHELLCHECK.PATH": "/Users/cyberpersons/Library/Application Support/JetBrains/PyCharm2025.1/plugins/Shell Script/shellcheck",
|
"SHELLCHECK.PATH": "/Users/cyberpersons/Library/Application Support/JetBrains/PyCharm2025.1/plugins/Shell Script/shellcheck",
|
||||||
"git-widget-placeholder": "stable",
|
"git-widget-placeholder": "v2.4.3",
|
||||||
"last_opened_file_path": "/Users/cyberpersons/cyberpanel",
|
"last_opened_file_path": "/Users/cyberpersons/cyberpanel",
|
||||||
"node.js.detected.package.eslint": "true",
|
"node.js.detected.package.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
@@ -117,6 +123,7 @@
|
|||||||
<workItem from="1754429757112" duration="3503000" />
|
<workItem from="1754429757112" duration="3503000" />
|
||||||
<workItem from="1754433799097" duration="517000" />
|
<workItem from="1754433799097" duration="517000" />
|
||||||
<workItem from="1754448353513" duration="2970000" />
|
<workItem from="1754448353513" duration="2970000" />
|
||||||
|
<workItem from="1754511414251" duration="12135000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ def loadLoginPage(request):
|
|||||||
|
|
||||||
token = hashPassword.generateToken('admin', '1234567')
|
token = hashPassword.generateToken('admin', '1234567')
|
||||||
|
|
||||||
email = 'example@example.org'
|
email = 'admin@cyberpanel.net'
|
||||||
admin = Administrator(userName="admin", password=password, type=1, email=email,
|
admin = Administrator(userName="admin", password=password, type=1, email=email,
|
||||||
firstName="Cyber", lastName="Panel", acl=acl, token=token)
|
firstName="Cyber", lastName="Panel", acl=acl, token=token)
|
||||||
admin.save()
|
admin.save()
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ def main():
|
|||||||
acl = ACL.objects.get(name='admin')
|
acl = ACL.objects.get(name='admin')
|
||||||
token = hashPassword.generateToken('admin', adminPass)
|
token = hashPassword.generateToken('admin', adminPass)
|
||||||
|
|
||||||
email = 'example@example.org'
|
email = 'admin@cyberpanel.net'
|
||||||
admin = Administrator(userName="admin", password=hashPassword.hash_password(adminPass), type=1, email=email,
|
admin = Administrator(userName="admin", password=hashPassword.hash_password(adminPass), type=1, email=email,
|
||||||
firstName="Cyber", lastName="Panel", acl=acl, token=token)
|
firstName="Cyber", lastName="Panel", acl=acl, token=token)
|
||||||
admin.save()
|
admin.save()
|
||||||
|
|||||||
@@ -17,10 +17,12 @@ from plogical import CyberCPLogFileWriter as logging
|
|||||||
from plogical.processUtilities import ProcessUtilities
|
from plogical.processUtilities import ProcessUtilities
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
|
||||||
class CustomACME:
|
class CustomACME:
|
||||||
def __init__(self, domain, admin_email, staging=False, provider='letsencrypt'):
|
def __init__(self, domain, admin_email, staging=False, provider='letsencrypt'):
|
||||||
"""Initialize CustomACME"""
|
"""Initialize CustomACME"""
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Initializing CustomACME for domain: {domain}, email: {admin_email}, staging: {staging}, provider: {provider}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Initializing CustomACME for domain: {domain}, email: {admin_email}, staging: {staging}, provider: {provider}')
|
||||||
self.domain = domain
|
self.domain = domain
|
||||||
self.admin_email = admin_email
|
self.admin_email = admin_email
|
||||||
self.staging = staging
|
self.staging = staging
|
||||||
@@ -55,7 +57,8 @@ class CustomACME:
|
|||||||
self.cert_path = f'/etc/letsencrypt/live/{domain}'
|
self.cert_path = f'/etc/letsencrypt/live/{domain}'
|
||||||
self.challenge_path = '/usr/local/lsws/Example/html/.well-known/acme-challenge'
|
self.challenge_path = '/usr/local/lsws/Example/html/.well-known/acme-challenge'
|
||||||
self.account_key_path = f'/etc/letsencrypt/accounts/{domain}.key'
|
self.account_key_path = f'/etc/letsencrypt/accounts/{domain}.key'
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Certificate path: {self.cert_path}, Challenge path: {self.challenge_path}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Certificate path: {self.cert_path}, Challenge path: {self.challenge_path}')
|
||||||
|
|
||||||
# Create accounts directory if it doesn't exist
|
# Create accounts directory if it doesn't exist
|
||||||
os.makedirs('/etc/letsencrypt/accounts', exist_ok=True)
|
os.makedirs('/etc/letsencrypt/accounts', exist_ok=True)
|
||||||
@@ -82,7 +85,8 @@ class CustomACME:
|
|||||||
logging.CyberCPLogFileWriter.writeToFile(f'Fetching ACME directory from {self.acme_directory}')
|
logging.CyberCPLogFileWriter.writeToFile(f'Fetching ACME directory from {self.acme_directory}')
|
||||||
response = requests.get(self.acme_directory)
|
response = requests.get(self.acme_directory)
|
||||||
self.directory = response.json()
|
self.directory = response.json()
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Successfully fetched ACME directory: {json.dumps(self.directory)}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Successfully fetched ACME directory: {json.dumps(self.directory)}')
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Error getting directory: {str(e)}')
|
logging.CyberCPLogFileWriter.writeToFile(f'Error getting directory: {str(e)}')
|
||||||
@@ -197,13 +201,10 @@ class CustomACME:
|
|||||||
logging.CyberCPLogFileWriter.writeToFile('Creating final JWS...')
|
logging.CyberCPLogFileWriter.writeToFile('Creating final JWS...')
|
||||||
jws = {
|
jws = {
|
||||||
"protected": protected_b64,
|
"protected": protected_b64,
|
||||||
|
"payload": payload_b64, # Always include payload field, even if empty
|
||||||
"signature": signature_b64
|
"signature": signature_b64
|
||||||
}
|
}
|
||||||
|
|
||||||
# Only add payload if it exists
|
|
||||||
if payload is not None:
|
|
||||||
jws["payload"] = payload_b64
|
|
||||||
|
|
||||||
# Ensure the JWS is properly formatted
|
# Ensure the JWS is properly formatted
|
||||||
jws_str = json.dumps(jws, separators=(',', ':'))
|
jws_str = json.dumps(jws, separators=(',', ':'))
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Final JWS: {jws_str}')
|
logging.CyberCPLogFileWriter.writeToFile(f'Final JWS: {jws_str}')
|
||||||
@@ -259,14 +260,17 @@ class CustomACME:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Check if External Account Binding is required (for ZeroSSL)
|
# Check if External Account Binding is required (for ZeroSSL)
|
||||||
if self.provider == 'zerossl' and 'meta' in self.directory and 'externalAccountRequired' in self.directory['meta']:
|
if self.provider == 'zerossl' and 'meta' in self.directory and 'externalAccountRequired' in self.directory[
|
||||||
|
'meta']:
|
||||||
if self.directory['meta']['externalAccountRequired']:
|
if self.directory['meta']['externalAccountRequired']:
|
||||||
logging.CyberCPLogFileWriter.writeToFile('ZeroSSL requires External Account Binding, getting EAB credentials...')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
'ZeroSSL requires External Account Binding, getting EAB credentials...')
|
||||||
|
|
||||||
# Get EAB credentials from ZeroSSL
|
# Get EAB credentials from ZeroSSL
|
||||||
eab_kid, eab_hmac_key = self._get_zerossl_eab_credentials()
|
eab_kid, eab_hmac_key = self._get_zerossl_eab_credentials()
|
||||||
if not eab_kid or not eab_hmac_key:
|
if not eab_kid or not eab_hmac_key:
|
||||||
logging.CyberCPLogFileWriter.writeToFile('Failed to get ZeroSSL EAB credentials, falling back to Let\'s Encrypt')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
'Failed to get ZeroSSL EAB credentials, falling back to Let\'s Encrypt')
|
||||||
# Fallback to Let's Encrypt
|
# Fallback to Let's Encrypt
|
||||||
self.provider = 'letsencrypt'
|
self.provider = 'letsencrypt'
|
||||||
self.acme_directory = "https://acme-v02.api.letsencrypt.org/directory"
|
self.acme_directory = "https://acme-v02.api.letsencrypt.org/directory"
|
||||||
@@ -294,12 +298,14 @@ class CustomACME:
|
|||||||
|
|
||||||
if response.status_code == 201:
|
if response.status_code == 201:
|
||||||
self.account_url = response.headers['Location']
|
self.account_url = response.headers['Location']
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Successfully created account. Account URL: {self.account_url}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Successfully created account. Account URL: {self.account_url}')
|
||||||
# Save the account key for future use
|
# Save the account key for future use
|
||||||
self._save_account_key()
|
self._save_account_key()
|
||||||
return True
|
return True
|
||||||
elif response.status_code == 429:
|
elif response.status_code == 429:
|
||||||
logging.CyberCPLogFileWriter.writeToFile('Rate limit hit for account creation. Using staging environment...')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
'Rate limit hit for account creation. Using staging environment...')
|
||||||
self.staging = True
|
self.staging = True
|
||||||
self.acme_directory = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
self.acme_directory = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||||
# Get new directory and nonce for staging
|
# Get new directory and nonce for staging
|
||||||
@@ -645,17 +651,20 @@ class CustomACME:
|
|||||||
order_status = response.json().get('status')
|
order_status = response.json().get('status')
|
||||||
if order_status == 'valid':
|
if order_status == 'valid':
|
||||||
self.certificate_url = response.json().get('certificate')
|
self.certificate_url = response.json().get('certificate')
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Successfully finalized order. Certificate URL: {self.certificate_url}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Successfully finalized order. Certificate URL: {self.certificate_url}')
|
||||||
return True
|
return True
|
||||||
elif order_status == 'invalid':
|
elif order_status == 'invalid':
|
||||||
logging.CyberCPLogFileWriter.writeToFile('Order validation failed')
|
logging.CyberCPLogFileWriter.writeToFile('Order validation failed')
|
||||||
return False
|
return False
|
||||||
elif order_status == 'processing':
|
elif order_status == 'processing':
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Order still processing, attempt {attempt + 1}/{max_attempts}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Order still processing, attempt {attempt + 1}/{max_attempts}')
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Order status check failed, attempt {attempt + 1}/{max_attempts}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Order status check failed, attempt {attempt + 1}/{max_attempts}')
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
|
|
||||||
logging.CyberCPLogFileWriter.writeToFile('Order processing timed out')
|
logging.CyberCPLogFileWriter.writeToFile('Order processing timed out')
|
||||||
@@ -671,15 +680,30 @@ class CustomACME:
|
|||||||
logging.CyberCPLogFileWriter.writeToFile('Downloading certificate...')
|
logging.CyberCPLogFileWriter.writeToFile('Downloading certificate...')
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Certificate URL: {self.certificate_url}')
|
logging.CyberCPLogFileWriter.writeToFile(f'Certificate URL: {self.certificate_url}')
|
||||||
|
|
||||||
# For certificate downloads, we can use a simple GET request
|
# Get a fresh nonce for the request
|
||||||
response = requests.get(self.certificate_url)
|
if not self._get_nonce():
|
||||||
|
logging.CyberCPLogFileWriter.writeToFile('Failed to get nonce for certificate download')
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Use POST-as-GET for certificate download (ACME v2 requirement)
|
||||||
|
jws = self._create_jws(None, self.certificate_url)
|
||||||
|
if not jws:
|
||||||
|
logging.CyberCPLogFileWriter.writeToFile('Failed to create JWS for certificate download')
|
||||||
|
return None
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'Content-Type': 'application/jose+json'
|
||||||
|
}
|
||||||
|
response = requests.post(self.certificate_url, data=jws, headers=headers)
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Certificate download response status: {response.status_code}')
|
logging.CyberCPLogFileWriter.writeToFile(f'Certificate download response status: {response.status_code}')
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Certificate download response headers: {response.headers}')
|
logging.CyberCPLogFileWriter.writeToFile(f'Certificate download response headers: {response.headers}')
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Certificate download response content: {response.text}')
|
|
||||||
|
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
logging.CyberCPLogFileWriter.writeToFile('Successfully downloaded certificate')
|
logging.CyberCPLogFileWriter.writeToFile('Successfully downloaded certificate')
|
||||||
return response.content
|
# The response should be the PEM-encoded certificate chain
|
||||||
|
return response.text.encode('utf-8') if isinstance(response.text, str) else response.content
|
||||||
|
else:
|
||||||
|
logging.CyberCPLogFileWriter.writeToFile(f'Certificate download failed: {response.text}')
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Error downloading certificate: {str(e)}')
|
logging.CyberCPLogFileWriter.writeToFile(f'Error downloading certificate: {str(e)}')
|
||||||
@@ -715,7 +739,8 @@ class CustomACME:
|
|||||||
logging.CyberCPLogFileWriter.writeToFile('Challenge validation failed')
|
logging.CyberCPLogFileWriter.writeToFile('Challenge validation failed')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Challenge still pending, attempt {attempt + 1}/{max_attempts}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Challenge still pending, attempt {attempt + 1}/{max_attempts}')
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
|
|
||||||
logging.CyberCPLogFileWriter.writeToFile('Challenge validation timed out')
|
logging.CyberCPLogFileWriter.writeToFile('Challenge validation timed out')
|
||||||
@@ -745,9 +770,9 @@ class CustomACME:
|
|||||||
|
|
||||||
# List of public DNS servers to check against
|
# List of public DNS servers to check against
|
||||||
dns_servers = [
|
dns_servers = [
|
||||||
'8.8.8.8', # Google DNS
|
'8.8.8.8', # Google DNS
|
||||||
'1.1.1.1', # Cloudflare DNS
|
'1.1.1.1', # Cloudflare DNS
|
||||||
'208.67.222.222' # OpenDNS
|
'208.67.222.222' # OpenDNS
|
||||||
]
|
]
|
||||||
|
|
||||||
# Function to check DNS record with specific DNS server
|
# Function to check DNS record with specific DNS server
|
||||||
@@ -876,11 +901,13 @@ class CustomACME:
|
|||||||
logging.CyberCPLogFileWriter.writeToFile('Order validation failed')
|
logging.CyberCPLogFileWriter.writeToFile('Order validation failed')
|
||||||
return False
|
return False
|
||||||
elif order_status == 'processing':
|
elif order_status == 'processing':
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Order still processing, attempt {attempt + 1}/{max_attempts}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Order still processing, attempt {attempt + 1}/{max_attempts}')
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Order status check failed, attempt {attempt + 1}/{max_attempts}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Order status check failed, attempt {attempt + 1}/{max_attempts}')
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
|
|
||||||
logging.CyberCPLogFileWriter.writeToFile('Order processing timed out')
|
logging.CyberCPLogFileWriter.writeToFile('Order processing timed out')
|
||||||
@@ -892,7 +919,8 @@ class CustomACME:
|
|||||||
def issue_certificate(self, domains, use_dns=False):
|
def issue_certificate(self, domains, use_dns=False):
|
||||||
"""Main method to issue certificate"""
|
"""Main method to issue certificate"""
|
||||||
try:
|
try:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Starting certificate issuance for domains: {domains}, use_dns: {use_dns}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Starting certificate issuance for domains: {domains}, use_dns: {use_dns}')
|
||||||
|
|
||||||
# Try to load existing account key first
|
# Try to load existing account key first
|
||||||
if self._load_account_key():
|
if self._load_account_key():
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import shlex
|
|||||||
import subprocess
|
import subprocess
|
||||||
import socket
|
import socket
|
||||||
from plogical.processUtilities import ProcessUtilities
|
from plogical.processUtilities import ProcessUtilities
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from websiteFunctions.models import ChildDomains, Websites
|
from websiteFunctions.models import ChildDomains, Websites
|
||||||
except:
|
except:
|
||||||
@@ -14,7 +15,6 @@ from plogical.acl import ACLManager
|
|||||||
|
|
||||||
|
|
||||||
class sslUtilities:
|
class sslUtilities:
|
||||||
|
|
||||||
Server_root = "/usr/local/lsws"
|
Server_root = "/usr/local/lsws"
|
||||||
redisConf = '/usr/local/lsws/conf/dvhost_redis.conf'
|
redisConf = '/usr/local/lsws/conf/dvhost_redis.conf'
|
||||||
|
|
||||||
@@ -108,7 +108,8 @@ class sslUtilities:
|
|||||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# Fallback for Python < 3.7
|
# Fallback for Python < 3.7
|
||||||
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
|
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
|
universal_newlines=True)
|
||||||
|
|
||||||
# If there's any output, the domain has A records
|
# If there's any output, the domain has A records
|
||||||
if result.stdout.strip():
|
if result.stdout.strip():
|
||||||
@@ -120,7 +121,8 @@ class sslUtilities:
|
|||||||
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
result = subprocess.run(command, shell=True, capture_output=True, text=True)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# Fallback for Python < 3.7
|
# Fallback for Python < 3.7
|
||||||
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
|
result = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
|
universal_newlines=True)
|
||||||
|
|
||||||
if result.stdout.strip():
|
if result.stdout.strip():
|
||||||
return True
|
return True
|
||||||
@@ -164,7 +166,6 @@ class sslUtilities:
|
|||||||
except BaseException as msg:
|
except BaseException as msg:
|
||||||
return 0, str(msg)
|
return 0, str(msg)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def CheckIfSSLNeedsToBeIssued(virtualHostName):
|
def CheckIfSSLNeedsToBeIssued(virtualHostName):
|
||||||
#### if website already have an SSL, better not issue again - need to check for wild-card
|
#### if website already have an SSL, better not issue again - need to check for wild-card
|
||||||
@@ -177,7 +178,6 @@ class sslUtilities:
|
|||||||
if os.path.exists(ProcessUtilities.debugPath):
|
if os.path.exists(ProcessUtilities.debugPath):
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'SSL provider for {virtualHostName} is {SSLProvider}.')
|
logging.CyberCPLogFileWriter.writeToFile(f'SSL provider for {virtualHostName} is {SSLProvider}.')
|
||||||
|
|
||||||
|
|
||||||
#### totally seprate check to see if both non-www and www are covered
|
#### totally seprate check to see if both non-www and www are covered
|
||||||
|
|
||||||
if SSLProvider == "(STAGING) Let's Encrypt":
|
if SSLProvider == "(STAGING) Let's Encrypt":
|
||||||
@@ -189,7 +189,8 @@ class sslUtilities:
|
|||||||
if len(domains) > 1:
|
if len(domains) > 1:
|
||||||
### need further checks here to see if ssl is valid for less then 15 days etc
|
### need further checks here to see if ssl is valid for less then 15 days etc
|
||||||
logging.CyberCPLogFileWriter.writeToFile(
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
'[CheckIfSSLNeedsToBeIssued] SSL exists for %s and both versions are covered, just need to ensure if SSL is valid for less then 15 days.' % (virtualHostName), 0)
|
'[CheckIfSSLNeedsToBeIssued] SSL exists for %s and both versions are covered, just need to ensure if SSL is valid for less then 15 days.' % (
|
||||||
|
virtualHostName), 0)
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
return sslUtilities.ISSUE_SSL
|
return sslUtilities.ISSUE_SSL
|
||||||
@@ -202,7 +203,7 @@ class sslUtilities:
|
|||||||
now = datetime.now()
|
now = datetime.now()
|
||||||
diff = finalDate - now
|
diff = finalDate - now
|
||||||
|
|
||||||
if int(diff.days) >= 15 and SSLProvider!='Denial':
|
if int(diff.days) >= 15 and SSLProvider != 'Denial':
|
||||||
logging.CyberCPLogFileWriter.writeToFile(
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
'[CheckIfSSLNeedsToBeIssued] SSL exists for %s and is not ready to fetch new SSL., skipping..' % (
|
'[CheckIfSSLNeedsToBeIssued] SSL exists for %s and is not ready to fetch new SSL., skipping..' % (
|
||||||
virtualHostName), 0)
|
virtualHostName), 0)
|
||||||
@@ -261,7 +262,6 @@ class sslUtilities:
|
|||||||
return str(msg)
|
return str(msg)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def checkSSLIPv6Listener():
|
def checkSSLIPv6Listener():
|
||||||
try:
|
try:
|
||||||
@@ -271,7 +271,8 @@ class sslUtilities:
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
except BaseException as msg:
|
except BaseException as msg:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [IO Error with main config file [checkSSLIPv6Listener]]")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
str(msg) + " [IO Error with main config file [checkSSLIPv6Listener]]")
|
||||||
return str(msg)
|
return str(msg)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -350,7 +351,8 @@ class sslUtilities:
|
|||||||
# If conflicts found, log them and return
|
# If conflicts found, log them and return
|
||||||
if conflicts:
|
if conflicts:
|
||||||
conflict_message = 'Configuration conflicts found: ' + '; '.join(conflicts)
|
conflict_message = 'Configuration conflicts found: ' + '; '.join(conflicts)
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Configuration conflicts for {virtualHostName}: {conflict_message}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Configuration conflicts for {virtualHostName}: {conflict_message}')
|
||||||
return 0, conflict_message
|
return 0, conflict_message
|
||||||
|
|
||||||
# Create challenge directory if it doesn't exist
|
# Create challenge directory if it doesn't exist
|
||||||
@@ -397,7 +399,8 @@ context /.well-known/acme-challenge {
|
|||||||
for line in lines:
|
for line in lines:
|
||||||
f.write(line)
|
f.write(line)
|
||||||
if line.find('DocumentRoot /home/') > -1 and check == 0:
|
if line.find('DocumentRoot /home/') > -1 and check == 0:
|
||||||
f.write(' Alias /.well-known/acme-challenge /usr/local/lsws/Example/html/.well-known/acme-challenge\n')
|
f.write(
|
||||||
|
' Alias /.well-known/acme-challenge /usr/local/lsws/Example/html/.well-known/acme-challenge\n')
|
||||||
check = 1
|
check = 1
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Error writing Apache configuration: {str(e)}')
|
logging.CyberCPLogFileWriter.writeToFile(f'Error writing Apache configuration: {str(e)}')
|
||||||
@@ -407,7 +410,8 @@ context /.well-known/acme-challenge {
|
|||||||
try:
|
try:
|
||||||
from plogical import installUtilities
|
from plogical import installUtilities
|
||||||
installUtilities.installUtilities.reStartLiteSpeed()
|
installUtilities.installUtilities.reStartLiteSpeed()
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Successfully configured ACME challenge for {virtualHostName}')
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f'Successfully configured ACME challenge for {virtualHostName}')
|
||||||
return 1, 'Successfully configured ACME challenge'
|
return 1, 'Successfully configured ACME challenge'
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f'Error restarting LiteSpeed: {str(e)}')
|
logging.CyberCPLogFileWriter.writeToFile(f'Error restarting LiteSpeed: {str(e)}')
|
||||||
@@ -418,7 +422,7 @@ context /.well-known/acme-challenge {
|
|||||||
return 0, f'Unexpected error: {str(e)}'
|
return 0, f'Unexpected error: {str(e)}'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def installSSLForDomain(virtualHostName, adminEmail='example@example.org'):
|
def installSSLForDomain(virtualHostName, adminEmail='domain@cyberpanel.net'):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
website = Websites.objects.get(domain=virtualHostName)
|
website = Websites.objects.get(domain=virtualHostName)
|
||||||
@@ -674,6 +678,14 @@ context /.well-known/acme-challenge {
|
|||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
|
# Replace example.org emails with domain-specific email
|
||||||
|
if adminEmail and ('example.org' in adminEmail or 'example.com' in adminEmail):
|
||||||
|
import re
|
||||||
|
# Remove special characters and create domain-based email
|
||||||
|
clean_domain = re.sub(r'[^a-zA-Z0-9]', '', virtualHostName)
|
||||||
|
adminEmail = f'{clean_domain}@cyberpanel.net'
|
||||||
|
logging.CyberCPLogFileWriter.writeToFile(f'Replacing invalid email with {adminEmail}')
|
||||||
|
|
||||||
Status = 1
|
Status = 1
|
||||||
|
|
||||||
if sslUtilities.CheckIfSSLNeedsToBeIssued(virtualHostName) == sslUtilities.ISSUE_SSL:
|
if sslUtilities.CheckIfSSLNeedsToBeIssued(virtualHostName) == sslUtilities.ISSUE_SSL:
|
||||||
@@ -700,18 +712,22 @@ context /.well-known/acme-challenge {
|
|||||||
# Check if www subdomain has DNS records before adding it (skip for hostnames)
|
# Check if www subdomain has DNS records before adding it (skip for hostnames)
|
||||||
if not isHostname and sslUtilities.checkDNSRecords(f'www.{virtualHostName}'):
|
if not isHostname and sslUtilities.checkDNSRecords(f'www.{virtualHostName}'):
|
||||||
domains.append(f'www.{virtualHostName}')
|
domains.append(f'www.{virtualHostName}')
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"www.{virtualHostName} has DNS records, including in SSL request")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"www.{virtualHostName} has DNS records, including in SSL request")
|
||||||
elif not isHostname:
|
elif not isHostname:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"www.{virtualHostName} has no DNS records, excluding from SSL request")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"www.{virtualHostName} has no DNS records, excluding from SSL request")
|
||||||
|
|
||||||
if aliasDomain:
|
if aliasDomain:
|
||||||
domains.append(aliasDomain)
|
domains.append(aliasDomain)
|
||||||
# Check if www.aliasDomain has DNS records
|
# Check if www.aliasDomain has DNS records
|
||||||
if sslUtilities.checkDNSRecords(f'www.{aliasDomain}'):
|
if sslUtilities.checkDNSRecords(f'www.{aliasDomain}'):
|
||||||
domains.append(f'www.{aliasDomain}')
|
domains.append(f'www.{aliasDomain}')
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"www.{aliasDomain} has DNS records, including in SSL request")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"www.{aliasDomain} has DNS records, including in SSL request")
|
||||||
else:
|
else:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"www.{aliasDomain} has no DNS records, excluding from SSL request")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"www.{aliasDomain} has no DNS records, excluding from SSL request")
|
||||||
|
|
||||||
# Check if Cloudflare is used
|
# Check if Cloudflare is used
|
||||||
use_dns = False
|
use_dns = False
|
||||||
@@ -750,18 +766,22 @@ context /.well-known/acme-challenge {
|
|||||||
# Check if www subdomain has DNS records before adding it (skip for hostnames)
|
# Check if www subdomain has DNS records before adding it (skip for hostnames)
|
||||||
if not isHostname and sslUtilities.checkDNSRecords(f'www.{virtualHostName}'):
|
if not isHostname and sslUtilities.checkDNSRecords(f'www.{virtualHostName}'):
|
||||||
domains.append(f'www.{virtualHostName}')
|
domains.append(f'www.{virtualHostName}')
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"www.{virtualHostName} has DNS records, including in SSL request")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"www.{virtualHostName} has DNS records, including in SSL request")
|
||||||
elif not isHostname:
|
elif not isHostname:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"www.{virtualHostName} has no DNS records, excluding from SSL request")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"www.{virtualHostName} has no DNS records, excluding from SSL request")
|
||||||
|
|
||||||
if aliasDomain:
|
if aliasDomain:
|
||||||
domains.append(aliasDomain)
|
domains.append(aliasDomain)
|
||||||
# Check if www.aliasDomain has DNS records
|
# Check if www.aliasDomain has DNS records
|
||||||
if sslUtilities.checkDNSRecords(f'www.{aliasDomain}'):
|
if sslUtilities.checkDNSRecords(f'www.{aliasDomain}'):
|
||||||
domains.append(f'www.{aliasDomain}')
|
domains.append(f'www.{aliasDomain}')
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"www.{aliasDomain} has DNS records, including in SSL request")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"www.{aliasDomain} has DNS records, including in SSL request")
|
||||||
else:
|
else:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"www.{aliasDomain} has no DNS records, excluding from SSL request")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"www.{aliasDomain} has no DNS records, excluding from SSL request")
|
||||||
|
|
||||||
acme = CustomACME(virtualHostName, adminEmail, staging=False, provider='zerossl')
|
acme = CustomACME(virtualHostName, adminEmail, staging=False, provider='zerossl')
|
||||||
if acme.issue_certificate(domains, use_dns=use_dns):
|
if acme.issue_certificate(domains, use_dns=use_dns):
|
||||||
@@ -794,9 +814,11 @@ context /.well-known/acme-challenge {
|
|||||||
# Check if www subdomain has DNS records (skip for hostnames)
|
# Check if www subdomain has DNS records (skip for hostnames)
|
||||||
if not isHostname and sslUtilities.checkDNSRecords(f'www.{virtualHostName}'):
|
if not isHostname and sslUtilities.checkDNSRecords(f'www.{virtualHostName}'):
|
||||||
domain_list += " -d www." + virtualHostName
|
domain_list += " -d www." + virtualHostName
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"www.{virtualHostName} has DNS records, including in acme.sh SSL request")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"www.{virtualHostName} has DNS records, including in acme.sh SSL request")
|
||||||
elif not isHostname:
|
elif not isHostname:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"www.{virtualHostName} has no DNS records, excluding from acme.sh SSL request")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"www.{virtualHostName} has no DNS records, excluding from acme.sh SSL request")
|
||||||
|
|
||||||
command = acmePath + " --issue" + domain_list \
|
command = acmePath + " --issue" + domain_list \
|
||||||
+ ' --cert-file ' + existingCertPath + '/cert.pem' + ' --key-file ' + existingCertPath + '/privkey.pem' \
|
+ ' --cert-file ' + existingCertPath + '/cert.pem' + ' --key-file ' + existingCertPath + '/privkey.pem' \
|
||||||
@@ -807,7 +829,8 @@ context /.well-known/acme-challenge {
|
|||||||
result = subprocess.run(command, capture_output=True, universal_newlines=True, shell=True)
|
result = subprocess.run(command, capture_output=True, universal_newlines=True, shell=True)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# Fallback for Python < 3.7
|
# Fallback for Python < 3.7
|
||||||
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True)
|
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
|
universal_newlines=True, shell=True)
|
||||||
|
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
command = acmePath + " --issue" + domain_list \
|
command = acmePath + " --issue" + domain_list \
|
||||||
@@ -819,7 +842,8 @@ context /.well-known/acme-challenge {
|
|||||||
result = subprocess.run(command, capture_output=True, universal_newlines=True, shell=True)
|
result = subprocess.run(command, capture_output=True, universal_newlines=True, shell=True)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# Fallback for Python < 3.7
|
# Fallback for Python < 3.7
|
||||||
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True)
|
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
|
universal_newlines=True, shell=True)
|
||||||
|
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
@@ -860,7 +884,8 @@ context /.well-known/acme-challenge {
|
|||||||
result = subprocess.run(command, capture_output=True, universal_newlines=True, shell=True)
|
result = subprocess.run(command, capture_output=True, universal_newlines=True, shell=True)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# Fallback for Python < 3.7
|
# Fallback for Python < 3.7
|
||||||
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True)
|
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
|
universal_newlines=True, shell=True)
|
||||||
|
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
return 1
|
return 1
|
||||||
@@ -910,7 +935,8 @@ def issueSSLForDomain(domain, adminEmail, sslpath, aliasDomain=None, isHostname=
|
|||||||
|
|
||||||
# For expired certificates, use --issue --force instead of --renew
|
# For expired certificates, use --issue --force instead of --renew
|
||||||
if is_expired:
|
if is_expired:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"Certificate is expired, using --issue --force for {domain}")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
f"Certificate is expired, using --issue --force for {domain}")
|
||||||
command = f'{acmePath} --issue {renewal_domains} --webroot /usr/local/lsws/Example/html --force'
|
command = f'{acmePath} --issue {renewal_domains} --webroot /usr/local/lsws/Example/html --force'
|
||||||
else:
|
else:
|
||||||
# Try to renew with explicit webroot
|
# Try to renew with explicit webroot
|
||||||
@@ -920,7 +946,8 @@ def issueSSLForDomain(domain, adminEmail, sslpath, aliasDomain=None, isHostname=
|
|||||||
result = subprocess.run(command, capture_output=True, text=True, shell=True)
|
result = subprocess.run(command, capture_output=True, text=True, shell=True)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# Fallback for Python < 3.7
|
# Fallback for Python < 3.7
|
||||||
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True)
|
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
|
universal_newlines=True, shell=True)
|
||||||
|
|
||||||
if result.returncode == 0:
|
if result.returncode == 0:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(f"Successfully renewed SSL for {domain}")
|
logging.CyberCPLogFileWriter.writeToFile(f"Successfully renewed SSL for {domain}")
|
||||||
@@ -948,13 +975,16 @@ def issueSSLForDomain(domain, adminEmail, sslpath, aliasDomain=None, isHostname=
|
|||||||
|
|
||||||
if os.path.exists(pathToStoreSSLFullChain):
|
if os.path.exists(pathToStoreSSLFullChain):
|
||||||
import OpenSSL
|
import OpenSSL
|
||||||
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, open(pathToStoreSSLFullChain, 'r').read())
|
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
|
||||||
|
open(pathToStoreSSLFullChain, 'r').read())
|
||||||
SSLProvider = x509.get_issuer().get_components()[1][1].decode('utf-8')
|
SSLProvider = x509.get_issuer().get_components()[1][1].decode('utf-8')
|
||||||
|
|
||||||
if SSLProvider != 'Denial':
|
if SSLProvider != 'Denial':
|
||||||
if sslUtilities.installSSLForDomain(domain) == 1:
|
if sslUtilities.installSSLForDomain(domain) == 1:
|
||||||
logging.CyberCPLogFileWriter.writeToFile("We are not able to get new SSL for " + domain + ". But there is an existing SSL, it might only be for the main domain (excluding www).")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
return [1, "We are not able to get new SSL for " + domain + ". But there is an existing SSL, it might only be for the main domain (excluding www)." + " [issueSSLForDomain]"]
|
"We are not able to get new SSL for " + domain + ". But there is an existing SSL, it might only be for the main domain (excluding www).")
|
||||||
|
return [1,
|
||||||
|
"We are not able to get new SSL for " + domain + ". But there is an existing SSL, it might only be for the main domain (excluding www)." + " [issueSSLForDomain]"]
|
||||||
|
|
||||||
command = 'openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=' + domain + '" -keyout ' + pathToStoreSSLPrivKey + ' -out ' + pathToStoreSSLFullChain
|
command = 'openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=' + domain + '" -keyout ' + pathToStoreSSLPrivKey + ' -out ' + pathToStoreSSLFullChain
|
||||||
cmd = shlex.split(command)
|
cmd = shlex.split(command)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import socket
|
|||||||
|
|
||||||
from plogical.acl import ACLManager
|
from plogical.acl import ACLManager
|
||||||
from plogical.processUtilities import ProcessUtilities
|
from plogical.processUtilities import ProcessUtilities
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from websiteFunctions.models import ChildDomains, Websites
|
from websiteFunctions.models import ChildDomains, Websites
|
||||||
except:
|
except:
|
||||||
@@ -17,7 +18,6 @@ except:
|
|||||||
|
|
||||||
|
|
||||||
class sslUtilities:
|
class sslUtilities:
|
||||||
|
|
||||||
Server_root = "/usr/local/lsws"
|
Server_root = "/usr/local/lsws"
|
||||||
redisConf = '/usr/local/lsws/conf/dvhost_redis.conf'
|
redisConf = '/usr/local/lsws/conf/dvhost_redis.conf'
|
||||||
|
|
||||||
@@ -57,7 +57,6 @@ class sslUtilities:
|
|||||||
return str(msg)
|
return str(msg)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def checkSSLIPv6Listener():
|
def checkSSLIPv6Listener():
|
||||||
try:
|
try:
|
||||||
@@ -67,7 +66,8 @@ class sslUtilities:
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
except BaseException as msg:
|
except BaseException as msg:
|
||||||
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [IO Error with main config file [checkSSLIPv6Listener]]")
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
|
str(msg) + " [IO Error with main config file [checkSSLIPv6Listener]]")
|
||||||
return str(msg)
|
return str(msg)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ class sslUtilities:
|
|||||||
return [0, "347 " + str(msg) + " [issueSSLForDomain]"]
|
return [0, "347 " + str(msg) + " [issueSSLForDomain]"]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def installSSLForDomain(virtualHostName, adminEmail='example@example.org'):
|
def installSSLForDomain(virtualHostName, adminEmail='domain@cyberpanel.net'):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
website = Websites.objects.get(domain=virtualHostName)
|
website = Websites.objects.get(domain=virtualHostName)
|
||||||
@@ -332,7 +332,6 @@ class sslUtilities:
|
|||||||
ProcessUtilities.executioner(command)
|
ProcessUtilities.executioner(command)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def FindIfDomainInCloudflare(virtualHostName):
|
def FindIfDomainInCloudflare(virtualHostName):
|
||||||
try:
|
try:
|
||||||
@@ -403,6 +402,14 @@ class sslUtilities:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def obtainSSLForADomain(virtualHostName, adminEmail, sslpath, aliasDomain=None):
|
def obtainSSLForADomain(virtualHostName, adminEmail, sslpath, aliasDomain=None):
|
||||||
|
# Replace example.org emails with domain-specific email
|
||||||
|
if adminEmail and ('example.org' in adminEmail or 'example.com' in adminEmail):
|
||||||
|
import re
|
||||||
|
# Remove special characters and create domain-based email
|
||||||
|
clean_domain = re.sub(r'[^a-zA-Z0-9]', '', virtualHostName)
|
||||||
|
adminEmail = f'{clean_domain}@cyberpanel.net'
|
||||||
|
logging.CyberCPLogFileWriter.writeToFile(f'Replacing invalid email with {adminEmail}')
|
||||||
|
|
||||||
sender_email = 'root@%s' % (socket.gethostname())
|
sender_email = 'root@%s' % (socket.gethostname())
|
||||||
|
|
||||||
CF_Check = 0
|
CF_Check = 0
|
||||||
@@ -419,7 +426,6 @@ class sslUtilities:
|
|||||||
if SSLProvider != 'Denial':
|
if SSLProvider != 'Denial':
|
||||||
return 1, 'This domain already have a valid SSL.'
|
return 1, 'This domain already have a valid SSL.'
|
||||||
|
|
||||||
|
|
||||||
CF_Check, message = sslUtilities.FindIfDomainInCloudflare(virtualHostName)
|
CF_Check, message = sslUtilities.FindIfDomainInCloudflare(virtualHostName)
|
||||||
|
|
||||||
DNS_TO_USE = ''
|
DNS_TO_USE = ''
|
||||||
@@ -456,8 +462,8 @@ class sslUtilities:
|
|||||||
command = acmePath + f" --issue -d {virtualHostName} -d *.{virtualHostName}" \
|
command = acmePath + f" --issue -d {virtualHostName} -d *.{virtualHostName}" \
|
||||||
+ ' --cert-file ' + existingCertPath + '/cert.pem' + ' --key-file ' + existingCertPath + '/privkey.pem' \
|
+ ' --cert-file ' + existingCertPath + '/cert.pem' + ' --key-file ' + existingCertPath + '/privkey.pem' \
|
||||||
+ ' --fullchain-file ' + existingCertPath + '/fullchain.pem' + f' --dns {DNS_TO_USE} -k ec-256 --force --server letsencrypt --dnssleep 20'
|
+ ' --fullchain-file ' + existingCertPath + '/fullchain.pem' + f' --dns {DNS_TO_USE} -k ec-256 --force --server letsencrypt --dnssleep 20'
|
||||||
#ResultText = open(logging.CyberCPLogFileWriter.fileName, 'r').read()
|
# ResultText = open(logging.CyberCPLogFileWriter.fileName, 'r').read()
|
||||||
#CurrentMessage = "Trying to obtain SSL for: " + virtualHostName + " and: www." + virtualHostName
|
# CurrentMessage = "Trying to obtain SSL for: " + virtualHostName + " and: www." + virtualHostName
|
||||||
# logging.CyberCPLogFileWriter.writeToFile(CurrentMessage, 0)
|
# logging.CyberCPLogFileWriter.writeToFile(CurrentMessage, 0)
|
||||||
|
|
||||||
logging.CyberCPLogFileWriter.writeToFile(command, 0)
|
logging.CyberCPLogFileWriter.writeToFile(command, 0)
|
||||||
@@ -480,7 +486,7 @@ class sslUtilities:
|
|||||||
+ '/cert.pem' + ' --key-file ' + existingCertPath + '/privkey.pem' \
|
+ '/cert.pem' + ' --key-file ' + existingCertPath + '/privkey.pem' \
|
||||||
+ ' --fullchain-file ' + existingCertPath + '/fullchain.pem' + f' --dns {DNS_TO_USE} -k ec-256 --force --server letsencrypt --dnssleep 20'
|
+ ' --fullchain-file ' + existingCertPath + '/fullchain.pem' + f' --dns {DNS_TO_USE} -k ec-256 --force --server letsencrypt --dnssleep 20'
|
||||||
|
|
||||||
#ResultText = open(logging.CyberCPLogFileWriter.fileName, 'r').read()
|
# ResultText = open(logging.CyberCPLogFileWriter.fileName, 'r').read()
|
||||||
CurrentMessage = '%s\nTrying to obtain SSL for: %s' % (finalText, virtualHostName)
|
CurrentMessage = '%s\nTrying to obtain SSL for: %s' % (finalText, virtualHostName)
|
||||||
|
|
||||||
finalText = '%s\nTrying to obtain SSL for: %s' % (finalText, virtualHostName)
|
finalText = '%s\nTrying to obtain SSL for: %s' % (finalText, virtualHostName)
|
||||||
@@ -494,8 +500,10 @@ class sslUtilities:
|
|||||||
'SSL Notification for %s.' % (virtualHostName))
|
'SSL Notification for %s.' % (virtualHostName))
|
||||||
|
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
logging.CyberCPLogFileWriter.writeToFile('Failed to obtain SSL, issuing self-signed SSL for: ' + virtualHostName, 0)
|
logging.CyberCPLogFileWriter.writeToFile(
|
||||||
logging.CyberCPLogFileWriter.SendEmail(sender_email, adminEmail, 'Failed to obtain SSL, issuing self-signed SSL for: ' + virtualHostName,
|
'Failed to obtain SSL, issuing self-signed SSL for: ' + virtualHostName, 0)
|
||||||
|
logging.CyberCPLogFileWriter.SendEmail(sender_email, adminEmail,
|
||||||
|
'Failed to obtain SSL, issuing self-signed SSL for: ' + virtualHostName,
|
||||||
'SSL Notification for %s.' % (virtualHostName))
|
'SSL Notification for %s.' % (virtualHostName))
|
||||||
return 0, output
|
return 0, output
|
||||||
else:
|
else:
|
||||||
@@ -510,7 +518,7 @@ class sslUtilities:
|
|||||||
"Trying to obtain SSL for: " + virtualHostName + ", www." + virtualHostName + ", " + aliasDomain + " and www." + aliasDomain + ",")
|
"Trying to obtain SSL for: " + virtualHostName + ", www." + virtualHostName + ", " + aliasDomain + " and www." + aliasDomain + ",")
|
||||||
|
|
||||||
command = acmePath + " --issue -d " + virtualHostName + " -d www." + virtualHostName \
|
command = acmePath + " --issue -d " + virtualHostName + " -d www." + virtualHostName \
|
||||||
+ ' -d ' + aliasDomain + ' -d www.' + aliasDomain\
|
+ ' -d ' + aliasDomain + ' -d www.' + aliasDomain \
|
||||||
+ ' --cert-file ' + existingCertPath + '/cert.pem' + ' --key-file ' + existingCertPath + '/privkey.pem' \
|
+ ' --cert-file ' + existingCertPath + '/cert.pem' + ' --key-file ' + existingCertPath + '/privkey.pem' \
|
||||||
+ ' --fullchain-file ' + existingCertPath + '/fullchain.pem' + f' --dns {DNS_TO_USE} -k ec-256 --force --server letsencrypt --dnssleep 20'
|
+ ' --fullchain-file ' + existingCertPath + '/fullchain.pem' + f' --dns {DNS_TO_USE} -k ec-256 --force --server letsencrypt --dnssleep 20'
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user