Browse Source

适配新版VNet, 去ssrpanel化

兔姬桑 4 years ago
parent
commit
fdc0fa62af

+ 11 - 8
.env.example

@@ -9,10 +9,11 @@ APP_LOCALE=zh-CN
 APP_FALLBACK_LOCALE=en
 LOG_CHANNEL=daily
 
+# 数据库
 DB_CONNECTION=mysql
 DB_HOST=127.0.0.1
 DB_PORT=3306
-DB_DATABASE=SSRPanel_OtakuMod
+DB_DATABASE=ProxyPanel
 DB_USERNAME=root
 DB_PASSWORD=root
 DB_STRICT=false
@@ -21,22 +22,24 @@ BROADCAST_DRIVER=redis
 CACHE_DRIVER=redis
 QUEUE_CONNECTION=redis
 SESSION_DRIVER=redis
+SESSION_CONNECTION=session
 SESSION_LIFETIME=120
 
+# Redis 设置
 REDIS_HOST=127.0.0.1
 REDIS_PASSWORD=null
 REDIS_PORT=6379
 
-MAIL_DRIVER=smtp
+MAIL_DRIVER=smtp #或使用 mailgun
+# SMTP设置
 MAIL_HOST=smtp.exmail.qq.com
 MAIL_PORT=465
-MAIL_USERNAME=admin@ssrpanel.com
+MAIL_USERNAME=admin@proxypanel.ml
 MAIL_PASSWORD=password
 MAIL_ENCRYPTION=ssl
-MAIL_LOG_CHANNEL=daily
-MAIL_FROM_ADDRESS=admin@ssrpanel.com
-MAIL_FROM_NAME=SSRPanel
-
+MAIL_FROM_ADDRESS=admin@proxypanel.ml
+MAIL_FROM_NAME=ProxyPanel
+# Mailgun设置
 MAILGUN_DOMAIN=
 MAILGUN_SECRET=
 
@@ -53,4 +56,4 @@ PUSHER_APP_CLUSTER=mt1
 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
 MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
 
-REDIRECT_HTTPS=true
+REDIRECT_HTTPS=true

+ 3 - 3
app/Http/Controllers/AdminController.php

