This commit is contained in:
usman@cyberpersons.com 2023-04-01 05:39:18 +05:00
parent 01cad22ed0
commit 13ecd28c4a
10 changed files with 1025 additions and 24 deletions

View File

@ -672,6 +672,29 @@
{% endif %}
<li id="sidebar-menu-item-backupV2">
<a href="{% url 'loadBackupHome' %}" title="{% trans 'BackupV2' %}">
<i class="glyph-icon tooltip-button icon-copy" title=".icon-folder"></i>
<span>{% trans "Backup V2" %}</span>
</a>
<div class="sidebar-submenu">
<ul>
<li><a href="{% url 'CreateV2Backup' %}"
title="{% trans "Create V2 Backup" %}"><span>{% trans "Create V2 Backup" %}</span></a>
</li>
<li><a href="{% url 'ConfigureV2Backup' %}"
title="{% trans "Configure V2 Backup" %}"><span>{% trans "Configure V2 Backup" %}</span></a>
</li>
<li><a href="{% url 'RestoreV2backupSite' %}"
title="{% trans "Restore V2 Backup" %}"><span>{% trans "Restore V2 Backup" %}</span></a>
</li>
</ul>
</div><!-- .sidebar-submenu -->
</li>
<li id="sidebar-menu-item-backup">
<a href="{% url 'loadBackupHome' %}" title="{% trans 'Backup' %}">
<i class="glyph-icon tooltip-button icon-copy" title=".icon-folder"></i>
@ -715,30 +738,6 @@
</div><!-- .sidebar-submenu -->
</li>
<li id="sidebar-menu-item-backupV2">
<a href="{% url 'loadBackupHome' %}" title="{% trans 'BackupV2' %}">
<i class="glyph-icon tooltip-button icon-copy" title=".icon-folder"></i>
<span>{% trans "Backup V2" %}</span>
</a>
<div class="sidebar-submenu">
<ul>
<li><a href="{% url 'CreateV2Backup' %}"
title="{% trans "Create V2 Backup" %}"><span>{% trans "Create V2 Backup" %}</span></a>
</li>
<li><a href="{% url 'ConfigureV2Backup' %}"
title="{% trans "Configure V2 Backup" %}"><span>{% trans "Configure V2 Backup" %}</span></a>
</li>
<li><a href="{% url 'RestoreV2backupSite' %}"
title="{% trans "Restore V2 Backup" %}"><span>{% trans "Restore V2 Backup" %}</span></a>
</li>
</ul>
</div><!-- .sidebar-submenu -->
</li>
<li id="sidebar-menu-item-incremental-backup">
<a href="{% url 'loadBackupHome' %}" title="{% trans 'Incremental Backup - Beta' %}">
<i class="glyph-icon tooltip-button icon-save" title="Incremental Backup"></i>
@ -772,6 +771,23 @@
</div>
</li>
<li id="sidebar-menu-item-ssl">
<a href="{% url 'v2ManageSSL' %}" title="{% trans 'SSL v2' %}">
<i class="glyph-icon tooltip-button icon-lock" title="{% trans 'SSL v2' %}"></i>
<span>{% trans "SSL v2" %}</span>
</a>
<div class="sidebar-submenu">
<ul>
{% if admin or manageSSL %}
<li class="manageSSL"><a href="{% url 'v2ManageSSL' %}"
title="{% trans 'Manage SSL v2' %}"><span>{% trans "Manage SSL v2" %}</span></a>
</li>
{% endif %}
</ul>
</div>
</li>
<li id="sidebar-menu-item-ssl">
<a href="{% url 'loadSSLHome' %}" title="{% trans 'SSL' %}">

View File

