Linux ip-172-26-2-223 5.4.0-1018-aws #18-Ubuntu SMP Wed Jun 24 01:15:00 UTC 2020 x86_64
Apache
: 172.26.2.223 | : 3.144.162.109
Cant Read [ /etc/named.conf ]
8.1.13
www
www.github.com/MadExploits
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
CPANEL RESET
CREATE WP USER
BLACK DEFEND!
README
+ Create Folder
+ Create File
/
www /
server /
panel /
mod /
project /
docker /
proxy /
[ HOME SHELL ]
Name
Size
Permission
Action
__init__.py
0
B
-rw-r--r--
base.py
150.24
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : base.py
# coding: utf-8 # ------------------------------------------------------------------- # 宝塔Linux面板 # ------------------------------------------------------------------- # Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved. # ------------------------------------------------------------------- # Author: wzz <wzz@bt.cn> # ------------------------------------------------------------------- import json import os # ------------------------------ # docker - 反向代理模型 # ------------------------------ import sys if "/www/server/panel/class" not in sys.path: sys.path.insert(0, "/www/server/panel/class") os.chdir("/www/server/panel") import public class main(): def __init__(self): self._proxy_path = '/www/server/proxy_project' self._proxy_config_path = self._proxy_path + '/sites' self._site_proxy_conf_path = "" if not os.path.exists(self._proxy_config_path): public.ExecShell('mkdir -p {}'.format(self._proxy_config_path)) public.ExecShell('chown -R www:www {}'.format(self._proxy_config_path)) public.ExecShell('chmod -R 755 {}'.format(self._proxy_config_path)) self._init_proxy_conf = { "site_name": "", "domain_list": [], "site_port": [], "https_port": "443", "ipv4_port_conf": "listen {listen_port};", "ipv6_port_conf": "listen [::]:{listen_port};", "port_conf": "listen {listen_port};{listen_ipv6}", "ipv4_ssl_port_conf": "{ipv4_port_conf}\n listen {https_port} ssl http2 ;", "ipv6_ssl_port_conf": "{ipv6_port_conf}\n listen [::]:{https_port} ssl http2 ;", "ipv4_http3_ssl_port_conf": "{ipv4_port_conf}\n listen {https_port} quic;\n listen {https_port} ssl;", "ipv6_http3_ssl_port_conf": "{ipv6_port_conf}\n listen [::]:{https_port} quic;\n listen [::]:{https_port} ssl ;", "site_path": "", "ssl_info": { "ssl_status": False, "ssl_default_conf": "#error_page 404/404.html;", "ssl_conf": '#error_page 404/404.html;\n ssl_certificate /www/server/panel/vhost/cert/{site_name}/fullchain.pem;\n ssl_certificate_key /www/server/panel/vhost/cert/{site_name}/privkey.pem;\n ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;\n ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;\n ssl_prefer_server_ciphers on;\n ssl_session_cache shared:SSL:10m;\n ssl_session_timeout 10m;\n add_header Strict-Transport-Security "max-age=31536000";\n error_page 497 https://$host$request_uri;', "force_ssl_conf": '#error_page 404/404.html;{force_conf}\n ssl_certificate /www/server/panel/vhost/cert/{site_name}/fullchain.pem;\n ssl_certificate_key /www/server/panel/vhost/cert/{site_name}/privkey.pem;\n ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;\n ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;\n ssl_prefer_server_ciphers on;\n ssl_session_cache shared:SSL:10m;\n ssl_session_timeout 10m;\n add_header Strict-Transport-Security "max-age=31536000";\n error_page 497 https://$host$request_uri;', "force_https": False, "force_conf": " #HTTP_TO_HTTPS_START\n if ($server_port !~ 443){\n rewrite ^(/.*)$ https://$host$1 permanent;\n }\n #HTTP_TO_HTTPS_END", }, "err_age_404": "", "err_age_502": "", "ip_limit": { "ip_black": [], "ip_white": [], }, "basic_auth": [], "proxy_cache": { "cache_status": False, "cache_zone": "", "static_cache": "", "expires": "1d", "cache_conf": "", }, "gzip": { "gzip_status": False, "gzip_min_length": "1k", "gzip_comp_level": "6", "gzip_types": "text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/json image/jpeg image/gif image/png font/ttf font/otf image/svg+xml application/xml+rss text/x-js", "gzip_conf": "gzip on;\n gzip_min_length 10k;\n gzip_buffers 4 16k;\n gzip_http_version 1.1;\n gzip_comp_level 2;\n gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;\n gzip_vary on;\n gzip_proxied expired no-cache no-store private auth;\n gzip_disable \"MSIE [1-6]\.\";", }, "subs_filter": False, "sub_filter": { "sub_filter_str": [], }, "websocket": { "websocket_status": True, "websocket_conf": "proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection $connection_upgrade;", }, "security": { "security_status": False, "static_resource": "jpg|jpeg|gif|png|js|css", "return_resource": "404", "http_status": False, "domains": "", "security_conf": " #SECURITY-START 防盗链配置" "\n location ~ .*\.({static_resource})$" "\n {{\n expires {expires};" "\n access_log /dev/null;" "\n valid_referers {domains};" "\n if ($invalid_referer){{" "\n return {return_resource};" "\n }}" "\n }}\n #SECURITY-END", }, "redirect": { "redirect_status": False, "redirect_conf": " #引用重定向规则,注释后配置的重定向代理将无效\n include /www/server/panel/vhost/nginx/redirect/{site_name}/*.conf;", }, "proxy_log": { "log_type": "default", "server_port": "", "log_path": "", "log_conf": "\naccess_log {log_path}/{site_name}.log;\n error_log {log_path}/{site_name}.error.log;", }, "default_cache": "proxy_cache_path /www/wwwroot/{site_name}/proxy_cache_dir levels=1:2 keys_zone={cache_name}_cache:20m inactive=1d max_size=5g;", "default_describe": "# 如果反代网站访问异常且这里已经配置了内容,请优先排查此处的配置是否正确\n", "http_block": "", "server_block": "", "remark": "", "proxy_info": [], } self._template_conf = '''{http_block} server {{ {port_conf} server_name {domains}; index index.php index.html index.htm default.php default.htm default.html; root {site_path}; #CERT-APPLY-CHECK--START # 用于SSL证书申请时的文件验证相关配置 -- 请勿删除 include /www/server/panel/vhost/nginx/well-known/{site_name}.conf; #CERT-APPLY-CHECK--END #SSL-START {ssl_start_msg} {ssl_info} #SSL-END #REDIRECT START {redirect_conf} #REDIRECT END #ERROR-PAGE-START {err_page_msg} {err_age_404} {err_age_502} #ERROR-PAGE-END #PHP-INFO-START PHP引用配置,可以注释或修改 {security_conf} include enable-php-00.conf; #PHP-INFO-END #IP-RESTRICT-START 限制访问ip的配置,IP黑白名单 {ip_limit_conf} #IP-RESTRICT-END #BASICAUTH START {auth_conf} #BASICAUTH END #SUB_FILTER START {sub_filter} #SUB_FILTER END #GZIP START {gzip_conf} #GZIP END #GLOBAL-CACHE START {proxy_cache} #GLOBAL-CACHE END #WEBSOCKET-SUPPORT START {websocket_support} #WEBSOCKET-SUPPORT END #PROXY-CONF-START {proxy_conf} #PROXY-CONF-END #SERVER-BLOCK START {server_block} #SERVER-BLOCK END #禁止访问的文件或目录 location ~ ^/(\.user.ini|\.htaccess|\.git|\.env|\.svn|\.project|LICENSE|README.md) {{ return 404; }} #一键申请SSL证书验证目录相关设置 location /.well-known{{ allow all; }} #禁止在证书验证目录放入敏感文件 if ( $uri ~ "^/\.well-known/.*\.(php|jsp|py|js|css|lua|ts|go|zip|tar\.gz|rar|7z|sql|bak)$" ) {{ return 403; }} #LOG START {server_log} {monitor_conf} #LOG END }}''' self._template_proxy_conf = '''location ^~ {proxy_path} {{ {ip_limit} {basic_auth} proxy_pass {proxy_pass}; proxy_set_header Host {proxy_host}; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-Port $remote_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header REMOTE-HOST $remote_addr; {SNI} {timeout_conf} {websocket_support} {custom_conf} {proxy_cache} {gzip} {sub_filter} {server_log} }}''' def structure_proxy_conf(self, get): ''' @name @author wzz <2024/4/19 下午4:29> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' sni_conf = "" if get.proxy_pass.startswith("https://"): sni_conf = "proxy_ssl_server_name on;" get.proxy_conf = self._template_proxy_conf.format( ip_limit="", gzip="", proxy_cache="", sub_filter="", server_log="", basic_auth="", proxy_pass=get.proxy_pass, proxy_host=get.proxy_host, proxy_path=get.proxy_path, SNI=sni_conf, custom_conf="", timeout_conf=get.proxy_timeout, websocket_support=self._init_proxy_conf["websocket"]["websocket_conf"], ) get.proxy_info = { "proxy_type": get.proxy_type, "proxy_path": get.proxy_path, "proxy_pass": get.proxy_pass, "proxy_host": get.proxy_host, "ip_limit": { "ip_black": [], "ip_white": [], }, "basic_auth": {}, "proxy_cache": { "cache_status": False, "cache_zone": get.site_name.replace(".", "_") + "_cache", "static_cache": "", "expires": "1d", "cache_conf": "", }, "gzip": { "gzip_status": False, "gzip_min_length": "1k", "gzip_comp_level": "6", "gzip_types": "text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/json image/jpeg image/gif image/png font/ttf font/otf image/svg+xml application/xml+rss text/x-js", "gzip_conf": "gzip on;\n gzip_min_length 10k;\n gzip_buffers 4 16k;\n gzip_http_version 1.1;\n gzip_comp_level 2;\n gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;\n gzip_vary on;\n gzip_proxied expired no-cache no-store private auth;\n gzip_disable \"MSIE [1-6]\.\";", }, "sub_filter": { "sub_filter_str": [], }, "websocket": { "websocket_status": True, "websocket_conf": "proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection $connection_upgrade;", }, "proxy_log": { "log_type": "off", "log_conf": get.server_log, }, "timeout": { "proxy_connect_timeout": "60", "proxy_send_timeout": "600", "proxy_read_timeout": "600", "timeout_conf": "proxy_connect_timeout 60s;\n proxy_send_timeout 600s;\n proxy_read_timeout 600s;", }, "custom_conf": "", "proxy_conf": get.proxy_conf, "remark": "", "template_proxy_conf": self._template_proxy_conf, } # 2024/4/18 上午10:53 构造反向代理的配置文件 def structure_nginx(self, get): ''' @name 构造反向代理的配置文件 @author wzz <2024/4/18 上午10:54> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.err_age_404 = get.get("err_age_404", "#error_page 404 /404.html;") get.err_age_502 = get.get("err_age_502", "#error_page 502 /502.html;") get.proxy_info = get.get("proxy_info", "") get.server_log = get.get( "server_log", self._init_proxy_conf["proxy_log"]["log_conf"].format( log_path=public.get_logs_path(), site_name=get.site_name ) ) get.remark = get.get("remark", "") get.server_block = get.get("server_block", "") get.websocket_status = get.get("websocket_status", True) get.proxy_timeout = "proxy_connect_timeout 60s;\n proxy_send_timeout 600s;\n proxy_read_timeout 600s;" self.structure_proxy_conf(get) is_subs = public.ExecShell("nginx -V 2>&1|grep 'ngx_http_substitutions_filter' -o")[0] self._init_proxy_conf["subs_filter"] = True if is_subs != "" else False self._init_proxy_conf["site_name"] = get.site_name self._init_proxy_conf["domain_list"] = get.domain_list self._init_proxy_conf["site_port"] = get.port_list self._init_proxy_conf["site_path"] = get.site_path self._init_proxy_conf["err_age_404"] = get.err_age_404 self._init_proxy_conf["err_age_502"] = get.err_age_502 self._init_proxy_conf["proxy_log"]["log_conf"] = get.server_log self._init_proxy_conf["remark"] = get.remark self._init_proxy_conf["http_block"] = "" self._init_proxy_conf["proxy_info"].append(get.proxy_info) self._init_proxy_conf["proxy_cache"]["cache_zone"] = get.site_name.replace(".", "_") + "_cache" # 2024/4/18 上午10:35 写入Nginx配置文件 def write_nginx_conf(self, get): ''' @name 写入Nginx配置文件 @author wzz <2024/4/18 上午10:36> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' # 这里可能会报错 self.structure_nginx(get) if len(get.port_list) > 1: ipv4_port_conf = "" ipv6_port_conf = "" for p in get.port_list: ipv4_port_conf += self._init_proxy_conf["ipv4_port_conf"].format(listen_port=p) + "\n " ipv6_port_conf += self._init_proxy_conf["ipv6_port_conf"].format(listen_port=p) + "\n " else: ipv4_port_conf = self._init_proxy_conf["ipv4_port_conf"].format(listen_port=get.port_list[0]) ipv6_port_conf = self._init_proxy_conf["ipv6_port_conf"].format(listen_port=get.port_list[0]) port_conf = ipv4_port_conf + "\n" + ipv6_port_conf # 2024/6/4 下午4:20 兼容新版监控报表的配置 monitor_conf = "" if os.path.exists("/www/server/panel/plugin/monitor/monitor_main.py"): monitor_conf = '''#Monitor-Config-Start 网站监控报表日志发送配置 access_log syslog:server=unix:/tmp/bt-monitor.sock,nohostname,tag={pid}__access monitor; error_log syslog:server=unix:/tmp/bt-monitor.sock,nohostname,tag={pid}__error; #Monitor-Config-End'''.format(pid=get.pid) conf = self._template_conf.format( http_block=get.http_block, server_block="", port_conf=port_conf, ssl_start_msg=public.getMsg('NGINX_CONF_MSG1'), err_page_msg=public.getMsg('NGINX_CONF_MSG2'), php_info_start=public.getMsg('NGINX_CONF_MSG3'), rewrite_start_msg=public.getMsg('NGINX_CONF_MSG4'), log_path=public.get_logs_path(), domains=' '.join(get.domain_list) if len(get.domain_list) > 1 else get.site_name, site_name=get.site_name, ssl_info="#error_page 404/404.html;", err_age_404=get.err_age_404, err_age_502=get.err_age_502, ip_limit_conf="", auth_conf="", sub_filter="", gzip_conf="", redirect_conf="", security_conf="", proxy_conf=get.proxy_conf, server_log=get.server_log, site_path=get.site_path, proxy_cache="", websocket_support=self._init_proxy_conf["websocket"]["websocket_conf"], monitor_conf=monitor_conf, ) # 写配置文件 well_known_path = "{}/vhost/nginx/well-known".format(public.get_panel_path()) if not os.path.exists(well_known_path): os.makedirs(well_known_path, 0o600) public.writeFile("{}/{}.conf".format(well_known_path, get.site_name), "") get.filename = public.get_setup_path() + '/panel/vhost/nginx/' + get.site_name + '.conf' return public.writeFile(get.filename, conf) # 2024/4/25 上午11:11 检查nginx是否支持http3 def check_http3_support(self): ''' @name 检查nginx是否支持http3 @author wzz <2024/4/25 上午11:13> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' return public.ExecShell("nginx -V 2>&1| grep 'http_v3_module' -o")[0] # 2024/7/29 下午3:00 添加反代前置配置检测 def check_before_create(self, get): ''' @name 添加反代前置配置检测 @author wzz <2024/7/29 下午3:01> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' from mod.base.web_conf import util webserver = util.webserver() if webserver != "nginx" or webserver is None: return public.returnResult(status=False, msg="仅支持Nginx,请安装Nginx后再使用!") from panelSite import panelSite site_obj = panelSite() site_obj.check_default() wc_err = public.checkWebConfig() if not wc_err: return public.returnResult( status=False, msg='ERROR: 检测到配置文件有错误,请先排除后再操作<br><br><a style="color:red;">' + wc_err.replace("\n", '<br>') + '</a>' ) get.site_name = util.to_puny_code(get.domain_list[0].strip().split(":")[0]).strip().lower() public.check_domain_cloud(get.site_name) if get.site_name.find('*') != -1: return public.return_message(-1, 0, public.lang("The primary domain name cannot be a generic DNS")) main_domain = get.site_name opid = public.M('domain').where("name=? and port=?", (main_domain, int(get.site_port))).getField('pid') if opid: if public.M('sites').where('id=?', (opid,)).count(): return public.returnResult(status=False, msg='网站【{}】已存在,请勿重复添加!'.format(main_domain)) public.M('domain').where('pid=?', (opid,)).delete() if public.M('binding').where('domain=?', (main_domain,)).count(): return public.returnResult(status=False, msg='网站【{}】已存在,请勿重复添加!'.format(main_domain)) sql = public.M('sites') if sql.where("name=?", (get.site_name,)).count(): if public.is_ipv4(get.site_name): get.site_name = get.site_name + "_" + str(get.site_port) else: return public.returnResult(status=False, msg='网站【{}】已存在,请勿重复添加!'.format(main_domain)) return public.returnResult(True) # 2024/7/29 下午2:39 创建必须目录 def create_must_dir(self, get): ''' @name @author wzz <2024/7/29 下午2:40> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' if not os.path.exists(self._site_path): public.ExecShell('mkdir -p {}'.format(self._site_path)) public.ExecShell('chown -R www:www {}'.format(self._site_path)) public.ExecShell('chmod -R 755 {}'.format(self._site_path)) if not os.path.exists(get.site_path): public.ExecShell('mkdir -p {}'.format(get.site_path)) public.ExecShell('chown -R www:www {}'.format(get.site_path)) public.ExecShell('chmod -R 755 {}'.format(get.site_path)) if not os.path.exists(get.site_path + "/proxy_cache_dir"): public.ExecShell('mkdir -p {}'.format(get.site_path + "/proxy_cache_dir")) public.ExecShell('chown -R www:www {}'.format(get.site_path + "/proxy_cache_dir")) public.ExecShell('chmod -R 755 {}'.format(get.site_path + "/proxy_cache_dir")) # 2024/7/29 上午11:46 创建完成后置检测 def check_after_create(self, get): ''' @name 创建完成后置检测 @author wzz <2024/7/29 上午11:47> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' wc_err = public.checkWebConfig() if not wc_err: public.ExecShell("rm -f {}".format(self._site_proxy_conf_path)) public.ExecShell("rm -rf {}".format(get.filename)) public.M('sites').where('id=?', (get.pid,)).delete() public.M('domain').where('pid=?', (get.pid,)).delete() public.M('dk_sites').where('id=?', (get.dk_pid,)).delete() public.M('dk_domain').where('pid=?', (get.dk_pid,)).delete() return public.returnResult( status=False, msg='ERROR: 检测到配置文件有错误,请先排除后再操作<br><br><a style="color:red;">' + wc_err.replace("\n", '<br>') + '</a>' ) if type(wc_err) != bool and "test failed" in wc_err: public.ExecShell("rm -f {}".format(self._site_proxy_conf_path)) public.ExecShell("rm -rf {}".format(get.filename)) public.M('sites').where('id=?', (get.pid,)).delete() public.M('domain').where('pid=?', (get.pid,)).delete() public.M('dk_sites').where('id=?', (get.dk_pid,)).delete() public.M('dk_domain').where('pid=?', (get.dk_pid,)).delete() return public.returnResult( status=False, msg='ERROR: 检测到配置文件有错误,请先排除后再操作<br><br><a style="color:red;">' + wc_err.replace("\n", '<br>') + '</a>' ) return public.returnResult(True) # 2024/7/29 上午11:31 插入sites表 def insert_sites(self, get): ''' @name 插入sites或dk_sites表 @author wzz <2024/7/29 上午11:32> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' # 2024/4/18 上午10:22 写入数据库 if get.add_type == "all" or get.add_type == "sites": addtime = public.getDate() pdata = { 'name': get.site_name, 'rname': get.site_name, 'path': "/www/wwwroot/" + get.site_name, 'ps': get.remark, 'status': 1, 'type_id': 0, 'project_type': 'proxy', 'project_config': json.dumps(self._init_proxy_conf), 'addtime': addtime, } try: get.pid = public.M('sites').insert(pdata) if get.pid.find("error: table sites has no column named rname") != -1: create_table_str = public.M('sqlite_master').where('type=? AND name=?', ('table', 'sites')).getField('sql') if create_table_str and 'rname' not in create_table_str: public.M('sites').execute('ALTER TABLE `sites` ADD COLUMN `rname` VARCHAR default "";') # 重新添加 get.pid = public.M('sites').insert(pdata) # public.print_log("添加反向代理---{}".format(get.pid)) except: public.print_log(public.get_error_info()) if not get.pid: return public.return_message(-1, 0, public.lang("The addition failed and the data could not be inserted into the site database")) for domain in get.domain_list: public.M('domain').insert({ 'name': domain, 'pid': str(get.pid), 'port': '80' if ":" not in domain else domain.split(":")[1], 'addtime': addtime, }) return public.return_message(0, 0, '') # 2024/7/29 上午11:46 插入dk_sites表 def insert_dk_sites(self, get): ''' @name 插入sites或dk_sites表 @author wzz <2024/7/29 上午11:32> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' # 2024/4/18 上午10:22 写入数据库 if get.add_type == "all" or get.add_type == "dk_sites": opid = public.M('dk_domain').where("name=? and port=?", (get.site_name, int(get.site_port))).getField('pid') if opid: public.M('dk_sites').where('id=?', (opid,)).delete() public.M('dk_domain').where('pid=?', (opid,)).delete() addtime = public.getDate() pdata = { 'name': get.site_name, 'rname': get.site_name, 'path': "/www/wwwroot/" + get.site_name, 'ps': get.remark, 'status': 1, 'type_id': 111, 'project_type': 'dk_proxy', 'project_config': json.dumps(self._init_proxy_conf), 'addtime': addtime, 'container_id': get.container_id, 'container_name': get.container_name, 'container_port': get.container_port, } get.dk_pid = public.M('dk_sites').insert(pdata) if not get.dk_pid: return public.return_message(-1, 0, public.lang("The add failed and the data could not be inserted into the docker website database")) for domain in get.domain_list: public.M('dk_domain').insert({ 'name': domain, 'pid': str(get.dk_pid), 'port': '80' if ":" not in domain else domain.split(":")[1], 'addtime': addtime, }) return public.returnResult(True) # 2024/4/18 上午9:26 创建反向代理 def create(self, get): ''' @name 创建反向代理 @author wzz <2024/4/18 上午9:27> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' # 2024/4/18 上午9:45 参数处理 get.domains = get.get("domains", "") get.proxy_path = get.get("proxy_path", "/") get.proxy_pass = get.get("proxy_pass", "") get.proxy_host = get.get("proxy_host", "$http_host") get.remark = get.get("remark", "") get.proxy_type = get.get("proxy_type", "http") get.add_type = get.get("add_type", "all") get.pid = get.get("pid", None) get.dk_pid = get.get("dk_pid", None) # 2024/4/18 上午9:45 参数校验 if not get.domains: return public.returnResult(status=False, msg="域名不能为空,至少输入一个域名!") if not get.proxy_pass: return public.returnResult(status=False, msg="代理目标不能为空!") if get.remark != "": get.remark = public.xssencode2(get.remark) if get.proxy_type == "unix": if not get.proxy_pass.startswith("/"): return public.returnResult(status=False, msg="unix文件路径必须以/开头,如/tmp/flask_app.sock!") if not get.proxy_pass.endswith(".sock"): return public.returnResult(status=False, msg="unix文件必须以.sock结尾,如/tmp/flask_app.sock!") if not os.path.exists(get.proxy_pass): return public.returnResult(status=False, msg="代理目标不存在!") get.proxy_pass = "http://unix:{}".format(get.proxy_pass) elif get.proxy_type == "http": if not get.proxy_pass.startswith("http://") and not get.proxy_pass.startswith("https://"): return public.returnResult(status=False, msg="代理目标必须以http://或https://开头!") get.domain_list = get.domains.split("\n") get.site_port = get.domain_list[0].strip().split(":")[1] if ":" in get.domain_list[0] else "80" get.port_list = [get.site_port] cbres = self.check_before_create(get) if not cbres["status"]: return cbres get.site_path = "/www/wwwroot/" + get.site_name if not public.checkPort(get.site_port): return public.returnResult(status=False, msg='端口【{}】不合法!'.format(get.site_port)) if len(get.domain_list) > 1: for domain in get.domain_list[1:]: if not ":" in domain.strip(): continue d_port = domain.strip().split(":")[1] if not public.checkPort(d_port): return public.returnResult(status=False, msg='端口【{}】不合法!'.format(d_port)) if not d_port in get.port_list: get.port_list.append(d_port) # 2024/4/18 上午10:21 添加端口到系统防火墙 from firewallModelV2.comModel import main as comModel firewall_com = comModel() get.port = get.site_port firewall_com.set_port_rule(get) # 2024/4/18 上午10:46 写入网站配置文件 get.http_block = "proxy_cache_path /www/wwwroot/{site_name}/proxy_cache_dir levels=1:2 keys_zone={cache_name}_cache:20m inactive=1d max_size=5g;".format( site_name=get.site_name, cache_name=get.site_name.replace(".", "_") ) # 2024/6/4 下午4:30 写nginx配置文件 self.write_nginx_conf(get) # 2024/4/18 上午10:22 写入数据库 ires = self.insert_sites(get) # self.insert_dk_sites(get) if ires["status"] == -1: return ires self._site_path = self._proxy_config_path + '/' + get.site_name self.create_must_dir(get) self._site_proxy_conf_path = '{}/{}.json'.format(self._site_path, get.site_name) public.writeFile(self._site_proxy_conf_path, json.dumps(self._init_proxy_conf)) cres = self.check_after_create(get) if not cres["status"]: return cres public.WriteLog('TYPE_SITE', 'SITE_ADD_SUCCESS', (get.site_name,)) public.set_module_logs('dk_site_proxy', 'create', 1) public.serviceReload() return public.returnResult(msg="docker反代添加成功!") def read_json_conf(self, get): ''' @name @author wzz <2024/4/18 下午9:53> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) try: proxy_json_conf = json.loads(public.readFile(conf_path)) except Exception as e: import traceback print(traceback.format_exc()) proxy_json_conf = {} return proxy_json_conf # 2024/4/18 下午9:58 设置全局日志 def set_global_log(self, get): ''' @name @author wzz <2024/4/18 下午9:58> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.log_type = get.get("log_type", "default") if not get.log_type in ["default", "file", "rsyslog", "off"]: return public.returnResult(status=False, msg="日志类型错误,请传入default/file/rsyslog/off!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.proxy_json_conf["proxy_log"]["log_type"] = get.log_type if get.log_type == "file": get.log_path = get.get("log_path", "") if get.log_path == "": return public.returnResult(status=False, msg="日志路径不能为空!") if not get.log_path.startswith("/"): return public.returnResult(status=False, msg="日志路径必须以/开头!") get.proxy_json_conf["proxy_log"]["log_path"] = get.log_path get.proxy_json_conf["proxy_log"]["log_conf"] = self._init_proxy_conf["proxy_log"]["log_conf"].format( log_path=get.log_path, site_name=get.site_name ) elif get.log_type == "rsyslog": get.log_path = get.get("log_path", "") if get.log_path == "": return public.returnResult(status=False, msg="日志路径不能为空!") site_name = get.site_name.replace(".", "_") get.proxy_json_conf["proxy_log"]["log_conf"] = ( "\n access_log syslog:server={server_host},nohostname,tag=nginx_{site_name}_access;" "\n error_log syslog:server={server_host},nohostname,tag=nginx_{site_name}_error;" .format( server_host=get.log_path, site_name=site_name )) get.proxy_json_conf["proxy_log"]["rsyslog_host"] = get.log_path elif get.log_type == "off": get.proxy_json_conf["proxy_log"]["log_conf"] = "\n access_log off;\n error_log off;" else: get.proxy_json_conf["proxy_log"]["log_conf"] = " " + self._init_proxy_conf["proxy_log"][ "log_conf"].format( log_path=public.get_logs_path(), site_name=get.site_name ) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) public.serviceReload() return public.returnResult(msg="设置成功!") # 2024/4/18 下午10:21 设置basic_auth def set_dir_auth(self, get): ''' @name 设置basic_auth @param auth_type: add/edit auth_path: /api username: admin password: admin @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.name = get.get("name", "") if get.name == "": return public.returnResult(status=False, msg="name不能为空!") get.auth_path = get.get("auth_path", "") if get.auth_path == "": return public.returnResult(status=False, msg="auth_path不能为空!") if not get.auth_path.startswith("/"): return public.returnResult(status=False, msg="auth_path必须以/开头!") get.username = get.get("username", "") get.password = get.get("password", "") if get.username == "" or get.password == "": return public.returnResult(status=False, msg="用户名和密码不能为空!") get.password = public.hasPwd(get.password) get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") if len(get.proxy_json_conf["basic_auth"]) == 0: return public.returnResult(status=False, msg="【{}】不存在http认证中,请先添加!".format(get.auth_path)) for i in range(len(get.proxy_json_conf["basic_auth"])): if get.proxy_json_conf["basic_auth"][i]["auth_path"] == get.auth_path: if get.proxy_json_conf["basic_auth"][i]["auth_name"] == get.name: get.proxy_json_conf["basic_auth"][i]["username"] = get.username get.proxy_json_conf["basic_auth"][i]["password"] = get.password break auth_file = "/www/server/pass/{site_name}/{name}.htpasswd".format(site_name=get.site_name, name=get.name) public.writeFile(auth_file, "{}:{}".format(get.username, get.password)) self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) public.serviceReload() return public.returnResult(msg="设置成功!") # 2024/4/22 下午4:17 添加指定网站的basic_auth def add_dir_auth(self, get): ''' @name 添加指定网站的basic_auth @author wzz <2024/4/22 下午4:17> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.auth_path = get.get("auth_path", "") if get.auth_path == "": return public.returnResult(status=False, msg="auth_path不能为空!") if not get.auth_path.startswith("/"): return public.returnResult(status=False, msg="auth_path必须以/开头!") get.name = get.get("name", "") if get.name == "": return public.returnResult(status=False, msg="name不能为空!") get.username = get.get("username", "") if get.username == "": return public.returnResult(status=False, msg="username不能为空!") get.password = get.get("password", "") if get.password == "": return public.returnResult(status=False, msg="password不能为空!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") auth_file = "/www/server/pass/{site_name}/{name}.htpasswd".format(site_name=get.site_name, name=get.name) auth_conf = { "auth_status": True, "auth_path": get.auth_path, "auth_name": get.name, "username": get.username, "password": public.hasPwd(get.password), "auth_file": auth_file, } if len(get.proxy_json_conf["basic_auth"]) != 0: for i in range(len(get.proxy_json_conf["basic_auth"])): if get.proxy_json_conf["basic_auth"][i]["auth_path"] == get.auth_path: return public.returnResult(status=False, msg="【{}】已存在http认证中,无法重复添加!".format(get.auth_path)) if not os.path.exists("/www/server/pass"): public.ExecShell("mkdir -p /www/server/pass") if not os.path.exists("/www/server/pass/{}".format(get.site_name)): public.ExecShell("mkdir -p /www/server/pass/{}".format(get.site_name)) public.writeFile(auth_file, "{}:{}".format(get.username, public.hasPwd(get.password))) get.proxy_json_conf["basic_auth"].append(auth_conf) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="Successfully added!") # 2024/4/23 上午9:34 删除指定网站的basic_auth def del_dir_auth(self, get): ''' @name 删除指定网站的basic_auth @author wzz <2024/4/23 上午9:35> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.auth_path = get.get("auth_path", "") if get.auth_path == "": return public.returnResult(status=False, msg="auth_path不能为空!") get.name = get.get("name", "") if get.name == "": return public.returnResult(status=False, msg="name不能为空!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") auth_file = "/www/server/pass/{site_name}/{name}.htpasswd".format(site_name=get.site_name, name=get.name) panel_port = public.readFile('/www/server/panel/data/port.pl') proxy_list = self.get_proxy_list(get) if proxy_list["data"][0]["proxy_pass"] == "https://127.0.0.1:{}".format(panel_port.strip()) and get.auth_path.strip() == "/": return public.return_message(-1, 0, public.lang("[{}] is the reverse generation of the panel, and the http authentication of [/] cannot be deleted!",get.site_name)) if len(get.proxy_json_conf["basic_auth"]) != 0: for i in range(len(get.proxy_json_conf["basic_auth"])): if get.proxy_json_conf["basic_auth"][i]["auth_path"] == get.auth_path: if get.proxy_json_conf["basic_auth"][i]["auth_name"] == get.name: get.proxy_json_conf["basic_auth"].pop(i) break public.ExecShell("rm -f {}".format(auth_file)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="删除成功!") # 2024/4/18 下午10:26 设置全局gzip def set_global_gzip(self, get): ''' @name 设置全局gzip @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.gzip_status = get.get("gzip_status/d", 999) if get.gzip_status == 999: return public.returnResult(status=False, msg="gzip_status不能为空,请传number 1或0!") get.gzip_min_length = get.get("gzip_min_length", "10k") get.gzip_comp_level = get.get("gzip_comp_level", "6") if get.gzip_min_length[0] == "0" or get.gzip_min_length.startswith("-"): return public.returnResult(status=False, msg="gzip_min_length参数不合法,请输入大于0的数字!") if get.gzip_comp_level == "0" or get.gzip_comp_level.startswith("-"): return public.returnResult(status=False, msg="gzip_comp_level参数不合法,请输入大于0的数字!") get.gzip_types = get.get( "gzip_types", "text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/json image/jpeg image/gif image/png font/ttf font/otf image/svg+xml application/xml+rss text/x-js" ) get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.proxy_json_conf["gzip"]["gzip_status"] = True if get.gzip_status == 1 else False if get.proxy_json_conf["gzip"]["gzip_status"]: get.proxy_json_conf["gzip"]["gzip_status"] = True get.proxy_json_conf["gzip"]["gzip_min_length"] = get.gzip_min_length get.proxy_json_conf["gzip"]["gzip_comp_level"] = get.gzip_comp_level get.proxy_json_conf["gzip"]["gzip_types"] = get.gzip_types get.gzip_conf = ("gzip on;" "\n gzip_min_length {gzip_min_length};" "\n gzip_buffers 4 16k;" "\n gzip_http_version 1.1;" "\n gzip_comp_level {gzip_comp_level};" "\n gzip_types {gzip_types};" "\n gzip_vary on;" "\n gzip_proxied expired no-cache no-store private auth;" "\n gzip_disable \"MSIE [1-6]\.\";").format( gzip_min_length=get.gzip_min_length, gzip_comp_level=get.gzip_comp_level, gzip_types=get.gzip_types ) get.proxy_json_conf["gzip"]["gzip_conf"] = get.gzip_conf else: get.proxy_json_conf["gzip"]["gzip_conf"] = "" update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/18 下午10:27 设置全局缓存 def set_global_cache(self, get): ''' @name 设置全局缓存 @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.cache_status = get.get("cache_status/d", 999) if get.cache_status == 999: return public.returnResult(status=False, msg="cache_status不能为空,请传number 1或0!") get.expires = get.get("expires", "1d") if get.expires[0] == "0" or get.expires.startswith("-"): return public.returnResult(status=False, msg="expires参数不合法,请输入大于0的数字!") expires = "expires {}".format(get.expires) get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") static_cache = ("\n location ~ .*\\.(css|js|jpe?g|gif|png|webp|woff|eot|ttf|svg|ico|css\.map|js\.map)$" "\n {{" "\n {expires};" "\n error_log /dev/null;" "\n access_log /dev/null;" "\n }}").format( expires=expires, ) cache_conf = ("\n proxy_cache {cache_zone};" "\n proxy_cache_key $host$uri$is_args$args;" "\n proxy_ignore_headers Set-Cookie Cache-Control expires X-Accel-Expires;" "\n proxy_cache_valid 200 304 301 302 {expires};" "\n proxy_cache_valid 404 1m;" "{static_cache}").format( cache_zone=get.proxy_json_conf["proxy_cache"]["cache_zone"], expires=get.expires, static_cache=get.proxy_json_conf["proxy_cache"]["static_cache"] if get.proxy_json_conf["proxy_cache"][ "static_cache"] != "" else static_cache ) get.proxy_json_conf["proxy_cache"]["cache_status"] = True if get.cache_status == 1 else False if get.proxy_json_conf["proxy_cache"]["cache_status"]: get.proxy_json_conf["proxy_cache"]["cache_status"] = True get.proxy_json_conf["proxy_cache"]["expires"] = get.expires get.proxy_json_conf["proxy_cache"]["cache_conf"] = cache_conf else: get.proxy_json_conf["proxy_cache"]["cache_status"] = False get.proxy_json_conf["proxy_cache"]["cache_conf"] = static_cache update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/18 下午10:43 设置全局websocket支持 def set_global_websocket(self, get): ''' @name @author wzz <2024/4/19 下午2:37> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.websocket_status = get.get("websocket_status/d", 999) if get.websocket_status == 999: return public.returnResult(status=False, msg="websocket_status不能为空,请传number 1或0!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") if get.websocket_status == 1: get.proxy_json_conf["websocket"]["websocket_status"] = True else: get.proxy_json_conf["websocket"]["websocket_status"] = False update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/19 下午2:54 设置备注 def set_remak(self, get): ''' @name 设置备注 @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.id = get.get("id", "") if get.id == "": return public.returnResult(status=False, msg="id不能为空!") get.remark = get.get("remark", "") get.table = "sites" get.ps = get.remark get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") from data import data data_obj = data() result = data_obj.setPs(get) if not result["status"]: public.returnResult(status=False, msg=result["msg"]) get.proxy_json_conf["remark"] = get.remark self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return public.returnResult(msg=result["msg"]) # 2024/4/19 下午2:59 添加反向代理 def add_proxy(self, get): ''' @name @author wzz <2024/4/19 下午3:00> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") if get.proxy_path == "": return public.returnResult(status=False, msg="proxy_path不能为空!") get.proxy_pass = get.get("proxy_pass", "") if get.proxy_pass == "": return public.returnResult(status=False, msg="proxy_pass不能为空!") get.proxy_host = get.get("proxy_host", "$http_host") get.proxy_type = get.get("proxy_type", "http") get.remark = get.get("remark", "") get.proxy_timeout = "proxy_connect_timeout 60s;\n proxy_send_timeout 600s;\n proxy_read_timeout 600s;" if get.remark != "": get.remark = public.xssencode2(get.remark) if get.proxy_type == "unix": if not get.proxy_pass.startswith("/"): return public.returnResult(status=False, msg="unix文件路径必须以/开头,如/tmp/flask_app.sock!") if not get.proxy_pass.endswith(".sock"): return public.returnResult(status=False, msg="unix文件必须以.sock结尾,如/tmp/flask_app.sock!") if not os.path.exists(get.proxy_pass): return public.returnResult(status=False, msg="代理目标不存在!") get.proxy_pass = "http://unix:{}".format(get.proxy_pass) elif get.proxy_type == "http": if not get.proxy_pass.startswith("http://") and not get.proxy_pass.startswith("https://"): return public.returnResult(status=False, msg="代理目标必须以http://或https://开头!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") # 2024/4/19 下午3:45 检测是否已经存在proxy_path,有的话就返回错误 for proxy_info in get.proxy_json_conf["proxy_info"]: if proxy_info["proxy_path"] == get.proxy_path: return public.returnResult(status=False, msg="【{}】已存在反向代理中,无法重复添加!".format(get.proxy_path)) if len(get.proxy_json_conf["basic_auth"]) != 0: for i in range(len(get.proxy_json_conf["basic_auth"])): if get.proxy_json_conf["basic_auth"][i]["auth_path"] == get.proxy_path: return public.returnResult(status=False, msg="【{}】已存在basicauth中,请先删除再添加反向代理!".format( get.proxy_path)) sni_conf = "" if get.proxy_pass.startswith("https://"): sni_conf = "proxy_ssl_server_name on;" get.proxy_conf = self._template_proxy_conf.format( ip_limit="", gzip="", proxy_cache="", sub_filter="", server_log="", basic_auth="", proxy_pass=get.proxy_pass, proxy_host=get.proxy_host, proxy_path=get.proxy_path, SNI=sni_conf, custom_conf="", timeout_conf=get.proxy_timeout, websocket_support=get.proxy_json_conf["websocket"]["websocket_conf"], ) get.proxy_json_conf["proxy_info"].append({ "proxy_type": get.proxy_type, "proxy_path": get.proxy_path, "proxy_pass": get.proxy_pass, "proxy_host": get.proxy_host, "ip_limit": { "ip_black": [], "ip_white": [], }, "basic_auth": {}, "proxy_cache": { "cache_status": False, "cache_zone": "", "static_cache": "", "expires": "1d", "cache_conf": "", }, "gzip": { "gzip_status": False, "gzip_min_length": "10k", "gzip_comp_level": "6", "gzip_types": "text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/json image/jpeg image/gif image/png font/ttf font/otf image/svg+xml application/xml+rss text/x-js", "gzip_conf": "gzip on;\n gzip_min_length 10k;\n gzip_buffers 4 16k;\n gzip_http_version 1.1;\n gzip_comp_level 2;\n gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;\n gzip_vary on;\n gzip_proxied expired no-cache no-store private auth;\n gzip_disable \"MSIE [1-6]\.\";", }, "sub_filter": { "sub_filter_str": [], }, "websocket": { "websocket_status": True, "websocket_conf": "proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection $connection_upgrade;", }, "proxy_log": { "log_type": "off", "log_conf": "", }, "timeout": { "proxy_connect_timeout": "60", "proxy_send_timeout": "600", "proxy_read_timeout": "600", "timeout_conf": "proxy_connect_timeout 60s;\n proxy_send_timeout 600s;\n proxy_read_timeout 600s;", }, "custom_conf": "", "proxy_conf": get.proxy_conf, "remark": get.remark, "template_proxy_conf": self._template_proxy_conf, }) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) public.set_module_logs('dk_site_proxy', 'add_proxy', 1) return public.returnResult(msg="Successfully added!") # 2024/4/19 下午9:45 删除指定站点 def delete(self, get): ''' @name @author wzz <2024/4/19 下午9:45> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") get.id = get.get("id", "") get.remove_path = get.get("remove_path/d", 0) if get.id == "": return public.returnResult(status=False, msg="id不能为空!") get.reload = get.get("reload/d", 1) if public.M('sites').where('id=?', (get.id,)).count() < 1: return public.returnResult(status=False, msg='指定站点不存在!') site_file = public.get_setup_path() + '/panel/vhost/nginx/' + get.site_name + '.conf' if os.path.exists(site_file): public.ExecShell('rm -f {}'.format(site_file)) redirect_dir = public.get_setup_path() + '/panel/vhost/nginx/redirect/' + get.site_name if os.path.exists(redirect_dir): public.ExecShell('rm -rf {}'.format(redirect_dir)) logs_file = public.get_logs_path() + '/{}*'.format(get.site_name) public.ExecShell('rm -f {}'.format(logs_file)) self._site_proxy_conf_path = "{path}/{site_name}".format( path=self._proxy_config_path, site_name=get.site_name ) public.ExecShell('rm -f {}'.format(self._site_proxy_conf_path)) if get.remove_path == 1: public.ExecShell('rm -rf /www/wwwroot/{}'.format(get.site_name)) if get.reload == 1: public.serviceReload() # 从数据库删除 public.M('sites').where("id=?", (get.id,)).delete() public.M('domain').where("pid=?", (get.id,)).delete() public.WriteLog('TYPE_SITE', "SITE_DEL_SUCCESS", (get.site_name,)) return public.returnResult(msg="反向代理项目删除成功!") # 2024/5/28 上午9:50 批量删除站点 def batch_delete(self, get): ''' @name 批量删除站点 @author wzz <2024/5/28 上午9:51> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_list = get.get("site_list", []) get.remove_path = get.get("remove_path/d", 0) get.reload = get.get("reload/d", 0) try: site_list = json.loads(get.site_list) except: return public.return_message(-1, 0, public.lang("Please pass in a list of websites that need to be deleted!")) acc_list = [] for site in site_list: args = public.dict_obj() args.site_name = site["site_name"] args.remove_path = get.remove_path args.reload = get.reload args.id = site["id"] de_result = self.delete(args) if not de_result["status"]: acc_list.append({"site_name": site["site_name"], "status": False}) continue acc_list.append({"site_name": site["site_name"], "status": True}) public.serviceReload() return public.return_message(0, 0, acc_list) # return public.returnResult(True, msg="Batch deletion of sites successful!", data=acc_list) # 2024/4/26 下午4:57 获取证书的部署状态 def get_site_ssl_info(self, siteName): ''' @name 获取证书的部署状态 @author wzz <2024/4/26 下午4:58> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' try: import time import re s_file = 'vhost/nginx/{}.conf'.format(siteName) is_apache = False if not os.path.exists(s_file): s_file = 'vhost/apache/{}.conf'.format(siteName) is_apache = True if not os.path.exists(s_file): return -1 s_conf = public.readFile(s_file) if not s_conf: return -1 ssl_file = None if is_apache: if s_conf.find('SSLCertificateFile') == -1: return -1 s_tmp = re.findall(r"SSLCertificateFile\s+(.+\.pem)", s_conf) if not s_tmp: return -1 ssl_file = s_tmp[0] else: if s_conf.find('ssl_certificate') == -1: return -1 s_tmp = re.findall(r"ssl_certificate\s+(.+\.pem);", s_conf) if not s_tmp: return -1 ssl_file = s_tmp[0] ssl_info = public.get_cert_data(ssl_file) if not ssl_info: return -1 ssl_info['endtime'] = int( int(time.mktime(time.strptime(ssl_info['notAfter'], "%Y-%m-%d")) - time.time()) / 86400) return ssl_info except: return -1 # 2024/4/19 下午10:05 获取所有project_type为proxy的站点,需要做分页配置,按照添加时间排序 def get_list(self, get): ''' @name 获取所有project_type为proxy的站点,需要做分页配置,按照添加时间排序 @param get: @return: ''' get.p = get.get("p/d", 1) get.limit = get.get("limit/d", 10) get.search = get.get("search", "") where = "project_type=?" if get.search != "": where += " and name like ?" param = ("proxy", "%{}%".format(get.search)) else: param = ("proxy",) import db sql = db.Sql() count = sql.table('sites').where(where, param).count() import page page = page.Page() data = {} info = {} info['count'] = count info['row'] = get.limit info['p'] = 1 if hasattr(get, 'p'): info['p'] = int(get['p']) if info['p'] < 1: info['p'] = 1 try: from flask import request info['uri'] = public.url_encode(request.full_path) except: info['uri'] = '' info['return_js'] = '' data['where'] = where data['page'] = page.GetPage(info) sql.table('sites').where(where, param) sql.field('id,name,path,status,ps,addtime,edate,rname').order('id desc') sql.limit(str(page.SHIFT) + ',' + str(page.ROW)) data['data'] = sql.select() try: path = '/www/server/btwaf/site.json' waf_res = json.loads(public.readFile(path)) except: waf_res = {} for site in data['data']: get.site_name = site["name"] project_config = self.read_json_conf(get) site["healthy"] = 1 site["waf"] = {} if not project_config: site["healthy"] = 0 site["conf_path"] = "" site["ssl"] = -1 site["proxy_pass"] = "" continue site["conf_path"] = public.get_setup_path() + '/panel/vhost/nginx/' + get.site_name + '.conf' site["ssl"] = self.get_site_ssl_info(get.site_name) site["proxy_pass"] = project_config["proxy_info"][0]["proxy_pass"] if waf_res: for waf in waf_res: if "open" in waf_res[waf]: site["waf"] = {"status": True} return public.returnResult(data=data) # 2024/4/19 下午11:46 给指定网站添加域名 def add_domain(self, get): ''' @name @author wzz <2024/4/19 下午11:46> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.id = get.get("id", "") if get.id == "": return public.returnResult(status=False, msg="id不能为空!") get.domains = get.get("domains", "") if get.domains == "": return public.returnResult(status=False, msg="domains不能为空!") if "," in get.domains: return public.returnResult(status=False, msg="域名不能包含逗号!") get.domain_list = get.domains.strip().replace(' ', '').split("\n") public.check_domain_cloud(get.domain_list[0]) get.domain = ",".join(get.domain_list) get.webname = get.site_name port_list = [] for domain in get.domain_list: if not ":" in domain.strip(): continue d_port = domain.strip().split(":")[1] if not public.checkPort(d_port): return public.returnResult(status=False, msg='域名【{}】的端口号不合法!'.format(domain)) port_list.append(d_port) # 2024/4/20 上午12:02 更新json文件 get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.proxy_json_conf["domain_list"].extend(get.domain_list) get.proxy_json_conf["site_port"].extend(port_list) self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) from panelSite import panelSite result = panelSite().AddDomain(get) if "status" in result and not result["status"]: return public.returnResult(status=False, msg=result["msg"]) return public.returnResult(status=True, data=result["domains"]) # 2024/4/20 上午12:07 删除指定网站的某个域名 def del_domain(self, get): ''' @name @author wzz <2024/4/20 上午12:07> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.id = get.get("id", "") if get.id == "": return public.returnResult(status=False, msg="id不能为空!") get.port = get.get("port", "") if get.port == "": return public.returnResult(status=False, msg="port不能为空!") get.domain = get.get("domain", "") if get.domain == "": return public.returnResult(status=False, msg="domain不能为空!") get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.webname = get.site_name # 2024/4/20 上午12:02 更新json文件 get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") if len(get.proxy_json_conf["domain_list"]) == 1: return public.returnResult(status=False, msg="至少保留一个域名!") while get.domain in get.proxy_json_conf["domain_list"]: get.proxy_json_conf["domain_list"].remove(get.domain) if get.port in get.proxy_json_conf["site_port"] and len(get.proxy_json_conf["site_port"]) != 1: while get.port in get.proxy_json_conf["site_port"]: get.proxy_json_conf["site_port"].remove(get.port) self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) from panelSite import panelSite result = panelSite().DelDomain(get) return public.returnResult(status=result["status"], msg=result["msg"]) # 2024/4/20 上午12:20 批量删除指定网站域名 def batch_del_domain(self, get): ''' @name 批量删除指定网站域名 @param get: @return: ''' get.id = get.get("id", "") if get.id == "": return public.returnResult(status=False, msg="id不能为空!") get.domains = get.get("domains", "") if get.domains == "": return public.returnResult(status=False, msg="domains不能为空!") get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.webname = get.site_name # 2024/4/20 上午12:02 更新json文件 get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") # if len(get.proxy_json_conf["domain_list"]) == 1: # return public.returnResult(status=False, msg="至少保留一个域名!") get.domain_list = get.domains.strip().replace(' ', '').split("\n") # if len(get.domain_list) == len(get.proxy_json_conf["domain_list"]): # return public.returnResult(status=False, msg="至少保留一个域名!") for domain in get.domain_list: while domain in get.proxy_json_conf["domain_list"]: get.proxy_json_conf["domain_list"].remove(domain) if ":" in domain: port = domain.split(":")[1] if len(get.proxy_json_conf["site_port"]) == 1: continue while port in get.proxy_json_conf["site_port"]: get.proxy_json_conf["site_port"].remove(port) self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) from panelSite import panelSite res_domains = [] for domain in get.domain_list: get.domain = domain get.port = "80" if ":" in domain: get.port = domain.split(":")[1] result = panelSite().DelDomain(get) res_domains.append({"name": domain, "status": result["status"], "msg": result["msg"]}) public.serviceReload() return public.returnResult(status=True, data=res_domains) # 2024/4/20 上午9:17 获取域名列表和https端口 def get_domain_list(self, get): ''' @name 获取域名列表和https端口 @param get: @return: ''' get.id = get.get("id", "") if get.id == "": return public.returnResult(status=False, msg="id不能为空!") get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.siteName = get.webname = get.site_name get.table = "domain" get.list = True get.search = get.id # 2024/4/20 上午12:02 更新json文件 get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") result_data = {} import data dataObject = data.data() result_data["domain_list"] = dataObject.getData(get) if get.proxy_json_conf["ssl_info"]["ssl_status"]: if not "https_port" in get.proxy_json_conf or get.proxy_json_conf["https_port"] == "": get.proxy_json_conf["https_port"] = "443" result_data["https_port"] = get.proxy_json_conf["https_port"] else: result_data["https_port"] = "未开启HTTPS" # 2024/4/20 上午9:21 domain_list里面没有的域名健康状态显示为0 for domain in result_data["domain_list"]: domain["healthy"] = 1 if domain["name"] not in get.proxy_json_conf["domain_list"]: domain["healthy"] = 0 public.set_module_logs('dk_site_proxy', 'get_domain_list', 1) return public.returnResult(data=result_data) # 2024/4/20 下午2:22 获取配置文件 def get_config(self, get): ''' @name @author wzz <2024/4/20 下午2:22> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") site_conf = public.readFile(public.get_setup_path() + '/panel/vhost/nginx/' + get.site_name + '.conf') ssl_conf = get.proxy_json_conf["ssl_info"]["ssl_conf"].format( site_name=get.site_name, ) if get.proxy_json_conf["ssl_info"]["force_https"]: ssl_conf = get.proxy_json_conf["ssl_info"]["force_ssl_conf"].format( site_name=get.site_name, force_conf=get.proxy_json_conf["ssl_info"]["force_ssl_conf"], ) if "如果反代网站访问异常且这里已经配置了内容,请优先排查此处的配置是否正确" in get.proxy_json_conf["http_block"]: http_block = get.proxy_json_conf["http_block"] else: http_block = '''# 可设置server|upstream|map等所有http字段,如: # server {{ # listen 10086; # server_name ... # }} # upstream stream_ser {{ # server back_test.com; # server ... # }} {default_describe} {http_block}'''.format( default_describe=self._init_proxy_conf["default_describe"], http_block=get.proxy_json_conf["http_block"], ) if "如果反代网站访问异常且这里已经配置了内容,请优先排查此处的配置是否正确" in get.proxy_json_conf["server_block"]: server_block = get.proxy_json_conf["server_block"] else: server_block = '''# 可设置server|location等所有server字段,如: # location /web {{ # try_files $uri $uri/ /index.php$is_args$args; # }} # error_page 404 /diy_404.html; {default_describe} {server_block}'''.format( default_describe=self._init_proxy_conf["default_describe"], server_block=get.proxy_json_conf["server_block"], ) data = { "site_conf": site_conf if not site_conf is False else "", "http_block": http_block, "server_block": server_block, "ssl_conf": ssl_conf, } return public.returnResult(data=data) # 2024/4/20 下午2:38 保存配置文件 def save_config(self, get): ''' @name 保存配置文件 @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.conf_type = get.get("conf_type", "") if get.conf_type == "": return public.returnResult(status=False, msg="conf_type不能为空!") get.body = get.get("body", "") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") if get.conf_type == "http_block": get.proxy_json_conf["http_block"] = get.body else: get.proxy_json_conf["server_block"] = get.body update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) public.serviceReload() return public.returnResult(msg="保存成功!") # 2024/4/20 下午3:11 根据proxy_json_conf,填入self._template_conf,然后生成nginx配置,保存到指定网站的conf文件中 def generate_config(self, get): """ @name 根据proxy_json_conf,填入self._template_conf,然后生成nginx配置,保存到指定网站的conf文件中 @param get: @return: """ # 2024/4/20 下午3:36 构造ip黑白名单 ip_black = "" ip_white = "" for ip in get.proxy_json_conf["ip_limit"]["ip_black"]: ip_black += ("deny {};\n ").format(ip) for ip in get.proxy_json_conf["ip_limit"]["ip_white"]: ip_white += ("allow {};\n ").format(ip) if ip_white != "": ip_white += "deny all;" ip_limit_conf = ip_black + "\n " + ip_white proxy_conf = "" ignore_path = [] if len(get.proxy_json_conf["proxy_info"]) != 0: for info in get.proxy_json_conf["proxy_info"]: proxy_auth_conf = "" if info["basic_auth"]: proxy_auth_conf = ("auth_basic \"Authorization\";" "\n auth_basic_user_file {auth_file};").format( auth_path=info["basic_auth"]["auth_path"], auth_file=info["basic_auth"]["auth_file"], ) if len(get.proxy_json_conf["basic_auth"]) != 0: for auth in get.proxy_json_conf["basic_auth"]: if info["proxy_path"] == auth["auth_path"]: ignore_path.append(auth["auth_path"]) proxy_auth_conf = ("auth_basic \"Authorization\";" "\n auth_basic_user_file {auth_file};").format( auth_path=auth["auth_path"], auth_file=auth["auth_file"], ) break p_ip_black = "" p_ip_white = "" for ip in info["ip_limit"]["ip_black"]: p_ip_black += ("deny {};\n ").format(ip) for ip in info["ip_limit"]["ip_white"]: p_ip_white += ("allow {};\n ").format(ip) if p_ip_white != "": p_ip_white += "deny all;" p_ip_limit_conf = p_ip_black + "\n " + p_ip_white if p_ip_black == "" and p_ip_white == "": p_ip_limit_conf = "" p_gzip_conf = "" if info["gzip"]["gzip_status"]: p_gzip_conf = info["gzip"]["gzip_conf"] p_sub_filter = "" if len(info["sub_filter"]["sub_filter_str"]) != 0: p_sub_filter = 'proxy_set_header Accept-Encoding \"\";' if not "subs_filter" in get.proxy_json_conf: get.proxy_json_conf["subs_filter"] = public.ExecShell("nginx -V 2>&1|grep 'ngx_http_substitutions_filter' -o")[0] != "" if not get.proxy_json_conf["subs_filter"]: for filter in info["sub_filter"]["sub_filter_str"]: p_sub_filter += "\n sub_filter {oldstr} {newstr};".format( oldstr=filter["oldstr"] if filter["oldstr"] != "" else "\"\"", newstr=filter["newstr"] if filter["newstr"] != "" else "\"\"", ) p_sub_filter += "\n sub_filter_once off;" else: for filter in info["sub_filter"]["sub_filter_str"]: p_sub_filter += "\n subs_filter {oldstr} {newstr} {sub_type};".format( oldstr=filter["oldstr"] if filter["oldstr"] != "" else "\"\"", newstr=filter["newstr"] if filter["newstr"] != "" else "\"\"", sub_type=filter["sub_type"] if "sub_type" in filter and filter["sub_type"] != "" else "\"\"", ) p_websocket_support = "" if info["websocket"]["websocket_status"]: p_websocket_support = info["websocket"]["websocket_conf"] timeout_conf = ("proxy_connect_timeout {proxy_connect_timeout};" "\n proxy_send_timeout {proxy_send_timeout};" "\n proxy_read_timeout {proxy_read_timeout};").format( proxy_connect_timeout=info["timeout"]["proxy_connect_timeout"].replace("s", "") + "s", proxy_send_timeout=info["timeout"]["proxy_send_timeout"].replace("s", "") + "s", proxy_read_timeout=info["timeout"]["proxy_read_timeout"].replace("s", "") + "s", ) sni_conf = "" if info["proxy_pass"].startswith("https://"): sni_conf = "proxy_ssl_server_name on;" tmp_conf = info["template_proxy_conf"].format( basic_auth=proxy_auth_conf, ip_limit=p_ip_limit_conf, gzip=p_gzip_conf, sub_filter=p_sub_filter, proxy_cache=info["proxy_cache"]["cache_conf"], server_log="", proxy_pass=info["proxy_pass"], proxy_host=info["proxy_host"], proxy_path=info["proxy_path"], custom_conf=info["custom_conf"], timeout_conf=timeout_conf, websocket_support=p_websocket_support, SNI=sni_conf, ) info["proxy_conf"] = tmp_conf proxy_conf += tmp_conf + "\n " # 2024/4/20 下午3:37 构造basicauth auth_conf = "" if len(get.proxy_json_conf["basic_auth"]) != 0: for auth in get.proxy_json_conf["basic_auth"]: if auth["auth_path"] not in ignore_path: tmp_conf = ("location ^~ {auth_path} {{" "\n auth_basic \"Authorization\";" "\n auth_basic_user_file {auth_file};" "\n }}").format(auth_path=auth["auth_path"], auth_file=auth["auth_file"]) auth_conf += tmp_conf + "\n " websocket_support = "" if get.proxy_json_conf["websocket"]["websocket_status"]: websocket_support = get.proxy_json_conf["websocket"]["websocket_conf"] gzip_conf = "" if get.proxy_json_conf["gzip"]["gzip_status"]: gzip_conf = get.proxy_json_conf["gzip"]["gzip_conf"] ssl_conf = "#error_page 404/404.html;" # listen_port = " ".join(get.proxy_json_conf["site_port"]) # listen_ipv6 = "\n listen [::]:{};".format(" ".join(get.proxy_json_conf["site_port"])) # port_conf = get.proxy_json_conf["port_conf"].format( # listen_port=listen_port, # listen_ipv6=listen_ipv6, # ) if not "https_port" in get.proxy_json_conf or get.proxy_json_conf["https_port"] == "": get.proxy_json_conf["https_port"] = "443" if not "ipv4_port_conf" in get.proxy_json_conf: get.proxy_json_conf["ipv4_port_conf"] = "listen {listen_port};" if not "ipv6_port_conf" in get.proxy_json_conf: get.proxy_json_conf["ipv6_port_conf"] = "listen [::]:{listen_port};" if not "ipv4_http3_ssl_port_conf" in get.proxy_json_conf: get.proxy_json_conf["ipv4_http3_ssl_port_conf"] = "{ipv4_port_conf}\n listen {https_port} quic;\n listen {https_port} ssl;" if not "ipv6_http3_ssl_port_conf" in get.proxy_json_conf: get.proxy_json_conf["ipv6_http3_ssl_port_conf"] = "{ipv6_port_conf}\n listen [::]:{https_port} quic;\n listen [::]:{https_port} ssl ;" if not "ipv4_ssl_port_conf" in get.proxy_json_conf: get.proxy_json_conf["ipv4_ssl_port_conf"] = "{ipv4_port_conf}\n listen {https_port} ssl http2 ;" if not "ipv6_ssl_port_conf" in get.proxy_json_conf: get.proxy_json_conf["ipv6_ssl_port_conf"] = "{ipv6_port_conf}\n listen [::]:{https_port} ssl http2 ;" ipv4_port_conf = "" ipv6_port_conf = "" for p in get.proxy_json_conf["site_port"]: ipv4_port_conf += get.proxy_json_conf["ipv4_port_conf"].format( listen_port=p, ) + "\n " ipv6_port_conf += get.proxy_json_conf["ipv6_port_conf"].format( listen_port=p, ) + "\n " if get.proxy_json_conf["ssl_info"]["ssl_status"]: if public.ExecShell("nginx -V 2>&1| grep 'http_v3_module' -o")[0] != "": ipv4_http3_ssl_port_conf = get.proxy_json_conf["ipv4_http3_ssl_port_conf"].format( ipv4_port_conf=ipv4_port_conf, https_port=get.proxy_json_conf["https_port"], ) + "\n " ipv6_http3_ssl_port_conf = get.proxy_json_conf["ipv6_http3_ssl_port_conf"].format( ipv6_port_conf=ipv6_port_conf, https_port=get.proxy_json_conf["https_port"], ) + "\n " port_conf = ipv4_http3_ssl_port_conf + ipv6_http3_ssl_port_conf + "\n http2 on;" else: ipv4_ssl_port_conf = get.proxy_json_conf["ipv4_ssl_port_conf"].format( ipv4_port_conf=ipv4_port_conf, https_port=get.proxy_json_conf["https_port"], ) + "\n " ipv6_ssl_port_conf = get.proxy_json_conf["ipv6_ssl_port_conf"].format( ipv6_port_conf=ipv6_port_conf, https_port=get.proxy_json_conf["https_port"], ) + "\n " port_conf = ipv4_ssl_port_conf + ipv6_ssl_port_conf ssl_conf = get.proxy_json_conf["ssl_info"]["ssl_conf"].format(site_name=get.site_name) if get.proxy_json_conf["ssl_info"]["force_https"]: ssl_conf = get.proxy_json_conf["ssl_info"]["force_ssl_conf"].format( site_name=get.site_name, force_conf=get.proxy_json_conf["ssl_info"]["force_conf"] ) else: port_conf = ipv4_port_conf + "\n" + ipv6_port_conf redirect_conf = "" if get.proxy_json_conf["redirect"]["redirect_status"]: redirect_conf = get.proxy_json_conf["redirect"]["redirect_conf"].format(site_name=get.site_name) security_conf = "" if get.proxy_json_conf["security"]["security_status"]: domains = get.proxy_json_conf["security"]["domains"] if not get.proxy_json_conf["security"][ "http_status"] else "none blocked " + get.proxy_json_conf["security"]["domains"] security_conf = get.proxy_json_conf["security"]["security_conf"].format( static_resource=get.proxy_json_conf["security"]["static_resource"], expires="30d", domains=domains.replace(",", " "), return_resource=get.proxy_json_conf["security"]["return_resource"], ) default_cache = get.proxy_json_conf["default_cache"].format( site_name=get.site_name, cache_name=get.site_name.replace(".", "_") ) get.http_block = default_cache + "\n" + get.proxy_json_conf["http_block"] # 2024/6/4 下午4:20 兼容新版监控报表的配置 monitor_conf = "" if (os.path.exists("/www/server/panel/plugin/monitor/monitor_main.py") and os.path.exists("/www/server/monitor/config/sites.json")): try: sites_data = json.loads(public.readFile("/www/server/monitor/config/sites.json")) if sites_data[get.site_name]["open"]: id = public.M('domain').where("name=?", (get.site_name,)).getField('id') monitor_conf = '''#Monitor-Config-Start 网站监控报表日志发送配置 access_log syslog:server=unix:/tmp/bt-monitor.sock,nohostname,tag={sid}__access monitor; error_log syslog:server=unix:/tmp/bt-monitor.sock,nohostname,tag={sid}__error; #Monitor-Config-End'''.format(sid=id) except: pass get.site_conf = self._template_conf.format( http_block=get.http_block, server_block=get.proxy_json_conf["server_block"], port_conf=port_conf, ssl_start_msg=public.getMsg('NGINX_CONF_MSG1'), err_page_msg=public.getMsg('NGINX_CONF_MSG2'), php_info_start=public.getMsg('NGINX_CONF_MSG3'), rewrite_start_msg=public.getMsg('NGINX_CONF_MSG4'), domains=' '.join(get.proxy_json_conf["domain_list"]) if len( get.proxy_json_conf["domain_list"]) > 1 else get.site_name, site_name=get.site_name, ssl_info=ssl_conf, err_age_404=get.proxy_json_conf["err_age_404"], err_age_502=get.proxy_json_conf["err_age_502"], ip_limit_conf=ip_limit_conf, auth_conf=auth_conf, sub_filter="", gzip_conf=gzip_conf, security_conf=security_conf, redirect_conf=redirect_conf, proxy_conf=proxy_conf, proxy_cache=get.proxy_json_conf["proxy_cache"]["cache_conf"], server_log=get.proxy_json_conf["proxy_log"]["log_conf"], site_path=get.proxy_json_conf["site_path"], websocket_support=websocket_support, monitor_conf=monitor_conf, ) # 2024/4/21 下午10:46 设置商业ssl证书 def set_cert(self, get): ''' @name @author wzz <2024/4/21 下午10:46> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.oid = get.get("oid", "") if get.oid == "": return public.returnResult(status=False, msg="oid不能为空!") get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.siteName = get.site_name get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") from panelSSL import panelSSL ssl_obj = panelSSL() set_result = ssl_obj.set_cert(get) if set_result["status"] == False: return set_result get.proxy_json_conf["ssl_info"]["ssl_status"] = True get.proxy_json_conf["https_port"] = "443" self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return set_result # 2024/4/21 下午11:03 关闭SSl证书 def close_ssl(self, get): ''' @name @author wzz <2024/4/21 下午11:04> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.siteName = get.site_name get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") from panelSite import panelSite result = panelSite().CloseSSLConf(get) if not result["status"]: return result get.proxy_json_conf["ssl_info"]["ssl_status"] = False get.proxy_json_conf["https_port"] = "443" self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return result # 2024/4/21 下午11:10 保存指定网站的SSL证书 def set_ssl(self, get): ''' @name 保存指定网站的SSL证书 @author wzz <2024/4/21 下午11:12> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.key = get.get("key", "") if get.key == "": return public.returnResult(status=False, msg="key不能为空!") get.csr = get.get("csr", "") if get.csr == "": return public.returnResult(status=False, msg="csr不能为空!") get.siteName = get.site_name get.type = -1 get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") from panelSite import panelSite result = panelSite().SetSSL(get) if not result["status"]: # return public.returnResult(status=False, msg=result["msg"]) return result get.proxy_json_conf["ssl_info"]["ssl_status"] = True get.proxy_json_conf["https_port"] = "443" self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return result # 2024/4/21 下午11:29 部署测试证书 def set_test_cert(self, get): ''' @name @author wzz <2024/4/21 下午11:30> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.partnerOrderId = get.get("partnerOrderId", "") if get.partnerOrderId == "": return public.returnResult(status=False, msg="partnerOrderId不能为空!") get.siteName = get.site_name get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") from panelSSL import panelSSL ssl_obj = panelSSL() set_result = ssl_obj.GetSSLInfo(get) if set_result["status"] == False: return set_result get.proxy_json_conf["ssl_info"]["ssl_status"] = True get.proxy_json_conf["https_port"] = "443" self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return set_result # 2024/4/21 下午11:33 申请let' encrypt证书 def apply_cert_api(self, get): ''' @name @author wzz <2024/4/21 下午11:34> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.domains = get.get("domains", "") if get.domains == "": return public.returnResult(status=False, msg="domains不能为空!") get.auth_type = get.get("auth_type", "") if get.auth_type == "": return public.returnResult(status=False, msg="auth_type不能为空!") get.auth_to = get.get("auth_to", "") if get.auth_to == "": return public.returnResult(status=False, msg="auth_to不能为空!") get.auto_wildcard = get.get("auto_wildcard", "") if get.auto_wildcard == "": return public.returnResult(status=False, msg="auto_wildcard不能为空!") get.id = get.get("id", "") if get.id == "": return public.returnResult(status=False, msg="id不能为空!") get.siteName = get.site_name get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") from acme_v2 import acme_v2 acme = acme_v2() result = acme.apply_cert_api(get) if not result["status"]: return result get.proxy_json_conf["ssl_info"]["ssl_status"] = True get.proxy_json_conf["https_port"] = "443" self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return result # 2024/4/21 下午11:36 验证let' encrypt dns def apply_dns_auth(self, get): ''' @name @author wzz <2024/4/21 下午11:36> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.index = get.get("index", "") if get.index == "": return public.returnResult(status=False, msg="index不能为空!") from acme_v2 import acme_v2 acme = acme_v2() return acme.apply_dns_auth(get) # 2024/4/21 下午11:44 设置证书夹里面的证书 def SetBatchCertToSite(self, get): ''' @name @author wzz <2024/4/21 下午11:44> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.BatchInfo = get.get("BatchInfo", "") if get.BatchInfo == "": return public.returnResult(status=False, msg="BatchInfo不能为空!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") from panelSSL import panelSSL ssl_obj = panelSSL() set_result = ssl_obj.SetBatchCertToSite(get) if not "successList" in set_result: return set_result for re in set_result["successList"]: if re["status"] and re["siteName"] == get.site_name: get.proxy_json_conf["ssl_info"]["ssl_status"] = True break self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return set_result # 2024/4/22 上午9:43 设置强制https def set_force_https(self, get): ''' @name 设置强制https @param get: site_name: 网站名 force_https: 1/0 @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.force_https = get.get("force_https/d", 999) if get.force_https == 999: return public.returnResult(status=False, msg="force_https不能为空!") get.siteName = get.site_name get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.proxy_json_conf["ssl_info"]["force_https"] = True if get.force_https == 1 else False from panelSite import panelSite if get.force_https == 1: result = panelSite().HttpToHttps(get) else: result = panelSite().CloseToHttps(get) if not result["status"]: return result self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return result # 2024/4/22 上午10:27 创建重定向 def CreateRedirect(self, get): ''' @name @author wzz <2024/4/22 上午10:27> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.domainorpath = get.get("domainorpath", "") if get.domainorpath == "": return public.returnResult(status=False, msg="domainorpath不能为空!") get.redirecttype = get.get("redirecttype", "") if get.redirecttype == "": return public.returnResult(status=False, msg="redirecttype不能为空!") get.redirectpath = get.get("redirectpath", "") if get.domainorpath == "path" and get.redirectpath == "": return public.returnResult(status=False, msg="redirectpath不能为空!") get.tourl = get.get("tourl", "") if get.tourl == "": return public.returnResult(status=False, msg="tourl不能为空!") get.redirectdomain = get.get("redirectdomain", "") if get.domainorpath == "domain" and get.redirectdomain == "": return public.returnResult(status=False, msg="redirectdomain不能为空!") get.redirectname = get.get("redirectname", "") if get.redirectname == "": return public.returnResult(status=False, msg="redirectname不能为空!") get.sitename = get.site_name get.type = 1 get.holdpath = 1 get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.proxy_json_conf["redirect"]["redirect_status"] = True from panelRedirect import panelRedirect result = panelRedirect().CreateRedirect(get) self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return result # 2024/4/22 上午10:45 删除指定网站的某个重定向规则 def DeleteRedirect(self, get): ''' @name 删除指定网站的某个重定向规则 @author wzz <2024/4/22 上午10:45> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.redirectname = get.get("redirectname", "") if get.redirectname == "": return public.returnResult(status=False, msg="redirectname不能为空!") get.sitename = get.site_name get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") from panelRedirect import panelRedirect redirect_list = panelRedirect().GetRedirectList(get) if len(redirect_list) == 0: get.proxy_json_conf["redirect"]["redirect_status"] = False self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return panelRedirect().DeleteRedirect(get) # 2024/4/23 上午10:38 编辑指定网站的某个重定向规则 def ModifyRedirect(self, get): ''' @name 编辑指定网站的某个重定向规则 @author wzz <2024/4/23 上午10:38> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.domainorpath = get.get("domainorpath", "") if get.domainorpath == "": return public.returnResult(status=False, msg="domainorpath不能为空!") get.redirecttype = get.get("redirecttype", "") if get.redirecttype == "": return public.returnResult(status=False, msg="redirecttype不能为空!") get.redirectpath = get.get("redirectpath", "") if get.domainorpath == "path" and get.redirectpath == "": return public.returnResult(status=False, msg="redirectpath不能为空!") get.tourl = get.get("tourl", "") if get.tourl == "": return public.returnResult(status=False, msg="tourl不能为空!") get.redirectdomain = get.get("redirectdomain", "") if get.domainorpath == "domain" and get.redirectdomain == "": return public.returnResult(status=False, msg="redirectdomain不能为空!") get.redirectname = get.get("redirectname", "") if get.redirectname == "": return public.returnResult(status=False, msg="redirectname不能为空!") get.sitename = get.site_name get.type = get.get("type/d", 1) get.holdpath = get.get("holdpath/d", 1) from panelRedirect import panelRedirect return panelRedirect().ModifyRedirect(get) # 2024/4/26 下午3:32 获取指定网站指定重定向规则的信息 def GetRedirectFile(self, get): ''' @name 获取指定网站指定重定向规则的信息 @author wzz <2024/4/26 下午3:32> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.path = get.get("path", "") if get.path == "": return public.returnResult(status=False, msg="path不能为空!") if not os.path.exists(get.path): return public.returnResult(status=False, msg="重定向已停止或配置文件目录不存在!") import files f = files.files() return f.GetFileBody(get) # 2024/4/22 上午11:12 设置防盗链 def SetSecurity(self, get): ''' @name 设置防盗链 @author wzz <2024/4/22 上午11:12> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.fix = get.get("fix", "") if get.fix == "": return public.returnResult(status=False, msg="fix不能为空!") get.domains = get.get("domains", "") if get.domains == "": return public.returnResult(status=False, msg="domains不能为空!") get.return_rule = get.get("return_rule", "") if get.return_rule == "": return public.returnResult(status=False, msg="return_rule不能为空!") get.http_status = get.get("http_status", "") if get.http_status == "": return public.returnResult(status=False, msg="http_status不能为空!") get.status = get.get("status", "") if get.status == "": return public.returnResult(status=False, msg="status不能为空!") get.id = get.get("id", "") if get.id == "": return public.returnResult(status=False, msg="id不能为空!") get.name = get.site_name get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.proxy_json_conf["security"]["security_status"] = True if get.status == "true" else False get.proxy_json_conf["security"]["static_resource"] = get.fix get.proxy_json_conf["security"]["domains"] = get.domains get.proxy_json_conf["security"]["return_resource"] = get.return_rule get.proxy_json_conf["security"]["http_status"] = True if get.http_status else False from panelSite import panelSite result = panelSite().SetSecurity(get) if not result["status"]: return result self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return result # 2024/4/23 下午3:07 添加全局IP黑白名单 def add_ip_limit(self, get): ''' @name 添加全局IP黑白名单 @author wzz <2024/4/23 下午3:08> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.ip_type = get.get("ip_type", "black") if get.ip_type not in ["black", "white"]: return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") get.ips = get.get("ips", "") if get.ips == "": return public.returnResult(status=False, msg="ips不能为空,请输入IP,一行一个!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.ips = get.ips.split("\n") for ip in get.ips: if ip not in get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)]: get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)].append(ip) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/23 下午3:12 删除全局IP黑白名单 def del_ip_limit(self, get): ''' @name 删除全局IP黑白名单 @author wzz <2024/4/23 下午3:12> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.ip_type = get.get("ip_type", "black") if get.ip_type not in ["black", "white"]: return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") get.ip = get.get("ip", "") if get.ip == "": return public.returnResult(status=False, msg="ip不能为空,请输入IP!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") if get.ip in get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)]: get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)].remove(get.ip) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="删除成功!") # 2024/4/23 下午3:13 批量删除全局IP黑白名单 def batch_del_ip_limit(self, get): ''' @name 批量删除全局IP黑白名单 @author wzz <2024/4/23 下午3:14> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.ip_type = get.get("ip_type", "black") if get.ip_type not in ["black", "white", "all"]: return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") get.ips = get.get("ips", "") if get.ips == "": return public.returnResult(status=False, msg="ips不能为空,请输入IP,一行一个!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.ips = get.ips.split("\n") for ip in get.ips: if get.ip_type == "all": if ip in get.proxy_json_conf["ip_limit"]["ip_black"]: get.proxy_json_conf["ip_limit"]["ip_black"].remove(ip) if ip in get.proxy_json_conf["ip_limit"]["ip_white"]: get.proxy_json_conf["ip_limit"]["ip_white"].remove(ip) else: if ip in get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)]: get.proxy_json_conf["ip_limit"]["ip_{}".format(get.ip_type)].remove(ip) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="删除成功!") # 2024/4/22 下午9:01 获取指定网站的方向代理列表 def get_proxy_list(self, get): ''' @name @author wzz <2024/4/22 下午9:02> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") if len(get.proxy_json_conf["proxy_info"]) == 0: return public.returnResult(status=False, msg="没有代理信息!") subs_filter = get.proxy_json_conf["subs_filter"] if "subs_filter" in get.proxy_json_conf else public.ExecShell("nginx -V 2>&1|grep 'ngx_http_substitutions_filter' -o")[0] != "" if get.proxy_path != "": for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: info["global_websocket"] = get.proxy_json_conf["websocket"]["websocket_status"] info["subs_filter"] = subs_filter if "http://unix:" in info["proxy_pass"]: info["proxy_pass"] = info["proxy_pass"].replace("http://unix:", "") return public.returnResult(data=info) else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) public.set_module_logs('dk_site_proxy', 'get_proxy_list', 1) return public.returnResult(data=get.proxy_json_conf["proxy_info"]) # 2024/4/23 上午11:16 获取指定网站的所有配置信息 def get_global_conf(self, get): ''' @name 获取指定网站的所有配置信息 @author wzz <2024/4/23 上午11:16> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") return public.returnResult(data=get.proxy_json_conf) # 2024/4/22 下午9:04 设置指定网站指定URL的反向代理 def set_url_proxy(self, get): ''' @name @author wzz <2024/4/22 下午9:04> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") if get.proxy_path == "": return public.returnResult(status=False, msg="proxy_path不能为空!") get.proxy_host = get.get("proxy_host", "") if get.proxy_host == "": return public.returnResult(status=False, msg="proxy_host不能为空!") get.proxy_pass = get.get("proxy_pass", "") if get.proxy_pass == "": return public.returnResult(status=False, msg="proxy_pass不能为空!") get.proxy_type = get.get("proxy_type", "") if get.proxy_type == "": return public.returnResult(status=False, msg="proxy_type不能为空!") get.proxy_connect_timeout = get.get("proxy_connect_timeout", "60s") get.proxy_send_timeout = get.get("proxy_send_timeout", "600s") get.proxy_read_timeout = get.get("proxy_read_timeout", "600s") get.remark = get.get("remark", "") if get.remark != "": get.remark = public.xssencode2(get.remark) if get.proxy_type == "unix": if not get.proxy_pass.startswith("http://unix:"): if not get.proxy_pass.startswith("/"): return public.returnResult(status=False, msg="unix文件路径必须以/或http://unix:开头,如/tmp/flask_app.sock!") if not get.proxy_pass.endswith(".sock"): return public.returnResult(status=False, msg="unix文件必须以.sock结尾,如/tmp/flask_app.sock!") if not os.path.exists(get.proxy_pass): return public.returnResult(status=False, msg="代理目标不存在!") get.proxy_pass = "http://unix:" + get.proxy_pass elif get.proxy_type == "http": if not get.proxy_pass.startswith("http://") and not get.proxy_pass.startswith("https://"): return public.returnResult(status=False, msg="代理目标必须以http://或https://开头!") get.websocket = get.get("websocket/d", 1) get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") if get.proxy_json_conf["websocket"]["websocket_status"] and get.websocket != 1: return public.returnResult(status=False, msg="全局websocket为开启状态,不允许单独关闭此URL的websocket支持!") for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: info["proxy_host"] = get.proxy_host info["proxy_pass"] = get.proxy_pass info["proxy_type"] = get.proxy_type info["timeout"]["proxy_connect_timeout"] = get.proxy_connect_timeout.replace("s", "") info["timeout"]["proxy_send_timeout"] = get.proxy_send_timeout.replace("s", "") info["timeout"]["proxy_read_timeout"] = get.proxy_read_timeout.replace("s", "") info["websocket"]["websocket_status"] = True if get.websocket == 1 else False info["remark"] = get.remark break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/22 下午9:34 删除指定网站指定URL的反向代理 def del_url_proxy(self, get): ''' @name 删除指定网站指定URL的反向代理 @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") if get.proxy_path == "": return public.returnResult(status=False, msg="proxy_path不能为空!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: get.proxy_json_conf["proxy_info"].remove(info) break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="删除成功!") # 2024/4/22 下午9:36 设置指定网站指定URL反向代理的备注 def set_url_remark(self, get): ''' @name 设置指定网站指定URL反向代理的备注 @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") if get.proxy_path == "": return public.returnResult(status=False, msg="proxy_path不能为空!") get.remark = get.get("remark", "") if get.remark != "": get.remark = public.xssencode2(get.remark) get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: info["remark"] = get.remark break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/22 下午9:40 添加指定网站指定URL的内容替换 def add_sub_filter(self, get): ''' @name 添加指定网站指定URL的内容替换 @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") if get.proxy_path == "": return public.returnResult(status=False, msg="proxy_path不能为空!") get.oldstr = get.get("oldstr", "") get.newstr = get.get("newstr", "") if get.oldstr == "" and get.newstr == "": return public.returnResult(status=False, msg="oldstr和newstr不能同时为空!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.sub_type = get.get("sub_type", "g") if get.sub_type == "": get.sub_type = "g" import re if not re.match(r'^[ior]+$|^g(?!.*o)|^o(?!.*g)$', get.sub_type): return public.returnResult(status=False, msg="get.sub_type 只能包含 'g'、'i'、'o' 或 'r' 中的字母组合,并且 'g' 和 'o' 不能同时存在!") is_subs = public.ExecShell("nginx -V 2>&1|grep 'ngx_http_substitutions_filter' -o")[0] if not is_subs and re.search(u'[\u4e00-\u9fa5]', get.oldstr + get.newstr): return public.returnResult(status=False, msg="您输入的内容包含中文,检测到当前nginx版本不支持,请尝试重新安装nginx 1.20以上的版本后重试!") if get.sub_type != "g" and not is_subs: return public.returnResult(status=False, msg="检测到当前nginx版本仅支持默认替换类型,请尝试重新安装nginx 1.20以上的版本后重试!") if not "g" in get.sub_type and not "o" in get.sub_type: get.sub_type = "g" + get.sub_type for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: for sub in info["sub_filter"]["sub_filter_str"]: if get.oldstr == sub["oldstr"]: return public.returnResult(status=False, msg="替换前内容:【{}】的配置信息已存在,请勿重复添加!".format( get.oldstr)) info["sub_filter"]["sub_filter_str"].append( { "sub_type": get.sub_type, "oldstr": get.oldstr, "newstr": get.newstr } ) break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/22 下午10:00 删除指定网站指定URL的内容替换 def del_sub_filter(self, get): ''' @name 删除指定网站指定URL的内容替换 @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") if get.proxy_path == "": return public.returnResult(status=False, msg="proxy_path不能为空!") get.oldstr = get.get("oldstr", "") get.newstr = get.get("newstr", "") if get.oldstr == "" and get.newstr == "": return public.returnResult(status=False, msg="oldstr和newstr不能同时为空!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: for sub in info["sub_filter"]["sub_filter_str"]: if get.oldstr == sub["oldstr"]: info["sub_filter"]["sub_filter_str"].remove(sub) break else: return public.returnResult(status=False, msg="未找到替换前内容:【{}】的配置信息!".format(get.oldstr)) break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="删除成功!") # 2024/4/22 下午10:03 设置指定网站指定URL的内容压缩 def set_url_gzip(self, get): ''' @name 设置指定网站指定URL的内容压缩 @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") if get.proxy_path == "": return public.returnResult(status=False, msg="proxy_path不能为空!") get.gzip_status = get.get("gzip_status/d", 999) if get.gzip_status == 999: return public.returnResult(status=False, msg="gzip_status不能为空,请传number 1或0!") get.gzip_min_length = get.get("gzip_min_length", "10k") get.gzip_comp_level = get.get("gzip_comp_level", "6") if get.gzip_min_length[0] == "0" or get.gzip_min_length.startswith("-"): return public.returnResult(status=False, msg="gzip_min_length参数不合法,请输入大于0的数字!") if get.gzip_comp_level == "0" or get.gzip_comp_level.startswith("-"): return public.returnResult(status=False, msg="gzip_comp_level参数不合法,请输入大于0的数字!") get.gzip_types = get.get( "gzip_types", "text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/json image/jpeg image/gif image/png font/ttf font/otf image/svg+xml application/xml+rss text/x-js" ) get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: info["gzip"]["gzip_status"] = True if get.gzip_status == 1 else False if get.gzip_status == 1: info["gzip"]["gzip_types"] = get.gzip_types info["gzip"]["gzip_min_length"] = get.gzip_min_length info["gzip"]["gzip_comp_level"] = get.gzip_comp_level info["gzip"]["gzip_conf"] = ("gzip on;" "\n gzip_min_length {gzip_min_length};" "\n gzip_buffers 4 16k;" "\n gzip_http_version 1.1;" "\n gzip_comp_level {gzip_comp_level};" "\n gzip_types {gzip_types};" "\n gzip_vary on;" "\n gzip_proxied expired no-cache no-store private auth;" "\n gzip_disable \"MSIE [1-6]\.\";").format( gzip_min_length=get.gzip_min_length, gzip_comp_level=get.gzip_comp_level, gzip_types=get.gzip_types, ) else: info["gzip"]["gzip_conf"] = "" break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/22 下午10:15 添加指定网站指定URL的IP黑白名单 def add_url_ip_limit(self, get): ''' @name 添加指定网站指定URL的IP黑白名单 @author wzz <2024/4/22 下午10:16> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") if get.proxy_path == "": return public.returnResult(status=False, msg="proxy_path不能为空!") get.ip_type = get.get("ip_type", "black") if get.ip_type not in ["black", "white"]: return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") get.ips = get.get("ips", "") if get.ips == "": return public.returnResult(status=False, msg="ips不能为空,请输入IP,一行一个!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.ips = get.ips.split("\n") for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: for ip in get.ips: if get.ip_type == "black": if not ip in info["ip_limit"]["ip_black"]: info["ip_limit"]["ip_black"].append(ip) else: if not ip in info["ip_limit"]["ip_white"]: info["ip_limit"]["ip_white"].append(ip) break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/22 下午10:21 删除指定网站指定URL的IP黑白名单 def del_url_ip_limit(self, get): ''' @name 删除指定网站指定URL的IP黑白名单 @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") if get.proxy_path == "": return public.returnResult(status=False, msg="proxy_path不能为空!") get.ip_type = get.get("ip_type", "black") if get.ip_type not in ["black", "white"]: return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") get.ip = get.get("ip", "") if get.ip == "": return public.returnResult(status=False, msg="ip不能为空,请输入IP!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: if get.ip in info["ip_limit"]["ip_{ip_type}".format(ip_type=get.ip_type)]: info["ip_limit"]["ip_{ip_type}".format(ip_type=get.ip_type)].remove(get.ip) break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/24 上午11:21 批量删除指定网站指定URL的IP黑白名单 def batch_del_url_ip_limit(self, get): ''' @name 批量删除指定网站指定URL的IP黑白名单 @author wzz <2024/4/24 上午11:22> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.ip_type = get.get("ip_type", "black") if get.ip_type not in ["black", "white", "all"]: return public.returnResult(status=False, msg="ip_type参数错误,必须传black或white!") get.ips = get.get("ips", "") if get.ips == "": return public.returnResult(status=False, msg="ips不能为空,请输入IP,一行一个!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: get.ips = get.ips.split("\n") if get.ip_type == "all": for ip in get.ips: if ip in info["ip_limit"]["ip_black"]: info["ip_limit"]["ip_black"].remove(ip) if ip in info["ip_limit"]["ip_white"]: info["ip_limit"]["ip_white"].remove(ip) else: for ip in get.ips: if ip in info["ip_limit"]["ip_{ip_type}".format(ip_type=get.ip_type)]: info["ip_limit"]["ip_{ip_type}".format(ip_type=get.ip_type)].remove(ip) break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="删除成功!") # 2024/4/22 下午8:14 设置指定网站指定URL的缓存 def set_url_cache(self, get): ''' @name 设置指定网站指定URL的缓存 @param get: @return: ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.cache_status = get.get("cache_status/d", 999) if get.cache_status == 999: return public.returnResult(status=False, msg="cache_status不能为空,请传number 1或0!") get.expires = get.get("expires", "1d") if get.expires[0] == "0" or get.expires.startswith("-"): return public.returnResult(status=False, msg="expires参数不合法,请输入大于0的数字!") expires = "expires {}".format(get.expires) get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") static_cache = ("\n location ~ .*\\.(css|js|jpe?g|gif|png|webp|woff|eot|ttf|svg|ico|css\.map|js\.map)$" "\n {{" "\n {expires};" "\n error_log /dev/null;" "\n access_log /dev/null;" "\n }}").format( expires=expires, ) for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: info["proxy_cache"]["cache_status"] = True if get.cache_status == 1 else False info["proxy_cache"]["expires"] = get.expires if get.cache_status == 1: info["proxy_cache"]["cache_conf"] = ("\n proxy_cache {cache_zone};" "\n proxy_cache_key $host$uri$is_args$args;" "\n proxy_ignore_headers Set-Cookie Cache-Control expires X-Accel-Expires;" "\n proxy_cache_valid 200 304 301 302 {expires};" "\n proxy_cache_valid 404 1m;" "{static_cache}").format( cache_zone=get.proxy_json_conf["proxy_cache"]["cache_zone"], expires=get.expires, static_cache=static_cache, ) else: info["proxy_cache"]["cache_conf"] = "" break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/24 上午9:57 设置指定网站指定URL的自定义配置 def set_url_custom_conf(self, get): ''' @name 设置指定网站指定URL的自定义配置 @author wzz <2024/4/24 上午9:58> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_path = get.get("proxy_path", "") if get.proxy_path == "": return public.returnResult(status=False, msg="proxy_path不能为空!") get.custom_conf = get.get("custom_conf", "") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") for info in get.proxy_json_conf["proxy_info"]: if info["proxy_path"] == get.proxy_path: info["custom_conf"] = get.custom_conf break else: return public.returnResult(status=False, msg="未找到此URL【{}】的代理信息!".format(get.proxy_path)) update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") @staticmethod def nginx_get_log_file(nginx_config: str, is_error_log: bool = False): import re if is_error_log: re_data = re.findall(r"error_log +(/(\S+/?)+) ?(.*?);", nginx_config) else: re_data = re.findall(r"access_log +(/(\S+/?)+) ?(.*?);", nginx_config) if re_data is None: return None for i in re_data: file_path = i[0].strip(";") if file_path != "/dev/null": return file_path return None def xsssec(self, text): replace_list = { "<": "<", ">": ">", "'": "'", '"': """, } for k, v in replace_list.items(): text = text.replace(k, v) return public.xssencode2(text) # 2024/4/24 下午5:39 获取指定网站的网站日志 def GetSiteLogs(self, get): ''' @name 获取指定网站的网站日志 @author wzz <2024/4/24 下午5:39> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.type = get.get("type", "access") log_name = get.site_name if get.type != "access": log_name = get.site_name + ".error" get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") if get.proxy_json_conf["proxy_log"]["log_type"] == "default": log_file = public.get_logs_path() + "/" + log_name + '.log' elif get.proxy_json_conf["proxy_log"]["log_type"] == "file": log_file = get.proxy_json_conf["proxy_log"]["log_path"] + "/" + log_name + '.log' else: return public.returnResult(data={"msg": "", "size": 0}) if os.path.exists(log_file): return public.returnResult( data={ "msg": self.xsssec(public.GetNumLines(log_file, 1000)), "size": public.to_size(os.path.getsize(log_file)) } ) return public.returnResult(data={"msg": "", "size": 0}) # 2024/4/25 上午10:51 清理指定网站的反向代理缓存 def clear_cache(self, get): ''' @name 清理指定网站的反向代理缓存 @author wzz <2024/4/25 上午10:51> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") cache_dir = "/www/wwwroot/{site_name}/proxy_cache_dir".format(site_name=get.site_name) if os.path.exists(cache_dir): public.ExecShell("rm -rf {cache_dir}/*".format(cache_dir=cache_dir)) public.serviceReload() return public.returnResult(msg="清理成功!") return public.returnResult(msg="清理失败,缓存目录不存在!") # 2024/4/25 下午9:24 设置指定网站的https端口 def set_https_port(self, get): ''' @name 设置指定网站的https端口 @author wzz <2024/4/25 下午9:24> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.site_name = get.get("site_name", "") if get.site_name == "": return public.returnResult(status=False, msg="site_name不能为空!") get.https_port = get.get("https_port", "443") if not public.checkPort(get.https_port) and get.https_port != "443": return public.returnResult(status=False, msg="https端口【{}】不合法!".format(get.https_port)) get.proxy_json_conf = self.read_json_conf(get) if not get.proxy_json_conf: return public.returnResult(status=False, msg="读取配置文件失败,请删除网站重新添加!") get.proxy_json_conf["https_port"] = get.https_port update_result = self.update_conf(get) if not update_result["status"]: return public.returnResult(status=False, msg=update_result["msg"]) return public.returnResult(msg="设置成功!") # 2024/4/23 下午2:12 保存并重新生成新的nginx配置文件 def update_conf(self, get): ''' @name @author wzz <2024/4/23 下午2:13> @param "data":{"参数名":""} <数据类型> 参数描述 @return dict{"status":True/False,"msg":"提示信息"} ''' get.conf_file = public.get_setup_path() + '/panel/vhost/nginx/' + get.site_name + '.conf' self.generate_config(get) get.data = get.site_conf get.encoding = "utf-8" get.path = get.conf_file import files f = files.files() save_result = f.SaveFileBody(get) if save_result["status"] == False: return public.returnResult(status=False, msg=save_result["msg"]) self._site_proxy_conf_path = "{path}/{site_name}/{site_name}.json".format( path=self._proxy_config_path, site_name=get.site_name ) public.writeFile(self._site_proxy_conf_path, json.dumps(get.proxy_json_conf)) return public.returnResult(msg="保存成功!")
Close