get(); // 判空 if ($website_lists->isEmpty()) { return response()->json([ 'code' => 0, 'msg' => '无数据', 'data' => [] ]); } return response()->json([ 'code' => 0, 'msg' => '获取成功', 'data' => $website_lists ]); } /** * 添加面板网站 * @param Request $request * @return JsonResponse */ public function add(Request $request): JsonResponse { // 消毒数据 try { $credentials = $this->validate($request, [ 'name' => 'required|max:255', 'domain' => 'required', 'path' => 'string|nullable|max:255', 'php' => 'required|integer', 'note' => 'string|nullable|max:255', 'db' => 'required|boolean', 'db_type' => 'required_if:db,true|string|max:10', 'db_name' => 'required_if:db,true|string|max:255', 'db_username' => 'required_if:db,true|string|max:255', 'db_password' => 'required_if:db,true|string|max:255', ]); } catch (ValidationException $e) { return response()->json([ 'message' => '参数错误', 'errors' => $e->errors() ], 422); } // path为空时,设置默认值 if (empty($credentials['path'])) { $credentials['path'] = '/www/wwwroot/' . $credentials['name']; } // ssl默认设置为0 $credentials['ssl'] = 0; // 运行状态默认设置为1 $credentials['status'] = 1; $domain = trim($credentials['domain']); // 入库 Website::query()->create($credentials); // 创建网站目录 shell_exec("mkdir -p " . $credentials['path']); // 创建index.html shell_exec("touch " . $credentials['path'] . "/index.html"); // 写入到index.html $index_html = << 耗子Linux面板

耗子Linux面板

这是耗子Linux面板的网站默认页面!

当您看到此页面,说明您的网站已创建成功。