@ -81,6 +81,69 @@ app.controller('sslIssueCtrl', function ($scope, $http) {
});
/* Java script code to issue SSL ends here */
/* Java script code to issue SSL V2 */
app.controller('sslIssueCtrlV2', function ($scope, $http) {
$scope.manageSSLLoading = true;
$scope.showbtn = function () {
$scope.issueSSLBtn = false;
};
$scope.issueSSL = function () {
$scope.manageSSLLoading = false;
var url = "/manageSSL/v2IssueSSL";
var data = {
virtualHost: $scope.virtualHost,
};
var config = {
headers: {
'X-CSRFToken': getCookie('csrftoken')
}
};
$http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas);
function ListInitialDatas(response) {
$scope.manageSSLLoading = true;
if (response.data.SSL === 1) {
$scope.sslStatus = 'Issued.';
$scope.sslLogs = response.data.sslLogs;
} else {
$scope.sslStatus = 'Failed.';
$scope.sslLogs = response.data.sslLogs;
}
}
function cantLoadInitialDatas(response) {
$scope.sslIssueCtrl = true;
$scope.manageSSLLoading = true;
$scope.issueSSLBtn = false;
$scope.canNotIssue = true;
$scope.sslIssued = true;
$scope.couldNotConnect = false;
}
};
});
/* Java script code to issue SSL V2 ends here */
/* Java script code to issue SSL for hostname */
app.controller('sslIssueForHostNameCtrl', function ($scope, $http) {

View File

@ -0,0 +1,175 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "SSL v2 - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "SSL v2" %} - <a target="_blank" href="http://go.cyberpanel.net/dns-records"
style="height: 23px;line-height: 21px;"
class="btn btn-border btn-alt border-red btn-link font-red"
title=""><span>{% trans "DNS Docs" %}</span></a></h2>
<p>{% trans "On this page, you have the option to configure DNS providers that CyberPanel can utilize for issuing SSL certificates, providing enhanced flexibility and ease of renewal." %}</p>
</div>
<div ng-controller="sslIssueCtrlV2" class="panel">
<div class="panel-body">
<h3 class="content-box-header">
{% trans "Add Records" %}
</h3>
<div class="example-box-wrapper">
<ul class="nav nav-tabs">
<li class="col-md-4 nav-item tab-mod active">
<a href="#tab-example-1" data-toggle="tab" class="h4 nav-link">
<i class="fa fa-cog btn-icon"></i>
<span>{% trans "Manage DNS" %}</span>
</a>
</li>
<li class="col-md-4 tab-mod nav-item">
<a href="#tab-example-3" data-toggle="tab" class="h4 nav-link">
<i class="fa fa-cogs btn-icon"></i>
<span>{% trans "API Settings" %}</span>
</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade active in" id="tab-example-1">
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row panel-body">
<div class="form-group">
<label class="col-sm-2 control-label">{% trans "Select Domain" %} </label>
<div class="col-sm-6">
<select ng-model="virtualHost"
class="form-control">
{% for items in websiteList %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
<div class="col-sm-4">
<button style="width: 100%;" type="button"
ng-click="issueSSL()"
class="btn btn-primary">{% trans "Issue SSL" %} <img
ng-hide="manageSSLLoading" src="{% static 'images/loading.gif' %}">
</button>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<h3 style="margin: 2%">SSL Status: {$ sslStatus $}</h3>
<div class="col-sm-12">
<textarea ng-model="sslLogs" class="form-control" rows="20"></textarea>
</div>
</div>
</div>
</form>
</div>
</div>
<div class="tab-pane fade" id="tab-example-3">
<form action="/" class="form-horizontal bordered-row panel-body">
<h2 style="margin-bottom: 2%">{% trans "Cloudflare Settings" %}</h2>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "CloudFlare Email" %}</label>
<div class="col-sm-6">
<input name="SAVED_CF_Email" type="text" class="form-control"
value="{{ SAVED_CF_Email }}" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "API Token" %}</label>
<div class="col-sm-6">
<input name="SAVED_CF_Key" type="text" class="form-control"
value="{{ SAVED_CF_Key }}" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="saveCFConfigs()"
class="btn btn-primary btn-lg">{% trans "Save" %}</button>
</div>
</div>
<!----- Godaddy --->
<h2 style="margin-bottom: 2%">{% trans "Godaddy Settings" %}</h2>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "CloudFlare Email" %}</label>
<div class="col-sm-6">
<input ng-init="cfEmail='{{ cfEmail }}'" name="cfEmail" type="text"
class="form-control"
ng-model="cfEmail"
required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "API Token" %}</label>
<div class="col-sm-6">
<input ng-init="cfToken='{{ cfToken }}'" name="cfToken" type="text"
class="form-control"
ng-model="cfToken"
required>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Sync local Records to CloudFlare" %} </label>
<div class="col-sm-6">
<select ng-model="cfSync" class="form-control">
<option>Enable</option>
<option>Disable</option>
</select>
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="saveCFConfigs()"
class="btn btn-primary btn-lg">{% trans "Save" %}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -12,4 +12,9 @@ urlpatterns = [
url(r'^sslForMailServer', views.sslForMailServer, name='sslForMailServer'),
url(r'^obtainMailServerSSL', views.obtainMailServerSSL, name='obtainMailServerSSL'),
## v2 functions
url(r'^v2ManageSSL', views.v2ManageSSL, name='v2ManageSSL'),
url(r'^v2IssueSSL', views.v2IssueSSL, name='v2IssueSSL'),
]

