Files
CyberPanel/plogical/sslUtilities.py

374 lines
16 KiB
Python
Raw Normal View History

2017-10-24 19:16:36 +05:00
import CyberCPLogFileWriter as logging
import shutil
import os
import shlex
import subprocess
2017-12-09 22:30:10 +05:00
import socket
2017-10-24 19:16:36 +05:00
class sslUtilities:
2017-12-09 22:30:10 +05:00
Server_root = "/usr/local/lsws"
2018-05-08 21:25:37 +05:00
@staticmethod
def checkIfSSLMap(virtualHostName):
try:
data = open("/usr/local/lsws/conf/httpd_config.conf").readlines()
sslCheck = 0
for items in data:
2018-05-12 02:21:42 +05:00
if items.find("listener") >-1 and items.find("SSL") > -1:
2018-05-08 21:25:37 +05:00
sslCheck = 1
continue
if sslCheck == 1:
if items.find("}") > -1:
return 0
if items.find(virtualHostName) > -1 and sslCheck == 1:
data = filter(None, items.split(" "))
if data[1] == virtualHostName:
return 1
except BaseException,msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [IO Error with main config file [checkIfSSLMap]]")
return 0
2017-10-24 19:16:36 +05:00
@staticmethod
def installSSLForDomain(virtualHostName):
2017-12-09 22:30:10 +05:00
pathToStoreSSL = sslUtilities.Server_root + "/conf/vhosts/" + "SSL-" + virtualHostName
confPath = sslUtilities.Server_root + "/conf/vhosts/" + virtualHostName
2017-10-24 19:16:36 +05:00
completePathToConfigFile = confPath + "/vhost.conf"
try:
map = " map " + virtualHostName + " " + virtualHostName + "\n"
2018-05-12 02:21:42 +05:00
if sslUtilities.checkSSLListener()!=1:
2017-10-24 19:16:36 +05:00
writeDataToFile = open("/usr/local/lsws/conf/httpd_config.conf", 'a')
listener = "listener SSL {" + "\n"
address = " address *:443" + "\n"
secure = " secure 1" + "\n"
keyFile = " keyFile " + pathToStoreSSL + "/privkey.pem" + "\n"
certFile = " certFile " + pathToStoreSSL + "/fullchain.pem" + "\n"
certChain = " certChain 1" + "\n"
sslProtocol = " sslProtocol 30" + "\n"
2017-10-24 19:16:36 +05:00
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(map)
writeDataToFile.writelines(final)
writeDataToFile.writelines("\n")
writeDataToFile.close()
else:
2017-10-26 23:50:59 +05:00
2018-05-08 21:25:37 +05:00
if sslUtilities.checkIfSSLMap(virtualHostName) == 0:
2017-10-24 19:16:36 +05:00
2018-05-08 21:25:37 +05:00
data = open("/usr/local/lsws/conf/httpd_config.conf").readlines()
writeDataToFile = open("/usr/local/lsws/conf/httpd_config.conf", 'w')
sslCheck = 0
2017-10-24 19:16:36 +05:00
2018-05-08 21:25:37 +05:00
for items in data:
2018-05-12 02:21:42 +05:00
if items.find("listener")>-1 and items.find("SSL") > -1:
2018-05-08 21:25:37 +05:00
sslCheck = 1
if (sslCheck == 1):
2018-05-12 02:21:42 +05:00
writeDataToFile.writelines(items)
2018-05-08 21:25:37 +05:00
writeDataToFile.writelines(map)
sslCheck = 0
2018-05-14 22:26:25 +05:00
else:
writeDataToFile.writelines(items)
2018-05-08 21:25:37 +05:00
writeDataToFile.close()
2017-10-24 19:16:36 +05:00
###################### 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 " + pathToStoreSSL + "/privkey.pem" + "\n"
certFile = " certFile " + pathToStoreSSL + "/fullchain.pem" + "\n"
certChain = " certChain 1" + "\n"
sslProtocol = " sslProtocol 30" + "\n"
2017-10-24 19:16:36 +05:00
final = "}"
writeSSLConfig.writelines("\n")
writeSSLConfig.writelines(vhssl)
writeSSLConfig.writelines(keyFile)
writeSSLConfig.writelines(certFile)
writeSSLConfig.writelines(certChain)
writeSSLConfig.writelines(sslProtocol)
writeSSLConfig.writelines(final)
writeSSLConfig.writelines("\n")
writeSSLConfig.close()
2017-12-09 22:30:10 +05:00
return 1
2017-10-24 19:16:36 +05:00
except BaseException,msg:
2017-12-09 22:30:10 +05:00
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [installSSLForDomain]]")
2017-10-24 19:16:36 +05:00
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,msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [IO Error with main config file [checkSSLListener]]")
return str(msg)
return 0
@staticmethod
2018-05-06 14:18:41 +05:00
def getDNSRecords(virtualHostName):
2017-10-24 19:16:36 +05:00
try:
2018-05-06 14:18:41 +05:00
withoutWWW = socket.gethostbyname(virtualHostName)
withWWW = socket.gethostbyname('www.' + virtualHostName)
2017-11-05 03:02:51 +05:00
2018-05-06 14:18:41 +05:00
return [1, withWWW, withoutWWW]
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
except BaseException, msg:
return [0, "347 " + str(msg) + " [issueSSLForDomain]"]
2017-10-24 19:16:36 +05:00
2017-12-16 11:59:47 +05:00
2018-05-06 14:18:41 +05:00
@staticmethod
2018-05-08 21:25:37 +05:00
def obtainSSLForADomain(virtualHostName,adminEmail,sslpath, aliasDomain = None):
2018-05-06 14:18:41 +05:00
try:
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
## Obtaining Server IP
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
ipFile = "/etc/cyberpanel/machineIP"
f = open(ipFile)
ipData = f.read()
serverIPAddress = ipData.split('\n', 1)[0]
2017-10-24 19:16:36 +05:00
2018-05-08 21:25:37 +05:00
if aliasDomain == None:
2017-10-24 19:16:36 +05:00
try:
logging.CyberCPLogFileWriter.writeToFile("Trying to obtain SSL for: " + virtualHostName + " and: www." + virtualHostName)
command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d www." + virtualHostName
output = subprocess.check_output(shlex.split(command))
logging.CyberCPLogFileWriter.writeToFile(
"Successfully obtained SSL for: " + virtualHostName + " and: www." + virtualHostName)
except subprocess.CalledProcessError, msg:
logging.CyberCPLogFileWriter.writeToFile(
"Failed to obtain SSL for: " + virtualHostName + " and: www." + virtualHostName)
try:
logging.CyberCPLogFileWriter.writeToFile(
"Trying to obtain SSL for: " + virtualHostName)
command = "certbot certonly -n --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName
output = subprocess.check_output(shlex.split(command))
logging.CyberCPLogFileWriter.writeToFile(
"Successfully obtained SSL for: " + virtualHostName)
except subprocess.CalledProcessError, msg:
logging.CyberCPLogFileWriter.writeToFile('Failed to obtain SSL, issuing self-signed SSL for: ' + virtualHostName)
return 0
2017-10-24 19:16:36 +05:00
pathToStoreSSL = sslUtilities.Server_root + "/conf/vhosts/" + "SSL-" + virtualHostName
2017-10-24 19:16:36 +05:00
if not os.path.exists(pathToStoreSSL):
os.mkdir(pathToStoreSSL)
2018-05-08 21:25:37 +05:00
pathToStoreSSLPrivKey = pathToStoreSSL + "/privkey.pem"
pathToStoreSSLFullChain = pathToStoreSSL + "/fullchain.pem"
##
if output.find('Congratulations!') > -1:
###### Copy SSL To config location ######
srcPrivKey = "/etc/letsencrypt/live/" + virtualHostName + "/privkey.pem"
srcFullChain = "/etc/letsencrypt/live/" + virtualHostName + "/fullchain.pem"
if os.path.exists(pathToStoreSSLPrivKey):
os.remove(pathToStoreSSLPrivKey)
if os.path.exists(pathToStoreSSLFullChain):
os.remove(pathToStoreSSLFullChain)
shutil.copy(srcPrivKey, pathToStoreSSLPrivKey)
shutil.copy(srcFullChain, pathToStoreSSLFullChain)
return 1
elif output.find('no action taken.') > -1:
return 1
elif output.find('Failed authorization procedure') > -1:
2018-05-08 21:25:37 +05:00
logging.CyberCPLogFileWriter.writeToFile(
'Failed authorization procedure for ' + virtualHostName + " while issuing Let's Encrypt SSL.")
return 0
elif output.find('Too many SSL requests for this domain, please try to get SSL at later time.') > -1:
logging.CyberCPLogFileWriter.writeToFile(
'Too many SSL requests for ' + virtualHostName + " please try to get SSL at later time.")
2018-05-08 21:25:37 +05:00
return 0
2018-05-06 14:18:41 +05:00
else:
2017-10-24 19:16:36 +05:00
2018-05-08 21:25:37 +05:00
ipRecords = sslUtilities.getDNSRecords(virtualHostName)
if ipRecords[0] == 1:
if serverIPAddress == ipRecords[1] and serverIPAddress == ipRecords[2]:
ipRecordsAlias = sslUtilities.getDNSRecords(aliasDomain)
if serverIPAddress == ipRecordsAlias[1] and serverIPAddress == ipRecordsAlias[2]:
command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d www." + virtualHostName + " -d " + aliasDomain + " -d www." + aliasDomain
else:
if serverIPAddress == ipRecordsAlias[2]:
command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d www." + virtualHostName + " -d " + aliasDomain
else:
command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d www." + virtualHostName
else:
if serverIPAddress == ipRecords[2]:
ipRecordsAlias = sslUtilities.getDNSRecords(aliasDomain)
if serverIPAddress == ipRecordsAlias[1] and serverIPAddress == ipRecordsAlias[2]:
command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d " + aliasDomain + " -d www." + aliasDomain
else:
if serverIPAddress == ipRecordsAlias[2]:
command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName + " -d " + aliasDomain
else:
command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + virtualHostName
logging.CyberCPLogFileWriter.writeToFile(
"SSL is issued without 'www' due to DNS error for domain : " + virtualHostName)
else:
ipRecordsAlias = sslUtilities.getDNSRecords(aliasDomain)
if serverIPAddress == ipRecordsAlias[1] and serverIPAddress == ipRecordsAlias[2]:
command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + aliasDomain + " -d www." + aliasDomain
else:
if serverIPAddress == ipRecordsAlias[2]:
command = "certbot certonly -n --expand --agree-tos --email " + adminEmail + " --webroot -w " + sslpath + " -d " + aliasDomain
else:
return 0
else:
logging.CyberCPLogFileWriter.writeToFile(
"Failed to obtain DNS records for " + virtualHostName + ", issuing self signed certificate.")
return 0
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
## SSL Paths
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
pathToStoreSSL = sslUtilities.Server_root + "/conf/vhosts/" + "SSL-" + virtualHostName
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
if not os.path.exists(pathToStoreSSL):
os.mkdir(pathToStoreSSL)
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
pathToStoreSSLPrivKey = pathToStoreSSL + "/privkey.pem"
pathToStoreSSLFullChain = pathToStoreSSL + "/fullchain.pem"
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
##
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
output = subprocess.check_output(shlex.split(command))
2017-10-24 19:16:36 +05:00
2018-05-08 21:25:37 +05:00
data = output.split('\n')
2017-10-24 19:16:36 +05:00
2018-05-08 21:25:37 +05:00
if output.find('Congratulations!') > -1:
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
###### Copy SSL To config location ######
2017-10-24 19:16:36 +05:00
2018-05-08 21:25:37 +05:00
for items in data:
if items.find(virtualHostName) > -1 and items.find('fullchain.pem') > -1:
srcFullChain = items.strip(' ')
elif items.find(virtualHostName) > -1 and items.find('privkey.pem') > -1:
srcPrivKey = items.strip(' ')
if os.path.exists(pathToStoreSSLPrivKey):
os.remove(pathToStoreSSLPrivKey)
if os.path.exists(pathToStoreSSLFullChain):
os.remove(pathToStoreSSLFullChain)
2018-05-06 14:18:41 +05:00
shutil.copy(srcPrivKey, pathToStoreSSLPrivKey)
shutil.copy(srcFullChain, pathToStoreSSLFullChain)
2017-10-24 19:16:36 +05:00
return 1
2018-05-08 21:25:37 +05:00
elif output.find('no action taken.') > -1:
return 1
2018-05-06 14:18:41 +05:00
elif output.find('Failed authorization procedure') > -1:
logging.CyberCPLogFileWriter.writeToFile('Failed authorization procedure for ' + virtualHostName + " while issuing Let's Encrypt SSL.")
return 0
elif output.find('Too many SSL requests for this domain, please try to get SSL at later time.') > -1:
logging.CyberCPLogFileWriter.writeToFile(
'Too many SSL requests for ' + virtualHostName + " please try to get SSL at later time.")
return 0
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
except BaseException,msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg) + " [Failed to obtain SSL. [obtainSSLForADomain]]")
return 0
2017-10-24 19:16:36 +05:00
def issueSSLForDomain(domain, adminEmail, sslpath, aliasDomain = None):
2018-05-06 14:18:41 +05:00
try:
2017-10-24 19:16:36 +05:00
2018-05-08 21:25:37 +05:00
if sslUtilities.obtainSSLForADomain(domain, adminEmail, sslpath, aliasDomain) == 1:
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
if sslUtilities.installSSLForDomain(domain) == 1:
return [1, "None"]
else:
return [0, "210 Failed to install SSL for domain. [issueSSLForDomain]"]
else:
pathToStoreSSL = sslUtilities.Server_root + "/conf/vhosts/" + "SSL-" + domain
2017-10-24 19:16:36 +05:00
2018-05-06 14:18:41 +05:00
if not os.path.exists(pathToStoreSSL):
2017-10-24 19:16:36 +05:00
os.mkdir(pathToStoreSSL)
pathToStoreSSLPrivKey = pathToStoreSSL + "/privkey.pem"
pathToStoreSSLFullChain = pathToStoreSSL + "/fullchain.pem"
2018-05-06 14:18:41 +05:00
command = 'openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -keyout ' + pathToStoreSSLPrivKey + ' -out ' + pathToStoreSSLFullChain
cmd = shlex.split(command)
subprocess.call(cmd)
2017-12-09 22:30:10 +05:00
if sslUtilities.installSSLForDomain(domain) == 1:
2018-05-06 14:18:41 +05:00
logging.CyberCPLogFileWriter.writeToFile("Self signed SSL issued for " + domain + ".")
2017-12-09 22:30:10 +05:00
return [1, "None"]
else:
2018-05-06 14:18:41 +05:00
return [0, "220 Failed to install SSL for domain. [issueSSLForDomain]"]
2017-12-09 22:30:10 +05:00
except BaseException,msg:
return [0, "347 "+ str(msg)+ " [issueSSLForDomain]"]