EOF; file_put_contents($credentials['path'] . "/index.html", $index_html); // 创建nginx配置 $port_list = ""; $domain_list = ""; $domain_arr = explode(PHP_EOL, $domain); foreach ($domain_arr as $key => $value) { $temp = explode(":", $value); $domain_list .= " " . $temp[0]; if (!isset($temp[1])) { if ($key == count($domain_arr) - 1) { $port_list .= " listen 80;"; } else { $port_list .= " listen 80;" . PHP_EOL; } } else { if ($key == count($domain_arr) - 1) { $port_list .= " listen " . $temp[1] . ";"; } else { $port_list .= " listen " . $temp[1] . ";" . PHP_EOL; } } } $nginx_config = << /www/server/vhost/rewrite/' . $credentials['name'] . '.conf'); shell_exec('echo "" > /www/server/vhost/ssl/' . $credentials['name'] . '.pem'); shell_exec('echo "" > /www/server/vhost/ssl/' . $credentials['name'] . '.key'); shell_exec("systemctl reload nginx"); // 创建数据库 if ($credentials['db']) { if ($credentials['db_type'] == 'mysql') { $password = Setting::query()->where('name', 'mysql_root_password')->value('value'); shell_exec("/www/server/mysql/bin/mysql -u root -p" . $password . " -e \"CREATE DATABASE IF NOT EXISTS " . $credentials['db_name'] . " DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;\" 2>&1"); shell_exec("/www/server/mysql/bin/mysql -u root -p" . $password . " -e \"CREATE USER '" . $credentials['db_username'] . "'@'localhost' IDENTIFIED BY '" . $credentials['db_password'] . "';\""); shell_exec("/www/server/mysql/bin/mysql -u root -p" . $password . " -e \"GRANT ALL PRIVILEGES ON " . $credentials['db_name'] . ".* TO '" . $credentials['db_username'] . "'@'localhost';\""); shell_exec("/www/server/mysql/bin/mysql -u root -p" . $password . " -e \"flush privileges;\""); } } $res['code'] = 0; $res['msg'] = 'success'; return response()->json($res); } /** * 删除面板网站 * @param Request $request * @return JsonResponse */ public function delete(Request $request): JsonResponse { $name = $request->input('name'); // 从数据库删除 Website::query()->where('name', $name)->delete(); // 删除站点目录 shell_exec("rm -rf /www/wwwroot/$name"); // 删除nginx配置 shell_exec("rm -rf /www/server/vhost/$name.conf"); // 删除rewrite配置 shell_exec("rm -rf /www/server/vhost/rewrite/$name.conf"); // 删除ssl配置 shell_exec("rm -rf /www/server/vhost/ssl/$name.pem"); shell_exec("rm -rf /www/server/vhost/ssl/$name.key"); $res['code'] = 0; $res['msg'] = 'success'; return response()->json($res); } /** * 获取网站全局设置 * @return */ public function get_website_default_settings() { return '待开发功能'; } /** * 保存网站全局设置 * @return */ public function save_website_default_settings() { return '待开发功能'; } /** * 获取面板网站设置 * @param Request $request * @return JsonResponse */ public function getSiteSettings(Request $request): JsonResponse { $name = $request->input('name'); $website = Website::query()->where('name', $name)->first(); // 通过name读取相应的nginx配置 $nginx_config = file_get_contents('/www/server/vhost/' . $name . '.conf'); // 从nginx配置中port标记位提取全部端口 $port_raw = $this->cut('# port标记位开始', '# port标记位结束', $nginx_config); preg_match_all('/listen\s+(.*);/', $port_raw, $matches); foreach ($matches[1] as $k => $v) { if ($k == 0) { $website['port'] = $v; } else { $website['port'] .= PHP_EOL . $v; } } // 从nginx配置中server_name标记位提取全部域名 $server_name_raw = $this->cut('# server_name标记位开始', '# server_name标记位结束', $nginx_config); preg_match_all('/server_name\s+(.+);/', $server_name_raw, $matches1); $domain_arr = explode(" ", $matches1[1][0]); foreach ($domain_arr as $k => $v) { if ($k == 0) { $website['domain'] = $v; } else { $website['domain'] .= PHP_EOL . $v; } } // 从nginx配置中root标记位提取全部根目录 $root_raw = $this->cut('# root标记位开始', '# root标记位结束', $nginx_config); preg_match_all('/root\s+(.+);/', $root_raw, $matches2); $website['root'] = $matches2[1][0]; // 从nginx配置中index标记位提取全部默认文件 $index_raw = $this->cut('# index标记位开始', '# index标记位结束', $nginx_config); preg_match_all('/index\s+(.+);/', $index_raw, $matches3); $website['index'] = $matches3[1][0]; if ($website['ssl'] == '1') { $ssl_certificate_raw = $this->cut('# ssl标记位开始', '# ssl标记位结束', $nginx_config); // 从nginx配置中ssl_certificate标记位提取全部证书路径 preg_match_all('/ssl_certificate\s+(.+);/', $ssl_certificate_raw, $matches4); $website['ssl_certificate'] = file_get_contents($matches4[1][0]); // 从nginx配置中ssl_certificate_key标记位提取全部证书密钥路径 preg_match_all('/ssl_certificate_key\s+(.+);/', $ssl_certificate_raw, $matches5); $website['ssl_certificate_key'] = file_get_contents($matches5[1][0]); $website['http_redirect'] = str_contains($nginx_config, '# http重定向标记位'); } // 读取伪静态文件的内容 $website['rewrite'] = file_get_contents('/www/server/vhost/rewrite/' . $name . '.conf'); // 读取配置原文 $website['config_raw'] = file_get_contents('/www/server/vhost/' . $name . '.conf'); // 读取访问日志 $website['log'] = shell_exec('tail -n 100 /www/wwwlogs/' . $name . '.log'); $res['code'] = 0; $res['msg'] = 'success'; $res['data'] = $website; return response()->json($res); } /** * 保存网站设置 * @param Request $request * @return JsonResponse */ public function saveSiteSettings(Request $request): JsonResponse { // 获取前端传递过来的数据 $config = $request->input('config'); $res['code'] = 0; $res['msg'] = 'success'; // 如果config_raw与本地配置文件不一致,则更新配置文件,然后返回 $config_raw = shell_exec('cat /www/server/vhost/' . $config['name'] . '.conf'); if (trim($config_raw) != trim($config['config_raw'])) { file_put_contents('/www/server/vhost/' . $config['name'] . '.conf', $config['config_raw']); return response()->json($res); } // 域名 $domain = "server_name"; $domain_arr = explode(PHP_EOL, $config['domain']); foreach ($domain_arr as $v) { $domain .= " " . $v; } $domain .= ';'; $domain_config_old = $this->cut('# server_name标记位开始', '# server_name标记位结束', $config_raw); if (!empty(trim($domain_config_old)) && $domain_config_old != PHP_EOL) { $config_raw = str_replace($domain_config_old, PHP_EOL . " " . $domain . PHP_EOL . ' ', $config_raw); } // 端口 $port = ""; $port_arr = explode(PHP_EOL, $config['port']); foreach ($port_arr as $k => $v) { if ($k != count($port_arr) - 1) { $port .= " listen " . $v . ';' . PHP_EOL; } else { $port .= " listen " . $v . ';'; } } $port_config_old = $this->cut('# port标记位开始', '# port标记位结束', $config_raw); if (!empty(trim($port_config_old)) && $port_config_old != PHP_EOL) { $config_raw = str_replace($port_config_old, PHP_EOL . $port . PHP_EOL . ' ', $config_raw); } // 如果开启ssl,则更新nginx配置文件 if ($config['ssl'] == '1') { // 写入证书 file_put_contents("/www/server/vhost/ssl/" . $config['name'] . '.pem', $config['ssl_certificate']); file_put_contents("/www/server/vhost/ssl/" . $config['name'] . '.key', $config['ssl_certificate_key']); $ssl_config = <<cut('# ssl标记位开始', '# ssl标记位结束', $config_raw); if (!empty(trim($ssl_config_old)) && $ssl_config_old != PHP_EOL) { $config_raw_clean = str_replace($ssl_config_old, "", $config_raw); } else { $config_raw_clean = $config_raw; } $config_raw = str_replace('# ssl标记位开始', $ssl_config, $config_raw_clean); } else { // 更新nginx配置文件 $ssl_config_old = $this->cut('# ssl标记位开始', '# ssl标记位结束', $config_raw); if (!empty(trim($ssl_config_old)) && $ssl_config_old != PHP_EOL) { $config_raw = str_replace($ssl_config_old, PHP_EOL . ' ', $config_raw); } } // 如果PHP版本不一致,则更新PHP版本 $php_old = Website::query()->where('name', $config['name'])->value('php'); if ($config['php'] != $php_old) { $php_config_old = $this->cut('# php标记位开始', '# php标记位结束', $config_raw); $php_config_new = PHP_EOL; $php_config_new .= <<where('name', $config['name'])->update(['php' => $config['php']]); Website::query()->where('name', $config['name'])->update(['ssl' => $config['ssl']]); file_put_contents('/www/server/vhost/' . $config['name'] . '.conf', $config_raw); file_put_contents('/www/server/vhost/rewrite/' . $config['name'] . '.conf', $config['rewrite_raw']); shell_exec('systemctl reload nginx'); return response()->json($res); } /** * 清理网站日志 * @param Request $request * @return JsonResponse */ public function cleanSiteLog(Request $request): JsonResponse { $name = $request->input('name'); shell_exec('echo "" > /www/wwwlogs/' . $name . '.log'); $res['code'] = 0; $res['msg'] = 'success'; return response()->json($res); } // 裁剪字符串 private function cut($begin, $end, $str): string { $b = mb_strpos($str, $begin) + mb_strlen($begin); $e = mb_strpos($str, $end) - $b; return mb_substr($str, $b, $e); } }