View File

@ -27,6 +27,91 @@ def manageSSL(request):
{'websiteList': websitesName}, 'manageSSL')
return proc.render()
def v2ManageSSL(request):
userID = request.session['userID']
currentACL = ACLManager.loadedACL(userID)
websitesName = ACLManager.findAllSites(currentACL, userID)
RetStatus, SAVED_CF_Key, SAVED_CF_Email = ACLManager.FetchCloudFlareAPIKeyFromAcme()
from plogical.dnsUtilities import DNS
DNS.ConfigurePowerDNSInAcme()
data = {}
data['SAVED_CF_Key'] = SAVED_CF_Key
data['SAVED_CF_Email'] = SAVED_CF_Email
data['websiteList'] = websitesName
proc = httpProc(request, 'manageSSL/v2ManageSSL.html',
data, 'manageSSL')
return proc.render()
def v2IssueSSL(request):
try:
userID = request.session['userID']
admin = Administrator.objects.get(pk=userID)
try:
if request.method == 'POST':
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
elif currentACL['manageSSL'] == 1:
pass
else:
return ACLManager.loadErrorJson('SSL', 0)
data = json.loads(request.body)
virtualHost = data['virtualHost']
if ACLManager.checkOwnership(virtualHost, admin, currentACL) == 1:
pass
else:
return ACLManager.loadErrorJson()
try:
website = ChildDomains.objects.get(domain=virtualHost)
adminEmail = website.master.adminEmail
path = website.path
except:
website = Websites.objects.get(domain=virtualHost)
adminEmail = website.adminEmail
path = "/home/" + virtualHost + "/public_html"
## ssl issue
execPath = "/usr/local/CyberCP/bin/python " + virtualHostUtilities.cyberPanel + "/plogical/virtualHostUtilities.py"
execPath = execPath + " issueSSLv2 --virtualHostName " + virtualHost + " --administratorEmail " + adminEmail + " --path " + path
output = ProcessUtilities.outputExecutioner(execPath)
if output.find("1,") > -1:
## ssl issue ends
website.ssl = 1
website.save()
data_ret = {'status': 1, "SSL": 1,
'error_message': "None", 'sslLogs': output}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
else:
data_ret = {'status': 0, "SSL": 0,
'error_message': output, 'sslLogs': output}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException as msg:
data_ret = {'status': 0, "SSL": 0,
'error_message': str(msg)}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except KeyError:
data_ret = {'status': 0, "SSL": 0,
'error_message': str(msg)}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
def issueSSL(request):
try:

View File

@ -977,3 +977,21 @@ class ACLManager:
else:
return 0
@staticmethod
def FetchCloudFlareAPIKeyFromAcme():
try:
command = 'grep SAVED_CF_Key= /root/.acme.sh/account.conf | cut -d= -f2 | tr -d "\'"'
SAVED_CF_Key = ProcessUtilities.outputExecutioner(command).rstrip('\n')
command = 'grep SAVED_CF_Email= /root/.acme.sh/account.conf | cut -d= -f2 | tr -d "\'"'
SAVED_CF_Email = ProcessUtilities.outputExecutioner(command).rstrip('\n')
if len(SAVED_CF_Key) > 3 and len(SAVED_CF_Email) > 3:
return 1, SAVED_CF_Key, SAVED_CF_Email
else:
return 0, 'Key not defined', SAVED_CF_Email
except BaseException as msg:
return 0, str(msg), None

View File

@ -794,3 +794,52 @@ class DNS:
except:
## There does not exist a zone for this domain.
pass
@staticmethod
def ConfigurePowerDNSInAcme():
try:
from plogical.randomPassword import generate_pass
path = '/root/.acme.sh/account.conf'
APIKey = generate_pass(16)
CurrentContent = ProcessUtilities.outputExecutioner(f'cat {path}')
if CurrentContent.find('PDNS_Url') == -1:
PDNSContent = f"""
{CurrentContent}
PDNS_Url='http://localhost:8081'
PDNS_ServerId='localhost'
PDNS_Token='{APIKey}'
"""
command = f'echo "{PDNSContent}" >> {path}'
ProcessUtilities.executioner(command,None, True)
PDNSPath = '/etc/pdns/pdns.conf'
PDNSConf = f"""
# Turn on the webserver API
webserver=yes
webserver-address=0.0.0.0
webserver-port=8081
# Set the API key for accessing the API
api=yes
api-key={APIKey}
webserver-allow-from=0.0.0.0/0
"""
command = f'echo "{PDNSConf}" >> {PDNSPath}'
ProcessUtilities.executioner(command,None, True)
command = 'systemctl restart pdns'
ProcessUtilities.executioner(command)
return 1, None
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(f'ConfigurePowerDNSInAcme, Error: {str(msg)}')
return 0, str(msg)

