Initial YakPanel commit
This commit is contained in:
14
class_v2/virtualModelV2/base.py
Normal file
14
class_v2/virtualModelV2/base.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# coding: utf-8
|
||||
import os, sys, time, json
|
||||
|
||||
panelPath = '/www/server/panel'
|
||||
os.chdir(panelPath)
|
||||
if not panelPath + "/class/" in sys.path:
|
||||
sys.path.insert(0, panelPath + "/class/")
|
||||
import public, re
|
||||
|
||||
|
||||
class virtualBase:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
744
class_v2/virtualModelV2/virtualModel.py
Normal file
744
class_v2/virtualModelV2/virtualModel.py
Normal file
@@ -0,0 +1,744 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# YakPanel
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 YakPanel(www.yakpanel.com) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: hwliang <hwl@yakpanel.com>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
# 虚拟空间平台模型
|
||||
#------------------------------
|
||||
import os,re,json,time
|
||||
# from virtualModelV2.base import virtualBase
|
||||
from flask import request
|
||||
import requests
|
||||
import public
|
||||
import yaml
|
||||
from public.validate import Param
|
||||
try:
|
||||
from YakPanel import session
|
||||
except :pass
|
||||
|
||||
class main():
|
||||
setup_path = public.get_setup_path()
|
||||
default_yaml = '{}/vhost_virtual/manifest/config/default.yaml'.format(setup_path)
|
||||
ssl_yaml = '{}/vhost_virtual/config/template/ssl.yaml.tpl'.format(setup_path)
|
||||
not_ssl_yaml = '{}/vhost_virtual/config/template/not_ssl.yaml.tpl'.format(setup_path)
|
||||
cert_path = '{}/vhost_virtual/data/cert'.format(setup_path)
|
||||
crt_path = '{}/vhost.crt'.format(cert_path)
|
||||
key_path = '{}/vhost.key'.format(cert_path)
|
||||
not_auto_ssl_file= '{}/vhost_virtual/config/not_auto_ssl.pl'.format(setup_path)
|
||||
server_ip_file = '{}/vhost_virtual/config/server_ip.pl'.format(setup_path)
|
||||
server_port_file = '{}/vhost_virtual/config/server_port.pl'.format(setup_path)
|
||||
server_domain_file = '{}/vhost_virtual/config/server_domain.pl'.format(setup_path)
|
||||
close_ssl_file= '{}/vhost_virtual/config/close_ssl.pl'.format(setup_path)
|
||||
not_accept_port_file = '{}/vhost_virtual/config/not_accept_port.pl'.format(setup_path)
|
||||
data={}
|
||||
firewall_exec="btpython /www/server/panel/script/vhost_virtual.py"
|
||||
VERSION_FILE = '{}/vhost_virtual/data/.ver'.format(public.get_setup_path())
|
||||
add_permissions='chmod +x {}/vhost_virtual/vhost_virtual'.format(public.get_setup_path())
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def return_message_vhost(self,status,code, msg,error_msg,data):
|
||||
"""
|
||||
@name 返回信息
|
||||
"""
|
||||
return {"status":status,"code":code,"msg":msg,"error_msg":error_msg,"message":data}
|
||||
|
||||
def forward_request(self, args: any, url_path: str) -> dict[str, any]:
|
||||
"""
|
||||
请求虚拟空间平台数据
|
||||
|
||||
@param args: 请求参数对象(需包含 get_items() 方法获取请求体)
|
||||
@param url_path: 接口路径(如 "account/get_type_list")
|
||||
@return: 接口响应结果(成功返回 JSON 数据,失败返回统一错误格式)
|
||||
"""
|
||||
# 1. 前置检查:服务是否已启动
|
||||
if not self.get_service_status_achieve():
|
||||
error_msg = public.lang("Account service not started, please start the service first")
|
||||
return self.return_message_vhost(-1, 500, error_msg, "", {})
|
||||
|
||||
# 2. 获取请求头:access_token
|
||||
access_token = public.ReadFile("/www/server/vhost_virtual/data/config/local_access_token.pl") or ""
|
||||
|
||||
# 3. 读取配置:确定请求协议(HTTP/HTTPS)和端口后缀
|
||||
protocol, port_suffix = self._get_vhost_protocol_and_port()
|
||||
|
||||
# 4. 确定请求主机地址
|
||||
request_host = self._get_request_host()
|
||||
|
||||
# 5. 构造完整请求 URL
|
||||
full_url = f"{protocol}://{request_host}{port_suffix}/{url_path}"
|
||||
public.print_log(f"vhost---------Constructed request URL: {full_url}") # 增强日志上下文
|
||||
|
||||
# 6. 发送 POST 请求并处理响应
|
||||
try:
|
||||
# 发送请求(超时30s,跳过SSL验证,携带access_token头)
|
||||
response = requests.post(
|
||||
url=full_url,
|
||||
data=args.get_items(),
|
||||
timeout=30,
|
||||
headers={"access_token": access_token},
|
||||
verify=False
|
||||
)
|
||||
# 处理正常响应
|
||||
response.raise_for_status() # 自动抛出 HTTP 错误(如404、500)
|
||||
return response.json()
|
||||
|
||||
# 捕获请求相关异常(细分异常类型,便于排查)
|
||||
except requests.exceptions.Timeout:
|
||||
error_msg = "Request timed out (timeout: 30s)"
|
||||
public.print_log(f"vhost---------Error: {error_msg}, URL: {full_url}")
|
||||
return self.return_message_vhost(-1, 500, error_msg, error_msg, {})
|
||||
|
||||
except requests.exceptions.HTTPError as e:
|
||||
error_msg = f"HTTP request failed (status: {e.response.status_code})"
|
||||
public.print_log(f"vhost---------Error: {error_msg}, URL: {full_url}, Details: {str(e)}")
|
||||
return self.return_message_vhost(-1, 500, error_msg, str(e), {})
|
||||
|
||||
except requests.exceptions.RequestException as e:
|
||||
error_msg = f"Request failed: {str(e)}"
|
||||
public.print_log(f"vhost---------Error: {error_msg}, URL: {full_url}")
|
||||
return self.return_message_vhost(-1, 500, error_msg, str(e), {})
|
||||
|
||||
def _get_vhost_protocol_and_port(self) -> tuple[str, str]:
|
||||
"""
|
||||
私有辅助方法:从配置文件读取虚拟主机的请求协议(HTTP/HTTPS)和端口后缀(如 ":8001")
|
||||
@return: (protocol: str, port_suffix: str)
|
||||
"""
|
||||
# 默认配置:HTTP + 8000端口
|
||||
protocol = "http"
|
||||
port_suffix = ":8000"
|
||||
|
||||
# 1. 读取主配置文件(yaml)
|
||||
try:
|
||||
with open(self.default_yaml, "r", encoding="utf-8") as f: # 指定编码,避免乱码
|
||||
config_data = yaml.safe_load(f) or {}
|
||||
server_config = config_data.get("server", {})
|
||||
|
||||
# 优先使用 HTTPS 端口(若配置存在)
|
||||
https_port = server_config.get("httpsAddr", "")
|
||||
if https_port:
|
||||
protocol = "https"
|
||||
port_suffix = https_port
|
||||
# 若HTTPS未配置,使用HTTP端口
|
||||
else:
|
||||
http_port = server_config.get("address", "")
|
||||
if http_port:
|
||||
port_suffix = http_port
|
||||
|
||||
# 配置文件读取失败:沿用默认配置,打印日志
|
||||
except FileNotFoundError:
|
||||
public.print_log(f"vhost---------Config file not found: {self.default_yaml}, use default port")
|
||||
except yaml.YAMLError as e:
|
||||
public.print_log(f"vhost---------YAML parse error: {str(e)}, use default port")
|
||||
except Exception as e:
|
||||
public.print_log(f"vhost---------Unknown error when reading config: {str(e)}, use default port")
|
||||
|
||||
# 2. 读取自定义端口文件(优先级高于主配置)
|
||||
try:
|
||||
if os.path.exists(self.server_port_file):
|
||||
custom_port = public.readFile(self.server_port_file).strip() # 去空格,避免无效字符
|
||||
if custom_port and custom_port.isdigit(): # 验证端口合法性(数字)
|
||||
port_suffix = f":{custom_port}"
|
||||
public.print_log(f"vhost---------Use custom port: {custom_port}")
|
||||
except Exception as e:
|
||||
public.print_log(f"vhost---------Error reading custom port file: {str(e)}")
|
||||
|
||||
return protocol, port_suffix
|
||||
|
||||
def _get_request_host(self) -> str:
|
||||
"""
|
||||
私有辅助方法:确定请求的主机地址(优先从配置文件读取,默认 127.0.0.1)
|
||||
@return: request_host: str
|
||||
"""
|
||||
default_host = "127.0.0.1"
|
||||
host_file = "/www/server/panel/data/domain.conf"
|
||||
server_domain_file = self.server_domain_file # 假设已在类中定义
|
||||
|
||||
# 检查配置文件是否存在(需同时满足两个文件存在才读取)
|
||||
if not (os.path.exists(host_file) and os.path.exists(server_domain_file)):
|
||||
public.print_log(f"vhost---------Host config file missing, use default host: {default_host}")
|
||||
return default_host
|
||||
|
||||
# 读取并清理主机地址
|
||||
host = public.ReadFile(host_file).strip()
|
||||
return host if host else default_host
|
||||
|
||||
|
||||
|
||||
def account(self,args):
|
||||
"""
|
||||
@name 获取用户信息
|
||||
"""
|
||||
return self.forward_request(args, 'account/get_account_list')
|
||||
|
||||
|
||||
|
||||
def get_account_list(self,args):
|
||||
"""
|
||||
@获取用户列表
|
||||
"""
|
||||
if not self.get_service_status_achieve():
|
||||
return self.return_message_vhost(-1, 500,public.lang("Account service not started, please start the service first"),"",{})
|
||||
result = self.forward_request(args, 'account/get_account_list')
|
||||
if result.get("status") == -1:
|
||||
return self.return_message_vhost(0, 200, "获取成功","",result.get("message"))
|
||||
return result
|
||||
|
||||
def remove_account(self,args):
|
||||
"""
|
||||
@删除用户
|
||||
"""
|
||||
return self.forward_request(args, 'account/remove_account')
|
||||
|
||||
def modify_account(self,args):
|
||||
"""
|
||||
@修改用户
|
||||
"""
|
||||
return self.forward_request(args, 'account/modify_account')
|
||||
|
||||
def create_account(self,args):
|
||||
"""
|
||||
@创建用户
|
||||
"""
|
||||
return self.forward_request(args, 'account/create_account')
|
||||
|
||||
|
||||
def get_type_list(self,args):
|
||||
"""
|
||||
@获取分类列表
|
||||
"""
|
||||
result = self.forward_request(args, 'account/get_type_list')
|
||||
if result.get("status") == -1:
|
||||
return self.return_message_vhost(0, 200, "获取成功","",result.get("message"))
|
||||
return result
|
||||
|
||||
def create_type(self,args):
|
||||
"""
|
||||
@创建分类
|
||||
"""
|
||||
return self.forward_request(args, 'account/create_type')
|
||||
|
||||
def remove_type(self,args):
|
||||
"""
|
||||
@删除分类
|
||||
"""
|
||||
return self.forward_request(args, 'account/remove_type')
|
||||
|
||||
def modify_type(self,args):
|
||||
"""
|
||||
@修改分类
|
||||
"""
|
||||
return self.forward_request(args, 'account/modify_type')
|
||||
|
||||
def package(self,args):
|
||||
"""
|
||||
@name 获取资源包信息
|
||||
"""
|
||||
return self.forward_request(args, 'account/get_package_list')
|
||||
|
||||
|
||||
def get_package_list(self,args):
|
||||
"""
|
||||
@获取资源包列表
|
||||
"""
|
||||
if not self.get_service_status_achieve():
|
||||
return self.return_message_vhost(-1, 500,public.lang("Account service not started, please start the service first"),"",{})
|
||||
return self.forward_request(args, 'account/get_package_list')
|
||||
|
||||
def create_package(self,args):
|
||||
"""
|
||||
@创建资源包
|
||||
"""
|
||||
return self.forward_request(args, 'account/create_package')
|
||||
|
||||
def modify_package(self,args):
|
||||
"""
|
||||
@修改资源包
|
||||
"""
|
||||
return self.forward_request(args, 'account/modify_package')
|
||||
|
||||
def remove_package(self,args):
|
||||
"""
|
||||
@删除资源包
|
||||
"""
|
||||
return self.forward_request(args, 'account/remove_package')
|
||||
|
||||
def logs(self,args):
|
||||
"""
|
||||
@name 获取日志信息
|
||||
"""
|
||||
return self.forward_request(args, 'log/get_logs')
|
||||
|
||||
def get_logs(self,args):
|
||||
"""
|
||||
@获取日志
|
||||
@sql_type = sqlserver
|
||||
"""
|
||||
if not self.get_service_status_achieve():
|
||||
return self.return_message_vhost(-1, 500,public.lang("Account service not started, please start the service first"),"",{})
|
||||
return self.forward_request(args, 'log/get_logs')
|
||||
|
||||
|
||||
def clean_logs(self,args):
|
||||
"""
|
||||
@清空日志
|
||||
@sql_type = sqlserver
|
||||
"""
|
||||
return self.forward_request(args, 'log/clean_logs')
|
||||
|
||||
def get_disk_list(self,args):
|
||||
"""
|
||||
@获取磁盘列表
|
||||
"""
|
||||
if not self.get_service_status_achieve():
|
||||
return self.return_message_vhost(-1, 500,public.lang("Account service not started, please start the service first"),"",{})
|
||||
return self.forward_request(args, 'account/get_disk_list')
|
||||
|
||||
def set_default_disk(self,args):
|
||||
"""
|
||||
@设置默认磁盘
|
||||
"""
|
||||
return self.forward_request(args, 'account/set_default_disk')
|
||||
|
||||
def get_account_temp_login_token(self,args):
|
||||
"""
|
||||
@获取临时登录Token
|
||||
"""
|
||||
return self.forward_request(args, 'account/get_account_temp_login_token')
|
||||
|
||||
|
||||
|
||||
def one_key_login(self,args):
|
||||
"""
|
||||
@一键登录
|
||||
"""
|
||||
return self.forward_request(args, 'account/one_key_login')
|
||||
|
||||
|
||||
def check_virtual_service(self,args):
|
||||
"""
|
||||
@检查虚拟空间服务是否安装
|
||||
"""
|
||||
return self.forward_request(args, 'account/check_virtual')
|
||||
|
||||
#开启指定挂载点的磁盘配额
|
||||
def enable_disk_quota(self,args):
|
||||
"""
|
||||
@开启指定挂载点的磁盘配额
|
||||
"""
|
||||
return self.forward_request(args, 'account/enable_disk_quota')
|
||||
|
||||
|
||||
def get_service_status_achieve(self):
|
||||
"""
|
||||
@获取虚拟空间服务状态
|
||||
"""
|
||||
result = public.ExecShell('systemctl status vhost_virtual.service')[0]
|
||||
if "Active: active (running)" in result:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
#启动虚拟空间服务
|
||||
def start_service(self,args):
|
||||
"""
|
||||
@启动虚拟空间服务
|
||||
"""
|
||||
public.ExecShell(self.add_permissions)
|
||||
public.WriteFile(self.not_accept_port_file,"true")
|
||||
public.ExecShell('systemctl start vhost_virtual.service')
|
||||
public.ExecShell('/www/server/v-apache/bin/apachectl graceful')
|
||||
os.remove(self.not_accept_port_file)
|
||||
# os.system("/etc/init.d/bt restart")
|
||||
if self.get_service_status_achieve():
|
||||
return public.return_message(0, 0, public.lang('start Successfully'))
|
||||
else:
|
||||
return public.return_message(-1, 0, public.lang('start Failed'))
|
||||
|
||||
#停止虚拟空间服务
|
||||
def stop_service(self,args):
|
||||
"""
|
||||
@停止虚拟空间服务
|
||||
"""
|
||||
public.ExecShell(self.add_permissions)
|
||||
public.WriteFile(self.not_accept_port_file,"true")
|
||||
public.ExecShell('systemctl stop vhost_virtual.service')
|
||||
os.remove(self.not_accept_port_file)
|
||||
# os.system("/etc/init.d/bt restart")
|
||||
if self.get_service_status_achieve():
|
||||
return public.return_message(-1, 0, public.lang('stop Failed'))
|
||||
else:
|
||||
return public.return_message(0, 0, public.lang('stop Successfully'))
|
||||
|
||||
#重启虚拟空间服务
|
||||
def restart_service(self,args):
|
||||
"""
|
||||
@重启虚拟空间服务
|
||||
"""
|
||||
public.ExecShell(self.add_permissions)
|
||||
public.WriteFile(self.not_accept_port_file,"true")
|
||||
public.ExecShell('systemctl restart vhost_virtual.service')
|
||||
public.ExecShell('/www/server/v-apache/bin/apachectl graceful')
|
||||
os.remove(self.not_accept_port_file)
|
||||
# os.system("/etc/init.d/bt restart")
|
||||
if self.get_service_status_achieve():
|
||||
return public.return_message(0, 0, public.lang('restart Successfully'))
|
||||
else:
|
||||
return public.return_message(-1, 0, public.lang('restart Failed'))
|
||||
|
||||
#重载虚拟空间服务
|
||||
def reload_service(self,args):
|
||||
"""
|
||||
@重载虚拟空间服务
|
||||
"""
|
||||
public.ExecShell(self.add_permissions)
|
||||
#写入文件
|
||||
public.WriteFile(self.not_accept_port_file,"true")
|
||||
public.ExecShell('systemctl restart vhost_virtual.service')
|
||||
os.remove(self.not_accept_port_file)
|
||||
# os.system("/etc/init.d/bt restart")
|
||||
return public.return_message(0, 0, public.lang('reload Successfully'))
|
||||
|
||||
#获取虚拟空间安装状态
|
||||
def get_service_info(self,args):
|
||||
"""
|
||||
@获取虚拟空间安装状态 install_status 0 未安装 1 安装中 2 已安装 run_status 0 停止 1 运行中
|
||||
"""
|
||||
install_status=0
|
||||
run_status=0
|
||||
if os.path.exists('{}/vhost_virtual'.format(self.setup_path)) and os.path.exists('{}/v-apache/bin/v-httpd'.format(self.setup_path)):
|
||||
install_status = 2
|
||||
# run_status = 1
|
||||
if self.get_service_status_achieve():
|
||||
run_status = 1
|
||||
elif public.M('tasks').where('name=? and status !=?',('Install [vhost_virtual-1.0]',1)).count() > 0:
|
||||
install_status = 1
|
||||
|
||||
# 读取版本号
|
||||
ver = public.readFile(self.VERSION_FILE)
|
||||
|
||||
# 无法直接从文件读取则设置默认值
|
||||
if not ver:
|
||||
ver = '1.0.0'
|
||||
|
||||
#当已经安装服务,取端口
|
||||
server_port="50443"
|
||||
if install_status==2 and self.check_version(ver, '2.1.9'):
|
||||
server_port = public.readFile(self.server_port_file)
|
||||
if server_port:
|
||||
server_port = server_port.strip()
|
||||
# else:
|
||||
# #获取不到端口,则自动修复
|
||||
# execstr="cd /www/server/panel/install && /bin/bash vhost_virtual.sh"
|
||||
# public.M('tasks').add('id,name,type,status,addtime,execstr',(None, 'Install [vhost_virtual-1.0]','execshell','0',time.strftime('%Y-%m-%d %H:%M:%S'),execstr))
|
||||
# public.writeFile('/tmp/panelTask.pl','True')
|
||||
|
||||
return public.return_message(0, 0, {'install_status': install_status,"run_status":run_status, "version": ver,"server_port":server_port})
|
||||
|
||||
|
||||
#获取虚拟空间安装进度
|
||||
def get_install_log(self,args):
|
||||
"""
|
||||
@获取虚拟空间安装进度
|
||||
"""
|
||||
log_string=public.ReadFile('/tmp/panelExec.log')
|
||||
return public.return_message(0, 0, log_string)
|
||||
|
||||
#安装虚拟空间服务
|
||||
def install_service(self,args):
|
||||
"""
|
||||
@安装虚拟空间服务
|
||||
"""
|
||||
#检测证书目录是否存在,不存在则创建
|
||||
if not os.path.exists(self.cert_path):
|
||||
os.makedirs(self.cert_path)
|
||||
if public.get_webserver() !="nginx" or not os.path.exists('{}/nginx/sbin/nginx'.format(public.get_setup_path())):
|
||||
return public.return_message(-1, 0, public.lang('At present, only nginx is supported as the web server. Please adjust the web server to nginx first and backup the website data when adjusting the web server'))
|
||||
#
|
||||
download_url="https://www.yakpanel.com/script/Multi-user_install.sh"
|
||||
# download_url="http://192.168.66.161/install/Multi-user_install_____III.sh" #内网测试
|
||||
install_path="{}/panel/install".format(public.get_setup_path())
|
||||
install_file=install_path+"/vhost_virtual.sh"
|
||||
if os.path.exists(install_file):
|
||||
os.remove(install_file)
|
||||
public.ExecShell("wget -O "+install_file+" "+download_url+" --no-check-certificate")
|
||||
if not os.path.exists(install_file):
|
||||
return public.return_message(-1, 0, public.lang('Installation script download failed'))
|
||||
if public.M('tasks').where('name=? and status=?',('Install [vhost_virtual-1.0]','0')).count() > 0:
|
||||
return public.return_message(-1, 0, public.lang('The task already exists'))
|
||||
else:
|
||||
execstr="cd /www/server/panel/install && /bin/bash vhost_virtual.sh"
|
||||
public.M('tasks').add('id,name,type,status,addtime,execstr',(None, 'Install [vhost_virtual-1.0]','execshell','0',time.strftime('%Y-%m-%d %H:%M:%S'),execstr))
|
||||
public.writeFile('/tmp/panelTask.pl','True')
|
||||
# 提交安装统计
|
||||
import threading
|
||||
threading.Thread(target=requests.post, kwargs={
|
||||
'url': '{}/api/panel/panel_count_daily'.format(public.OfficialApiBase()),
|
||||
'data': {
|
||||
'name': 'vhost_virtual',
|
||||
}}).start()
|
||||
# 添加放行端口
|
||||
import firewalls
|
||||
get = public.dict_obj()
|
||||
get.port = "50443"
|
||||
get.ps = "vhost virtual service"
|
||||
firewalls.firewalls().AddAcceptPort(get)
|
||||
return public.return_message(0, 0, public.lang('The installation task has been added to the task queue'))
|
||||
|
||||
# 版本更新
|
||||
def update_service(self, args):
|
||||
# # 更新脚本(测试)
|
||||
# cmd = 'wget -O /www/server/vhost_virtual.zip http://192.168.66.99/vhost_virtual.zip && unzip -q -o /www/server/vhost_virtual.zip -d /www/server/ && systemctl restart vhost_virtual.service'
|
||||
# public.ExecShell(cmd)
|
||||
|
||||
# 下载更新脚本
|
||||
download_url = "https://www.yakpanel.com/script/Multi-user_install.sh"
|
||||
install_path = "{}/panel/install".format(public.get_setup_path())
|
||||
install_file = install_path + "/vhost_virtual.sh"
|
||||
if os.path.exists(install_file):
|
||||
os.remove(install_file)
|
||||
public.ExecShell("wget -O " + install_file + " " + download_url + " --no-check-certificate")
|
||||
|
||||
# 执行更新脚本
|
||||
cmd = 'cd /www/server/panel/install && /bin/bash vhost_virtual.sh'
|
||||
public.ExecShell(cmd)
|
||||
|
||||
return public.return_message(0, 0, public.lang('The upgrade was successful'))
|
||||
|
||||
|
||||
#设置证书
|
||||
def save_server_ssl(self,args):
|
||||
args.certificate = args.certificate.strip()
|
||||
args.private_key = args.private_key.strip()
|
||||
#验证证书
|
||||
if not args.certificate or not args.private_key:
|
||||
return self.return_message_vhost(-1, 0, public.lang('Certificate content cannot be empty'),"",{})
|
||||
import ssl_info
|
||||
ssl_info = ssl_info.ssl_info()
|
||||
issuer = self.analyze_ssl(args.certificate)
|
||||
if issuer.get("organizationName") == "Let's Encrypt":
|
||||
args.certificate += "\n"
|
||||
if args.private_key.find('KEY') == -1:
|
||||
return self.return_message_vhost(-1, 0, public.lang('Private Key ERROR, please check!'),"",{})
|
||||
if args.certificate.find('CERTIFICATE') == -1:
|
||||
return self.return_message_vhost(-1, 0, public.lang('Certificate ERROR, please check!'),"",{})
|
||||
public.writeFile('/tmp/cert.pl', args.certificate)
|
||||
if not public.CheckCert('/tmp/cert.pl'):
|
||||
return self.return_message_vhost(-1, 0, public.lang('Error getting certificate'),"",{})
|
||||
|
||||
# # 验证证书和密钥是否匹配格式是否为pem
|
||||
# check_flag, check_msg = ssl_info.verify_certificate_and_key_match(args.private_key, args.certificate)
|
||||
# if not check_flag: return self.return_message_vhost(-1, 0, public.lang(check_msg),"","")
|
||||
# 验证证书链是否完整
|
||||
check_chain_flag, check_chain_msg = ssl_info.verify_certificate_chain(args.certificate)
|
||||
if not check_chain_flag:
|
||||
return self.return_message_vhost(-1, 0, public.lang(check_chain_msg),"",{})
|
||||
backup_cert = '/tmp/backup_vhost_cert'
|
||||
backup_key = '/tmp/backup_vhost_key'
|
||||
|
||||
# import shutil
|
||||
# if os.path.exists(backup_cert): shutil.rmtree(backup_cert)
|
||||
# if os.path.exists(backup_key): shutil.rmtree(backup_key)
|
||||
# if os.path.exists(crt_path): shutil.move(crt_path, backup_cert)
|
||||
# if os.path.exists(Key_path): shutil.move(Key_path, backup_key)
|
||||
old_cert = public.readFile(self.crt_path)
|
||||
old_key = public.readFile(self.key_path)
|
||||
if os.path.exists(self.crt_path): os.rename(self.crt_path,self.crt_path+".bak")
|
||||
|
||||
#写入证书
|
||||
public.writeFile(self.crt_path,args.certificate)
|
||||
public.writeFile(self.key_path,args.private_key)
|
||||
public.ExecShell('chown www:www {} {}'.format(self.crt_path,self.key_path))
|
||||
ssl_config = public.readFile(self.ssl_yaml)
|
||||
public.writeFile(self.default_yaml,ssl_config)
|
||||
if os.path.exists(self.close_ssl_file): os.remove(self.close_ssl_file)
|
||||
public.ExecShell('systemctl restart vhost_virtual.service')
|
||||
if not self.get_service_status_achieve():
|
||||
if old_cert and old_key:
|
||||
public.writeFile(self.crt_path,old_cert)
|
||||
public.writeFile(self.key_path,old_key)
|
||||
else:
|
||||
if os.path.exists(self.crt_path):os.remove(self.crt_path)
|
||||
if os.path.exists(self.key_path):os.remove(self.key_path)
|
||||
not_ssl_config = public.readFile(self.not_ssl_yaml)
|
||||
public.writeFile(self.default_yaml,not_ssl_config)
|
||||
public.ExecShell('systemctl restart vhost_virtual.service')
|
||||
return self.return_message_vhost(-1, 0, public.lang('Please verify if the certificate format and content are correct'),"",{})
|
||||
|
||||
public.writeFile(self.not_auto_ssl_file,'True')
|
||||
|
||||
|
||||
#放行端口
|
||||
public.M('tasks').add('id,name,type,status,addtime,execstr',(None, 'firewall accept port','execshell','0',time.strftime('%Y-%m-%d %H:%M:%S'),self.firewall_exec))
|
||||
public.writeFile('/tmp/panelTask.pl','True')
|
||||
return self.return_message_vhost(0, 0, public.lang('set Successfully'),"",{})
|
||||
# return public.return_message(0, 0, public.lang('set Successfully'))
|
||||
|
||||
def analyze_ssl(self, csr):
|
||||
issuer_dic = {}
|
||||
try:
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
cert = x509.load_pem_x509_certificate(csr.encode("utf-8"), default_backend())
|
||||
issuer = cert.issuer
|
||||
for i in issuer:
|
||||
issuer_dic[i.oid._name] = i.value
|
||||
except:
|
||||
pass
|
||||
return issuer_dic
|
||||
|
||||
|
||||
#关闭证书
|
||||
def close_server_ssl(self,args):
|
||||
public.WriteFile(self.close_ssl_file,"true")
|
||||
#删除备份
|
||||
if os.path.exists(self.crt_path+".bak"): os.remove(self.crt_path+".bak")
|
||||
if os.path.exists(self.key_path+".bak"): os.remove(self.key_path+".bak")
|
||||
if os.path.exists(self.crt_path): os.rename(self.crt_path,self.crt_path+".bak")
|
||||
if os.path.exists(self.key_path): os.rename(self.key_path,self.key_path+".bak")
|
||||
not_ssl_config = public.readFile(self.not_ssl_yaml)
|
||||
public.writeFile(self.default_yaml,not_ssl_config)
|
||||
public.ExecShell('systemctl restart vhost_virtual.service')
|
||||
#放行端口
|
||||
public.M('tasks').add('id,name,type,status,addtime,execstr',(None, 'firewall accept port','execshell','0',time.strftime('%Y-%m-%d %H:%M:%S'),self.firewall_exec))
|
||||
public.writeFile('/tmp/panelTask.pl','True')
|
||||
public.writeFile(self.not_auto_ssl_file,'True')
|
||||
return self.return_message_vhost(0, 0, public.lang('close Successfully'),"",{})
|
||||
|
||||
#获取证书
|
||||
def get_server_ssl(self,args):
|
||||
sslCert = public.readFile(self.crt_path)
|
||||
sslKey = public.readFile(self.key_path)
|
||||
if not sslCert or not sslKey:
|
||||
if os.path.exists(self.crt_path+".bak") and os.path.exists(self.key_path+".bak"):
|
||||
sslCert = public.readFile(self.crt_path+".bak")
|
||||
sslKey = public.readFile(self.key_path+".bak")
|
||||
else:
|
||||
sslCert = ''
|
||||
sslKey = ''
|
||||
return public.return_message(0, 0, {'certificate':sslCert,'private_key':sslKey})
|
||||
|
||||
|
||||
#设置ip地址
|
||||
def set_server_address(self,args):
|
||||
"""
|
||||
@设置ip地址 ip ip地址 domain 域名
|
||||
"""
|
||||
#验证ip地址
|
||||
if public.is_ipv6(args.address):
|
||||
return public.return_message(-1, 0, public.lang('IPv6 address is not supported'))
|
||||
if not public.checkIp(args.address) and not public.is_domain(args.address):
|
||||
return public.return_message(-1, 0, public.lang('Please check if the host address is correct, for example: 192.168.1.20'))
|
||||
if public.checkIp(args.address):
|
||||
public.WriteFile(self.server_ip_file,args.address)
|
||||
if os.path.exists(self.server_domain_file):
|
||||
os.remove(self.server_domain_file)
|
||||
else:
|
||||
public.WriteFile(self.server_domain_file,args.address)
|
||||
public.ExecShell('systemctl restart vhost_virtual.service')
|
||||
public.ExecShell("/etc/init.d/bt restart")
|
||||
return self.return_message_vhost(0, 0, public.lang('set Successfully'),"",{})
|
||||
|
||||
#获取ip地址
|
||||
def get_server_address(self,args):
|
||||
"""
|
||||
@获取ip地址
|
||||
"""
|
||||
ip = ""
|
||||
domain = ""
|
||||
if os.path.exists(self.server_domain_file):
|
||||
domain = public.ReadFile(self.server_domain_file)
|
||||
try:
|
||||
ip = public.ReadFile(self.server_ip_file)
|
||||
if not ip: ip = public.GetClientIp()
|
||||
except:
|
||||
ip = public.GetClientIp()
|
||||
|
||||
protocol = "http"
|
||||
port = ":8000"
|
||||
with open(self.default_yaml, 'r') as file:
|
||||
self.data=yaml.safe_load(file)
|
||||
try:
|
||||
if self.data["server"].get("httpsAddr"):
|
||||
protocol = "https"
|
||||
port = self.data["server"]["httpsAddr"]
|
||||
else:
|
||||
if self.data["server"].get("address"):
|
||||
port = self.data["server"]["address"]
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
|
||||
return self.return_message_vhost(0, 200, "获取成功","",{"ip":ip,"domain":domain,"protocol":protocol,"port":port})
|
||||
|
||||
#自定义端口
|
||||
def modify_service_port(self,args):
|
||||
"""
|
||||
@修改服务端口
|
||||
"""
|
||||
# 校验参数
|
||||
try:
|
||||
args.validate([
|
||||
Param('port').Require().Number(">=", 1).Number("<=", 65535),
|
||||
], [
|
||||
public.validate.trim_filter(),
|
||||
])
|
||||
except Exception as ex:
|
||||
public.print_log("error info: {}".format(ex))
|
||||
return public.return_message(-1, 0, str(ex))
|
||||
#默认端口检测
|
||||
ports = ['21','22', '25', '80', '443', '8080', '888', '8888', '7800']
|
||||
if args.port in ports:
|
||||
return public.return_message(-1, 0, public.lang("Do NOT use common default port!"))
|
||||
#检测新旧端口是否一致
|
||||
server_port = public.readFile(self.server_port_file)
|
||||
if not server_port:
|
||||
return public.return_message(-1, 0, "Port acquisition exception, please restart the service and try again")
|
||||
if args.port == server_port:
|
||||
return public.return_message(-1, 0, "The old and new port are consistent and have not been modified")
|
||||
|
||||
#端口占用检测
|
||||
if self.IsOpen(args.port):
|
||||
return public.return_message(-1, 0,'This port is already occupied, please modify your project port, port: {}'.format(args.port))
|
||||
# 添加放行端口
|
||||
import firewalls
|
||||
args.ps = "vhost virtual service"
|
||||
firewalls.firewalls().AddAcceptPort(args)
|
||||
public.WriteFile(self.server_port_file,args.port)
|
||||
public.ExecShell('systemctl restart vhost_virtual.service')
|
||||
public.ExecShell('/www/server/v-apache/bin/apachectl graceful')
|
||||
return public.return_message(0, 0, public.lang('Operation executed'))
|
||||
|
||||
|
||||
def IsOpen(self,port):
|
||||
#检查端口是否占用
|
||||
if not port: return False
|
||||
import socket
|
||||
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||
try:
|
||||
s.connect(('127.0.0.1',int(port)))
|
||||
s.shutdown(2)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
# 查看子面板版本并比较 低于指定版本 禁止使用
|
||||
def check_version(self,cur_ver, min_ver):
|
||||
cur_major, cur_minor, cur_patch = map(int, cur_ver.split('.'))
|
||||
min_major, min_minor, min_patch = map(int, min_ver.split('.'))
|
||||
if cur_major < min_major:
|
||||
return False
|
||||
|
||||
if cur_major == min_major and cur_minor < min_minor:
|
||||
return False
|
||||
|
||||
if cur_major == min_major and cur_minor == min_minor and cur_patch < min_patch:
|
||||
return False
|
||||
|
||||
return True
|
||||
Reference in New Issue
Block a user