REAPI/app/core/BtWafService.php
c8a97d8ea6 feat(core): 添加内网IP更新宝塔安全功能
- 新增 checkNwIp 方法,用于查询内网IP并更新宝塔安全规则
- 实现域名解析功能,支持多个域名的IP解析- 添加白名单规则更新逻辑,可创建或更新管理后台IP白名单
- 新增王白名单规则删除功能
- 优化了与宝塔服务器的HTTP通信方法
2025-04-12 18:06:19 +08:00

368 lines
16 KiB
PHP

<?php
namespace app\core;
use think\admin\Service as Base;
use app\gateway\service\RedisService;
use app\gateway\service\AuthService;
use app\gateway\service\CurlService;
use dever\Log;
use think\Db;
/**
* 宝塔waf
* Class Cate
* @package app\btwaf
*/
class BtWafService
{
/**
* 应用实例
* @var Db
*/
protected $db;
/**
* 表名
* @var table
*/
protected $table = '';
protected $BT_KEY = ''; //接口密钥
protected $BT_PANEL = ''; //面板地址
protected $config = array(
# 系统状态相关接口
'GetSystemTotal' => '/system?action=GetSystemTotal', //获取系统基础统计
'GetDiskInfo' => '/system?action=GetDiskInfo', //获取磁盘分区信息
'GetNetWork' => '/system?action=GetNetWork', //获取实时状态信息(CPU、内存、网络、负载)
'GetTaskCount' => '/ajax?action=GetTaskCount', //检查是否有安装任务
'UpdatePanel' => '/ajax?action=UpdatePanel', //检查面板更新
# 网站管理相关接口
'Websites' => '/data?action=getData&table=sites', //获取网站列表
'Webtypes' => '/site?action=get_site_types', //获取网站分类
'GetPHPVersion' => '/site?action=GetPHPVersion', //获取已安装的 PHP 版本列表
'GetSitePHPVersion' => '/site?action=GetSitePHPVersion', //获取指定网站运行的PHP版本
'SetPHPVersion' => '/site?action=SetPHPVersion', //修改指定网站的PHP版本
'SetHasPwd' => '/site?action=SetHasPwd', //开启并设置网站密码访问
'CloseHasPwd' => '/site?action=CloseHasPwd', //关闭网站密码访问
'GetDirUserINI' => '/site?action=GetDirUserINI', //获取网站几项开关(防跨站、日志、密码访问)
'WebAddSite' => '/site?action=AddSite', //创建网站
'WebDeleteSite' => '/site?action=DeleteSite', //删除网站
'WebSiteStop' => '/site?action=SiteStop', //停用网站
'WebSiteStart' => '/site?action=SiteStart', //启用网站
'WebSetEdate' => '/site?action=SetEdate', //设置网站有效期
'WebSetPs' => '/data?action=setPs&table=sites', //修改网站备注
'WebBackupList' => '/data?action=getData&table=backup', //获取网站备份列表
'WebToBackup' => '/site?action=ToBackup', //创建网站备份
'WebDelBackup' => '/site?action=DelBackup', //删除网站备份
'WebDoaminList' => '/data?action=getData&table=domain', //获取网站域名列表
'GetDirBinding' => '/site?action=GetDirBinding', //获取网站域名绑定二级目录信息
'AddDirBinding' => '/site?action=AddDirBinding', //添加网站子目录域名
'DelDirBinding' => '/site?action=DelDirBinding', //删除网站绑定子目录
'GetDirRewrite' => '/site?action=GetDirRewrite', //获取网站子目录伪静态规则
'WebAddDomain' => '/site?action=AddDomain', //添加网站域名
'WebDelDomain' => '/site?action=DelDomain', //删除网站域名
'GetSiteLogs' => '/site?action=GetSiteLogs', //获取网站日志
'GetSecurity' => '/site?action=GetSecurity', //获取网站盗链状态及规则信息
'SetSecurity' => '/site?action=SetSecurity', //设置网站盗链状态及规则信息
'GetSSL' => '/site?action=GetSSL', //获取SSL状态及证书详情
'HttpToHttps' => '/site?action=HttpToHttps', //强制HTTPS
'CloseToHttps' => '/site?action=CloseToHttps', //关闭强制HTTPS
'SetSSL' => '/site?action=SetSSL', //设置SSL证书
'CloseSSLConf' => '/site?action=CloseSSLConf', //关闭SSL
'WebGetIndex' => '/site?action=GetIndex', //获取网站默认文件
'WebSetIndex' => '/site?action=SetIndex', //设置网站默认文件
'GetLimitNet' => '/site?action=GetLimitNet', //获取网站流量限制信息
'SetLimitNet' => '/site?action=SetLimitNet', //设置网站流量限制信息
'CloseLimitNet' => '/site?action=CloseLimitNet', //关闭网站流量限制
'Get301Status' => '/site?action=Get301Status', //获取网站301重定向信息
'Set301Status' => '/site?action=Set301Status', //设置网站301重定向信息
'GetRewriteList' => '/site?action=GetRewriteList', //获取可选的预定义伪静态列表
'GetFileBody' => '/files?action=GetFileBody', //获取指定预定义伪静态规则内容(获取文件内容)
'SaveFileBody' => '/files?action=SaveFileBody', //保存伪静态规则内容(保存文件内容)
'GetProxyList' => '/site?action=GetProxyList', //获取网站反代信息及状态
'CreateProxy' => '/site?action=CreateProxy', //添加网站反代信息
'ModifyProxy' => '/site?action=ModifyProxy', //修改网站反代信息
# Ftp管理
'WebFtpList' => '/data?action=getData&table=ftps', //获取FTP信息列表
'SetUserPassword' => '/ftp?action=SetUserPassword', //修改FTP账号密码
'SetStatus' => '/ftp?action=SetStatus', //启用/禁用FTP
# Sql管理
'WebSqlList' => '/data?action=getData&table=databases', //获取SQL信息列表
'ResDatabasePass' => '/database?action=ResDatabasePassword', //修改SQL账号密码
'SQLToBackup' => '/database?action=ToBackup', //创建sql备份
'SQLDelBackup' => '/database?action=DelBackup', //删除sql备份
'download' => '/download?filename=', //下载备份文件(目前暂停使用)
# 插件管理
'deployment' => '/plugin?action=a&name=deployment&s=GetList&type=0', //宝塔一键部署列表
'SetupPackage' => '/plugin?action=a&name=deployment&s=SetupPackage', //部署任务
#宝塔WAF
'WAF_customize_rule' =>'/plugin?action=a&name=btwaf&s=update_customize_rule', //Nginx自定义规则
'WAF_customize_rule_create' =>'/plugin?action=a&name=btwaf&s=create_customize_rule', //Nginx自定义规则
'WAF_customize_rule_list' => '/plugin?action=a&name=btwaf&s=get_customize_list', //Nginx自定义规则列表
'WAF_customize_rule_del' => '/plugin?action=a&name=btwaf&s=remove_customize_rule',
);
/**
* 初始化服务
* @return $this
*/
/**
* 初始化
* @param [type] $bt_panel 宝塔接口地址
* @param [type] $bt_key 宝塔Api密钥
*/
public function __construct()
{
$bt_panel = sysconf('BtApi_ip');
$bt_key = sysconf('BtApi_password');
if ($bt_panel) $this->BT_PANEL = $bt_panel;
if ($bt_key) $this->BT_KEY = $bt_key;
header('Content-type: application/json');
}
public function db($table = false)
{
$table = $table ? $table : $this->table;
$this->db = $this->app->db->name($table);
return $this->db;
}
/**
* 构造带有签名的关联数组
*/
public function GetKeyData(){
$now_time = time();
$p_data = array(
'request_token' => md5($now_time.''.md5($this->BT_KEY)),
'request_time' => $now_time
);
return $p_data;
}
/**
* 获取系统基础统计
*/
public function update_waf_whiteIp($rule_id,$whiteName,$domain,$ip_white){
# {"name":"ip白名单-6","servers":["apis.gcdat.com"],"status":1,"is_global":0,"priority":0,"root":{"logic":"or","type":"block","option":null,"children":[{"logic":"and","type":"block","option":null,"children":[{"type":"option","logic":"","children":[],"option":{"type":"ip","operator":"eq","left_factor":"","right_factor":"8.149.139.230"}}]},{"logic":"and","type":"block","option":null,"children":[{"type":"option","logic":"","children":[],"option":{"type":"ip","operator":"eq","left_factor":"","right_factor":"122.234.200.204"}}]}]},"action":{"type":"allow","response":{"type":"","response_id":0,"status":0,"headers":{},"body":""}}}
$p_data = $this->GetKeyData();
if(isset($rule_id)&& $rule_id){
$url = $this->BT_PANEL.$this->config["WAF_customize_rule"];
$p_data['id'] = $rule_id;
}else{
$url = $this->BT_PANEL.$this->config["WAF_customize_rule_create"];
}
$info = array();
$info['name'] = $whiteName;
$info['servers'] = [$domain];
$info['status'] = 1;
$info['is_global'] = 0;
$info['priority'] = 0;
$root_info = [];
$root_info['logic'] = 'or';
$root_info['type'] = 'block';
$root_info['option'] = null;
// $children;
$num = 0;
// var_dump($ip_white);die;
foreach ($ip_white as $k => $v){
$children[$num]['logic'] = 'and';
$children[$num]['type'] = 'block';
$children[$num]['option'] = null;
$children[$num]['children'][0]['type'] = 'option';
$children[$num]['children'][0]['logic'] = '';
$children[$num]['children'][0]['children'] = [];
$children[$num]['children'][0]['option'] = [
'type' => 'ip',
'operator' => 'eq',
'left_factor' => '',
'right_factor' => $v,
];
$num++;
}
$root_info['children'] = $children;
$info['root'] = $root_info;
$info['action'] = [
'type'=>'allow',
'response'=>[
'type'=>'',
'response_id'=>0,
'status'=>0,
'headers'=>[],
'body'=>''
]
];
// var_dump($info);die;
$json = json_encode($info,JSON_UNESCAPED_UNICODE);
// var_dump($json);die;
//
$p_data['infos'] = $json;
// var_dump($p_data);
$result = $this->HttpPostCookie($url,$p_data);
// var_dump($p_data);die;
$data = json_decode($result,true);
return $data;
}
public function update_waf_whiteIp_lj($rule_id,$whiteName,$domain,$ip_white){
#{"name":"后台管理白名单","servers":["htadmin.gcdat.com"],"status":1,"is_global":0,"priority":0,"root":{"logic":"or","type":"block","option":null,"children":[{"logic":"and","type":"block","option":null,"children":[{"type":"option","logic":"","children":[],"option":{"type":"ip","operator":"neq","left_factor":"","right_factor":"36.20.116.48"}},{"type":"option","logic":"","children":[],"option":{"type":"ip","operator":"neq","left_factor":"","right_factor":"60.176.85.193"}}]}]},"action":{"type":"deny","response":{"type":"no_response","response_id":0,"status":0,"headers":{},"body":""}}}
// {"name":"管理后台IP白名单","servers":["htadmin.gcdat.com"],"status":1,"is_global":0,"priority":0,"root":{"logic":"or","type":"block","option":null,"children":[{"logic":"and","type":"block","option":null,"children":[{"type":"option","logic":"","children":[],"option":{"type":"ip","operator":"neq","left_factor":"","right_factor":"10.0.0.1"}},{"type":"option","logic":"","children":[],"option":{"type":"ip","operator":"neq","left_factor":"","right_factor":"192.168.0.1"}}]}]},"action":{"type":"deny","response":{"type":"black_page","response_id":0,"status":0,"headers":{},"body":""}}}
// {"name":"管理后台IP白名单","servers":["htadmin.gcdat.com"],"status":1,"is_global":0,"priority":0,"root":{"logic":"or","type":"block","option":null,"children":[{"type":"option","logic":"","children":[],"option":{"option":{"type":"ip","operator":"neq","left_factor":"","right_factor":"36.20.116.48"}}},{"type":"option","logic":"","children":[],"option":{"option":{"type":"ip","operator":"neq","left_factor":"","right_factor":"36.20.116.48"}}}]},"action":{"type":"deny","response":{"type":"no_response","response_id":0,"status":0,"headers":[],"body":""}}}
$p_data = $this->GetKeyData();
if(isset($rule_id)&& $rule_id){
$url = $this->BT_PANEL.$this->config["WAF_customize_rule"];
$p_data['id'] = $rule_id;
}else{
$url = $this->BT_PANEL.$this->config["WAF_customize_rule_create"];
}
$info = array();
$info['name'] = $whiteName;
$info['servers'] = [$domain];
$info['status'] = 1;
$info['is_global'] = 0;
$info['priority'] = 0;
$root_info = [];
$root_info['logic'] = 'or';
$root_info['type'] = 'block';
$root_info['option'] = null;
$children = [
'logic'=>'and',
'type'=>'block',
'option'=>null,
];
// $children;
$num = 0;
// var_dump($ip_white);die;
foreach ($ip_white as $k => $v){
//
$children['children'][$num]['type'] = 'option';
$children['children'][$num]['logic'] = '';
$children['children'][$num]['children'] = [];
$children['children'][$num]['option'] = [
'type' => 'ip',
'operator' => 'neq',
'left_factor' => '',
'right_factor' => $v,
];
$num++;
}
$root_info['children'][] = $children;
$info['root'] = $root_info;
$info['action'] = [
'type'=>'deny',
'response'=>[
'type'=>'no_response',
'response_id'=>0,
'status'=>0,
'headers'=>[],
'body'=>''
]
];
// var_dump($info);die;
$json = json_encode($info,JSON_UNESCAPED_UNICODE);
// var_dump($json);die;
//
$p_data['infos'] = $json;
// var_dump($p_data);
$result = $this->HttpPostCookie($url,$p_data);
// var_dump($p_data);die;
return json_decode($result,true);
}
public function remove_waf_whiteIp($rule_id){
$p_data = $this->GetKeyData();
if(isset($rule_id)&& $rule_id){
$url = $this->BT_PANEL.$this->config["WAF_customize_rule_del"];
$p_data['id'] = $rule_id;
}else{
return false;
}
$result = $this->HttpPostCookie($url,$p_data);
return json_decode($result,true);
}
private function HttpPostCookie($url, $data,$timeout = 60)
{
//定义cookie保存位置
$cookie_file='./'.md5($this->BT_PANEL).'.cookie';
if(!file_exists($cookie_file)){
$fp = fopen($cookie_file,'w+');
fclose($fp);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
public function get_customize_list(){
$url = $this->BT_PANEL.$this->config["WAF_customize_rule_list"];
// var_dump($url);die;
$p_data = $this->GetKeyData();
$result = $this->HttpPostCookie($url,$p_data);
$data = json_decode($result,true);
return $data;
}
#
}