533
plogical/sslv2.py Executable file
View File

@ -0,0 +1,533 @@
import time
import requests
from plogical import CyberCPLogFileWriter as logging
import os
import shlex
import subprocess
import socket
from plogical.acl import ACLManager
from plogical.processUtilities import ProcessUtilities
try:
from websiteFunctions.models import ChildDomains, Websites
except:
pass
class sslUtilities:
Server_root = "/usr/local/lsws"
redisConf = '/usr/local/lsws/conf/dvhost_redis.conf'
@staticmethod
def checkIfSSLMap(virtualHostName):
try:
data = open("/usr/local/lsws/conf/httpd_config.conf").readlines()
sslCheck = 0
for items in data:
if items.find("listener") > - 1 and items.find("SSL") > -1:
sslCheck = 1
continue
if sslCheck == 1:
if items.find("}") > -1:
return 0
if items.find(virtualHostName) > -1 and sslCheck == 1:
data = [_f for _f in items.split(" ") if _f]
if data[1] == virtualHostName:
return 1
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [IO Error with main config file [checkIfSSLMap]]")
return 0
@staticmethod
def checkSSLListener():
try:
data = open("/usr/local/lsws/conf/httpd_config.conf").readlines()
for items in data:
if items.find("listener SSL") > -1:
return 1
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [IO Error with main config file [checkSSLListener]]")
return str(msg)
return 0
@staticmethod
def checkSSLIPv6Listener():
try:
data = open("/usr/local/lsws/conf/httpd_config.conf").readlines()
for items in data:
if items.find("listener SSL IPv6") > -1:
return 1
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [IO Error with main config file [checkSSLIPv6Listener]]")
return str(msg)
return 0
@staticmethod
def getDNSRecords(virtualHostName):
try:
withoutWWW = socket.gethostbyname(virtualHostName)
withWWW = socket.gethostbyname('www.' + virtualHostName)
return [1, withWWW, withoutWWW]
except BaseException as msg:
return [0, "347 " + str(msg) + " [issueSSLForDomain]"]
@staticmethod
def installSSLForDomain(virtualHostName, adminEmail='example@example.org'):
try:
website = Websites.objects.get(domain=virtualHostName)
adminEmail = website.adminEmail
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile('%s [installSSLForDomain:72]' % (str(msg)))
if ProcessUtilities.decideServer() == ProcessUtilities.OLS:
confPath = sslUtilities.Server_root + "/conf/vhosts/" + virtualHostName
completePathToConfigFile = confPath + "/vhost.conf"
try:
map = " map " + virtualHostName + " " + virtualHostName + "\n"
if sslUtilities.checkSSLListener() != 1:
writeDataToFile = open("/usr/local/lsws/conf/httpd_config.conf", 'a')
listener = "listener SSL {" + "\n"
address = " address *:443" + "\n"
secure = " secure 1" + "\n"
keyFile = " keyFile /etc/letsencrypt/live/" + virtualHostName + "/privkey.pem\n"
certFile = " certFile /etc/letsencrypt/live/" + virtualHostName + "/fullchain.pem\n"
certChain = " certChain 1" + "\n"
sslProtocol = " sslProtocol 24" + "\n"
enableECDHE = " enableECDHE 1" + "\n"
renegProtection = " renegProtection 1" + "\n"
sslSessionCache = " sslSessionCache 1" + "\n"
enableSpdy = " enableSpdy 15" + "\n"
enableStapling = " enableStapling 1" + "\n"
ocspRespMaxAge = " ocspRespMaxAge 86400" + "\n"
map = " map " + virtualHostName + " " + virtualHostName + "\n"
final = "}" + "\n" + "\n"
writeDataToFile.writelines("\n")
writeDataToFile.writelines(listener)
writeDataToFile.writelines(address)
writeDataToFile.writelines(secure)
writeDataToFile.writelines(keyFile)
writeDataToFile.writelines(certFile)
writeDataToFile.writelines(certChain)
writeDataToFile.writelines(sslProtocol)
writeDataToFile.writelines(enableECDHE)
writeDataToFile.writelines(renegProtection)
writeDataToFile.writelines(sslSessionCache)
writeDataToFile.writelines(enableSpdy)
writeDataToFile.writelines(enableStapling)
writeDataToFile.writelines(ocspRespMaxAge)
writeDataToFile.writelines(map)
writeDataToFile.writelines(final)
writeDataToFile.writelines("\n")
writeDataToFile.close()
elif sslUtilities.checkSSLIPv6Listener() != 1:
writeDataToFile = open("/usr/local/lsws/conf/httpd_config.conf", 'a')
listener = "listener SSL IPv6 {" + "\n"
address = " address [ANY]:443" + "\n"
secure = " secure 1" + "\n"
keyFile = " keyFile /etc/letsencrypt/live/" + virtualHostName + "/privkey.pem\n"
certFile = " certFile /etc/letsencrypt/live/" + virtualHostName + "/fullchain.pem\n"
certChain = " certChain 1" + "\n"
sslProtocol = " sslProtocol 24" + "\n"
enableECDHE = " enableECDHE 1" + "\n"
renegProtection = " renegProtection 1" + "\n"
sslSessionCache = " sslSessionCache 1" + "\n"
enableSpdy = " enableSpdy 15" + "\n"
enableStapling = " enableStapling 1" + "\n"
ocspRespMaxAge = " ocspRespMaxAge 86400" + "\n"
map = " map " + virtualHostName + " " + virtualHostName + "\n"
final = "}" + "\n" + "\n"
writeDataToFile.writelines("\n")
writeDataToFile.writelines(listener)
writeDataToFile.writelines(address)
writeDataToFile.writelines(secure)
writeDataToFile.writelines(keyFile)
writeDataToFile.writelines(certFile)
writeDataToFile.writelines(certChain)
writeDataToFile.writelines(sslProtocol)
writeDataToFile.writelines(enableECDHE)
writeDataToFile.writelines(renegProtection)
writeDataToFile.writelines(sslSessionCache)
writeDataToFile.writelines(enableSpdy)
writeDataToFile.writelines(enableStapling)
writeDataToFile.writelines(ocspRespMaxAge)
writeDataToFile.writelines(map)
writeDataToFile.writelines(final)
writeDataToFile.writelines("\n")
writeDataToFile.close()
else:
if sslUtilities.checkIfSSLMap(virtualHostName) == 0:
data = open("/usr/local/lsws/conf/httpd_config.conf").readlines()
writeDataToFile = open("/usr/local/lsws/conf/httpd_config.conf", 'w')
sslCheck = 0
for items in data:
if items.find("listener") > -1 and items.find("SSL") > -1:
sslCheck = 1
if (sslCheck == 1):
writeDataToFile.writelines(items)
writeDataToFile.writelines(map)
sslCheck = 0
else:
writeDataToFile.writelines(items)
writeDataToFile.close()
###################### Write per host Configs for SSL ###################
data = open(completePathToConfigFile, "r").readlines()
## check if vhssl is already in vhconf file
vhsslPresense = 0
for items in data:
if items.find("vhssl") > -1:
vhsslPresense = 1
if vhsslPresense == 0:
writeSSLConfig = open(completePathToConfigFile, "a")
vhssl = "vhssl {" + "\n"
keyFile = " keyFile /etc/letsencrypt/live/" + virtualHostName + "/privkey.pem\n"
certFile = " certFile /etc/letsencrypt/live/" + virtualHostName + "/fullchain.pem\n"
certChain = " certChain 1" + "\n"
sslProtocol = " sslProtocol 24" + "\n"
enableECDHE = " enableECDHE 1" + "\n"
renegProtection = " renegProtection 1" + "\n"
sslSessionCache = " sslSessionCache 1" + "\n"
enableSpdy = " enableSpdy 15" + "\n"
enableStapling = " enableStapling 1" + "\n"
ocspRespMaxAge = " ocspRespMaxAge 86400" + "\n"
final = "}"
writeSSLConfig.writelines("\n")
writeSSLConfig.writelines(vhssl)
writeSSLConfig.writelines(keyFile)
writeSSLConfig.writelines(certFile)
writeSSLConfig.writelines(certChain)
writeSSLConfig.writelines(sslProtocol)
writeSSLConfig.writelines(enableECDHE)
writeSSLConfig.writelines(renegProtection)
writeSSLConfig.writelines(sslSessionCache)
writeSSLConfig.writelines(enableSpdy)
writeSSLConfig.writelines(enableStapling)
writeSSLConfig.writelines(ocspRespMaxAge)
writeSSLConfig.writelines(final)
writeSSLConfig.writelines("\n")
writeSSLConfig.close()
return 1
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [installSSLForDomain]]")
return 0
else:
if not os.path.exists(sslUtilities.redisConf):
confPath = sslUtilities.Server_root + "/conf/vhosts/" + virtualHostName
completePathToConfigFile = confPath + "/vhost.conf"
## Check if SSL VirtualHost already exists
data = open(completePathToConfigFile, 'r').readlines()
for items in data:
if items.find('*:443') > -1:
return 1
try:
try:
chilDomain = ChildDomains.objects.get(domain=virtualHostName)
externalApp = chilDomain.master.externalApp
DocumentRoot = ' DocumentRoot ' + chilDomain.path + '\n'
except BaseException as msg:
website = Websites.objects.get(domain=virtualHostName)
externalApp = website.externalApp
DocumentRoot = ' DocumentRoot /home/' + virtualHostName + '/public_html\n'
data = open(completePathToConfigFile, 'r').readlines()
phpHandler = ''
for items in data:
if items.find('AddHandler') > -1 and items.find('php') > -1:
phpHandler = items
break
confFile = open(completePathToConfigFile, 'a')
cacheRoot = """ <IfModule LiteSpeed>
CacheRoot lscache
CacheLookup on
</IfModule>
"""
VirtualHost = '\n<VirtualHost *:443>\n\n'
ServerName = ' ServerName ' + virtualHostName + '\n'
ServerAlias = ' ServerAlias www.' + virtualHostName + '\n'
ServerAdmin = ' ServerAdmin ' + adminEmail + '\n'
SeexecUserGroup = ' SuexecUserGroup ' + externalApp + ' ' + externalApp + '\n'
CustomLogCombined = ' CustomLog /home/' + virtualHostName + '/logs/' + virtualHostName + '.access_log combined\n'
confFile.writelines(VirtualHost)
confFile.writelines(ServerName)
confFile.writelines(ServerAlias)
confFile.writelines(ServerAdmin)
confFile.writelines(SeexecUserGroup)
confFile.writelines(DocumentRoot)
confFile.writelines(CustomLogCombined)
confFile.writelines(cacheRoot)
SSLEngine = ' SSLEngine on\n'
SSLVerifyClient = ' SSLVerifyClient none\n'
SSLCertificateFile = ' SSLCertificateFile /etc/letsencrypt/live/' + virtualHostName + '/fullchain.pem\n'
SSLCertificateKeyFile = ' SSLCertificateKeyFile /etc/letsencrypt/live/' + virtualHostName + '/privkey.pem\n'
confFile.writelines(SSLEngine)
confFile.writelines(SSLVerifyClient)
confFile.writelines(SSLCertificateFile)
confFile.writelines(SSLCertificateKeyFile)
confFile.writelines(phpHandler)
VirtualHostEnd = '</VirtualHost>\n'
confFile.writelines(VirtualHostEnd)
confFile.close()
return 1
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [installSSLForDomain]")
return 0
else:
cert = open('/etc/letsencrypt/live/' + virtualHostName + '/fullchain.pem').read().rstrip('\n')
key = open('/etc/letsencrypt/live/' + virtualHostName + '/privkey.pem', 'r').read().rstrip('\n')
command = 'redis-cli hmset "ssl:%s" crt "%s" key "%s"' % (virtualHostName, cert, key)
logging.CyberCPLogFileWriter.writeToFile('hello world aaa')
logging.CyberCPLogFileWriter.writeToFile(command)
ProcessUtilities.executioner(command)
return 1
@staticmethod
def FindIfDomainInCloudflare(virtualHostName):
try:
import tldextract
RetStatus, SAVED_CF_Key, SAVED_CF_Email = ACLManager.FetchCloudFlareAPIKeyFromAcme()
if RetStatus:
extractDomain = tldextract.extract(virtualHostName)
topLevelDomain = extractDomain.domain + '.' + extractDomain.suffix
logging.CyberCPLogFileWriter.writeToFile(f'domain: {topLevelDomain}')
import CloudFlare
params = {'name': topLevelDomain, 'per_page': 50}
cf = CloudFlare.CloudFlare(email=SAVED_CF_Email, token=SAVED_CF_Key)
try:
zones = cf.zones.get(params=params)
except BaseException as msg:
return 0, str(msg)
for zone in sorted(zones, key=lambda v: v['name']):
logging.CyberCPLogFileWriter.writeToFile(f'zone: {zone["name"]}')
if zone['name'] == virtualHostName:
if zone['status'] == 'active':
return 1, None
return 0, 'Zone not found in Cloudflare'
else:
return 0, 'Error in finding keys.'
except BaseException as msg:
return 0, str(msg)
@staticmethod
def FindIfDomainInPowerDNS(virtualHostName):
try:
import tldextract
from plogical.dnsUtilities import DNS
from dns.models import Domains
extractDomain = tldextract.extract(virtualHostName)
topLevelDomain = extractDomain.domain + '.' + extractDomain.suffix
zone = Domains.objects.get(name=topLevelDomain)
DNS.createDNSRecord(zone, f'cptest.{topLevelDomain}', 'A', ACLManager.GetServerIP(), 0, 3600)
time.sleep(2)
result = socket.getaddrinfo(f'cptest.{topLevelDomain}', None, socket.AF_INET)[0]
# Return the IP address as a string
if result[4][0] == ACLManager.GetServerIP():
return 1, None
else:
return 0, 'IP Does not match'
except BaseException as msg:
return 0, str(msg)
@staticmethod
def obtainSSLForADomain(virtualHostName, adminEmail, sslpath, aliasDomain=None):
sender_email = 'root@%s' % (socket.gethostname())
CF_Check = 0
Namecheck_Check = 0
CyberPanel_Check = 0
CF_Check, message = sslUtilities.FindIfDomainInCloudflare(virtualHostName)
DNS_TO_USE = ''
if CF_Check:
DNS_TO_USE = 'dns_cf'
else:
CyberPanel_Check, message = sslUtilities.FindIfDomainInPowerDNS(virtualHostName)
if CyberPanel_Check:
DNS_TO_USE = 'dns_pdns'
else:
return 0, 'Domain is not active in any of the configured DNS provider.'
try:
acmePath = '/root/.acme.sh/acme.sh'
### register account for zero ssl
command = '%s --register-account -m %s' % (acmePath, adminEmail)
subprocess.check_output(shlex.split(command))
# if ProcessUtilities.decideDistro() == ProcessUtilities.ubuntu:
# acmePath = '/home/cyberpanel/.acme.sh/acme.sh'
if aliasDomain is None:
existingCertPath = '/etc/letsencrypt/live/' + virtualHostName
if not os.path.exists(existingCertPath):
command = 'mkdir -p ' + existingCertPath
subprocess.check_output(shlex.split(command))
try:
command = acmePath + " --issue -d " + virtualHostName + " -d www." + virtualHostName \
+ ' --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'
#ResultText = open(logging.CyberCPLogFileWriter.fileName, 'r').read()
#CurrentMessage = "Trying to obtain SSL for: " + virtualHostName + " and: www." + virtualHostName
# logging.CyberCPLogFileWriter.writeToFile(CurrentMessage, 0)
logging.CyberCPLogFileWriter.writeToFile(command, 0)
output = subprocess.check_output(shlex.split(command)).decode("utf-8")
logging.CyberCPLogFileWriter.writeToFile(
"Successfully obtained SSL for: " + virtualHostName + " and: www." + virtualHostName, 0)
logging.CyberCPLogFileWriter.SendEmail(sender_email, adminEmail, output,
'SSL Notification for %s.' % (virtualHostName))
except subprocess.CalledProcessError:
logging.CyberCPLogFileWriter.writeToFile(
"Failed to obtain SSL for: " + virtualHostName + " and: www." + virtualHostName, 0)
finalText = "Failed to obtain SSL for: " + virtualHostName + " and: www." + virtualHostName
try:
command = acmePath + " --issue -d " + virtualHostName + ' --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'
#ResultText = open(logging.CyberCPLogFileWriter.fileName, 'r').read()
CurrentMessage = '%s\nTrying to obtain SSL for: %s' % (finalText, virtualHostName)
finalText = '%s\nTrying to obtain SSL for: %s' % (finalText, virtualHostName)
logging.CyberCPLogFileWriter.writeToFile("Trying to obtain SSL for: " + virtualHostName, 0)
logging.CyberCPLogFileWriter.writeToFile(command)
output = subprocess.check_output(shlex.split(command)).decode("utf-8")
logging.CyberCPLogFileWriter.writeToFile(
"Successfully obtained SSL for: " + virtualHostName, 0)
finalText = '%s\nSuccessfully obtained SSL for: %s.' % (finalText, virtualHostName)
logging.CyberCPLogFileWriter.SendEmail(sender_email, adminEmail, finalText,
'SSL Notification for %s.' % (virtualHostName))
except subprocess.CalledProcessError:
logging.CyberCPLogFileWriter.writeToFile('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))
return 0, output
else:
existingCertPath = '/etc/letsencrypt/live/' + virtualHostName
if not os.path.exists(existingCertPath):
command = 'mkdir -p ' + existingCertPath
subprocess.call(shlex.split(command))
try:
logging.CyberCPLogFileWriter.writeToFile(
"Trying to obtain SSL for: " + virtualHostName + ", www." + virtualHostName + ", " + aliasDomain + " and www." + aliasDomain + ",")
command = acmePath + " --issue -d " + virtualHostName + " -d www." + virtualHostName \
+ ' -d ' + aliasDomain + ' -d www.' + aliasDomain\
+ ' --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'
output = subprocess.check_output(shlex.split(command)).decode("utf-8")
logging.CyberCPLogFileWriter.writeToFile(
"Successfully obtained SSL for: " + virtualHostName + ", www." + virtualHostName + ", " + aliasDomain + "and www." + aliasDomain + ",")
except subprocess.CalledProcessError:
logging.CyberCPLogFileWriter.writeToFile(
"Failed to obtain SSL for: " + virtualHostName + ", www." + virtualHostName + ", " + aliasDomain + "and www." + aliasDomain + ",")
return 0, output
##
if output.find('Cert success') > -1:
return 1, output
else:
return 0, output
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [Failed to obtain SSL. [obtainSSLForADomain]]")
return 0, str(msg)
def issueSSLForDomain(domain, adminEmail, sslpath, aliasDomain=None):
try:
retStatus, message = sslUtilities.obtainSSLForADomain(domain, adminEmail, sslpath, aliasDomain)
if retStatus == 1:
if sslUtilities.installSSLForDomain(domain, adminEmail) == 1:
return [1, message]
else:
return [0, message]
else:
return [0, message]
except BaseException as msg:
return [0, "347 " + str(msg) + " [issueSSLForDomain]"]

View File

@ -0,0 +1,26 @@
import socket
def check_dns_record_socket(domain_name):
"""
Queries the A record for a given domain name using the socket module.
Args:
domain_name (str): The domain name to query.
Returns:
The IP address as a string, or None if the record is not found.
"""
try:
# Query the A record
result = socket.getaddrinfo(domain_name, None, socket.AF_INET)[0]
# Return the IP address as a string
return result[4][0]
except (socket.gaierror, IndexError):
# The domain does not exist or the record is not found
return None
# Check the A record for google.com
result = check_dns_record_socket("wpmautic.net")
print(result) # Output: 216.58.194.174

View File

@ -309,6 +309,35 @@ class virtualHostUtilities:
print("0," + str(msg))
return 0, str(msg)
@staticmethod
def issueSSLv2(virtualHost, path, adminEmail):
try:
import plogical.sslv2 as sslv2
retValues = sslv2.issueSSLForDomain(virtualHost, adminEmail, path)
if retValues[0] == 0:
print("0," + str(retValues[1]))
logging.CyberCPLogFileWriter.writeToFile(str(retValues[1]))
return 0, str(retValues[1])
installUtilities.installUtilities.reStartLiteSpeed()
command = 'systemctl restart postfix'
ProcessUtilities.executioner(command)
command = 'systemctl restart dovecot'
ProcessUtilities.executioner(command)
print(f"1,{str(retValues[1])}")
return 1, str(retValues[1])
except BaseException as msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [issueSSL]")
print("0," + str(msg))
return 0, str(msg)
@staticmethod
def getAccessLogs(fileName, page, externalApp):
try:
@ -1522,6 +1551,8 @@ def main():
tempStatusPath)
elif args.function == "issueSSL":
virtualHostUtilities.issueSSL(args.virtualHostName, args.path, args.administratorEmail)
elif args.function == "issueSSLv2":
virtualHostUtilities.issueSSLv2(args.virtualHostName, args.path, args.administratorEmail)
elif args.function == "changePHP":
vhost.changePHP(args.path, args.phpVersion)
elif args.function == "getAccessLogs":