diff --git a/app/common.php b/app/common.php index 3815d78..bf6bd2d 100644 --- a/app/common.php +++ b/app/common.php @@ -434,8 +434,9 @@ function curl_client($url, $data = null, $referer = null, $cookie = null, $heade $ret = curl_exec($ch); $errno = curl_errno($ch); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); diff --git a/app/controller/Cert.php b/app/controller/Cert.php index 9a1b104..ae6a1e6 100644 --- a/app/controller/Cert.php +++ b/app/controller/Cert.php @@ -276,6 +276,7 @@ class Cert extends BaseController 'addtime' => date('Y-m-d H:i:s'), 'issuer' => '', 'status' => 0, + 'isauto' => 1, ]; $domains = array_map('trim', $domains); $domains = array_filter($domains, function ($v) { diff --git a/app/controller/Domain.php b/app/controller/Domain.php index a78a4cc..85ef6c2 100644 --- a/app/controller/Domain.php +++ b/app/controller/Domain.php @@ -250,12 +250,14 @@ class Domain extends BaseController $is_hide = input('post.is_hide/d'); $is_sso = input('post.is_sso/d'); $is_notice = input('post.is_notice/d'); + $expiretime = input('post.expiretime', null, 'trim'); $remark = input('post.remark', null, 'trim'); if (empty($remark)) $remark = null; Db::name('domain')->where('id', $id)->update([ 'is_hide' => $is_hide, 'is_sso' => $is_sso, 'is_notice' => $is_notice, + 'expiretime' => $expiretime ? $expiretime : null, 'remark' => $remark, ]); return json(['code' => 0, 'msg' => '修改域名配置成功!']); @@ -419,8 +421,8 @@ class Domain extends BaseController $type = input('post.type', null, 'trim'); $line = input('post.line', null, 'trim'); $status = input('post.status', null, 'trim'); - $offset = input('post.offset/d'); - $limit = input('post.limit/d'); + $offset = input('post.offset/d', 0); + $limit = input('post.limit/d', 10); if ($limit == 0) { $page = 1; } else { @@ -543,10 +545,14 @@ class Domain extends BaseController $dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']); $recordid = $dns->updateDomainRecord($recordid, $name, $type, $value, $line, $ttl, $mx, $weight, $remark); if ($recordid) { - if (is_array($recordinfo['Value'])) $recordinfo['Value'] = implode(',', $recordinfo['Value']); - if ($recordinfo['Name'] != $name || $recordinfo['Type'] != $type || $recordinfo['Value'] != $value) { - $this->add_log($drow['name'], '修改解析', $recordinfo['Name'].' ['.$recordinfo['Type'].'] '.$recordinfo['Value'].' → '.$name.' ['.$type.'] '.$value.' (线路:'.$line.' TTL:'.$ttl.')'); - } elseif($recordinfo['Line'] != $line || $recordinfo['TTL'] != $ttl) { + if ($recordinfo) { + if (is_array($recordinfo['Value'])) $recordinfo['Value'] = implode(',', $recordinfo['Value']); + if ($recordinfo['Name'] != $name || $recordinfo['Type'] != $type || $recordinfo['Value'] != $value) { + $this->add_log($drow['name'], '修改解析', $recordinfo['Name'].' ['.$recordinfo['Type'].'] '.$recordinfo['Value'].' → '.$name.' ['.$type.'] '.$value.' (线路:'.$line.' TTL:'.$ttl.')'); + } elseif($recordinfo['Line'] != $line || $recordinfo['TTL'] != $ttl) { + $this->add_log($drow['name'], '修改解析', $name.' ['.$type.'] '.$value.' (线路:'.$line.' TTL:'.$ttl.')'); + } + } else { $this->add_log($drow['name'], '修改解析', $name.' ['.$type.'] '.$value.' (线路:'.$line.' TTL:'.$ttl.')'); } return json(['code' => 0, 'msg' => '修改解析记录成功!']); @@ -790,6 +796,9 @@ class Domain extends BaseController } if (is_null($line)) { $line = DnsHelper::$line_name[$dnstype]['DEF']; + if ($dnstype == 'cloudflare' && input('post.proxy/d', 0) == 1) { + $line = '1'; + } } $dns = DnsHelper::getModel($drow['aid'], $drow['name'], $drow['thirdid']); diff --git a/app/data/domain_root.txt b/app/data/domain_root.txt index e7c75d1..ce068e2 100644 --- a/app/data/domain_root.txt +++ b/app/data/domain_root.txt @@ -288,6 +288,7 @@ uk.com us.com uy.com za.com +it.com co.cr ed.cr fi.cr @@ -1341,6 +1342,7 @@ zagan.pl zarow.pl zgora.pl zgorzelec.pl +co.pl co.pn net.pn org.pn @@ -1925,4 +1927,18 @@ edu.kg edu.cn eu.org us.kg -ggff.net \ No newline at end of file +xx.kg +qzz.io +dpdns.org +ggff.net +ac.ru +edu.ru +com.ru +msk.ru +net.ru +nov.ru +org.ru +pp.ru +spb.ru +uk.co +gov.scot \ No newline at end of file diff --git a/app/lib/DeployHelper.php b/app/lib/DeployHelper.php index 2fed8a3..3cabb64 100644 --- a/app/lib/DeployHelper.php +++ b/app/lib/DeployHelper.php @@ -229,6 +229,45 @@ class DeployHelper ], 'taskinputs' => [], ], + 'btwaf' => [ + 'name' => '堡塔云WAF', + 'class' => 1, + 'icon' => 'bt.ico', + 'note' => null, + 'tasknote' => '', + 'inputs' => [ + 'url' => [ + 'name' => '面板地址', + 'type' => 'input', + 'placeholder' => '堡塔云WAF面板地址', + 'note' => '填写规则如:http://192.168.1.100:8379 ,不要带其他后缀', + 'required' => true, + ], + 'key' => [ + 'name' => '接口密钥', + 'type' => 'input', + 'placeholder' => '面板设置->API接口', + 'required' => true, + ], + 'proxy' => [ + 'name' => '使用代理服务器', + 'type' => 'radio', + 'options' => [ + '0' => '否', + '1' => '是', + ], + 'value' => '0' + ], + ], + 'taskinputs' => [ + 'sites' => [ + 'name' => '网站名称列表', + 'type' => 'textarea', + 'placeholder' => '填写要部署证书的网站名称,每行一个', + 'required' => true, + ], + ], + ], 'cdnfly' => [ 'name' => 'Cdnfly', 'class' => 1, diff --git a/app/lib/cert/tencent.php b/app/lib/cert/tencent.php index 1c0dc28..e413adf 100644 --- a/app/lib/cert/tencent.php +++ b/app/lib/cert/tencent.php @@ -15,14 +15,15 @@ class tencent implements CertInterface private $service = "ssl"; private $version = "2019-12-05"; private $logger; + private $proxy; private TencentCloud $client; public function __construct($config, $ext = null) { $this->SecretId = $config['SecretId']; $this->SecretKey = $config['SecretKey']; - $proxy = isset($config['proxy']) ? $config['proxy'] == 1 : false; - $this->client = new TencentCloud($this->SecretId, $this->SecretKey, $this->endpoint, $this->service, $this->version, null, $proxy); + $this->proxy = isset($config['proxy']) ? $config['proxy'] == 1 : false; + $this->client = new TencentCloud($this->SecretId, $this->SecretKey, $this->endpoint, $this->service, $this->version, null, $this->proxy); $this->email = $config['email']; } @@ -102,7 +103,9 @@ class tencent implements CertInterface 'ServiceType' => 'nginx', ]; $data = $this->request('DescribeDownloadCertificateUrl', $param); - $file_data = get_curl($data['DownloadCertificateUrl']); + $file_data = curl_client($data['DownloadCertificateUrl'], null, null, null, null, $this->proxy); + $file_data = $file_data['body'] ?? null; + if (empty($file_data)) throw new Exception('下载证书失败'); $file_path = app()->getRuntimePath() . 'cert/' . $data['DownloadFilename']; $file_name = substr($data['DownloadFilename'], 0, -4); file_put_contents($file_path, $file_data); diff --git a/app/lib/client/AWS.php b/app/lib/client/AWS.php index 36b841d..170dd50 100644 --- a/app/lib/client/AWS.php +++ b/app/lib/client/AWS.php @@ -285,8 +285,9 @@ class AWS $response = curl_exec($ch); $errno = curl_errno($ch); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($etag) { diff --git a/app/lib/client/Aliyun.php b/app/lib/client/Aliyun.php index a2c34b1..42575bb 100644 --- a/app/lib/client/Aliyun.php +++ b/app/lib/client/Aliyun.php @@ -62,8 +62,9 @@ class Aliyun $errno = curl_errno($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } curl_close($ch); diff --git a/app/lib/client/AliyunNew.php b/app/lib/client/AliyunNew.php index eca2a89..b59d25e 100644 --- a/app/lib/client/AliyunNew.php +++ b/app/lib/client/AliyunNew.php @@ -168,8 +168,9 @@ class AliyunNew $response = curl_exec($ch); $errno = curl_errno($ch); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); diff --git a/app/lib/client/AliyunOSS.php b/app/lib/client/AliyunOSS.php index c1993aa..7d6108d 100644 --- a/app/lib/client/AliyunOSS.php +++ b/app/lib/client/AliyunOSS.php @@ -119,8 +119,9 @@ class AliyunOSS $errno = curl_errno($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } curl_close($ch); diff --git a/app/lib/client/BaiduCloud.php b/app/lib/client/BaiduCloud.php index 3dc9b21..ba352a9 100644 --- a/app/lib/client/BaiduCloud.php +++ b/app/lib/client/BaiduCloud.php @@ -158,8 +158,9 @@ class BaiduCloud $errno = curl_errno($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } curl_close($ch); diff --git a/app/lib/client/Ctyun.php b/app/lib/client/Ctyun.php index e60263c..6c92863 100644 --- a/app/lib/client/Ctyun.php +++ b/app/lib/client/Ctyun.php @@ -144,8 +144,9 @@ class Ctyun $response = curl_exec($ch); $errno = curl_errno($ch); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } curl_close($ch); diff --git a/app/lib/client/HuaweiCloud.php b/app/lib/client/HuaweiCloud.php index b37babd..c07aac8 100644 --- a/app/lib/client/HuaweiCloud.php +++ b/app/lib/client/HuaweiCloud.php @@ -163,8 +163,9 @@ class HuaweiCloud $response = curl_exec($ch); $errno = curl_errno($ch); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); diff --git a/app/lib/client/Jdcloud.php b/app/lib/client/Jdcloud.php index 75fd7cf..e47f7bf 100644 --- a/app/lib/client/Jdcloud.php +++ b/app/lib/client/Jdcloud.php @@ -167,8 +167,9 @@ class Jdcloud $response = curl_exec($ch); $errno = curl_errno($ch); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); diff --git a/app/lib/client/Qiniu.php b/app/lib/client/Qiniu.php index 6ae17f7..b9a3f4d 100644 --- a/app/lib/client/Qiniu.php +++ b/app/lib/client/Qiniu.php @@ -121,8 +121,9 @@ class Qiniu $errno = curl_errno($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } curl_close($ch); diff --git a/app/lib/client/TencentCloud.php b/app/lib/client/TencentCloud.php index 05b0e68..3cb6d04 100644 --- a/app/lib/client/TencentCloud.php +++ b/app/lib/client/TencentCloud.php @@ -113,8 +113,9 @@ class TencentCloud $response = curl_exec($ch); $errno = curl_errno($ch); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } curl_close($ch); diff --git a/app/lib/client/Volcengine.php b/app/lib/client/Volcengine.php index fc31837..e5a975a 100644 --- a/app/lib/client/Volcengine.php +++ b/app/lib/client/Volcengine.php @@ -218,8 +218,9 @@ class Volcengine $response = curl_exec($ch); $errno = curl_errno($ch); if ($errno) { + $errmsg = curl_error($ch); curl_close($ch); - throw new Exception('Curl error: ' . curl_error($ch)); + throw new Exception('Curl error: ' . $errmsg); } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); diff --git a/app/lib/deploy/btwaf.php b/app/lib/deploy/btwaf.php new file mode 100644 index 0000000..402b54e --- /dev/null +++ b/app/lib/deploy/btwaf.php @@ -0,0 +1,134 @@ +url = rtrim($config['url'], '/'); + $this->key = $config['key']; + $this->proxy = $config['proxy'] == 1; + } + + public function check() + { + if (empty($this->url) || empty($this->key)) throw new Exception('请填写面板地址和接口密钥'); + + $path = '/api/user/latest_version'; + $response = $this->request($path, []); + $result = json_decode($response, true); + if (isset($result['code']) && $result['code'] == 0) { + return true; + } else { + throw new Exception(isset($result['res']) ? $result['res'] : '面板地址无法连接'); + } + } + + public function deploy($fullchain, $privatekey, $config, &$info) + { + $sites = explode("\n", $config['sites']); + $success = 0; + $errmsg = null; + foreach ($sites as $site) { + $siteName = trim($site); + if (empty($siteName)) continue; + try { + $this->deploySite($siteName, $fullchain, $privatekey); + $this->log("网站 {$siteName} 证书部署成功"); + $success++; + } catch (Exception $e) { + $errmsg = $e->getMessage(); + $this->log("网站 {$siteName} 证书部署失败:" . $errmsg); + } + } + if ($success == 0) { + throw new Exception($errmsg ? $errmsg : '要部署的网站不存在'); + } + } + + private function deploySite($siteName, $fullchain, $privatekey) + { + $site_id = null; + $listen_ssl_port = ['443']; + $path = '/api/wafmastersite/get_site_list'; + $data = ['p' => 1, 'p_size' => 10, 'site_name' => $siteName]; + $response = $this->request($path, $data); + $result = json_decode($response, true); + if (isset($result['code']) && $result['code'] == 0) { + foreach ($result['res']['list'] as $site) { + if ($site['site_name'] == $siteName) { + $site_id = $site['site_id']; + if (isset($site['server']['listen_ssl_port']) && !empty($site['server']['listen_ssl_port'])) { + $listen_ssl_port = $site['server']['listen_ssl_port']; + } + break; + } + } + if (!$site_id) { + throw new Exception("网站名称不存在"); + } + } elseif (isset($result['res'])) { + throw new Exception($result['res']); + } else { + throw new Exception($response ? $response : '返回数据解析失败'); + } + $path = '/api/wafmastersite/modify_site'; + $data = [ + 'types' => 'openCert', + 'site_id' => $site_id, + 'server' => [ + 'listen_ssl_port' => $listen_ssl_port, + 'ssl' => [ + 'is_ssl' => 1, + 'private_key' => $privatekey, + 'full_chain' => $fullchain, + ], + ] + ]; + $response = $this->request($path, $data); + $result = json_decode($response, true); + if (isset($result['code']) && $result['code'] == 0) { + return true; + } elseif (isset($result['res'])) { + throw new Exception($result['res']); + } else { + throw new Exception($response ? $response : '返回数据解析失败'); + } + } + + public function setLogger($func) + { + $this->logger = $func; + } + + private function log($txt) + { + if ($this->logger) { + call_user_func($this->logger, $txt); + } + } + + private function request($path, $params) + { + $url = $this->url . $path; + + $now_time = time(); + $headers = [ + 'waf_request_time: ' . $now_time, + 'waf_request_token: ' . md5($now_time . md5($this->key)), + 'Content-Type: application/json', + ]; + $post = $params ? json_encode($params) : null; + $response = curl_client($url, $post, null, null, $headers, $this->proxy, 'POST'); + return $response['body']; + } +} diff --git a/app/lib/deploy/opanel.php b/app/lib/deploy/opanel.php index 43c54b6..7082959 100644 --- a/app/lib/deploy/opanel.php +++ b/app/lib/deploy/opanel.php @@ -14,7 +14,7 @@ class opanel implements DeployInterface public function __construct($config) { - $this->url = rtrim($config['url'], '/') . '/api/' . $config['version'] ?: 'v1'; + $this->url = rtrim($config['url'], '/') . '/api/' . (isset($config['version']) ? $config['version'] : 'v1'); $this->key = $config['key']; $this->proxy = $config['proxy'] == 1; } diff --git a/app/view/domain/batchadd2.html b/app/view/domain/batchadd2.html index 74ed860..220e9ea 100644 --- a/app/view/domain/batchadd2.html +++ b/app/view/domain/batchadd2.html @@ -37,6 +37,17 @@ tbody tr>td:nth-child(3){min-width:300px;word-break:break-all;}
+ +
+ +
+ + +