@@ -1205,7 +1205,7 @@ class AdminController extends Controller {
 	// 推送通知测试
 	public function sendTestNotification(): JsonResponse {
 		if(self::$systemConfig['is_notification']){
-			$result = PushNotification::send('这是测试的标题', 'SSRPanel_OM测试内容');
+			$result = PushNotification::send('这是测试的标题', 'ProxyPanel测试内容');
 			if($result == false){
 				return Response::json(['status' => 'fail', 'message' => '发送失败,请重新尝试!']);
 			}
@@ -1266,8 +1266,8 @@ class AdminController extends Controller {
 
 		$spreadsheet = new Spreadsheet();
 		$spreadsheet->getProperties()
-		            ->setCreator('SSRPanel')
-		            ->setLastModifiedBy('SSRPanel')
+		            ->setCreator('ProxyPanel')
+		            ->setLastModifiedBy('ProxyPanel')
 		            ->setTitle('邀请码')
 		            ->setSubject('邀请码')
 		            ->setDescription('')

+ 1 - 1
app/Http/Controllers/Api/LoginController.php

@@ -107,7 +107,7 @@ class LoginController extends Controller {
 				'text'         => '',
 				'buy_link'     => '',
 				'money'        => '0.00',
-				'sspannelName' => 'ssrpanel',
+				'sspannelName' => 'proxypanel',
 				'usedTraffic'  => flowAutoShow($user->u + $user->d),
 				'Traffic'      => flowAutoShow($user->transfer_enable),
 				'all'          => 1,

+ 1 - 0
app/Http/Controllers/Api/WebApi/TrojanController.php

@@ -18,6 +18,7 @@ class TrojanController extends BaseController {
 			'speed_limit'  => $node->speed_limit,
 			'client_limit' => $node->client_limit,
 			'push_port'    => $node->push_port,
+			'redirect_url' => Helpers::systemConfig()['redirect_url'],
 			'trojan_port'  => $node->port,
 			'secret'       => $node->auth->secret,
 			'license'      => Helpers::systemConfig()['trojan_license'],

+ 4 - 3
app/Http/Controllers/Api/WebApi/V2RayController.php

@@ -13,7 +13,7 @@ class V2RayController extends BaseController {
 	// 获取节点信息
 	public function getNodeInfo($id): JsonResponse {
 		$node = SsNode::query()->whereId($id)->first();
-		$nodeTls = NodeCertificate::query()->whereId($node->server)->first();
+		$nodeDv = NodeCertificate::query()->whereId($node->server)->first();
 
 		return $this->returnData('获取节点信息成功', 'success', 200, [
 			'id'              => $node->id,
@@ -21,9 +21,10 @@ class V2RayController extends BaseController {
 			'speed_limit'     => $node->speed_limit,
 			'client_limit'    => $node->client_limit,
 			'push_port'       => $node->push_port,
+			'redirect_url'    => Helpers::systemConfig()['redirect_url'],
 			'secret'          => $node->auth->secret,
-			'key'             => $nodeTls? $nodeTls->key : '',
-			'pem'             => $nodeTls? $nodeTls->pem : '',
+			'key'             => $nodeDv? $nodeDv->key : '',
+			'pem'             => $nodeDv? $nodeDv->pem : '',
 			'v2_license'      => Helpers::systemConfig()['v2ray_license'],
 			'v2_alter_id'     => $node->v2_alter_id,
 			'v2_port'         => $node->v2_port,

+ 3 - 1
app/Http/Controllers/Api/WebApi/VNetController.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers\Api\WebApi;
 
+use App\Components\Helpers;
 use App\Models\SsNode;
 use App\Models\User;
 use Illuminate\Http\JsonResponse;
@@ -24,7 +25,8 @@ class VNetController extends BaseController {
 			'port'         => strval($node->port),
 			'passwd'       => $node->passwd?: '',
 			'push_port'    => $node->push_port,
-			'secret'       => $node->auth->secret
+			'secret'       => $node->auth->secret,
+			'redirect_url' => Helpers::systemConfig()['redirect_url']
 		]);
 	}
 

+ 6 - 10
app/Models/Rule.php

@@ -8,23 +8,19 @@ use Illuminate\Database\Eloquent\Model;
 /**
  * 审计规则
  *
- * @property int                        $id
- * @property int                        $type    类型:1-正则表达式、2-域名、3-IP、4-协议
- * @property string                     $name    规则描述
- * @property string                     $pattern 规则值
- * @property \Illuminate\Support\Carbon $created_at
- * @property \Illuminate\Support\Carbon $updated_at
- * @property-read mixed                 $type_api_label
- * @property-read mixed                 $type_label
+ * @property int         $id
+ * @property int         $type    类型:1-正则表达式、2-域名、3-IP、4-协议
+ * @property string      $name    规则描述
+ * @property string      $pattern 规则值
+ * @property-read string $type_api_label
+ * @property-read string $type_label
  * @method static Builder|Rule newModelQuery()
  * @method static Builder|Rule newQuery()
  * @method static Builder|Rule query()
- * @method static Builder|Rule whereCreatedAt($value)
  * @method static Builder|Rule whereId($value)
  * @method static Builder|Rule whereName($value)
  * @method static Builder|Rule wherePattern($value)
  * @method static Builder|Rule whereType($value)
- * @method static Builder|Rule whereUpdatedAt($value)
  * @mixin \Eloquent
  */
 class Rule extends Model {

+ 4 - 1
app/Models/SsNode.php

@@ -53,7 +53,7 @@ use Illuminate\Database\Eloquent\Relations\HasOne;
  * @property \Illuminate\Support\Carbon                                              $created_at
  * @property \Illuminate\Support\Carbon                                              $updated_at
  * @property-read \App\Models\NodeAuth|null                                          $auth
- * @property-read mixed                                                              $type_label
+ * @property-read string                                                             $type_label
  * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\SsNodeLabel[] $label
  * @property-read int|null                                                           $label_count
  * @method static Builder|SsNode newModelQuery()
@@ -129,6 +129,9 @@ class SsNode extends Model {
 			case 3:
 				$type_label = 'Trojan';
 				break;
+			case 4:
+				$type_label = 'VNet';
+				break;
 			default:
 				$type_label = 'UnKnown';
 		}

+ 2 - 2
config/version.php

@@ -1,6 +1,6 @@
 <?php
 
 return [
-    'number' => '210',
-    'name' => 'SSRPanel_OtakuMod'
+    'number' => '2.4.a',
+    'name' => 'ProxyPanel'
 ];

+ 1 - 1
public/index.php

@@ -7,7 +7,7 @@
  * @author   Taylor Otwell <taylor@laravel.com>
  */
 
-// 判断是否安装SSRPanel
+// 判断是否安装ProxyPanel
 if (!is_file(__DIR__.'/../.env'))
 {
     header("location:./install.php");

+ 36 - 134
public/install.php

@@ -9,17 +9,9 @@
 
 // error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
 // ini_set('display_errors', '1');
-// 定义目录分隔符
-define('DS', DIRECTORY_SEPARATOR);
-
-// 定义根目录
-define('ROOT_PATH', __DIR__.DS.'..'.DS);
-
-// 定义应用目录
-define('APP_PATH', ROOT_PATH.'app'.DS);
-
-// 安装包目录
-define('INSTALL_PATH', ROOT_PATH.'sql'.DS);
+define('DS', DIRECTORY_SEPARATOR); // 定义目录分隔符
+define('ROOT_PATH', __DIR__.DS.'..'.DS); // 定义根目录
+define('DB_PATH', ROOT_PATH.'sql'.DS.'db.sql');// 数据库
 
 // 判断文件或目录是否有写的权限
 function is_really_writable($file) {
@@ -36,54 +28,9 @@ function is_really_writable($file) {
 	return true;
 }
 
-// 写配置文件
-function write_ini_file($assoc_arr, $path, $has_sections = false) {
-	$content = "";
-	if($has_sections){
-		foreach($assoc_arr as $key => $elem){
-			$content .= "[".$key."]\n";
-			foreach($elem as $key2 => $elem2){
-				if(is_array($elem2)){
-					for($i = 0; $i < count($elem2); $i++){
-						$content .= $key2."[] = \"".$elem2[$i]."\"\n";
-					}
-				}elseif($elem2 == ""){
-					$content .= $key2." = \n";
-				}else{
-					$content .= $key2." = \"".$elem2."\"\n";
-				}
-			}
-		}
-	}else{
-		foreach($assoc_arr as $key => $elem){
-			if(is_array($elem)){
-				for($i = 0; $i < count($elem); $i++){
-					$content .= $key."[] = \"".$elem[$i]."\"\n";
-				}
-			}elseif($elem == ""){
-				$content .= $key." = \n";
-			}else{
-				$content .= $key." = \"".$elem."\"\n";
-			}
-		}
-	}
-
-	if(!$handle = fopen($path, 'w')){
-		return false;
-	}
-
-	if(!fwrite($handle, $content)){
-		return false;
-	}
-
-	fclose($handle);
-
-	return true;
-}
-
-$sitename = "OtakuCloud";
+$name = "ProxyPanel";
 
-// 检测目录是否存在
+// 检测依赖组件目录是否存在
 $checkDirs = [
 	'vendor',
 ];
@@ -100,11 +47,13 @@ $exampleConfigFile = ROOT_PATH.'.env.example';
 // 锁定的文件
 $lockFile = ROOT_PATH.'.env';
 if(is_file($lockFile)){
-	$errInfo = "当前已经安装{$sitename},如果需要重新安装,请手动移除.env文件";
-}elseif(version_compare(PHP_VERSION, '7.1.3', '<')){
-	$errInfo = "当前PHP版本(".PHP_VERSION.")过低,请使用PHP7.1.3及以上版本";
+	$errInfo = "如果需要重新安装,请备份数据库后手动移除 .env 文件";
+}elseif(version_compare(PHP_VERSION, '7.3.0', '<')){
+	$errInfo = "当前PHP版本(".PHP_VERSION.")过低,请使用PHP7.3.0及以上版本";
+}elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'){
+	$errInfo = "当前系统环境为Windows,无法进行安装";
 }elseif(!is_file($exampleConfigFile)){
-	$errInfo = "缺失标准配置文件.env.example";
+	$errInfo = "缺失标准配置文件 .env.example";
 }elseif(!extension_loaded("PDO")){
 	$errInfo = "当前PHP环境未启用PDO组件,无法进行安装";
 }elseif(!is_really_writable(ROOT_PATH)){
@@ -123,7 +72,7 @@ if(is_file($lockFile)){
 	$dirArr = [];
 	foreach($checkDirs as $k => $v){
 		if(!is_dir(ROOT_PATH.$v)){
-			$errInfo = '请先在'.$sitename.'根目录下执行 php composer.phar install 安装依赖';
+			$errInfo = '请先在'.$name."根目录下执行<b>php composer.phar install</b> 安装依赖";
 			break;
 		}
 	}
@@ -138,41 +87,27 @@ if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST'){
 
 	$err = '';
 	$APP_KEY = md5(time().mt_rand(1, 1000000));
-	$DB_HOST = isset($_POST['mysqlHost'])? $_POST['mysqlHost'] : '127.0.0.1';
-	$DB_PORT = isset($_POST['mysqlHostport'])? $_POST['mysqlHostport'] : 3306;
+	$DB_HOST = isset($_POST['mysqlHost'])? trim($_POST['mysqlHost']) : '127.0.0.1';
+	$DB_PORT = isset($_POST['mysqlPort'])? trim($_POST['mysqlPort']) : 3306;
 	$hostArr = explode(':', $DB_HOST);
 	if(count($hostArr) > 1){
 		$DB_HOST = $hostArr[0];
 		$DB_PORT = $hostArr[1];
 	}
-	$DB_USERNAME = isset($_POST['mysqlUsername'])? $_POST['mysqlUsername'] : 'root';
-	$DB_PASSWORD = isset($_POST['mysqlPassword'])? $_POST['mysqlPassword'] : '';
-	$DB_DATABASE = isset($_POST['mysqlDatabase'])? $_POST['mysqlDatabase'] : 'proxypanel';
-	//    $adminUsername = isset($_POST['adminUsername']) ? $_POST['adminUsername'] : 'admin';
-	//    $adminPassword = isset($_POST['adminPassword']) ? $_POST['adminPassword'] : 'admin';
-	//    $adminPasswordConfirmation = isset($_POST['adminPasswordConfirmation']) ? $_POST['adminPasswordConfirmation'] : 'admin';
-	//    $adminEmail = isset($_POST['adminEmail']) ? $_POST['adminEmail'] : 'admin@admin.com';
-	//    if ($adminPassword !== $adminPasswordConfirmation) {
-	//        echo "两次输入的密码不一致";
-	//        exit;
-	//    } else if (!preg_match("/^\w+$/", $adminUsername)) {
-	//        echo "用户名只能输入字母、数字、下划线";
-	//        exit;
-	//    } else if (!preg_match("/^[\S]+$/", $adminPassword)) {
-	//        echo "密码不能包含空格";
-	//        exit;
-	//    } else if (strlen($adminUsername) < 3 || strlen($adminUsername) > 12) {
-	//        echo "用户名请输入3~12位字符";
-	//        exit;
-	//    } else if (strlen($adminPassword) < 6 || strlen($adminPassword) > 16 || stripos($adminPassword, ' ') !== false) {
-	//        echo "密码请输入6~16位字符,不能包含空格";
-	//        exit;
-	//    }
+	$DB_USERNAME = isset($_POST['mysqlUsername'])? trim($_POST['mysqlUsername']) : 'proxypanel';
+	$DB_PASSWORD = isset($_POST['mysqlPassword'])? trim($_POST['mysqlPassword']) : 'proxypanel';
+	$DB_DATABASE = isset($_POST['mysqlDatabase'])? trim($_POST['mysqlDatabase']) : 'proxypanel';
+
 	try{
-		// 检测能否读取安装文件
-		$sql = @file_get_contents(INSTALL_PATH.'db.sql');
+		// 检测能否读取数据库文件
+		$sql = @file_get_contents(DB_PATH);
 		if(!$sql){
-			throw new Exception("无法读取所需的sql/db.sql,请检查是否有读权限");
+			throw new Exception("无法读取所需的".DB_PATH.",请检查是否有读权限");
+		}
+
+		$config = @file_get_contents($exampleConfigFile);
+		if(!$config){
+			throw new Exception("无法读取配置.env.example文件,请检查是否有读权限");
 		}
 
 		$pdo = new PDO("mysql:host={$DB_HOST};port={$DB_PORT}", $DB_USERNAME, $DB_PASSWORD, [
@@ -191,21 +126,14 @@ if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST'){
 		$pdo->query("USE `{$DB_DATABASE}`");
 		$pdo->exec($sql);
 
-		$config = @file_get_contents($exampleConfigFile);
-		if(!$config){
-			throw new Exception("无法写入读取配置.env.example文件,请检查是否有读权限");
-		}
-
+		// 写入数据库配置到.env文件
 		$callback = function($matches) use ($APP_KEY, $DB_HOST, $DB_PORT, $DB_USERNAME, $DB_PASSWORD, $DB_DATABASE) {
 			$field = $matches[1];
 			$replace = ${"{$field}"};
 			return "{$matches[1]}={$replace}".PHP_EOL;
 		};
-
 		$config = preg_replace_callback("/(APP_KEY|DB_HOST|DB_DATABASE|DB_USERNAME|DB_PASSWORD|DB_PORT)=(.*)(\s+)/",
 			$callback, $config);
-
-		// 检测能否成功写入数据库配置
 		$result = @file_put_contents($ConfigFile, $config);
 		if(!$result){
 			throw new Exception("无法写入数据库信息到.env文件,请检查是否有写权限");
@@ -228,11 +156,11 @@ if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST'){
 	<meta charset="utf-8">
 	<meta http-equiv="X-UA-Compatible" content="IE=edge">
 	<title>安装<?php
-		echo $sitename; ?></title>
+		echo $name; ?></title>
 	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
 	<meta name="renderer" content="webkit">
 
-	<style type="text/css">
+	<style>
 		body {
 			background: #5c97bd;
 			margin: 0;
@@ -356,7 +284,7 @@ if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST'){
 <body>
 <div class="container">
 	<h2>安装 <?php
-		echo $sitename; ?></h2>
+		echo $name; ?></h2>
 	<div>
 		<form method="post">
 			<?php
@@ -393,58 +321,32 @@ if(isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST'){
 
 				<div class="form-field">
 					<label>MySQL 端口号</label>
-					<input type="number" name="mysqlHostport" value="3306">
+					<input type="number" name="mysqlPort" value="3306">
 				</div>
 			</div>
 
-			<!--            <div class="form-group">-->
-			<!--                <div class="form-field">-->
-			<!--                    <label>管理者用户名</label>-->
-			<!--                    <input name="adminUsername" value="admin" required=""/>-->
-			<!--                </div>-->
-			<!---->
-			<!--                <div class="form-field">-->
-			<!--                    <label>管理者Email</label>-->
-			<!--                    <input name="adminEmail" value="admin@admin.com" required="">-->
-			<!--                </div>-->
-			<!---->
-			<!--                <div class="form-field">-->
-			<!--                    <label>管理者密码</label>-->
-			<!--                    <input type="password" name="adminPassword" required="">-->
-			<!--                </div>-->
-			<!---->
-			<!--                <div class="form-field">-->
-			<!--                    <label>重复密码</label>-->
-			<!--                    <input type="password" name="adminPasswordConfirmation" required="">-->
-			<!--                </div>-->
-			<!--            </div>-->
-
 			<div class="form-buttons">
 				<button type="submit" <?php
-				echo $errInfo? 'disabled' : '' ?>>点击安装
+				echo $errInfo? 'disabled' : '' ?>>安装
 				</button>
 			</div>
 		</form>
 
-		<!-- jQuery -->
 		<script src="//cdn.staticfile.org/jquery/2.1.4/jquery.min.js" type="text/javascript"></script>
-
-		<script type="text/javascript">
+		<script>
 			$(function () {
 
 				$('form').on('submit', function (e) {
 					e.preventDefault();
 
-					var $button = $(this).find('button')
-						.text('安装中...')
-						.prop('disabled', true);
+					var $button = $(this).find('button').text('安装中...').prop('disabled', true);
 
 					$.post('', $(this).serialize())
 						.done(function (ret) {
 							if (ret === 'success') {
 								$('#error').hide();
-								$("#success").text("<?php echo $sitename; ?>安装成功,请使用默认用户名test@test.com、密码123456登录,并尽快修改密码并重置订阅地址。").show();
-								$('<a class="btn" href="./">进入ProxyPanel</a>').insertAfter($button);
+								$("#success").text("安装成功,请使用[用户名:test@test.com、密码:123456]登录").show();
+								$('<a class="btn" href="./admin/login">登录后台</a>').insertAfter($button);
 								$button.remove();
 								localStorage.setItem("fastep", "installed");
 							} else {

+ 3 - 0
public/nginx.htaccess

@@ -0,0 +1,3 @@
+location / {
+    try_files $uri $uri/ /index.php$is_args$args;
+}

+ 15 - 0
resources/views/admin/config/system.blade.php

@@ -209,6 +209,20 @@
 											<span class="offset-md-3 text-help"> 自定义维护内容信息 </span>
 										</div>
 									</div>
+									<div class="form-group col-lg-6">
+										<div class="row">
+											<label class="col-md-3" for="redirect_url">重定向地址</label>
+											<div class="col-md-6">
+												<div class="input-group">
+													<textarea class="form-control" rows="3" id="redirect_url">{{$redirect_url}}</textarea>
+													<span class="input-group-append">
+														<button class="btn btn-primary" type="button" onclick="update('redirect_url')">修改</button>
+													</span>
+												</div>
+											</div>
+											<span class="offset-md-3 text-help"> 触发审计规则时访问请求被阻断并重定向至该地址 </span>
+										</div>
+									</div>
 								</div>
 							</form>
 						</div>
@@ -506,6 +520,7 @@
 													</span>
 												</div>
 											</div>
+											<span class="text-help offset-md-3">后端自动签发/载入TLS证书时用(节点的设置值优先级高于此处)</span>
 										</div>
 									</div>
 								</div>

+ 3 - 3
resources/views/admin/node/authList.blade.php

@@ -85,7 +85,7 @@
 						</h4>
 					</div>
 					<div class="modal-body">
-						@if($vl->node->type == '2')
+						@if($vl->node->type === 2)
 							<div class="alert alert-info  text-break">
 								<div class="text-center red-700 mb-5">VNET-V2Ray</div>
 								(yum install curl 2> /dev/null || apt install curl 2> /dev/null) \<br>
@@ -136,7 +136,7 @@
 								<br>
 								实时日志:journalctl -u v2ray -f
 							</div>
-						@elseif($vl->node->type == '3')
+						@elseif($vl->node->type === 3)
 							@if(!$vl->node->server)
 								<h3>请先<a href="/node/edit?id={{$vl->node->id}}" target="_blank">填写节点域名</a>并将域名解析到节点对应的IP上</h3>
 							@else
@@ -152,7 +152,7 @@
 									<br>
 									<br>
 									<div class="text-center red-700 mb-5">操作命令</div>
-									更新:curl -L -s https://bit.ly/33UdELu | bash
+									更新:curl -L -s https://bit.ly/3esZ7ec | bash
 									<br>
 									卸载:curl -L -s https://bit.ly/2Jl9bs7 | bash
 									<br>

+ 2 - 2
resources/views/admin/node/certificateList.blade.php

@@ -32,8 +32,8 @@
 						<tr>
 							<td> {{$vo->id}} </td>
 							<td> {{$vo->domain}} </td>
-							<td> {{$vo->key ? '✔' : '❌'}} </td>
-							<td> {{$vo->pem ? '✔' : '❌'}} </td>
+							<td> {{$vo->key ? '✔' : '❌'}} </td>
+							<td> {{$vo->pem ? '✔' : '❌'}} </td>
 							<td> {{$vo->issuer}} </td>
 							<td> {{$vo->from}} </td>
 							<td> {{$vo->to}} </td>

+ 1 - 2
resources/views/admin/node/nodeInfo.blade.php

@@ -671,11 +671,10 @@
 				'<ol>' +
 				'<li>请勿直接复制黏贴以下配置,SSR(R)会报错的</li>' +
 				'<li>确保服务器时间为CST</li>' +
-				'<li>具体请看<a href="https://github.com/ssrpanel/SSRPanel/wiki/%E5%8D%95%E7%AB%AF%E5%8F%A3%E5%A4%9A%E7%94%A8%E6%88%B7%E7%9A%84%E5%9D%91" target="_blank">WIKI</a></li>' +
 				'</ol>' +
 				'&emsp;&emsp;"additional_ports" : {<br />' +
 				'&emsp;&emsp;&emsp;"443": {<br />' +
-				'&emsp;&emsp;&emsp;&emsp;"passwd": "@HentaiCloud!",<br />' +
+				'&emsp;&emsp;&emsp;&emsp;"passwd": "ProxyPanel",<br />' +
 				'&emsp;&emsp;&emsp;&emsp;"method": "none",<br />' +
 				'&emsp;&emsp;&emsp;&emsp;"protocol": "auth_chain_a",<br />' +
 				'&emsp;&emsp;&emsp;&emsp;"protocol_param": "#",<br />' +

+ 21 - 36
sql/db.sql

@@ -415,7 +415,8 @@ VALUES ('1', 'is_rand_port', 0),
        ('108', 'paypal_password', ''),
        ('109', 'paypal_secret', ''),
        ('110', 'paypal_certificate', ''),
-       ('111', 'paypal_app_id', '');
+       ('111', 'paypal_app_id', ''),
+       ('112', 'redirect_url', '');
 
 -- ----------------------------
 -- Table structure for article
@@ -1251,8 +1252,6 @@ CREATE TABLE `rule`
     `type`       TINYINT(1)       NOT NULL DEFAULT '1' COMMENT '类型:1-正则表达式、2-域名、3-IP、4-协议',
     `name`       VARCHAR(100)     NOT NULL COMMENT '规则描述',
     `pattern`    TEXT             NOT NULL COMMENT '规则值',
-    `created_at` DATETIME         NOT NULL,
-    `updated_at` DATETIME         NOT NULL,
     PRIMARY KEY (`id`)
 ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT ='审计规则';
 
@@ -1260,50 +1259,36 @@ CREATE TABLE `rule`
 -- ----------------------------
 -- Records of rule
 -- ----------------------------
-INSERT INTO `rule`(`id`, `type`, `name`, `pattern`, `created_at`, `updated_at`)
+INSERT INTO `rule`(`id`, `type`, `name`, `pattern`)
 VALUES (1, '1', '360',
-        '(.*\.||)(^360|0360|1360|3600|360safe|^so|qhimg|qhmsg|^yunpan|qihoo|qhcdn|qhupdate|360totalsecurity|360shouji|qihucdn|360kan|secmp)\.(cn|com|net)',
-        '2019-07-19 15:04:11', '2019-07-19 15:04:11'),
-       (2, '1', '腾讯管家', '(\.guanjia\.qq\.com|qqpcmgr|QQPCMGR)', '2019-07-19 15:04:11', '2019-07-19 15:04:11'),
-       (3, '1', '金山毒霸', '(.*\.||)(rising|kingsoft|duba|xindubawukong|jinshanduba)\.(com|net|org)',
-        '2019-07-19 15:04:11', '2019-07-19 15:04:11'),
-       (4, '1', '暗网相关', '(.*\.||)(netvigator|torproject)\.(cn|com|net|org)', '2019-07-19 15:04:11',
-        '2019-07-19 15:04:11'),
+        '(.*\.||)(^360|0360|1360|3600|360safe|^so|qhimg|qhmsg|^yunpan|qihoo|qhcdn|qhupdate|360totalsecurity|360shouji|qihucdn|360kan|secmp)\.(cn|com|net)'),
+       (2, '1', '腾讯管家', '(\.guanjia\.qq\.com|qqpcmgr|QQPCMGR)'),
+       (3, '1', '金山毒霸', '(.*\.||)(rising|kingsoft|duba|xindubawukong|jinshanduba)\.(com|net|org)'),
+       (4, '1', '暗网相关', '(.*\.||)(netvigator|torproject)\.(cn|com|net|org)'),
        (5, '1', '百度定位',
-        '(api|ps|sv|offnavi|newvector|ulog\\.imap|newloc|tracknavi)(\\.map|)\\.(baidu|n\\.shifen)\\.com',
-        '2019-07-19 15:05:06', '2019-07-19 15:05:06'),
+        '(api|ps|sv|offnavi|newvector|ulog\\.imap|newloc|tracknavi)(\\.map|)\\.(baidu|n\\.shifen)\\.com'),
        (6, '1', '法轮功类',
-        '(.*\\.||)(dafahao|minghui|dongtaiwang|dajiyuan|falundata|shenyun|tuidang|epochweekly|epochtimes|ntdtv|falundafa|wujieliulan|zhengjian)\\.(org|com|net)',
-        '2019-07-19 15:05:46', '2019-07-19 15:05:46'),
+        '(.*\\.||)(dafahao|minghui|dongtaiwang|dajiyuan|falundata|shenyun|tuidang|epochweekly|epochtimes|ntdtv|falundafa|wujieliulan|zhengjian)\\.(org|com|net)'),
        (7, '1', 'BT扩展名',
-        '(torrent|\\.torrent|peer_id=|info_hash|get_peers|find_node|BitTorrent|announce_peer|announce\\.php\\?passkey=)',
-        '2019-07-19 15:06:07', '2019-07-19 15:06:07'),
+        '(torrent|\\.torrent|peer_id=|info_hash|get_peers|find_node|BitTorrent|announce_peer|announce\\.php\\?passkey=)'),
        (8, '1', '邮件滥发',
-        '((^.*\@)(guerrillamail|guerrillamailblock|sharklasers|grr|pokemail|spam4|bccto|chacuo|027168)\.(info|biz|com|de|net|org|me|la)|Subject|HELO|SMTP)',
-        '2019-07-19 15:06:20', '2019-07-19 15:06:20'),
-       (9, '1', '迅雷下载', '(.?)(xunlei|sandai|Thunder|XLLiveUD)(.)', '2019-07-19 15:06:31', '2019-07-19 15:06:31'),
+        '((^.*\@)(guerrillamail|guerrillamailblock|sharklasers|grr|pokemail|spam4|bccto|chacuo|027168)\.(info|biz|com|de|net|org|me|la)|Subject|HELO|SMTP)'),
+       (9, '1', '迅雷下载', '(.?)(xunlei|sandai|Thunder|XLLiveUD)(.)'),
        (10, '1', '大陆应用',
-        '(.*\\.||)(qq|163|sohu|sogoucdn|sogou|uc|58|taobao|qpic|bilibili|hdslb|sina|douban|doubanio|xiaohongshu|sinaimg|weibo|xiaomi)\\.(org|com|net|cn)',
-        '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+        '(.*\\.||)(baidu|qq|163|189|10000|10010|10086|sohu|sogoucdn|sogou|uc|58|taobao|qpic|bilibili|hdslb|acgvideo|sina|douban|doubanio|xiaohongshu|sinaimg|weibo|xiaomi|youzanyun|meituan|dianping|biliapi|huawei|pinduoduo|cnzz)\\.(org|com|net|cn)'),
        (11, '1', '大陆银行',
-        '(.*\\.||)(icbc|ccb|boc|bankcomm|abchina|cmbchina|psbc|cebbank|cmbc|pingan|spdb|citicbank|cib|hxb|bankofbeijing|hsbank|tccb|4001961200|bosc|hkbchina|njcb|nbcb|lj-bank|bjrcb|jsbchina|gzcb|cqcbank|czbank|hzbank|srcb|cbhb|cqrcb|grcbank|qdccb|bocd|hrbcb|jlbank|bankofdl|qlbchina|dongguanbank|cscb|hebbank|drcbank|zzbank|bsb|xmccb|hljrcc|jxnxs|gsrcu|fjnx|sxnxs|gx966888|gx966888|zj96596|hnnxs|ahrcu|shanxinj|hainanbank|scrcu|gdrcu|hbxh|ynrcc|lnrcc|nmgnxs|hebnx|jlnls|js96008|hnnx|sdnxs)\\.(org|com|net|cn)',
-        '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+        '(.*\\.||)(icbc|ccb|boc|bankcomm|abchina|cmbchina|psbc|cebbank|cmbc|pingan|spdb|citicbank|cib|hxb|bankofbeijing|hsbank|tccb|4001961200|bosc|hkbchina|njcb|nbcb|lj-bank|bjrcb|jsbchina|gzcb|cqcbank|czbank|hzbank|srcb|cbhb|cqrcb|grcbank|qdccb|bocd|hrbcb|jlbank|bankofdl|qlbchina|dongguanbank|cscb|hebbank|drcbank|zzbank|bsb|xmccb|hljrcc|jxnxs|gsrcu|fjnx|sxnxs|gx966888|gx966888|zj96596|hnnxs|ahrcu|shanxinj|hainanbank|scrcu|gdrcu|hbxh|ynrcc|lnrcc|nmgnxs|hebnx|jlnls|js96008|hnnx|sdnxs)\\.(org|com|net|cn)'),
        (12, '1', '台湾银行',
-        '(.*\\.||)(firstbank|bot|cotabank|megabank|tcb-bank|landbank|hncb|bankchb|tbb|ktb|tcbbank|scsb|bop|sunnybank|kgibank|fubon|ctbcbank|cathaybk|eximbank|bok|ubot|feib|yuantabank|sinopac|esunbank|taishinbank|jihsunbank|entiebank|hwataibank|csc|skbank)\\.(org|com|net|tw)',
-        '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+        '(.*\\.||)(firstbank|bot|cotabank|megabank|tcb-bank|landbank|hncb|bankchb|tbb|ktb|tcbbank|scsb|bop|sunnybank|kgibank|fubon|ctbcbank|cathaybk|eximbank|bok|ubot|feib|yuantabank|sinopac|esunbank|taishinbank|jihsunbank|entiebank|hwataibank|csc|skbank)\\.(org|com|net|tw)'),
        (13, '1', '大陆第三方支付',
-        '(.*\\.||)(alipay|baifubao|yeepay|99bill|95516|51credit|cmpay|tenpay|lakala|jdpay)\\.(org|com|net|cn)',
-        '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
-       (14, '1', '台湾特供', '(.*\.||)(visa|mycard|mastercard|gov|gash|beanfun|bank|line)\.(org|com|net|cn|tw|jp|kr)',
-        '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+        '(.*\\.||)(alipay|baifubao|yeepay|99bill|95516|51credit|cmpay|tenpay|lakala|jdpay)\\.(org|com|net|cn)'),
+       (14, '1', '台湾特供', '(.*\.||)(visa|mycard|mastercard|gov|gash|beanfun|bank|line)\.(org|com|net|cn|tw|jp|kr)'),
        (15, '1', '涉政治类',
-        '(.*\\.||)(shenzhoufilm|secretchina|renminbao|aboluowang|mhradio|guangming|zhengwunet|soundofhope|yuanming|zhuichaguoji|fgmtv|xinsheng|shenyunperformingarts|epochweekly|tuidang|shenyun|falundata|bannedbook|pincong|ogate|voachinese)\\.(org|com|net|rocks)',
-        '0000-00-00 00:00:00', '0000-00-00 00:00:00'),
+        '(.*\\.||)(shenzhoufilm|secretchina|renminbao|aboluowang|mhradio|guangming|zhengwunet|soundofhope|yuanming|zhuichaguoji|fgmtv|xinsheng|shenyunperformingarts|epochweekly|tuidang|shenyun|falundata|bannedbook|pincong|rfi|mingjingnews|boxun|rfa|scmp|ogate|voachinese)\\.(org|com|net|rocks|fr)'),
        (16, '1', '流媒体',
-        '(.*\.||)(youtube|googlevideo|hulu|netflix|nflxvideo|akamai|nflximg|hbo|mtv|bbc|tvb)\.(org|club|com|net|tv)',
-        '2019-11-19 15:04:11', '2019-11-19 15:04:11'),
-       (17, '1', '测速类', '(.*\.||)(fast|speedtest)\.(org|com|net|cn)', '2019-11-19 15:04:11', '2019-11-19 15:04:11'),
-       (18, '1', '涉洗钱', '(.*\.||)(metatrader4|metatrader5|mql5)\.(org|com|net)', '2020-7-9 14:25:11', '2020-7-9 14:25:11');
+        '(.*\.||)(youtube|googlevideo|hulu|netflix|nflxvideo|akamai|nflximg|hbo|mtv|bbc|tvb)\.(org|club|com|net|tv)'),
+       (17, '1', '测速类', '(.*\.||)(fast|speedtest)\.(org|com|net|cn)'),
+       (18, '1', '外汇交易类', '(.*\.||)(metatrader4|metatrader5|mql5)\.(org|com|net)');
 
 -- ----------------------------
 -- Table structure for rule_group

+ 11 - 0
sql/mod/20200719.sql

@@ -0,0 +1,11 @@
+-- 触发审计规则后强制跳转地址
+INSERT INTO `config` VALUES ('112', 'redirect_url', '');
+
+-- 移除审计规则无用字段
+ALTER TABLE `rule`
+    DROP COLUMN `created_at`,
+    DROP COLUMN `updated_at`;
+
+-- 加入新审计规则条目:外汇交易类
+INSERT INTO `rule` (`id`, `type`, `name`, `pattern`)
+VALUES (18, '1', '外汇交易类', '(.*\.||)(metatrader4|metatrader5|mql5)\.(org|com|net)');