From c65091394ade8e623c55283390d10cb22c73b868 Mon Sep 17 00:00:00 2001 From: Sulaiman Date: Mon, 8 Jul 2024 21:26:07 +0700 Subject: [PATCH] Summary lib --- .env.example | 6 +- composer.json | 16 +- dockerComposer.yml | 56 +- grizzly.sh | 2013 ++++++++++++++++++++++++++ grizzly_standalone.sh | 1013 +++++++++++++ lib/archive/install_script_v2.1.5.sh | 1863 ++++++++++++++++++++++++ lib/archive/install_script_v2.1.6.sh | 1901 ++++++++++++++++++++++++ lib/archive/install_script_v2.1.7.sh | 1974 +++++++++++++++++++++++++ lib/archive/install_script_v2.1.8.sh | 1980 +++++++++++++++++++++++++ lib/archive/install_script_v2.2.0.sh | 2005 +++++++++++++++++++++++++ lib/archive/install_script_v2.2.1.sh | 2005 +++++++++++++++++++++++++ lib/archive/install_script_v2.3.0.sh | 2013 ++++++++++++++++++++++++++ 12 files changed, 16806 insertions(+), 39 deletions(-) create mode 100644 grizzly.sh create mode 100644 grizzly_standalone.sh create mode 100644 lib/archive/install_script_v2.1.5.sh create mode 100644 lib/archive/install_script_v2.1.6.sh create mode 100644 lib/archive/install_script_v2.1.7.sh create mode 100644 lib/archive/install_script_v2.1.8.sh create mode 100644 lib/archive/install_script_v2.2.0.sh create mode 100644 lib/archive/install_script_v2.2.1.sh create mode 100644 lib/archive/install_script_v2.3.0.sh diff --git a/.env.example b/.env.example index 95ae7d9..a7c5ee0 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -APP_NAME=Trojan-Panel +APP_NAME=grizzly APP_ENV=production APP_KEY= APP_DEBUG=false @@ -9,8 +9,8 @@ LOG_CHANNEL=stack DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 -DB_DATABASE=trojan -DB_USERNAME=trojan +DB_DATABASE=grizzly +DB_USERNAME=grizzly DB_PASSWORD= BROADCAST_DRIVER=log diff --git a/composer.json b/composer.json index f587e08..0e17ed2 100644 --- a/composer.json +++ b/composer.json @@ -1,17 +1,17 @@ { - "name": "laravel/laravel", - "description": "The Laravel Framework.", - "keywords": ["framework", "laravel"], - "license": "MIT", + "name": "lib/lib", + "description": "The lib Framework.", + "keywords": ["framework", "lib"], + "license": "other", "type": "project", "require": { "php": "^7.1.3", "fideloper/proxy": "^4.0", - "laravel/framework": "5.7.*", - "laravel/tinker": "^1.0" + "lib/framework": "5.7.*", + "lib/tinker": "^1.0" }, "require-dev": { - "beyondcode/laravel-dump-server": "^1.0", + "beyondcode/lib-dump-server": "^1.0", "filp/whoops": "^2.0", "fzaninotto/faker": "^1.4", "mockery/mockery": "^1.0", @@ -33,7 +33,7 @@ } }, "extra": { - "laravel": { + "lib": { "dont-discover": [ ] } diff --git a/dockerComposer.yml b/dockerComposer.yml index 5468a4d..ab69472 100644 --- a/dockerComposer.yml +++ b/dockerComposer.yml @@ -1,9 +1,9 @@ version: '3' services: - trojan-panel-caddy: + grizzly: image: caddy:2.6.2 - container_name: trojan-panel-caddy + container_name: grizzly restart: always network_mode: host volumes: @@ -13,33 +13,33 @@ services: - "/tpdata/caddy/logs/:/tpdata/caddy/logs/" command: caddy run --config /tpdata/caddy/config.json - trojan-panel-mariadb: + grizzly-mariadb: image: mariadb:10.7.3 - container_name: trojan-panel-mariadb + container_name: grizzly-mariadb restart: always network_mode: host environment: - MYSQL_DATABASE: trojan_panel_db + MYSQL_DATABASE: grizzly_db MYSQL_ROOT_PASSWORD: "${mariadb_pas}" TZ: Asia/Shanghai command: --port=9507 - trojan-panel-redis: + grizzly-redis: image: redis:6.2.7 - container_name: trojan-panel-redis + container_name: grizzly-redis restart: always network_mode: host command: redis-server --requirepass ${redis_pass} --port 6378 - trojan-panel: - image: jonssonyan/trojan-panel - container_name: trojan-panel + grizzly: + image: jonssonyan/grizzly + container_name: grizzly restart: always network_mode: host volumes: - - "/tpdata/web/:/tpdata/trojan-panel/webfile/" - - "/tpdata/trojan-panel/logs/:/tpdata/trojan-panel/logs/" - - "/tpdata/trojan-panel/config/:/tpdata/trojan-panel/config/" + - "/tpdata/web/:/tpdata/grizzly/webfile/" + - "/tpdata/grizzly/logs/:/tpdata/grizzly/logs/" + - "/tpdata/grizzly/config/:/tpdata/grizzly/config/" - "/etc/localtime:/etc/localtime" environment: - "GIN_MODE=release" @@ -52,28 +52,28 @@ services: - "redis_pass=${redis_pass}" - "server_port=8081" - trojan-panel-ui: - image: jonssonyan/trojan-panel-ui - container_name: trojan-panel-ui + grizzly-ui: + image: jonssonyan/grizzly-ui + container_name: grizzly-ui restart: always network_mode: host volumes: - - "/tpdata/trojan-panel-ui/nginx/default.conf:/etc/nginx/conf.d/default.conf" + - "/tpdata/grizzly-ui/nginx/default.conf:/etc/nginx/conf.d/default.conf" - "/tpdata/cert/:/tpdata/cert/" - trojan-panel-core: - image: jonssonyan/trojan-panel-core - container_name: trojan-panel-core + grizzly-core: + image: jonssonyan/grizzly-core + container_name: grizzly-core restart: always network_mode: host volumes: - - "/tpdata/trojan-panel-core/bin/xray/config/:/tpdata/trojan-panel-core/bin/xray/config/" - - "/tpdata/trojan-panel-core/bin/trojango/config/:/tpdata/trojan-panel-core/bin/trojango/config/" - - "/tpdata/trojan-panel-core/bin/hysteria/config/:/tpdata/trojan-panel-core/bin/hysteria/config/" - - "/tpdata/trojan-panel-core/bin/naiveproxy/config/:/tpdata/trojan-panel-core/bin/naiveproxy/config/" - - "/tpdata/trojan-panel-core/bin/hysteria2/config/:/tpdata/trojan-panel-core/bin/hysteria2/config/" - - "/tpdata/trojan-panel-core/logs/:/tpdata/trojan-panel-core/logs/" - - "/tpdata/trojan-panel-core/config/:/tpdata/trojan-panel-core/config/" + - "/tpdata/grizzly-core/bin/xray/config/:/tpdata/grizzly-core/bin/xray/config/" + - "/tpdata/grizzly-core/bin/trojango/config/:/tpdata/grizzly-core/bin/trojango/config/" + - "/tpdata/grizzly-core/bin/hysteria/config/:/tpdata/grizzly-core/bin/hysteria/config/" + - "/tpdata/grizzly-core/bin/naiveproxy/config/:/tpdata/grizzly-core/bin/naiveproxy/config/" + - "/tpdata/grizzly-core/bin/hysteria2/config/:/tpdata/grizzly-core/bin/hysteria2/config/" + - "/tpdata/grizzly-core/logs/:/tpdata/grizzly-core/logs/" + - "/tpdata/grizzly-core/config/:/tpdata/grizzly-core/config/" - "/tpdata/cert/:/tpdata/cert/" - "/tpdata/web/:/tpdata/web/" - "/etc/localtime:/etc/localtime" @@ -83,7 +83,7 @@ services: - "mariadb_port=9507" - "mariadb_user=root" - "mariadb_pas=${mariadb_pas}" - - "database=trojan_panel_db" + - "database=grizzly_db" - "account-table=account" - "redis_host=127.0.0.1" - "redis_port=6378" diff --git a/grizzly.sh b/grizzly.sh new file mode 100644 index 0000000..bc19292 --- /dev/null +++ b/grizzly.sh @@ -0,0 +1,2013 @@ +#!/usr/bin/env bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +# System Required: CentOS 7+/Ubuntu 18+/Debian 10+ +# Version: v2.3.2 +# Description: One click Install Trojan Panel server +# Author: jonssonyan +# Github: https://github.com/trojanpanel/install-script + +init_var() { + ECHO_TYPE="echo -e" + + package_manager="" + release="" + get_arch="" + can_google=0 + + # Docker + DOCKER_MIRROR='"https://hub-mirror.c.163.com","https://ccr.ccs.tencentyun.com","https://mirror.baidubce.com","https://dockerproxy.com"' + + # Project directory + TP_DATA="/tpdata/" + + STATIC_HTML="https://github.com/trojanpanel/install-script/releases/download/v1.0/html.tar.gz" + + # Web + WEB_PATH="/tpdata/web/" + + # Cert + CERT_PATH="/tpdata/cert/" + DOMAIN_FILE="/tpdata/domain.lock" + domain="" + crt_path="" + key_path="" + + # Caddy2 + CADDY_DATA="/tpdata/caddy/" + CADDY_CONFIG="${CADDY_DATA}config.json" + CADDY_LOG="${CADDY_DATA}logs/" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + caddy_port=80 + caddy_remote_port=8863 + your_email="" + ssl_option=1 + ssl_module_type=1 + ssl_module="acme" + + # Nginx + NGINX_DATA="/tpdata/nginx/" + NGINX_CONFIG="${NGINX_DATA}default.conf" + nginx_port=80 + nginx_remote_port=8863 + nginx_https=1 + + # MariaDB + MARIA_DATA="/tpdata/mariadb/" + mariadb_ip="127.0.0.1" + mariadb_port=9507 + mariadb_user="root" + mariadb_pas="" + + # Redis + REDIS_DATA="/tpdata/redis/" + redis_host="127.0.0.1" + redis_port=6378 + redis_pass="" + + # Trojan Panel Frontend + TROJAN_PANEL_UI_DATA="/tpdata/trojan-panel-ui/" + # Nginx + UI_NGINX_DATA="${TROJAN_PANEL_UI_DATA}nginx/" + UI_NGINX_CONFIG="${UI_NGINX_DATA}default.conf" + trojan_panel_ui_port=8888 + ui_https=1 + trojan_panel_ip="127.0.0.1" + trojan_panel_server_port=8081 + + # Trojan Panel Backend + TROJAN_PANEL_DATA="/tpdata/trojan-panel/" + TROJAN_PANEL_WEBFILE="${TROJAN_PANEL_DATA}webfile/" + TROJAN_PANEL_LOGS="${TROJAN_PANEL_DATA}logs/" + TROJAN_PANEL_CONFIG="${TROJAN_PANEL_DATA}config/" + trojan_panel_config_path="${TROJAN_PANEL_DATA}config/config.ini" + trojan_panel_port=8081 + + # Trojan Panel Core + TROJAN_PANEL_CORE_DATA="/tpdata/trojan-panel-core/" + TROJAN_PANEL_CORE_LOGS="${TROJAN_PANEL_CORE_DATA}logs/" + TROJAN_PANEL_CORE_CONFIG="${TROJAN_PANEL_CORE_DATA}config/" + trojan_panel_core_config_path="${TROJAN_PANEL_CORE_DATA}config/config.ini" + database="trojan_panel_db" + account_table="account" + grpc_port=8100 + trojan_panel_core_port=8082 + + # Version + trojan_panel_ui_current_version="" + trojan_panel_ui_latest_version="v2.3.0" + trojan_panel_current_version="" + trojan_panel_latest_version="v2.3.1" + trojan_panel_core_current_version="" + trojan_panel_core_latest_version="v2.3.1" + + # SQL + sql_215="alter table account change validity_period preset_expire int unsigned default 0 not null comment '预设过期时长';alter table account add preset_quota bigint default 0 not null comment '预设配额' after preset_expire;update account set preset_quota = quota where last_login_time = 0;update account set quota = 0 where last_login_time = 0;alter table node add priority int default 100 not null comment '优先级' after port;INSERT INTO casbin_rule (p_type, v0, v1, v2, v3, v4, v5) VALUES ('p', 'sysadmin', '/api/account/clashSubscribeForSb', 'GET', 'default', 'default', 'default');alter table node_hysteria add server_name varchar(64) default '' not null comment '用于验证服务端证书的 hostname' after down_mbps;alter table node_hysteria add insecure tinyint(1) default 0 not null comment '忽略一切证书错误' after server_name;alter table node_hysteria add fast_open tinyint(1) default 0 not null comment '启用 Fast Open (降低连接建立延迟)' after insecure;" + sql_230="CREATE TABLE node_hysteria2 ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', obfs_password varchar(64) NOT NULL DEFAULT '' COMMENT '混淆密码', up_mbps int(10) NOT NULL DEFAULT '100' COMMENT '单客户端最大上传速度 单位:Mbps', down_mbps int(10) NOT NULL DEFAULT '100' COMMENT '单客户端最大下载速度 单位:Mbps', server_name varchar(64) NOT NULL DEFAULT '' COMMENT '用于验证服务端证书的 hostname', insecure tinyint(1) NOT NULL DEFAULT '0' COMMENT '忽略一切证书错误', create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Hysteria2节点';INSERT INTO node_type (id, name, create_time, update_time) VALUES (5, 'hysteria2', '2022-04-01 00:00:00', '2022-04-01 00:00:00');" +} + +echo_content() { + case $1 in + "red") + ${ECHO_TYPE} "\033[31m$2\033[0m" + ;; + "green") + ${ECHO_TYPE} "\033[32m$2\033[0m" + ;; + "yellow") + ${ECHO_TYPE} "\033[33m$2\033[0m" + ;; + "blue") + ${ECHO_TYPE} "\033[34m$2\033[0m" + ;; + "purple") + ${ECHO_TYPE} "\033[35m$2\033[0m" + ;; + "skyBlue") + ${ECHO_TYPE} "\033[36m$2\033[0m" + ;; + "white") + ${ECHO_TYPE} "\033[37m$2\033[0m" + ;; + esac +} + +mkdir_tools() { + # Project directory + mkdir -p ${TP_DATA} + + # Web + mkdir -p ${WEB_PATH} + + # Cert + mkdir -p ${CERT_PATH} + touch ${DOMAIN_FILE} + + # Caddy2 + mkdir -p ${CADDY_DATA} + touch ${CADDY_CONFIG} + mkdir -p ${CADDY_LOG} + + # Nginx + mkdir -p ${NGINX_DATA} + touch ${NGINX_CONFIG} + + # MariaDB + mkdir -p ${MARIA_DATA} + + # Redis + mkdir -p ${REDIS_DATA} + + # Trojan Panel Frontend + mkdir -p ${TROJAN_PANEL_UI_DATA} + # Nginx + mkdir -p ${UI_NGINX_DATA} + touch ${UI_NGINX_CONFIG} + + # Trojan Panel Backend + mkdir -p ${TROJAN_PANEL_DATA} + mkdir -p ${TROJAN_PANEL_LOGS} + + # Trojan Panel Core + mkdir -p ${TROJAN_PANEL_CORE_DATA} + mkdir -p ${TROJAN_PANEL_CORE_LOGS} +} + +can_connect() { + ping -c2 -i0.3 -W1 "$1" &>/dev/null + if [[ "$?" == "0" ]]; then + return 0 + else + return 1 + fi +} + +# query .ini configuration file information +get_ini_value() { + local config_file="$1" + local key="$2" + local section="" + local section_flag=0 + + # split group and key names + IFS='.' read -r group_name key_name <<<"$key" + + while IFS='=' read -r name val; do + # processing section name + if [[ $name =~ ^\[(.*)\]$ ]]; then + section="${BASH_REMATCH[1]}" + if [[ $section == $group_name ]]; then + section_flag=1 + else + section_flag=0 + fi + continue + fi + + # extract the value of the configuration item + if [[ $section_flag -eq 1 && $name == $key_name ]]; then + echo "$val" + return + fi + done <"$config_file" +} + +# Version number comparison greater than or equal to +version_ge() { + local v1=${1#v} + local v2=${2#v} + + local v1_parts=(${v1//./ }) + local v2_parts=(${v2//./ }) + + for ((i = 0; i < 3; i++)); do + if ((${v1_parts[i]} < ${v2_parts[i]})); then + echo false + return 0 + elif ((${v1_parts[i]} > ${v2_parts[i]})); then + echo true + return 0 + fi + done + echo true +} + +check_sys() { + if [[ $(command -v yum) ]]; then + package_manager='yum' + elif [[ $(command -v dnf) ]]; then + package_manager='dnf' + elif [[ $(command -v apt) ]]; then + package_manager='apt' + elif [[ $(command -v apt-get) ]]; then + package_manager='apt-get' + fi + + if [[ -z "${package_manager}" ]]; then + echo_content red "The system is not currently supported" + exit 0 + fi + + if [[ -n $(find /etc -name "redhat-release") ]] || grep /dev/null) ]]; then + echo_content green "---> Install Docker" + + # turn off firewall + if [[ "${release}" == "centos" ]]; then + systemctl disable firewalld + elif [[ "${release}" == "debian" || "${release}" == "ubuntu" ]]; then + sudo ufw disable + fi + + # set time zone + timedatectl set-timezone Asia/Shanghai + + if [[ ${can_google} == 0 ]]; then + sh <(curl -sL https://get.docker.com) --mirror Aliyun + mkdir -p /etc/docker && + cat >/etc/docker/daemon.json </etc/docker/daemon.json </dev/null) ]]; then + echo_content skyBlue "---> Docker installation completed" + else + echo_content red "---> Docker installation failed" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Docker" + fi +} + +# Custom Settings Certificate +install_custom_cert() { + if [[ -z "$(cat "${DOMAIN_FILE}")" ]]; then + while read -r -p "Please enter the file path of the .crt certificate (required): " crt_path; do + if [[ -z "${crt_path}" ]]; then + echo_content red "Path cannot be empty" + else + if [[ ! -f "${crt_path}" ]]; then + echo_content red "The file path for the .crt certificate does not exist" + else + cp "${crt_path}" "${CERT_PATH}$1.crt" + break + fi + fi + done + while read -r -p "Please enter the file path of the .key certificate (required): " key_path; do + if [[ -z "${key_path}" ]]; then + echo_content red "Path cannot be empty" + else + if [[ ! -f "${key_path}" ]]; then + echo_content red "The file path for the .key certificate does not exist" + else + cp "${key_path}" "${CERT_PATH}$1.key" + break + fi + fi + done + cat >${DOMAIN_FILE} < Custom settings certificate installation completed" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + fi +} + +# Caddy2 https custom settings certificate configuration file +caddy2_https_config() { + domain=$1 + cat >${CADDY_CONFIG} <${CADDY_CONFIG} < Install Caddy2+https" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "Please enter the port of Caddy2 (default: 80): " caddy_port + [[ -z "${caddy_port}" ]] && caddy_port=80 + read -r -p "Please enter the forwarding port of Caddy2 (default: 8863): " caddy_remote_port + [[ -z "${caddy_remote_port}" ]] && caddy_remote_port=8863 + + echo_content yellow "Tip: Please confirm that the domain name has been resolved to this machine, otherwise the installation may fail" + while read -r -p "Please enter your domain name (required): " domain; do + if [[ -z "${domain}" ]]; then + echo_content red "Domain name cannot be empty" + else + break + fi + done + + read -r -p "Please enter your email (optional): " your_email + + while read -r -p "Please choose the way to set up the certificate? (1/automatically apply for and renew the certificate 2/manually set the certificate path default: 1: " ssl_option; do + if [[ -z ${ssl_option} || ${ssl_option} == 1 ]]; then + while read -r -p "Please choose the way to apply for the certificate (1/acme 2/zerossl default: 1: " ssl_module_type; do + if [[ -z "${ssl_module_type}" || ${ssl_module_type} == 1 ]]; then + ssl_module="acme" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + break + elif [[ ${ssl_module_type} == 2 ]]; then + ssl_module="zerossl" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme.zerossl.com-v2-dv90/" + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + caddy2_https_auto_config "${domain}" + break + elif [[ ${ssl_option} == 2 ]]; then + install_custom_cert "${domain}" + caddy2_https_config "${domain}" + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + # Caddy2 temporary listening port for automatic certificate application + if [[ -n $(lsof -i:${caddy_port},${caddy_remote_port} -t) ]]; then + kill -9 "$(lsof -i:${caddy_port},${caddy_remote_port} -t)" + fi + + docker pull caddy:2.6.2 && + docker run -d --name trojan-panel-caddy --restart always \ + --network=host \ + -v "${CADDY_CONFIG}":"${CADDY_CONFIG}" \ + -v ${CERT_PATH}:"${CADDY_CERT_DIR}${domain}/" \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v ${CADDY_LOG}:${CADDY_LOG} \ + caddy:2.6.2 caddy run --config ${CADDY_CONFIG} + + cat >${DOMAIN_FILE} < Caddy2+https installation completed" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> Caddy2+https installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Caddy2+https" + fi +} + +# Nginx http configuration file +nginx_http_config() { + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + error_page 497 http://\$host:${nginx_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Nginx https configuration file +nginx_https_config() { + domain=$1 + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + return 301 http://\$host:${nginx_remote_port}\$request_uri; +} + +server { + listen ${nginx_remote_port} ssl; + server_name localhost; + + # force ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + # cache validity period + ssl_session_timeout 5m; + # secure link optional encryption protocol + ssl_protocols TLSv1.3; + # encryption algorithm + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + # use server-side preferred algorithm + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${nginx_remote_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Install Nginx +install_nginx() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + echo_content green "---> Install Nginx" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "Please enter the port of Nginx (default: 80): " nginx_port + [[ -z "${nginx_port}" ]] && nginx_port=80 + read -r -p "Please enter the forwarding port of Nginx (default: 8863): " nginx_remote_port + [[ -z "${nginx_remote_port}" ]] && nginx_remote_port=8863 + + while read -r -p "Please choose whether to enable https in Nginx? (0/off 1/on default: 1): " nginx_https; do + if [[ -z ${nginx_https} || ${nginx_https} == 1 ]]; then + install_custom_cert "custom_cert" + nginx_https_config "custom_cert" + break + elif [[ ${nginx_https} == 0 ]]; then + nginx_http_config + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + docker pull nginx:1.20-alpine && + docker run -d --name trojan-panel-nginx --restart always \ + --network=host \ + -v "${NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + nginx:1.20-alpine + + if [[ -n $(docker ps -q -f "name=^trojan-panel-nginx$" -f "status=running") ]]; then + echo_content skyBlue "---> Nginx installation completed" + else + echo_content red "---> Nginx installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Nginx" + fi +} + +# Install a web server +install_reverse_proxy() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$|^trojan-panel-nginx$") ]]; then + echo_content green "---> Install a web server" + + while :; do + echo_content yellow "1. Install Caddy2+https (recommend)" + echo_content yellow "2. Install Nginx" + echo_content yellow "3. Not install" + read -r -p "Please select (default: 1): " whether_install_reverse_proxy + [[ -z "${whether_install_reverse_proxy}" ]] && whether_install_reverse_proxy=1 + + case ${whether_install_reverse_proxy} in + 1) + install_caddy2 + break + ;; + 2) + install_nginx + break + ;; + 3) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done + + echo_content skyBlue "---> Web server installation completed" + fi +} + +# Set certificate +install_cert() { + if [[ -z "$(cat "${DOMAIN_FILE}")" ]]; then + echo_content green "---> Set certificate" + + while :; do + echo_content yellow "1. Custom certificate" + echo_content yellow "2. Not set" + read -r -p "Please select (default: 1): " whether_install_cert + [[ -z "${whether_install_cert}" ]] && whether_install_cert=1 + + case ${whether_install_cert} in + 1) + install_custom_cert "custom_cert" + break + ;; + 2) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done + + echo_content green "---> Certificate setup completed" + fi +} + +# Install MariaDB +install_mariadb() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> Install MariaDB" + + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + if [[ "${mariadb_user}" == "root" ]]; then + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + else + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e MYSQL_USER="${mariadb_user}" \ + -e MYSQL_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + fi + + if [[ -n $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content skyBlue "---> MariaDB installation completed" + echo_content yellow "---> The MariaDB password of root (please keep it safe): ${mariadb_pas}" + if [[ "${mariadb_user}" != "root" ]]; then + echo_content yellow "---> The MariaDB password of ${mariadb_user} (please keep it safe): ${mariadb_pas}" + fi + else + echo_content red "---> MariaDB installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed MariaDB" + fi +} + +# Install Redis +install_redis() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> Install Redis" + + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker pull redis:6.2.7 && + docker run -d --name trojan-panel-redis --restart always \ + --network=host \ + redis:6.2.7 \ + redis-server --requirepass "${redis_pass}" --port "${redis_port}" + + if [[ -n $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content skyBlue "---> Redis installation completed" + echo_content yellow "---> Redis password (please keep it safe): ${redis_pass}" + else + echo_content red "---> Redis installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Redis" + fi +} + +# Trojan Panel Frontend Nginx http configuration file +ui_http_config() { + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port}; + server_name localhost; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + error_page 497 http://\$host:${trojan_panel_ui_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Trojan Panel Frontend Nginx https configuration file +ui_https_config() { + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port} ssl; + server_name localhost; + + # force ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + # cache validity period + ssl_session_timeout 5m; + # secure link optional encryption protocol + ssl_protocols TLSv1.3; + # encryption algorithm + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + # use server-side preferred algorithm + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${trojan_panel_ui_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Install Trojan Panel Frontend +install_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> Install Trojan Panel Frontend" + + read -r -p "Please enter the IP address of the Trojan Panel Backend (default: local host): " trojan_panel_ip + [[ -z "${trojan_panel_ip}" ]] && trojan_panel_ip="127.0.0.1" + read -r -p "Please enter the service port of the Trojan Panel Backend (default: 8081): " trojan_panel_server_port + [[ -z "${trojan_panel_server_port}" ]] && trojan_panel_server_port=8081 + + read -r -p "Please enter the port of the Trojan Panel Frontend (default: 8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + while read -r -p "Please choose whether to enable https on the Trojan Panel Frontend? (0/off 1/on default: 1): " ui_https; do + if [[ -z ${ui_https} || ${ui_https} == 1 ]]; then + install_custom_cert "custom_cert" + domain=$(cat "${DOMAIN_FILE}") + ui_https_config + break + elif [[ ${ui_https} == 0 ]]; then + ui_http_config + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + docker pull jonssonyan/trojan-panel-ui && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Frontend installation completed" + + https_flag=$([[ -z ${ui_https} || ${ui_https} == 1 ]] && echo "https" || echo "http") + domain_or_ip=$([[ -z ${domain} || "${domain}" == "custom_cert" ]] && echo "ip" || echo "${domain}") + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel Frontend installed successfully" + echo_content yellow "Web management panel address: ${https_flag}://${domain_or_ip}:${trojan_panel_ui_port}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel Frontend installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Frontend" + fi +} + +# Install Trojan Panel Backend +install_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> Install Trojan Panel Backend" + + read -r -p "Please enter the service port of the Trojan Panel Backend (default: 8081): " trojan_panel_port + [[ -z "${trojan_panel_port}" ]] && trojan_panel_port=8081 + + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -e "create database if not exists trojan_panel_db;" &>/dev/null + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker pull jonssonyan/trojan-panel && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Backend installation completed" + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel Backend installed successfully" + echo_content yellow "MariaDB ${mariadb_user} password (please keep it safe): ${mariadb_pas}" + echo_content yellow "Redis password (please keep it safe): ${redis_pass}" + echo_content yellow "System administrator Default username: sysadmin Default password: 123456" + echo_content yellow "Please log in to the management panel to change the password in time" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel Backend installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Backend" + fi +} + +# Install Trojan Panel Core +install_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> Install Trojan Panel Core" + + read -r -p "Please enter the service port of the Trojan Panel Core (default: 8082): " trojan_panel_core_port + [[ -z "${trojan_panel_core_port}" ]] && trojan_panel_core_port=8082 + + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + read -r -p "Please enter the database name (default: trojan_panel_db): " database + [[ -z "${database}" ]] && database="trojan_panel_db" + read -r -p "Please enter the user table name of the database (default: account): " account_table + [[ -z "${account_table}" ]] && account_table="account" + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + read -r -p "Please enter the API port (default: 8100): " grpc_port + [[ -z "${grpc_port}" ]] && grpc_port=8100 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria2/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria2/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Core installation completed" + else + echo_content red "---> Trojan Panel Core installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Core" + fi +} + +# Update Trojan Panel database structure +update_trojan_panel_database() { + echo_content skyBlue "---> Update Trojan Panel database structure" + + version_214_215=("v2.1.4") + if [[ "${version_214_215[*]}" =~ "${trojan_panel_current_version}" ]]; then + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "${sql_215}" &>/dev/null && + trojan_panel_current_version="v2.1.5" + fi + version_215_230=("v2.1.5" "v2.1.6" "v2.1.7" "v2.1.8" "v2.2.0" "v2.2.1") + if [[ "${version_215_230[*]}" =~ "${trojan_panel_current_version}" ]]; then + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "${sql_230}" &>/dev/null && + trojan_panel_current_version="v2.3.0" + fi + + echo_content skyBlue "---> Trojan Panel database structure update completed" +} + +# Update Trojan Panel Core database structure +update_trojan_panel_core_database() { + echo_content skyBlue "---> Update Trojan Panel Core database structure" + + echo_content skyBlue "---> Trojan Panel Core database structure update completed" +} + +# Update Trojan Panel Frontend +update_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content red "---> Please install the Trojan Panel Frontend first" + exit 0 + fi + + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + if [[ -z "${trojan_panel_ui_current_version}" || ! "${trojan_panel_ui_current_version}" =~ ^v.* ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Frontend (trojan-panel-ui) is ${trojan_panel_ui_current_version} the latest version is ${trojan_panel_ui_latest_version}" + + if [[ "${trojan_panel_ui_current_version}" != "${trojan_panel_ui_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Frontend" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui + + docker pull jonssonyan/trojan-panel-ui && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Frontend update completed" + else + echo_content red "---> Trojan Panel Frontend update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Frontend" + fi +} + +# Update Trojan Panel Backend +update_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content red "---> Please install the Trojan Panel Backend first" + exit 0 + fi + + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + if [[ -z "${trojan_panel_current_version}" || ! "${trojan_panel_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_current_version}" "v2.1.4") ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Backend (trojan-panel) is ${trojan_panel_current_version} The latest version is ${trojan_panel_latest_version}" + + if [[ "${trojan_panel_current_version}" != "${trojan_panel_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Backend" + + mariadb_ip=$(get_ini_value ${trojan_panel_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + trojan_panel_port=$(get_ini_value ${trojan_panel_config_path} server.port) + + update_trojan_panel_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel + + docker pull jonssonyan/trojan-panel && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel backend update completed" + else + echo_content red "---> Trojan Panel Backend update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Backend" + fi +} + +# Update Trojan Panel Core +update_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content red "---> Please install the Trojan Panel Core first" + exit 0 + fi + + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + if [[ -z "${trojan_panel_core_current_version}" || ! "${trojan_panel_core_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_core_current_version}" "v2.1.1") ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Core (trojan-panel-core) is ${trojan_panel_core_current_version} The latest version is ${trojan_panel_core_latest_version}" + + if [[ "${trojan_panel_core_current_version}" != "${trojan_panel_core_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Core" + + mariadb_ip=$(get_ini_value ${trojan_panel_core_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_core_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_core_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_core_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_core_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_core_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_core_config_path} redis.password) + grpc_port=$(get_ini_value ${trojan_panel_core_config_path} grpc.port) + trojan_panel_core_port=$(get_ini_value ${trojan_panel_core_config_path} server.port) + + update_trojan_panel_core_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria2/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria2/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core + + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Core update completed" + else + echo_content red "---> Trojan Panel Core update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Core" + fi +} + +# Uninstall Caddy2+https +uninstall_caddy2() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> Uninstall Caddy2+https" + + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_DATA} + + echo_content skyBlue "---> Caddy2+https uninstallation completed" + else + echo_content red "---> Please install Caddy2+https first" + fi +} + +# Uninstall Nginx +uninstall_nginx() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx") ]]; then + echo_content green "---> Uninstall Nginx" + + docker rm -f trojan-panel-nginx && + rm -rf ${NGINX_DATA} + + echo_content skyBlue "---> Nginx uninstallation completed" + else + echo_content red "---> Please install Nginx first" + fi +} + +# Uninstall MariaDB +uninstall_mariadb() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> Uninstall MariaDB" + + docker rm -f trojan-panel-mariadb && + rm -rf ${MARIA_DATA} + + echo_content skyBlue "---> MariaDB uninstall completed" + else + echo_content red "---> Please install MariaDB first" + fi +} + +# Uninstall Redis +uninstall_redis() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> Uninstall Redis" + + docker rm -f trojan-panel-redis && + rm -rf ${REDIS_DATA} + + echo_content skyBlue "---> Redis uninstall completed" + else + echo_content red "---> Please install Redis first" + fi +} + +# Uninstall Trojan Panel Frontend +uninstall_trojan_panel_ui() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> Uninstall Trojan Panel Frontend" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui && + rm -rf ${TROJAN_PANEL_UI_DATA} + + echo_content skyBlue "---> Trojan Panel Frontend uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Frontend first" + fi +} + +# Uninstall Trojan Panel Backend +uninstall_trojan_panel() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> Uninstall Trojan Panel Backend" + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel && + rm -rf ${TROJAN_PANEL_DATA} + + echo_content skyBlue "---> Trojan Panel Backend uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Backend first" + fi +} + +# Uninstall Trojan Panel Core +uninstall_trojan_panel_core() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> Uninstall Trojan Panel Core" + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core && + rm -rf ${TROJAN_PANEL_CORE_DATA} + + echo_content skyBlue "---> Trojan Panel Core uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Core first" + fi +} + +# Uninstall all Trojan Panel related containers +uninstall_all() { + echo_content green "---> Uninstall all Trojan Panel related containers" + + docker rm -f $(docker ps -a -q -f "name=^trojan-panel") + docker rmi -f $(docker images | grep "^jonssonyan/trojan-panel" | awk '{print $3}') + rm -rf ${TP_DATA} + + echo_content skyBlue "---> Uninstall all Trojan Panel related containers completed" +} + +# Modify Trojan Panel Frontend port +update_trojan_panel_ui_port() { + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content green "---> Modify Trojan Panel Frontend port" + + trojan_panel_ui_port=$(grep 'listen.*ssl' ${UI_NGINX_CONFIG} | awk '{print $2}') + if [[ -z "${trojan_panel_ui_port}" ]]; then + ui_https=0 + trojan_panel_ui_port=$(grep -oP 'listen\s+\K\d+' ${UI_NGINX_CONFIG} | awk 'NR==1') + fi + if [[ -z "${trojan_panel_ui_port}" ]]; then + echo_content red "---> Trojan Panel Frontend port not queried" + exit 0 + fi + echo_content yellow "Tip: The current port of the Trojan Panel Frontend (trojan-panel-ui) is ${trojan_panel_ui_port}" + + read -r -p "Please enter the new port of the Trojan Panel Frontend (default: 8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + + if [[ ${ui_https} == 0 ]]; then + # http + sed -i "s/listen.*;/listen ${trojan_panel_ui_port};/g" ${UI_NGINX_CONFIG} && + sed -i "s/http:\/\/\$host:.*\$request_uri;/http:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + else + # https + sed -i "s/listen.*ssl;/listen ${trojan_panel_ui_port} ssl;/g" ${UI_NGINX_CONFIG} && + sed -i "s/https:\/\/\$host:.*\$request_uri;/https:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + fi + + if [[ "$?" == "0" ]]; then + echo_content skyBlue "---> Trojan Panel Frontend port modification completed" + else + echo_content red "---> Trojan Panel Frontend port modification failed" + fi + else + echo_content red "---> The Trojan Panel Frontend is not installed or is running abnormally, please repair or uninstall and reinstall and try again" + fi +} + +# Refresh Redis cache +redis_flush_all() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content red "---> Please install Redis first" + exit 0 + fi + + if [[ -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis is running abnormally" + exit 0 + fi + + echo_content green "---> Refresh Redis cache" + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + echo_content skyBlue "---> Redis cache refresh completed" +} + +# Replace certificate +change_cert() { + domain_1=$(cat "${DOMAIN_FILE}") + + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_LOG}* && + echo "" >${CADDY_CONFIG} && + rm -rf ${WEB_PATH}* + fi + + rm -rf ${CERT_PATH}* && + echo "" >${DOMAIN_FILE} + + install_reverse_proxy + install_cert + + domain_2=$(cat "${DOMAIN_FILE}") + if [[ -n "${domain_1}" && -n "${domain_2}" ]]; then + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${NGINX_CONFIG} && + docker restart trojan-panel-nginx + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${UI_NGINX_DATA} && + docker restart trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + find /tpdata/trojan-panel-core/bin/ -type f -exec sed -i "s/${domain_1}/${domain_2}/g" {} + && + sed -i "s/${domain_1}/${domain_2}/g" ${trojan_panel_core_config_path} && + docker restart trojan-panel-core + fi + fi +} + +# Forgot sysadmin password +forget_pass() { + while :; do + echo_content yellow "1. Query MariaDB password" + echo_content yellow "2. Query Redis password" + echo_content yellow "3. Reset the username and password of the admin panel system administrator" + echo_content yellow "4. Quit" + read -r -p "Please choose (default: 4): " forget_pass_option + [[ -z "${forget_pass_option}" ]] && forget_pass_option=4 + case ${forget_pass_option} in + 1) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + echo_content red "\n==============================================================" + echo_content yellow "MariaDB ${mariadb_user} password (please keep it safe): ${mariadb_pas}" + echo_content red "\n==============================================================" + else + echo_content red "---> Please execute on the Trojan Panel backend server" + fi + ;; + 2) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + echo_content red "\n==============================================================" + echo_content yellow "Redis password (please keep it safe): ${redis_pass}" + echo_content red "\n==============================================================" + else + echo_content red "---> Please execute on the Trojan Panel backend server" + fi + ;; + 3) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "update account set username = 'sysadmin',pass = 'tFjD2X1F6i9FfWp2GDU5Vbi1conuaChDKIYbw9zMFrqvMoSz',hash='4366294571b8b267d9cf15b56660f0a70659568a86fc270a52fdc9e5',deleted = 0 where id = 1 limit 1" + if [[ "$?" == "0" ]]; then + echo_content red "\n==============================================================" + echo_content yellow "System administrator Default username: sysadmin Default password: 123456" + echo_content yellow "Please log in to the management panel to change the password in time" + echo_content red "\n==============================================================" + else + echo_content red "Admin panel sysadmin username and password reset failed" + fi + else + echo_content red "---> Please execute on the MariaDB server" + fi + ;; + 4) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done +} + +# Fault detection +failure_testing() { + echo_content green "---> Start troubleshooting" + if [[ ! $(docker -v 2>/dev/null) ]]; then + echo_content red "---> Docker is running abnormally" + else + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + if [[ -z $(docker ps -q -f "name=^trojan-panel-caddy$" -f "status=running") ]]; then + echo_content red "---> Caddy2 is running abnormally and the running log is as follows:" + docker logs trojan-panel-caddy + fi + domain=$(cat "${DOMAIN_FILE}") + if [[ -n ${domain} && ! -f "${CERT_PATH}${domain}.crt" ]]; then + echo_content red "---> The certificate application is abnormal, please try 1. Change the sub-domain name to re-build 2. Restart the server to re-apply for the certificate 3. Re-build and select the custom certificate option" + if [[ -f ${CADDY_LOG}error.log ]]; then + echo_content red "Caddy2 error log is as follows:" + tail -n 20 ${CADDY_LOG}error.log | grep error + fi + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") && -z $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content red "---> The MariaDB is running abnormally and the running log is as follows:" + docker logs trojan-panel-mariadb + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") && -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> The Redis is running abnormally and the running log is as follows:" + docker logs trojan-panel-redis + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -z $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Backend is running abnormally and the running log is as follows:" + if [[ -f ${TROJAN_PANEL_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -z $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Frontend is running abnormally and the running log is as follows:" + docker logs trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -z $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Core is running abnormally and the running log is as follows:" + if [[ -f ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel-core + fi + fi + fi + echo_content green "---> Troubleshooting ended" +} + +log_query() { + while :; do + echo_content skyBlue "Applications that can query logs are as follows:" + echo_content yellow "1. Trojan Panel Backend" + echo_content yellow "2. Trojan Panel Frontend" + echo_content yellow "3. Quit" + read -r -p "Please select an application (default: 3): " select_log_query_type + [[ -z "${select_log_query_type}" ]] && select_log_query_type=3 + + case ${select_log_query_type} in + 1) + log_file_path=${TROJAN_PANEL_LOGS}trojan-panel.log + ;; + 2) + log_file_path=${TROJAN_PANEL_CORE_LOGS}trojan-panel-core.log + ;; + 3) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + + read -r -p "Please enter the number of rows to query (default: 20): " select_log_query_line_type + [[ -z "${select_log_query_line_type}" ]] && select_log_query_line_type=20 + + if [[ -f ${log_file_path} ]]; then + echo_content skyBlue "The log is as follows:" + tail -n ${select_log_query_line_type} ${log_file_path} + else + echo_content red "No log file exists" + fi + done +} + +version_query() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + echo_content yellow "The current version of Trojan Panel Frontend(trojan-panel-ui) is ${trojan_panel_ui_current_version} the latest version is ${trojan_panel_ui_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + echo_content yellow "The current version of Trojan Panel Backend(trojan-panel) is ${trojan_panel_current_version} the latest version is ${trojan_panel_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + echo_content yellow "The current version of Trojan Panel Core(trojan-panel-core) is ${trojan_panel_core_current_version} the latest version is ${trojan_panel_core_latest_version}" + fi +} + +main() { + cd "$HOME" || exit 0 + init_var + mkdir_tools + check_sys + depend_install + clear + echo_content red "\n==============================================================" + echo_content skyBlue "System Required: CentOS 7+/Ubuntu 18+/Debian 10+" + echo_content skyBlue "Version: v2.3.2" + echo_content skyBlue "Description: One click Install Trojan Panel server" + echo_content skyBlue "Author: jonssonyan " + echo_content skyBlue "Github: https://github.com/trojanpanel" + echo_content skyBlue "Docs: https://trojanpanel.github.io" + echo_content red "\n==============================================================" + echo_content yellow "1. Install Trojan Panel Frontend" + echo_content yellow "2. Install Trojan Panel Backend" + echo_content yellow "3. Install Trojan Panel Core" + echo_content yellow "4. Install Caddy2+https" + echo_content yellow "5. Install Nginx" + echo_content yellow "6. Install MariaDB" + echo_content yellow "7. Install Redis" + echo_content green "\n==============================================================" + echo_content yellow "8. Update Trojan Panel Frontend" + echo_content yellow "9. Update Trojan Panel Backend" + echo_content yellow "10. Update Trojan Panel Core" + echo_content green "\n==============================================================" + echo_content yellow "11. Uninstall Trojan Panel Frontend" + echo_content yellow "12. Uninstall Trojan Panel Backend" + echo_content yellow "13. Uninstall Trojan Panel Core" + echo_content yellow "14. Uninstall Caddy2+https" + echo_content yellow "15. Uninstall Nginx" + echo_content yellow "16. Uninstall MariaDB" + echo_content yellow "17. Uninstall Redis" + echo_content yellow "18. Uninstall all Trojan Panel related containers" + echo_content green "\n==============================================================" + echo_content yellow "19. Modify Trojan Panel Frontend port" + echo_content yellow "20. Refresh Redis cache" + echo_content yellow "21. Replace certificate" + echo_content yellow "22. Forgot sysadmin password" + echo_content green "\n==============================================================" + echo_content yellow "23. Fault detection" + echo_content yellow "24. Log query" + echo_content yellow "25. Version query" + read -r -p "Please choose: " selectInstall_type + case ${selectInstall_type} in + 1) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_ui + ;; + 2) + install_docker + install_mariadb + install_redis + install_trojan_panel + ;; + 3) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_core + ;; + 4) + install_docker + install_caddy2 + ;; + 5) + install_docker + install_nginx + ;; + 6) + install_docker + install_mariadb + ;; + 7) + install_docker + install_redis + ;; + 8) + update_trojan_panel_ui + ;; + 9) + update_trojan_panel + ;; + 10) + update_trojan_panel_core + ;; + 11) + uninstall_trojan_panel_ui + ;; + 12) + uninstall_trojan_panel + ;; + 13) + uninstall_trojan_panel_core + ;; + 14) + uninstall_caddy2 + ;; + 15) + uninstall_nginx + ;; + 16) + uninstall_mariadb + ;; + 17) + uninstall_redis + ;; + 18) + uninstall_all + ;; + 19) + update_trojan_panel_ui_port + ;; + 20) + redis_flush_all + ;; + 21) + change_cert + ;; + 22) + forget_pass + ;; + 23) + failure_testing + ;; + 24) + log_query + ;; + 25) + version_query + ;; + *) + echo_content red "No such option" + ;; + esac +} + +main diff --git a/grizzly_standalone.sh b/grizzly_standalone.sh new file mode 100644 index 0000000..b769f44 --- /dev/null +++ b/grizzly_standalone.sh @@ -0,0 +1,1013 @@ +#!/usr/bin/env bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +init_var() { + ECHO_TYPE="echo -e" + + package_manager="" + release="" + get_arch="" + can_google=0 + + # Docker + DOCKER_MIRROR='"https://registry.docker-cn.com","https://hub-mirror.c.163.com","https://docker.mirrors.ustc.edu.cn"' + + # Project directory + TP_DATA="/tpdata/" + + STATIC_HTML="https://github.com/trojanpanel/install-script/releases/download/v1.0/html.tar.gz" + + # Web + WEB_PATH="/tpdata/web/" + + # Cert + CERT_PATH="/tpdata/cert/" + DOMAIN_FILE="/tpdata/domain.lock" + domain="" + + # Caddy2 + CADDY_DATA="/tpdata/caddy/" + CADDY_CONFIG="${CADDY_DATA}config.json" + CADDY_LOG="${CADDY_DATA}logs/" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + caddy_port=80 + caddy_remote_port=8863 + your_email="" + ssl_module_type=1 + ssl_module="acme" + + # TrojanGO + TROJANGO_DATA="/tpdata/trojanGO/" + TROJANGO_STANDALONE_CONFIG="/tpdata/trojanGO/standalone_config.json" + trojanGO_port=443 + trojanGO_websocket_enable=0 + trojanGO_websocket_path="trojan-panel-websocket-path" + trojanGO_shadowsocks_enable=0 + trojanGO_shadowsocks_method="AES-128-GCM" + trojanGO_shadowsocks_password="" + trojanGO_mux_enable=1 + # trojan + trojan_pas="" + remote_addr="127.0.0.1" + + # Hysteria + HYSTERIA_DATA="/tpdata/hysteria/" + HYSTERIA_STANDALONE_CONFIG="/tpdata/hysteria/standalone_config.json" + hysteria_port=443 + hysteria_password="" + hysteria_protocol="udp" + hysteria_up_mbps=100 + hysteria_down_mbps=100 + + # NaiveProxy + NAIVEPROXY_DATA="/tpdata/naiveproxy/" + NAIVEPROXY_STANDALONE_CONFIG="/tpdata/naiveproxy/standalone_config.json" + naiveproxy_port=443 + naiveproxy_username="" + naiveproxy_pass="" +} + +echo_content() { + case $1 in + "red") + ${ECHO_TYPE} "\033[31m$2\033[0m" + ;; + "green") + ${ECHO_TYPE} "\033[32m$2\033[0m" + ;; + "yellow") + ${ECHO_TYPE} "\033[33m$2\033[0m" + ;; + "blue") + ${ECHO_TYPE} "\033[34m$2\033[0m" + ;; + "purple") + ${ECHO_TYPE} "\033[35m$2\033[0m" + ;; + "skyBlue") + ${ECHO_TYPE} "\033[36m$2\033[0m" + ;; + "white") + ${ECHO_TYPE} "\033[37m$2\033[0m" + ;; + esac +} + +mkdir_tools() { + # Project directory + mkdir -p ${TP_DATA} + + # Web + mkdir -p ${WEB_PATH} + + # Cert + mkdir -p ${CERT_PATH} + touch ${DOMAIN_FILE} + + # Caddy2 + mkdir -p ${CADDY_DATA} + touch ${CADDY_CONFIG} + mkdir -p ${CADDY_LOG} + + # TrojanGO + mkdir -p ${TROJANGO_DATA} + touch ${TROJANGO_STANDALONE_CONFIG} + + # Hysteria + mkdir -p ${HYSTERIA_DATA} + touch ${HYSTERIA_STANDALONE_CONFIG} + + # NaiveProxy + mkdir -p ${NAIVEPROXY_DATA} + touch ${NAIVEPROXY_STANDALONE_CONFIG} +} + +can_connect() { + ping -c2 -i0.3 -W1 "$1" &>/dev/null + if [[ "$?" == "0" ]]; then + return 0 + else + return 1 + fi +} + +check_sys() { + if [[ $(command -v yum) ]]; then + package_manager='yum' + elif [[ $(command -v dnf) ]]; then + package_manager='dnf' + elif [[ $(command -v apt) ]]; then + package_manager='apt' + elif [[ $(command -v apt-get) ]]; then + package_manager='apt-get' + fi + + if [[ -z "${package_manager}" ]]; then + echo_content red "The system is not currently supported" + exit 0 + fi + + if [[ -n $(find /etc -name "redhat-release") ]] || grep /dev/null) ]]; then + echo_content green "---> Install Docker" + + # turn off firewall + if [[ "$(firewall-cmd --state 2>/dev/null)" == "running" ]]; then + if [[ "${release}" == "centos" ]]; then + systemctl disable firewalld + elif [[ "${release}" == "debian" || "${release}" == "ubuntu" ]]; then + sudo ufw disable + fi + fi + + # set time zone + timedatectl set-timezone Asia/Shanghai + + if [[ ${can_google} == 0 ]]; then + sh <(curl -sL https://get.docker.com) --mirror Aliyun + mkdir -p /etc/docker && + cat >/etc/docker/daemon.json </etc/docker/daemon.json </dev/null) ]]; then + echo_content skyBlue "---> Docker installation completed" + else + echo_content red "---> Docker installation failed" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Docker" + fi +} + +# Caddy2 https automatic application and renewal certificate configuration file +caddy2_https_auto_config() { + cat >${CADDY_CONFIG} < Install Caddy2+https" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "Please enter the port of Caddy2 (default: 80): " caddy_port + [[ -z "${caddy_port}" ]] && caddy_port=80 + read -r -p "Please enter the forwarding port of Caddy2 (default: 8863): " caddy_remote_port + [[ -z "${caddy_remote_port}" ]] && caddy_remote_port=8863 + + echo_content yellow "Tip: Please confirm that the domain name has been resolved to this machine, otherwise the installation may fail" + while read -r -p "Please enter your domain name (required): " domain; do + if [[ -z "${domain}" ]]; then + echo_content red "Domain name cannot be empty" + else + break + fi + done + + read -r -p "Please enter your email (optional): " your_email + + while read -r -p "Please choose the way to apply for the certificate (1/acme 2/zerossl default: 1: " ssl_module_type; do + if [[ -z "${ssl_module_type}" || ${ssl_module_type} == 1 ]]; then + ssl_module="acme" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + break + elif [[ ${ssl_module_type} == 2 ]]; then + ssl_module="zerossl" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme.zerossl.com-v2-dv90/" + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + caddy2_https_auto_config + + # Caddy2 temporary listening port for automatic certificate application + if [[ -n $(lsof -i:${caddy_port},${caddy_remote_port} -t) ]]; then + kill -9 "$(lsof -i:${caddy_port},${caddy_remote_port} -t)" + fi + + docker pull caddy:2.6.2 && + docker run -d --name trojan-panel-caddy --restart always \ + --network=host \ + -v "${CADDY_CONFIG}":"${CADDY_CONFIG}" \ + -v ${CERT_PATH}:"${CADDY_CERT_DIR}${domain}/" \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v ${CADDY_LOG}:${CADDY_LOG} \ + caddy:2.6.2 caddy run --config ${CADDY_CONFIG} + + if [[ -n $(docker ps -q -f "name=^trojan-panel-caddy$" -f "status=running") ]]; then + cat >${DOMAIN_FILE} < Caddy2+https installation completed" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> Caddy2+https installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Caddy2+https" + fi +} + +# Install TrojanGO+Caddy2+Web+TLS+Websocket +install_trojanGO_standalone() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-trojanGO-standalone$") ]]; then + echo_content green "---> Install TrojanGO+Caddy2+Web+TLS+Websocket" + + read -r -p "Please enter the port of TrojanGO (default: 443): " trojanGO_port + [[ -z "${trojanGO_port}" ]] && trojanGO_port=443 + while read -r -p "Please enter TrojanGO password (required): " trojan_pas; do + if [[ -z "${trojan_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + while read -r -p "Is multiplexing enabled? (0/disabled 1/enabled default: 1): " trojanGO_mux_enable; do + if [[ -z "${trojanGO_mux_enable}" || ${trojanGO_mux_enable} == 1 ]]; then + trojanGO_mux_enable=1 + break + elif [[ ${trojanGO_mux_enable} == 0 ]]; then + trojanGO_mux_enable=0 + break + else + echo_content red "Cannot enter other characters except 0 and 1" + fi + done + + while read -r -p "Is Websocket enabled? (0/disabled 1/enabled default: 0): " trojanGO_websocket_enable; do + if [[ -z "${trojanGO_websocket_enable}" || ${trojanGO_websocket_enable} == 0 ]]; then + trojanGO_websocket_enable=0 + break + elif [[ ${trojanGO_websocket_enable} == 1 ]]; then + trojanGO_websocket_enable=1 + read -r -p "Please enter the Websocket path (default: trojan-panel-websocket-path): " trojanGO_websocket_path + [[ -z "${trojanGO_websocket_path}" ]] && trojanGO_websocket_path="trojan-panel-websocket-path" + break + else + echo_content red "Cannot enter other characters except 0 and 1" + fi + done + + while read -r -p "Do you want to enable Shadowsocks AEAD encryption? (0/disabled 1/enabled default: 0): " trojanGO_shadowsocks_enable; do + if [[ -z "${trojanGO_shadowsocks_enable}" || ${trojanGO_shadowsocks_enable} == 0 ]]; then + trojanGO_shadowsocks_enable=0 + break + elif [[ ${trojanGO_shadowsocks_enable} == 1 ]]; then + echo_content skyBlue "Shadowsocks AEAD encryption method is as follows:" + echo_content yellow "1. AES-128-GCM(default)" + echo_content yellow "2. CHACHA20-IETF-POLY1305" + echo_content yellow "3. AES-256-GCM" + read -r -p "Please enter the Shadowsocks AEAD encryption method (default: 1): " select_method_type + [[ -z "${select_method_type}" ]] && select_method_type=1 + case ${select_method_type} in + 1) + trojanGO_shadowsocks_method="AES-128-GCM" + ;; + 2) + trojanGO_shadowsocks_method="CHACHA20-IETF-POLY1305" + ;; + 3) + trojanGO_shadowsocks_method="AES-256-GCM" + ;; + *) + trojanGO_shadowsocks_method="AES-128-GCM" + ;; + esac + + while read -r -p "Please enter the Shadowsocks AEAD encryption password (required): " trojanGO_shadowsocks_password; do + if [[ -z "${trojanGO_shadowsocks_password}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + break + else + echo_content yellow "Cannot enter other characters except 0 and 1" + fi + done + + cat >${TROJANGO_STANDALONE_CONFIG} < TrojanGO+Caddy+Web+TLS+Websocket installation completed" + echo_content red "\n==============================================================" + echo_content skyBlue "TrojanGO+Caddy+Web+TLS+Websocket installed successfully" + echo_content yellow "domain: ${domain}" + echo_content yellow "Port of TrojanGO: ${trojanGO_port}" + echo_content yellow "Password for TrojanGO: ${trojan_pas}" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + if [[ ${trojanGO_websocket_enable} == 1 ]]; then + echo_content yellow "Websocket Path: ${trojanGO_websocket_path}" + fi + if [[ ${trojanGO_shadowsocks_enable} == 1 ]]; then + echo_content yellow "Shadowsocks AEAD encryption method: ${trojanGO_shadowsocks_method}" + echo_content yellow "Shadowsocks AEAD encryption password: ${trojanGO_shadowsocks_password}" + fi + echo_content red "\n==============================================================" + else + echo_content red "---> TrojanGO+Caddy+Web+TLS+Websocket fails to install or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed TrojanGO+Caddy+Web+TLS+Websocket" + fi +} + +# Install Hysteria +install_hysteria_standalone() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-hysteria-standalone$") ]]; then + echo_content green "---> Install Hysteria" + + echo_content skyBlue "Hysteria's schema is as follows:" + echo_content yellow "1. udp(default)" + echo_content yellow "2. faketcp" + read -r -p "Please enter the mode of Hysteria (default: 1): " selectProtocolType + [[ -z "${selectProtocolType}" ]] && selectProtocolType=1 + case ${selectProtocolType} in + 1) + hysteria_protocol="udp" + ;; + 2) + hysteria_protocol="faketcp" + ;; + *) + hysteria_protocol="udp" + ;; + esac + read -r -p "Please enter the port of Hysteria (default: 443): " hysteria_port + [[ -z ${hysteria_port} ]] && hysteria_port=443 + read -r -p "Please enter the maximum upload speed of a single client/Mbps (default: 100): " hysteria_up_mbps + [[ -z "${hysteria_up_mbps}" ]] && hysteria_up_mbps=100 + read -r -p "Please enter the maximum download speed of a single client/Mbps (default: 100): " hysteria_down_mbps + [[ -z "${hysteria_down_mbps}" ]] && hysteria_down_mbps=100 + while read -r -p "Please enter the password of Hysteria (required): " hysteria_password; do + if [[ -z ${hysteria_password} ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + cat >${HYSTERIA_STANDALONE_CONFIG} < Hysteria installation completed" + echo_content red "\n==============================================================" + echo_content skyBlue "Hysteria installed successfully" + echo_content yellow "domain: ${domain}" + echo_content yellow "Port of Hysteria: ${hysteria_port}" + echo_content yellow "Password for Hysteria: ${hysteria_password}" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> Hysteria installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Hysteria" + fi +} + +# Install NaiveProxy (Caddy+ForwardProxy) +install_navieproxy_standalone() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-navieproxy-standalone$") ]]; then + echo_content green "---> Install NaiveProxy (Caddy+ForwardProxy)" + + read -r -p "Please enter the port of NaiveProxy (default: 443): " naiveproxy_port + [[ -z "${naiveproxy_port}" ]] && naiveproxy_port=443 + while read -r -p "Please enter the username of NaiveProxy (required): " naiveproxy_username; do + if [[ -z "${naiveproxy_username}" ]]; then + echo_content red "Username can not be empty" + else + break + fi + done + while read -r -p "Please enter the password of NaiveProxy (required): " naiveproxy_pass; do + if [[ -z "${naiveproxy_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + domain=$(cat "${DOMAIN_FILE}") + cat >${NAIVEPROXY_STANDALONE_CONFIG} < NaiveProxy(Caddy+ForwardProxy) installation completed" + echo_content red "\n==============================================================" + echo_content skyBlue "NaiveProxy(Caddy+ForwardProxy) installed successfully" + echo_content yellow "domain: ${domain}" + echo_content yellow "Port of NaiveProxy: ${naiveproxy_port}" + echo_content yellow "Username for NaiveProxy: ${naiveproxy_username}" + echo_content yellow "Password for NaiveProxy: ${naiveproxy_pass}" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> NaiveProxy(Caddy+ForwardProxy) failed to install or run abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed NaiveProxy(Caddy+ForwardProxy)" + fi +} + +# Uninstall Caddy2 +uninstall_caddy2() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> Uninstall Caddy2" + + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_DATA} + + echo_content skyBlue "---> Caddy2 uninstallation completed" + else + echo_content red "---> Please install Caddy2 first" + fi +} + +# Uninstall TrojanGO+Caddy+Web+TLS+Websocket +uninstall_trojanGO_standalone() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-trojanGO-standalone$") ]]; then + echo_content green "---> Uninstall TrojanGO+Caddy+Web+TLS+Websocket" + + docker rm -f trojan-panel-trojanGO-standalone && + docker rmi -f p4gefau1t/trojan-go && + rm -f ${TROJANGO_STANDALONE_CONFIG} + + echo_content skyBlue "---> TrojanGO+Caddy+Web+TLS+Websocket uninstallation completed" + else + echo_content red "---> Please install TrojanGO+Caddy+Web+TLS+Websocket first" + fi +} + +# Uninstall Hysteria +uninstall_hysteria_standalone() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-hysteria-standalone$") ]]; then + echo_content green "---> Uninstall Hysteria" + + docker rm -f trojan-panel-hysteria-standalone && + docker rmi -f tobyxdd/hysteria && + rm -f ${HYSTERIA_STANDALONE_CONFIG} + + echo_content skyBlue "---> Hysteria uninstallation completed" + else + echo_content red "---> Please install Hysteria" + fi +} + +# Uninstall NaiveProxy (Caddy+ForwardProxy) +uninstall_navieproxy_standalone() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-navieproxy-standalone$") ]]; then + echo_content green "---> Uninstall NaiveProxy (Caddy+ForwardProxy)" + + docker rm -f trojan-panel-navieproxy-standalone && + docker rmi -f jonssonyan/caddy-forwardproxy && + rm -f ${NAIVEPROXY_STANDALONE_CONFIG} + + echo_content skyBlue "---> NaiveProxy(Caddy+ForwardProxy) uninstallation completed" + else + echo_content red "---> Please install NaiveProxy(Caddy+ForwardProxy)" + fi +} + +# Uninstall all Trojan Panel related containers +uninstall_all() { + echo_content green "---> Uninstall all Trojan Panel related containers" + + docker rm -f $(docker ps -a -q -f "name=^trojan-panel") + docker rmi -f $(docker images | grep "^jonssonyan/trojan-panel" | awk '{print $3}') + rm -rf ${TP_DATA} + + echo_content skyBlue "---> Uninstall all Trojan Panel related containers completed" +} + +# Fault detection +failure_testing() { + echo_content green "---> Start troubleshooting" + if [[ ! $(docker -v 2>/dev/null) ]]; then + echo_content red "---> Docker is running abnormally" + else + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + if [[ -z $(docker ps -q -f "name=^trojan-panel-caddy$" -f "status=running") ]]; then + echo_content red "---> Caddy2 is running abnormally and the running log is as follows:" + docker logs trojan-panel-caddy + fi + domain=$(cat "${DOMAIN_FILE}") + if [[ -n ${domain} && ! -f "${CERT_PATH}${domain}.crt" ]]; then + echo_content red "---> The certificate application is abnormal, please try 1. Change the sub-domain name to re-build 2. Restart the server to re-apply for the certificate 3. Re-build and select the custom certificate option" + if [[ -f ${CADDY_LOG}error.log ]]; then + echo_content red "Caddy2 error log is as follows:" + tail -n 20 ${CADDY_LOG}error.log | grep error + fi + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-trojanGO-standalone$") && -z $(docker ps -q -f "name=^trojan-panel-trojanGO-standalone$" -f "status=running") ]]; then + echo_content red "---> TrojanGO is running abnormally" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-hysteria-standalone$") && -z $(docker ps -q -f "name=^trojan-panel-hysteria-standalone$" -f "status=running") ]]; then + echo_content red "---> Hysteria is running abnormally" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-navieproxy-standalone$") && -z $(docker ps -q -f "name=^trojan-panel-navieproxy-standalone$" -f "status=running") ]]; then + echo_content red "---> NaiveProxy(Caddy+ForwardProxy) is running abnormally" + fi + fi + echo_content green "---> Troubleshooting ended" +} + +main() { + cd "$HOME" || exit 0 + init_var + mkdir_tools + check_sys + depend_install + clear + echo_content red "\n==============================================================" + echo_content skyBlue "System Required: CentOS 7+/Ubuntu 18+/Debian 10+" + echo_content skyBlue "Description: One click Install Trojan Panel standalone server" + echo_content skyBlue "Author: jonssonyan " + echo_content skyBlue "Github: https://github.com/trojanpanel" + echo_content skyBlue "Docs: https://trojanpanel.github.io" + echo_content red "\n==============================================================" + echo_content yellow "2. Install TrojanGO+Caddy2+Web+TLS+Websocket" + echo_content yellow "3. Install Hysteria" + echo_content yellow "4. Install NaiveProxy(Caddy2+ForwardProxy)" + echo_content yellow "5. Install Caddy2+https" + echo_content green "\n==============================================================" + echo_content yellow "7. Uninstall TrojanGO+Caddy2+Web+TLS+Websocket" + echo_content yellow "8. Uninstall Hysteria" + echo_content yellow "9. Uninstall NaiveProxy(Caddy2+ForwardProxy)" + echo_content yellow "10. Uninstall Caddy2+https" + echo_content yellow "11. Uninstall all Trojan Panel related containers" + echo_content green "\n==============================================================" + echo_content yellow "12. Fault detection" + read -r -p "Please choose: " selectInstall_type + case ${selectInstall_type} in + 1) + install_docker + install_caddy2 + install_trojanGO_standalone + ;; + 2) + install_docker + install_caddy2 + install_hysteria_standalone + ;; + 3) + install_docker + install_caddy2 + install_navieproxy_standalone + ;; + 4) + install_docker + install_caddy2 + ;; + 5) + uninstall_trojanGO_standalone + ;; + 6) + uninstall_hysteria_standalone + ;; + 7) + uninstall_navieproxy_standalone + ;; + 8) + uninstall_caddy2 + ;; + 9) + uninstall_all + ;; + 10) + failure_testing + ;; + *) + echo_content red "No such option" + ;; + esac +} + +main diff --git a/lib/archive/install_script_v2.1.5.sh b/lib/archive/install_script_v2.1.5.sh new file mode 100644 index 0000000..7c052a2 --- /dev/null +++ b/lib/archive/install_script_v2.1.5.sh @@ -0,0 +1,1863 @@ +#!/usr/bin/env bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +# System Required: CentOS 7+/Ubuntu 18+/Debian 10+ +# Version: v2.1.5 +# Description: One click Install Trojan Panel server +# Author: jonssonyan +# Github: https://github.com/trojanpanel/install-script + +init_var() { + ECHO_TYPE="echo -e" + + package_manager="" + release="" + get_arch="" + can_google=0 + + # Docker + DOCKER_MIRROR='"https://hub-mirror.c.163.com","https://ccr.ccs.tencentyun.com","https://mirror.baidubce.com","https://dockerproxy.com"' + + # 项目目录 + TP_DATA="/tpdata/" + + STATIC_HTML="https://github.com/trojanpanel/install-script/releases/download/v1.0/html.tar.gz" + + # web + WEB_PATH="/tpdata/web/" + + # cert + CERT_PATH="/tpdata/cert/" + DOMAIN_FILE="/tpdata/domain.lock" + domain="" + crt_path="" + key_path="" + + # Caddy + CADDY_DATA="/tpdata/caddy/" + CADDY_CONFIG="${CADDY_DATA}config.json" + CADDY_LOG="${CADDY_DATA}logs/" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + caddy_port=80 + caddy_remote_port=8863 + your_email="" + ssl_option=1 + ssl_module_type=1 + ssl_module="acme" + + # Nginx + NGINX_DATA="/tpdata/nginx/" + NGINX_CONFIG="${NGINX_DATA}default.conf" + nginx_port=80 + nginx_remote_port=8863 + nginx_https=1 + + # MariaDB + MARIA_DATA="/tpdata/mariadb/" + mariadb_ip="127.0.0.1" + mariadb_port=9507 + mariadb_user="root" + mariadb_pas="" + + #Redis + REDIS_DATA="/tpdata/redis/" + redis_host="127.0.0.1" + redis_port=6378 + redis_pass="" + + # Trojan Panel前端 + TROJAN_PANEL_UI_DATA="/tpdata/trojan-panel-ui/" + # Nginx + UI_NGINX_DATA="${TROJAN_PANEL_UI_DATA}nginx/" + UI_NGINX_CONFIG="${UI_NGINX_DATA}default.conf" + trojan_panel_ui_port=8888 + ui_https=1 + trojan_panel_ip="127.0.0.1" + trojan_panel_server_port=8081 + + # Trojan Panel后端 + TROJAN_PANEL_DATA="/tpdata/trojan-panel/" + TROJAN_PANEL_WEBFILE="${TROJAN_PANEL_DATA}webfile/" + TROJAN_PANEL_LOGS="${TROJAN_PANEL_DATA}logs/" + TROJAN_PANEL_CONFIG="${TROJAN_PANEL_DATA}config/" + trojan_panel_config_path="${TROJAN_PANEL_DATA}config/config.ini" + trojan_panel_port=8081 + + # Trojan Panel内核 + TROJAN_PANEL_CORE_DATA="/tpdata/trojan-panel-core/" + TROJAN_PANEL_CORE_LOGS="${TROJAN_PANEL_CORE_DATA}logs/" + TROJAN_PANEL_CORE_CONFIG="${TROJAN_PANEL_CORE_DATA}config/" + trojan_panel_core_config_path="${TROJAN_PANEL_CORE_DATA}config/config.ini" + database="trojan_panel_db" + account_table="account" + grpc_port=8100 + trojan_panel_core_port=8082 + + # Update + trojan_panel_ui_current_version="" + trojan_panel_ui_latest_version="v2.1.5" + trojan_panel_current_version="" + trojan_panel_latest_version="v2.1.4" + trojan_panel_core_current_version="" + trojan_panel_core_latest_version="v2.1.1" + + # SQL +} + +echo_content() { + case $1 in + "red") + ${ECHO_TYPE} "\033[31m$2\033[0m" + ;; + "green") + ${ECHO_TYPE} "\033[32m$2\033[0m" + ;; + "yellow") + ${ECHO_TYPE} "\033[33m$2\033[0m" + ;; + "blue") + ${ECHO_TYPE} "\033[34m$2\033[0m" + ;; + "purple") + ${ECHO_TYPE} "\033[35m$2\033[0m" + ;; + "skyBlue") + ${ECHO_TYPE} "\033[36m$2\033[0m" + ;; + "white") + ${ECHO_TYPE} "\033[37m$2\033[0m" + ;; + esac +} + +mkdir_tools() { + # 项目目录 + mkdir -p ${TP_DATA} + + # web + mkdir -p ${WEB_PATH} + + # cert + mkdir -p ${CERT_PATH} + touch ${DOMAIN_FILE} + + # Caddy + mkdir -p ${CADDY_DATA} + touch ${CADDY_CONFIG} + mkdir -p ${CADDY_LOG} + + # Nginx + mkdir -p ${NGINX_DATA} + touch ${NGINX_CONFIG} + + # MariaDB + mkdir -p ${MARIA_DATA} + + # Redis + mkdir -p ${REDIS_DATA} + + # Trojan Panel前端 + mkdir -p ${TROJAN_PANEL_UI_DATA} + # # Nginx + mkdir -p ${UI_NGINX_DATA} + touch ${UI_NGINX_CONFIG} + + # Trojan Panel后端 + mkdir -p ${TROJAN_PANEL_DATA} + mkdir -p ${TROJAN_PANEL_LOGS} + + # Trojan Panel内核 + mkdir -p ${TROJAN_PANEL_CORE_DATA} + mkdir -p ${TROJAN_PANEL_CORE_LOGS} +} + +can_connect() { + ping -c2 -i0.3 -W1 "$1" &>/dev/null + if [[ "$?" == "0" ]]; then + return 0 + else + return 1 + fi +} + +get_ini_value() { + local config_file="$1" + local key="$2" + local section="" + local section_flag=0 + + # 拆分组名和键名 + IFS='.' read -r group_name key_name <<<"$key" + + while IFS='=' read -r name val; do + # 处理节名称 + if [[ $name =~ ^\[(.*)\]$ ]]; then + section="${BASH_REMATCH[1]}" + if [[ $section == $group_name ]]; then + section_flag=1 + else + section_flag=0 + fi + continue + fi + + # 提取配置项的值 + if [[ $section_flag -eq 1 && $name == $key_name ]]; then + echo "$val" + return + fi + done <"$config_file" +} + +# Version number comparison greater than or equal to +version_ge() { + local v1=${1#v} + local v2=${2#v} + + local v1_parts=(${v1//./ }) + local v2_parts=(${v2//./ }) + + for ((i = 0; i < 3; i++)); do + if ((${v1_parts[i]} < ${v2_parts[i]})); then + echo false + return 0 + elif ((${v1_parts[i]} > ${v2_parts[i]})); then + echo true + return 0 + fi + done + echo true +} + +check_sys() { + if [[ $(command -v yum) ]]; then + package_manager='yum' + elif [[ $(command -v dnf) ]]; then + package_manager='dnf' + elif [[ $(command -v apt) ]]; then + package_manager='apt' + elif [[ $(command -v apt-get) ]]; then + package_manager='apt-get' + fi + + if [[ -z "${package_manager}" ]]; then + echo_content red "暂不支持该系统" + exit 0 + fi + + if [[ -n $(find /etc -name "redhat-release") ]] || grep /dev/null) ]]; then + echo_content green "---> 安装Docker" + + # 关闭防火墙 + if [[ "${release}" == "centos" ]]; then + systemctl disable firewalld + elif [[ "${release}" == "debian" || "${release}" == "ubuntu" ]]; then + sudo ufw disable + fi + + # 时区 + timedatectl set-timezone Asia/Shanghai + + if [[ ${can_google} == 0 ]]; then + sh <(curl -sL https://get.docker.com) --mirror Aliyun + # 设置Docker国内源 + mkdir -p /etc/docker && + cat >/etc/docker/daemon.json </etc/docker/daemon.json </dev/null) ]]; then + echo_content skyBlue "---> Docker安装完成" + else + echo_content red "---> Docker安装失败" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Docker" + fi +} + +# 安装Caddy2 +install_caddy2() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> 安装Caddy2" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "请输入Caddy的端口(默认:80): " caddy_port + [[ -z "${caddy_port}" ]] && caddy_port=80 + read -r -p "请输入Caddy的转发端口(默认:8863): " caddy_remote_port + [[ -z "${caddy_remote_port}" ]] && caddy_remote_port=8863 + + echo_content yellow "提示:请确认域名已经解析到本机 否则可能安装失败" + while read -r -p "请输入你的域名(必填): " domain; do + if [[ -z "${domain}" ]]; then + echo_content red "域名不能为空" + else + break + fi + done + + read -r -p "请输入你的邮箱(可选): " your_email + + while read -r -p "请选择设置证书的方式?(1/自动申请和续签证书 2/手动设置证书路径 默认:1/自动申请和续签证书): " ssl_option; do + if [[ -z ${ssl_option} || ${ssl_option} == 1 ]]; then + while read -r -p "请选择申请证书的方式(1/acme 2/zerossl 默认:1/acme): " ssl_module_type; do + if [[ -z "${ssl_module_type}" || ${ssl_module_type} == 1 ]]; then + ssl_module="acme" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + break + elif [[ ${ssl_module_type} == 2 ]]; then + ssl_module="zerossl" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme.zerossl.com-v2-dv90/" + break + else + echo_content red "不可以输入除1和2之外的其他字符" + fi + done + + cat >${CADDY_CONFIG} <${CADDY_CONFIG} <${DOMAIN_FILE} < Caddy安装完成" + else + echo_content red "---> Caddy安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Caddy" + fi +} + +# 安装Nginx +install_nginx() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + echo_content green "---> 安装Nginx" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "请输入Nginx的端口(默认:80): " nginx_port + [[ -z "${nginx_port}" ]] && nginx_port=80 + read -r -p "请输入Nginx的转发端口(默认:8863): " nginx_remote_port + [[ -z "${nginx_remote_port}" ]] && nginx_remote_port=8863 + + while read -r -p "请选择Nginx是否开启https?(0/关闭 1/开启 默认:1/开启): " nginx_https; do + if [[ -z ${nginx_https} || ${nginx_https} == 1 ]]; then + install_custom_cert "custom_cert" + domain=$(cat "${DOMAIN_FILE}") + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + return 301 http://\$host:${nginx_remote_port}\$request_uri; +} + +server { + listen ${nginx_remote_port} ssl; + server_name localhost; + + #强制ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + #缓存有效期 + ssl_session_timeout 5m; + #安全链接可选的加密协议 + ssl_protocols TLSv1.3; + #加密算法 + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + #使用服务器端的首选算法 + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${nginx_remote_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + else + if [[ ${nginx_https} != 0 ]]; then + echo_content red "不可以输入除0和1之外的其他字符" + else + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + error_page 497 http://\$host:${nginx_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + fi + fi + done + + docker pull nginx:1.20-alpine && + docker run -d --name trojan-panel-nginx --restart always \ + --network=host \ + -v "${NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + nginx:1.20-alpine + + if [[ -n $(docker ps -q -f "name=^trojan-panel-nginx$" -f "status=running") ]]; then + echo_content skyBlue "---> Nginx安装完成" + else + echo_content red "---> Nginx安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Nginx" + fi +} + +# 设置伪装Web +install_reverse_proxy() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$|^trojan-panel-nginx$") ]]; then + echo_content green "---> 设置伪装Web" + + while :; do + echo_content yellow "1. 安装Caddy 2(推荐)" + echo_content yellow "2. 安装Nginx" + echo_content yellow "3. 不设置" + read -r -p "请选择(默认:1): " whether_install_reverse_proxy + [[ -z "${whether_install_reverse_proxy}" ]] && whether_install_reverse_proxy=1 + + case ${whether_install_reverse_proxy} in + 1) + install_caddy2 + break + ;; + 2) + install_nginx + break + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + done + + echo_content skyBlue "---> 伪装Web设置完成" + fi +} + +install_custom_cert() { + while read -r -p "请输入证书的.crt文件路径(必填): " crt_path; do + if [[ -z "${crt_path}" ]]; then + echo_content red "路径不能为空" + else + if [[ ! -f "${crt_path}" ]]; then + echo_content red "证书的.crt文件路径不存在" + else + cp "${crt_path}" "${CERT_PATH}$1.crt" + break + fi + fi + done + while read -r -p "请输入证书的.key文件路径(必填): " key_path; do + if [[ -z "${key_path}" ]]; then + echo_content red "路径不能为空" + else + if [[ ! -f "${key_path}" ]]; then + echo_content red "证书的.key文件路径不存在" + else + cp "${key_path}" "${CERT_PATH}$1.key" + break + fi + fi + done + cat >${DOMAIN_FILE} < 设置证书" + + while :; do + echo_content yellow "1. 安装Caddy 2(自动申请/续签证书)" + echo_content yellow "2. 手动设置证书路径" + echo_content yellow "3. 不设置" + read -r -p "请选择(默认:1): " whether_install_cert + [[ -z "${whether_install_cert}" ]] && whether_install_cert=1 + + case ${whether_install_cert} in + 1) + install_caddy2 + break + ;; + 2) + install_custom_cert "custom_cert" + break + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + done + + echo_content green "---> 证书设置完成" + fi +} + +# 安装MariaDB +install_mariadb() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> 安装MariaDB" + + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + if [[ "${mariadb_user}" == "root" ]]; then + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + else + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e MYSQL_USER="${mariadb_user}" \ + -e MYSQL_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + fi + + if [[ -n $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content skyBlue "---> MariaDB安装完成" + echo_content yellow "---> MariaDB root的数据库密码(请妥善保存): ${mariadb_pas}" + if [[ "${mariadb_user}" != "root" ]]; then + echo_content yellow "---> MariaDB ${mariadb_user}的数据库密码(请妥善保存): ${mariadb_pas}" + fi + else + echo_content red "---> MariaDB安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了MariaDB" + fi +} + +# 安装Redis +install_redis() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> 安装Redis" + + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker pull redis:6.2.7 && + docker run -d --name trojan-panel-redis --restart always \ + --network=host \ + redis:6.2.7 \ + redis-server --requirepass "${redis_pass}" --port "${redis_port}" + + if [[ -n $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content skyBlue "---> Redis安装完成" + echo_content yellow "---> Redis的数据库密码(请妥善保存): ${redis_pass}" + else + echo_content red "---> Redis安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Redis" + fi +} + +# 安装Trojan Panel前端 +install_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> 安装Trojan Panel前端" + + read -r -p "请输入Trojan Panel后端的IP地址(默认:本机后端): " trojan_panel_ip + [[ -z "${trojan_panel_ip}" ]] && trojan_panel_ip="127.0.0.1" + read -r -p "请输入Trojan Panel后端的服务端口(默认:8081): " trojan_panel_server_port + [[ -z "${trojan_panel_server_port}" ]] && trojan_panel_server_port=8081 + + read -r -p "请输入Trojan Panel前端端口(默认:8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + while read -r -p "请选择Trojan Panel前端是否开启https?(0/关闭 1/开启 默认:1/开启): " ui_https; do + if [[ -z ${ui_https} || ${ui_https} == 1 ]]; then + install_cert + domain=$(cat "${DOMAIN_FILE}") + # 配置Nginx + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port} ssl; + server_name localhost; + + #强制ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + #缓存有效期 + ssl_session_timeout 5m; + #安全链接可选的加密协议 + ssl_protocols TLSv1.3; + #加密算法 + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + #使用服务器端的首选算法 + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${trojan_panel_ui_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + else + if [[ ${ui_https} != 0 ]]; then + echo_content red "不可以输入除0和1之外的其他字符" + else + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port}; + server_name localhost; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + error_page 497 http://\$host:${trojan_panel_ui_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + fi + fi + done + + docker pull jonssonyan/trojan-panel-ui:2.1.5 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.5 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel前端安装完成" + + https_flag=$([[ -z ${ui_https} || ${ui_https} == 1 ]] && echo "https" || echo "http") + domain_or_ip=$([[ -z ${domain} || "${domain}" == "custom_cert" ]] && echo "ip" || echo "${domain}") + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel前端安装成功" + echo_content yellow "管理面板地址: ${https_flag}://${domain_or_ip}:${trojan_panel_ui_port}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel前端安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel前端" + fi +} + +# 安装Trojan Panel后端 +install_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> 安装Trojan Panel后端" + + read -r -p "请输入Trojan Panel后端的服务端口(默认:8081): " trojan_panel_port + [[ -z "${trojan_panel_port}" ]] && trojan_panel_port=8081 + + read -r -p "请输入数据库的IP地址(默认:本机数据库): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -e "create database if not exists trojan_panel_db;" &>/dev/null + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker pull jonssonyan/trojan-panel:2.1.4 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.1.4 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel后端安装完成" + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel后端安装成功" + echo_content yellow "MariaDB ${mariadb_user}的密码(请妥善保存): ${mariadb_pas}" + echo_content yellow "Redis的密码(请妥善保存): ${redis_pass}" + echo_content yellow "系统管理员 默认用户名: sysadmin 默认密码: 123456 请及时登陆管理面板修改密码" + echo_content yellow "Trojan Panel私钥和证书目录: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel后端安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel后端" + fi +} + +# 安装Trojan Panel内核 +install_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> 安装Trojan Panel内核" + + read -r -p "请输入Trojan Panel内核的服务端口(默认:8082): " trojan_panel_core_port + [[ -z "${trojan_panel_core_port}" ]] && trojan_panel_core_port=8082 + + read -r -p "请输入数据库的IP地址(默认:本机数据库): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + read -r -p "请输入数据库名称(默认:trojan_panel_db): " database + [[ -z "${database}" ]] && database="trojan_panel_db" + read -r -p "请输入数据库的用户表名称(默认:account): " account_table + [[ -z "${account_table}" ]] && account_table="account" + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + read -r -p "请输入API的端口(默认:8100): " grpc_port + [[ -z "${grpc_port}" ]] && grpc_port=8100 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.1.1 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.1.1 + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel内核安装完成" + else + echo_content red "---> Trojan Panel内核安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel内核" + fi +} + +# 更新Trojan Panel数据结构 +update_trojan_panel_database() { + echo_content skyBlue "---> 更新Trojan Panel数据结构" + + echo_content skyBlue "---> Trojan Panel数据结构更新完成" +} + +# 更新Trojan Panel内核数据结构 +update_trojan_panel_core_database() { + echo_content skyBlue "---> 更新Trojan Panel内核数据结构" + + echo_content skyBlue "---> Trojan Panel内核数据结构更新完成" +} + +# 更新Trojan Panel前端 +update_trojan_panel_ui() { + # 判断Trojan Panel前端是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content red "---> 请先安装Trojan Panel前端" + exit 0 + fi + + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + if [[ -z "${trojan_panel_ui_current_version}" || ! "${trojan_panel_ui_current_version}" =~ ^v.* ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel前端(trojan-panel-ui)当前版本为 ${trojan_panel_ui_current_version} 最新版本为 ${trojan_panel_ui_latest_version}" + + if [[ "${trojan_panel_ui_current_version}" != "${trojan_panel_ui_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel前端" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.5 + + docker pull jonssonyan/trojan-panel-ui:2.1.5 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.5 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel前端更新完成" + else + echo_content red "---> Trojan Panel前端更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel前端已经是最新版" + fi +} + +# 更新Trojan Panel后端 +update_trojan_panel() { + # 判断Trojan Panel后端是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content red "---> 请先安装Trojan Panel后端" + exit 0 + fi + + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + if [[ -z "${trojan_panel_current_version}" || ! "${trojan_panel_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_current_version}" "v2.1.4") ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel后端(trojan-panel)当前版本为 ${trojan_panel_current_version} 最新版本为 ${trojan_panel_latest_version}" + + if [[ "${trojan_panel_current_version}" != "${trojan_panel_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel后端" + + mariadb_ip=$(get_ini_value ${trojan_panel_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + trojan_panel_port=$(get_ini_value ${trojan_panel_config_path} server.port) + + update_trojan_panel_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.1.4 + + docker pull jonssonyan/trojan-panel:2.1.4 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.1.4 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel后端更新完成" + else + echo_content red "---> Trojan Panel后端更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel后端已经是最新版" + fi +} + +# 更新Trojan Panel内核 +update_trojan_panel_core() { + # 判断Trojan Panel内核是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content red "---> 请先安装Trojan Panel内核" + exit 0 + fi + + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + if [[ -z "${trojan_panel_core_current_version}" || ! "${trojan_panel_core_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_core_current_version}" "v2.1.1") ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel内核(trojan-panel-core)当前版本为 ${trojan_panel_core_current_version} 最新版本为 ${trojan_panel_core_latest_version}" + + if [[ "${trojan_panel_core_current_version}" != "${trojan_panel_core_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel内核" + + mariadb_ip=$(get_ini_value ${trojan_panel_core_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_core_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_core_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_core_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_core_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_core_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_core_config_path} redis.password) + grpc_port=$(get_ini_value ${trojan_panel_core_config_path} grpc.port) + trojan_panel_core_port=$(get_ini_value ${trojan_panel_core_config_path} server.port) + + update_trojan_panel_core_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.1.1 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.1.1 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.1.1 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel内核更新完成" + else + echo_content red "---> Trojan Panel内核更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel内核已经是最新版" + fi +} + +# 卸载Caddy2 +uninstall_caddy2() { + # 判断Caddy2是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> 卸载Caddy2" + + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_DATA} + + echo_content skyBlue "---> Caddy2卸载完成" + else + echo_content red "---> 请先安装Caddy2" + fi +} + +# 卸载Nginx +uninstall_nginx() { + # 判断Caddy2是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx") ]]; then + echo_content green "---> 卸载Nginx" + + docker rm -f trojan-panel-nginx && + rm -rf ${NGINX_DATA} + + echo_content skyBlue "---> Nginx卸载完成" + else + echo_content red "---> 请先安装Nginx" + fi +} + +# 卸载MariaDB +uninstall_mariadb() { + # 判断MariaDB是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> 卸载MariaDB" + + docker rm -f trojan-panel-mariadb && + rm -rf ${MARIA_DATA} + + echo_content skyBlue "---> MariaDB卸载完成" + else + echo_content red "---> 请先安装MariaDB" + fi +} + +# 卸载Redis +uninstall_redis() { + # 判断Redis是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> 卸载Redis" + + docker rm -f trojan-panel-redis && + rm -rf ${REDIS_DATA} + + echo_content skyBlue "---> Redis卸载完成" + else + echo_content red "---> 请先安装Redis" + fi +} + +# 卸载Trojan Panel前端 +uninstall_trojan_panel_ui() { + # 判断Trojan Panel前端是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> 卸载Trojan Panel前端" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.5 && + rm -rf ${TROJAN_PANEL_UI_DATA} + + echo_content skyBlue "---> Trojan Panel前端卸载完成" + else + echo_content red "---> 请先安装Trojan Panel前端" + fi +} + +# 卸载Trojan Panel后端 +uninstall_trojan_panel() { + # 判断Trojan Panel后端是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> 卸载Trojan Panel后端" + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.1.4 && + rm -rf ${TROJAN_PANEL_DATA} + + echo_content skyBlue "---> Trojan Panel后端卸载完成" + else + echo_content red "---> 请先安装Trojan Panel后端" + fi +} + +# 卸载Trojan Panel内核 +uninstall_trojan_panel_core() { + # 判断Trojan Panel内核是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> 卸载Trojan Panel内核" + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.1.1 && + rm -rf ${TROJAN_PANEL_CORE_DATA} + + echo_content skyBlue "---> Trojan Panel内核卸载完成" + else + echo_content red "---> 请先安装Trojan Panel内核" + fi +} + +# 卸载全部Trojan Panel相关的容器 +uninstall_all() { + echo_content green "---> 卸载全部Trojan Panel相关的容器" + + docker rm -f $(docker ps -a -q -f "name=^trojan-panel") + docker rmi -f $(docker images | grep "^jonssonyan/trojan-panel" | awk '{print $3}') + rm -rf ${TP_DATA} + + echo_content skyBlue "---> 卸载全部Trojan Panel相关的容器完成" +} + +# 修改Trojan Panel前端端口 +update_trojan_panel_ui_port() { + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content green "---> 修改Trojan Panel前端端口" + + trojan_panel_ui_port=$(grep 'listen.*ssl' ${UI_NGINX_CONFIG} | awk '{print $2}') + if [[ -z "${trojan_panel_ui_port}" ]]; then + ui_https=0 + trojan_panel_ui_port=$(grep -oP 'listen\s+\K\d+' ${UI_NGINX_CONFIG} | awk 'NR==1') + fi + if [[ -z "${trojan_panel_ui_port}" ]]; then + echo_content red "---> 未查询到Trojan Panel前端的端口" + exit 0 + fi + echo_content yellow "提示:Trojan Panel前端(trojan-panel-ui)当前端口为 ${trojan_panel_ui_port}" + + read -r -p "请输入Trojan Panel前端新端口(默认:8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + + if [[ ${ui_https} == 0 ]]; then + # http + sed -i "s/listen.*;/listen ${trojan_panel_ui_port};/g" ${UI_NGINX_CONFIG} && + sed -i "s/http:\/\/\$host:.*\$request_uri;/http:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + else + # https + sed -i "s/listen.*ssl;/listen ${trojan_panel_ui_port} ssl;/g" ${UI_NGINX_CONFIG} && + sed -i "s/https:\/\/\$host:.*\$request_uri;/https:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + fi + + if [[ "$?" == "0" ]]; then + echo_content skyBlue "---> Trojan Panel前端端口修改完成" + else + echo_content red "---> Trojan Panel前端端口修改失败" + fi + else + echo_content red "---> Trojan Panel前端未安装或运行异常,请修复或卸载重装后重试" + fi +} + +# 刷新Redis缓存 +redis_flush_all() { + # 判断Redis是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content red "---> 请先安装Redis" + exit 0 + fi + + if [[ -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis运行异常" + exit 0 + fi + + echo_content green "---> 刷新Redis缓存" + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + echo_content skyBlue "---> Redis缓存刷新完成" +} + +# 故障检测 +failure_testing() { + echo_content green "---> 故障检测开始" + if [[ ! $(docker -v 2>/dev/null) ]]; then + echo_content red "---> Docker运行异常" + else + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + if [[ -z $(docker ps -q -f "name=^trojan-panel-caddy$" -f "status=running") ]]; then + echo_content red "---> Caddy2运行异常 错误日志如下:" + docker logs trojan-panel-caddy + fi + domain=$(cat "${DOMAIN_FILE}") + if [[ -z ${domain} || ! -d "${CERT_PATH}" || ! -f "${CERT_PATH}${domain}.crt" ]]; then + echo_content red "---> 证书申请异常,请尝试 1.换个子域名重新搭建 2.重启服务器将重新申请证书 3.重新搭建选择自定义证书选项 日志如下:" + if [[ -f ${CADDY_LOG}error.log ]]; then + tail -n 20 ${CADDY_LOG}error.log | grep error + else + docker logs trojan-panel-caddy + fi + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") && -z $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content red "---> MariaDB运行异常 日志如下:" + docker logs trojan-panel-mariadb + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") && -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis运行异常 日志如下:" + docker logs trojan-panel-redis + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -z $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel后端运行异常 日志如下:" + if [[ -f ${TROJAN_PANEL_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -z $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel前端运行异常 日志如下:" + docker logs trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -z $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel内核运行异常 日志如下:" + if [[ -f ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel-core + fi + fi + fi + echo_content green "---> 故障检测结束" +} + +log_query() { + while :; do + echo_content skyBlue "可以查询日志的应用如下:" + echo_content yellow "1. Trojan Panel后端" + echo_content yellow "2. Trojan Panel内核" + echo_content yellow "3. 退出" + read -r -p "请选择应用(默认:1): " select_log_query_type + [[ -z "${select_log_query_type}" ]] && select_log_query_type=1 + + case ${select_log_query_type} in + 1) + log_file_path=${TROJAN_PANEL_LOGS}trojan-panel.log + ;; + 2) + log_file_path=${TROJAN_PANEL_CORE_LOGS}trojan-panel-core.log + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + + read -r -p "请输入查询的行数(默认:20): " select_log_query_line_type + [[ -z "${select_log_query_line_type}" ]] && select_log_query_line_type=20 + + if [[ -f ${log_file_path} ]]; then + echo_content skyBlue "日志如下:" + tail -n ${select_log_query_line_type} ${log_file_path} + else + echo_content red "不存在日志文件" + fi + done +} + +version_query() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + echo_content yellow "Trojan Panel前端(trojan-panel-ui)当前版本为 ${trojan_panel_ui_current_version} 最新版本为 ${trojan_panel_ui_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + echo_content yellow "Trojan Panel后端(trojan-panel)当前版本为 ${trojan_panel_current_version} 最新版本为 ${trojan_panel_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + echo_content yellow "Trojan Panel内核(trojan-panel-core)当前版本为 ${trojan_panel_core_current_version} 最新版本为 ${trojan_panel_core_latest_version}" + fi +} + +main() { + cd "$HOME" || exit 0 + init_var + mkdir_tools + check_sys + depend_install + clear + echo_content red "\n==============================================================" + echo_content skyBlue "System Required: CentOS 7+/Ubuntu 18+/Debian 10+" + echo_content skyBlue "Version: v2.1.5" + echo_content skyBlue "Description: One click Install Trojan Panel server" + echo_content skyBlue "Author: jonssonyan " + echo_content skyBlue "Github: https://github.com/trojanpanel" + echo_content skyBlue "Docs: https://trojanpanel.github.io" + echo_content red "\n==============================================================" + echo_content yellow "1. 安装Trojan Panel前端" + echo_content yellow "2. 安装Trojan Panel后端" + echo_content yellow "3. 安装Trojan Panel内核" + echo_content yellow "4. 安装Caddy2" + echo_content yellow "5. 安装Nginx" + echo_content yellow "6. 安装MariaDB" + echo_content yellow "7. 安装Redis" + echo_content green "\n==============================================================" + echo_content yellow "8. 更新Trojan Panel前端" + echo_content yellow "9. 更新Trojan Panel后端" + echo_content yellow "10. 更新Trojan Panel内核" + echo_content green "\n==============================================================" + echo_content yellow "11. 卸载Trojan Panel前端" + echo_content yellow "12. 卸载Trojan Panel后端" + echo_content yellow "13. 卸载Trojan Panel内核" + echo_content yellow "14. 卸载Caddy2" + echo_content yellow "15. 卸载Nginx" + echo_content yellow "16. 卸载MariaDB" + echo_content yellow "17. 卸载Redis" + echo_content yellow "18. 卸载全部Trojan Panel相关的应用" + echo_content green "\n==============================================================" + echo_content yellow "19. 修改Trojan Panel前端端口" + echo_content yellow "20. 刷新Redis缓存" + echo_content green "\n==============================================================" + echo_content yellow "21. 故障检测" + echo_content yellow "22. 日志查询" + echo_content yellow "23. 版本查询" + read -r -p "请选择:" selectInstall_type + case ${selectInstall_type} in + 1) + install_docker + install_cert + install_trojan_panel_ui + ;; + 2) + install_docker + install_mariadb + install_redis + install_trojan_panel + ;; + 3) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_core + ;; + 4) + install_docker + install_caddy2 + ;; + 5) + install_docker + install_nginx + ;; + 6) + install_docker + install_mariadb + ;; + 7) + install_docker + install_redis + ;; + 8) + update_trojan_panel_ui + ;; + 9) + update_trojan_panel + ;; + 10) + update_trojan_panel_core + ;; + 11) + uninstall_trojan_panel_ui + ;; + 12) + uninstall_trojan_panel + ;; + 13) + uninstall_trojan_panel_core + ;; + 14) + uninstall_caddy2 + ;; + 15) + uninstall_nginx + ;; + 16) + uninstall_mariadb + ;; + 17) + uninstall_redis + ;; + 18) + uninstall_all + ;; + 19) + update_trojan_panel_ui_port + ;; + 20) + redis_flush_all + ;; + 21) + failure_testing + ;; + 22) + log_query + ;; + 23) + version_query + ;; + *) + echo_content red "没有这个选项" + ;; + esac +} + +main diff --git a/lib/archive/install_script_v2.1.6.sh b/lib/archive/install_script_v2.1.6.sh new file mode 100644 index 0000000..3e38931 --- /dev/null +++ b/lib/archive/install_script_v2.1.6.sh @@ -0,0 +1,1901 @@ +#!/usr/bin/env bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +# System Required: CentOS 7+/Ubuntu 18+/Debian 10+ +# Version: v2.1.6 +# Description: One click Install Trojan Panel server +# Author: jonssonyan +# Github: https://github.com/trojanpanel/install-script + +init_var() { + ECHO_TYPE="echo -e" + + package_manager="" + release="" + get_arch="" + can_google=0 + + # Docker + DOCKER_MIRROR='"https://hub-mirror.c.163.com","https://ccr.ccs.tencentyun.com","https://mirror.baidubce.com","https://dockerproxy.com"' + + # 项目目录 + TP_DATA="/tpdata/" + + STATIC_HTML="https://github.com/trojanpanel/install-script/releases/download/v1.0/html.tar.gz" + + # web + WEB_PATH="/tpdata/web/" + + # cert + CERT_PATH="/tpdata/cert/" + DOMAIN_FILE="/tpdata/domain.lock" + domain="" + crt_path="" + key_path="" + + # Caddy + CADDY_DATA="/tpdata/caddy/" + CADDY_CONFIG="${CADDY_DATA}config.json" + CADDY_LOG="${CADDY_DATA}logs/" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + caddy_port=80 + caddy_remote_port=8863 + your_email="" + ssl_option=1 + ssl_module_type=1 + ssl_module="acme" + + # Nginx + NGINX_DATA="/tpdata/nginx/" + NGINX_CONFIG="${NGINX_DATA}default.conf" + nginx_port=80 + nginx_remote_port=8863 + nginx_https=1 + + # MariaDB + MARIA_DATA="/tpdata/mariadb/" + mariadb_ip="127.0.0.1" + mariadb_port=9507 + mariadb_user="root" + mariadb_pas="" + + #Redis + REDIS_DATA="/tpdata/redis/" + redis_host="127.0.0.1" + redis_port=6378 + redis_pass="" + + # Trojan Panel前端 + TROJAN_PANEL_UI_DATA="/tpdata/trojan-panel-ui/" + # Nginx + UI_NGINX_DATA="${TROJAN_PANEL_UI_DATA}nginx/" + UI_NGINX_CONFIG="${UI_NGINX_DATA}default.conf" + trojan_panel_ui_port=8888 + ui_https=1 + trojan_panel_ip="127.0.0.1" + trojan_panel_server_port=8081 + + # Trojan Panel后端 + TROJAN_PANEL_DATA="/tpdata/trojan-panel/" + TROJAN_PANEL_WEBFILE="${TROJAN_PANEL_DATA}webfile/" + TROJAN_PANEL_LOGS="${TROJAN_PANEL_DATA}logs/" + TROJAN_PANEL_CONFIG="${TROJAN_PANEL_DATA}config/" + trojan_panel_config_path="${TROJAN_PANEL_DATA}config/config.ini" + trojan_panel_port=8081 + + # Trojan Panel内核 + TROJAN_PANEL_CORE_DATA="/tpdata/trojan-panel-core/" + TROJAN_PANEL_CORE_LOGS="${TROJAN_PANEL_CORE_DATA}logs/" + TROJAN_PANEL_CORE_CONFIG="${TROJAN_PANEL_CORE_DATA}config/" + trojan_panel_core_config_path="${TROJAN_PANEL_CORE_DATA}config/config.ini" + database="trojan_panel_db" + account_table="account" + grpc_port=8100 + trojan_panel_core_port=8082 + + # Update + trojan_panel_ui_current_version="" + trojan_panel_ui_latest_version="v2.1.5" + trojan_panel_current_version="" + trojan_panel_latest_version="v2.1.4" + trojan_panel_core_current_version="" + trojan_panel_core_latest_version="v2.1.1" + + # SQL +} + +echo_content() { + case $1 in + "red") + ${ECHO_TYPE} "\033[31m$2\033[0m" + ;; + "green") + ${ECHO_TYPE} "\033[32m$2\033[0m" + ;; + "yellow") + ${ECHO_TYPE} "\033[33m$2\033[0m" + ;; + "blue") + ${ECHO_TYPE} "\033[34m$2\033[0m" + ;; + "purple") + ${ECHO_TYPE} "\033[35m$2\033[0m" + ;; + "skyBlue") + ${ECHO_TYPE} "\033[36m$2\033[0m" + ;; + "white") + ${ECHO_TYPE} "\033[37m$2\033[0m" + ;; + esac +} + +mkdir_tools() { + # 项目目录 + mkdir -p ${TP_DATA} + + # web + mkdir -p ${WEB_PATH} + + # cert + mkdir -p ${CERT_PATH} + touch ${DOMAIN_FILE} + + # Caddy + mkdir -p ${CADDY_DATA} + touch ${CADDY_CONFIG} + mkdir -p ${CADDY_LOG} + + # Nginx + mkdir -p ${NGINX_DATA} + touch ${NGINX_CONFIG} + + # MariaDB + mkdir -p ${MARIA_DATA} + + # Redis + mkdir -p ${REDIS_DATA} + + # Trojan Panel前端 + mkdir -p ${TROJAN_PANEL_UI_DATA} + # # Nginx + mkdir -p ${UI_NGINX_DATA} + touch ${UI_NGINX_CONFIG} + + # Trojan Panel后端 + mkdir -p ${TROJAN_PANEL_DATA} + mkdir -p ${TROJAN_PANEL_LOGS} + + # Trojan Panel内核 + mkdir -p ${TROJAN_PANEL_CORE_DATA} + mkdir -p ${TROJAN_PANEL_CORE_LOGS} +} + +can_connect() { + ping -c2 -i0.3 -W1 "$1" &>/dev/null + if [[ "$?" == "0" ]]; then + return 0 + else + return 1 + fi +} + +get_ini_value() { + local config_file="$1" + local key="$2" + local section="" + local section_flag=0 + + # 拆分组名和键名 + IFS='.' read -r group_name key_name <<<"$key" + + while IFS='=' read -r name val; do + # 处理节名称 + if [[ $name =~ ^\[(.*)\]$ ]]; then + section="${BASH_REMATCH[1]}" + if [[ $section == $group_name ]]; then + section_flag=1 + else + section_flag=0 + fi + continue + fi + + # 提取配置项的值 + if [[ $section_flag -eq 1 && $name == $key_name ]]; then + echo "$val" + return + fi + done <"$config_file" +} + +# Version number comparison greater than or equal to +version_ge() { + local v1=${1#v} + local v2=${2#v} + + local v1_parts=(${v1//./ }) + local v2_parts=(${v2//./ }) + + for ((i = 0; i < 3; i++)); do + if ((${v1_parts[i]} < ${v2_parts[i]})); then + echo false + return 0 + elif ((${v1_parts[i]} > ${v2_parts[i]})); then + echo true + return 0 + fi + done + echo true +} + +check_sys() { + if [[ $(command -v yum) ]]; then + package_manager='yum' + elif [[ $(command -v dnf) ]]; then + package_manager='dnf' + elif [[ $(command -v apt) ]]; then + package_manager='apt' + elif [[ $(command -v apt-get) ]]; then + package_manager='apt-get' + fi + + if [[ -z "${package_manager}" ]]; then + echo_content red "暂不支持该系统" + exit 0 + fi + + if [[ -n $(find /etc -name "redhat-release") ]] || grep /dev/null) ]]; then + echo_content green "---> 安装Docker" + + # 关闭防火墙 + if [[ "${release}" == "centos" ]]; then + systemctl disable firewalld + elif [[ "${release}" == "debian" || "${release}" == "ubuntu" ]]; then + sudo ufw disable + fi + + # 时区 + timedatectl set-timezone Asia/Shanghai + + if [[ ${can_google} == 0 ]]; then + sh <(curl -sL https://get.docker.com) --mirror Aliyun + # 设置Docker国内源 + mkdir -p /etc/docker && + cat >/etc/docker/daemon.json </etc/docker/daemon.json </dev/null) ]]; then + echo_content skyBlue "---> Docker安装完成" + else + echo_content red "---> Docker安装失败" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Docker" + fi +} + +# 安装Caddy2 +install_caddy2() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> 安装Caddy2" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "请输入Caddy的端口(默认:80): " caddy_port + [[ -z "${caddy_port}" ]] && caddy_port=80 + read -r -p "请输入Caddy的转发端口(默认:8863): " caddy_remote_port + [[ -z "${caddy_remote_port}" ]] && caddy_remote_port=8863 + + echo_content yellow "提示:请确认域名已经解析到本机 否则可能安装失败" + while read -r -p "请输入你的域名(必填): " domain; do + if [[ -z "${domain}" ]]; then + echo_content red "域名不能为空" + else + break + fi + done + + read -r -p "请输入你的邮箱(可选): " your_email + + while read -r -p "请选择设置证书的方式?(1/自动申请和续签证书 2/手动设置证书路径 默认:1/自动申请和续签证书): " ssl_option; do + if [[ -z ${ssl_option} || ${ssl_option} == 1 ]]; then + while read -r -p "请选择申请证书的方式(1/acme 2/zerossl 默认:1/acme): " ssl_module_type; do + if [[ -z "${ssl_module_type}" || ${ssl_module_type} == 1 ]]; then + ssl_module="acme" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + break + elif [[ ${ssl_module_type} == 2 ]]; then + ssl_module="zerossl" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme.zerossl.com-v2-dv90/" + break + else + echo_content red "不可以输入除1和2之外的其他字符" + fi + done + + cat >${CADDY_CONFIG} <${CADDY_CONFIG} <${DOMAIN_FILE} < Caddy安装完成" + else + echo_content red "---> Caddy安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Caddy" + fi +} + +# 安装Nginx +install_nginx() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + echo_content green "---> 安装Nginx" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "请输入Nginx的端口(默认:80): " nginx_port + [[ -z "${nginx_port}" ]] && nginx_port=80 + read -r -p "请输入Nginx的转发端口(默认:8863): " nginx_remote_port + [[ -z "${nginx_remote_port}" ]] && nginx_remote_port=8863 + + while read -r -p "请选择Nginx是否开启https?(0/关闭 1/开启 默认:1/开启): " nginx_https; do + if [[ -z ${nginx_https} || ${nginx_https} == 1 ]]; then + install_custom_cert "custom_cert" + domain=$(cat "${DOMAIN_FILE}") + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + return 301 http://\$host:${nginx_remote_port}\$request_uri; +} + +server { + listen ${nginx_remote_port} ssl; + server_name localhost; + + #强制ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + #缓存有效期 + ssl_session_timeout 5m; + #安全链接可选的加密协议 + ssl_protocols TLSv1.3; + #加密算法 + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + #使用服务器端的首选算法 + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${nginx_remote_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + else + if [[ ${nginx_https} != 0 ]]; then + echo_content red "不可以输入除0和1之外的其他字符" + else + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + error_page 497 http://\$host:${nginx_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + fi + fi + done + + docker pull nginx:1.20-alpine && + docker run -d --name trojan-panel-nginx --restart always \ + --network=host \ + -v "${NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + nginx:1.20-alpine + + if [[ -n $(docker ps -q -f "name=^trojan-panel-nginx$" -f "status=running") ]]; then + echo_content skyBlue "---> Nginx安装完成" + else + echo_content red "---> Nginx安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Nginx" + fi +} + +# 设置伪装Web +install_reverse_proxy() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$|^trojan-panel-nginx$") ]]; then + echo_content green "---> 设置伪装Web" + + while :; do + echo_content yellow "1. 安装Caddy 2(推荐)" + echo_content yellow "2. 安装Nginx" + echo_content yellow "3. 不设置" + read -r -p "请选择(默认:1): " whether_install_reverse_proxy + [[ -z "${whether_install_reverse_proxy}" ]] && whether_install_reverse_proxy=1 + + case ${whether_install_reverse_proxy} in + 1) + install_caddy2 + break + ;; + 2) + install_nginx + break + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + done + + echo_content skyBlue "---> 伪装Web设置完成" + fi +} + +install_custom_cert() { + while read -r -p "请输入证书的.crt文件路径(必填): " crt_path; do + if [[ -z "${crt_path}" ]]; then + echo_content red "路径不能为空" + else + if [[ ! -f "${crt_path}" ]]; then + echo_content red "证书的.crt文件路径不存在" + else + cp "${crt_path}" "${CERT_PATH}$1.crt" + break + fi + fi + done + while read -r -p "请输入证书的.key文件路径(必填): " key_path; do + if [[ -z "${key_path}" ]]; then + echo_content red "路径不能为空" + else + if [[ ! -f "${key_path}" ]]; then + echo_content red "证书的.key文件路径不存在" + else + cp "${key_path}" "${CERT_PATH}$1.key" + break + fi + fi + done + cat >${DOMAIN_FILE} < 设置证书" + + while :; do + echo_content yellow "1. 安装Caddy 2(自动申请/续签证书)" + echo_content yellow "2. 手动设置证书路径" + echo_content yellow "3. 不设置" + read -r -p "请选择(默认:1): " whether_install_cert + [[ -z "${whether_install_cert}" ]] && whether_install_cert=1 + + case ${whether_install_cert} in + 1) + install_caddy2 + break + ;; + 2) + install_custom_cert "custom_cert" + break + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + done + + echo_content green "---> 证书设置完成" + fi +} + +# 安装MariaDB +install_mariadb() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> 安装MariaDB" + + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + if [[ "${mariadb_user}" == "root" ]]; then + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + else + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e MYSQL_USER="${mariadb_user}" \ + -e MYSQL_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + fi + + if [[ -n $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content skyBlue "---> MariaDB安装完成" + echo_content yellow "---> MariaDB root的数据库密码(请妥善保存): ${mariadb_pas}" + if [[ "${mariadb_user}" != "root" ]]; then + echo_content yellow "---> MariaDB ${mariadb_user}的数据库密码(请妥善保存): ${mariadb_pas}" + fi + else + echo_content red "---> MariaDB安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了MariaDB" + fi +} + +# 安装Redis +install_redis() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> 安装Redis" + + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker pull redis:6.2.7 && + docker run -d --name trojan-panel-redis --restart always \ + --network=host \ + redis:6.2.7 \ + redis-server --requirepass "${redis_pass}" --port "${redis_port}" + + if [[ -n $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content skyBlue "---> Redis安装完成" + echo_content yellow "---> Redis的数据库密码(请妥善保存): ${redis_pass}" + else + echo_content red "---> Redis安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Redis" + fi +} + +# 安装Trojan Panel前端 +install_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> 安装Trojan Panel前端" + + read -r -p "请输入Trojan Panel后端的IP地址(默认:本机后端): " trojan_panel_ip + [[ -z "${trojan_panel_ip}" ]] && trojan_panel_ip="127.0.0.1" + read -r -p "请输入Trojan Panel后端的服务端口(默认:8081): " trojan_panel_server_port + [[ -z "${trojan_panel_server_port}" ]] && trojan_panel_server_port=8081 + + read -r -p "请输入Trojan Panel前端端口(默认:8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + while read -r -p "请选择Trojan Panel前端是否开启https?(0/关闭 1/开启 默认:1/开启): " ui_https; do + if [[ -z ${ui_https} || ${ui_https} == 1 ]]; then + install_cert + domain=$(cat "${DOMAIN_FILE}") + # 配置Nginx + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port} ssl; + server_name localhost; + + #强制ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + #缓存有效期 + ssl_session_timeout 5m; + #安全链接可选的加密协议 + ssl_protocols TLSv1.3; + #加密算法 + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + #使用服务器端的首选算法 + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${trojan_panel_ui_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + else + if [[ ${ui_https} != 0 ]]; then + echo_content red "不可以输入除0和1之外的其他字符" + else + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port}; + server_name localhost; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + error_page 497 http://\$host:${trojan_panel_ui_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + fi + fi + done + + docker pull jonssonyan/trojan-panel-ui:2.1.5 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.5 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel前端安装完成" + + https_flag=$([[ -z ${ui_https} || ${ui_https} == 1 ]] && echo "https" || echo "http") + domain_or_ip=$([[ -z ${domain} || "${domain}" == "custom_cert" ]] && echo "ip" || echo "${domain}") + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel前端安装成功" + echo_content yellow "管理面板地址: ${https_flag}://${domain_or_ip}:${trojan_panel_ui_port}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel前端安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel前端" + fi +} + +# 安装Trojan Panel后端 +install_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> 安装Trojan Panel后端" + + read -r -p "请输入Trojan Panel后端的服务端口(默认:8081): " trojan_panel_port + [[ -z "${trojan_panel_port}" ]] && trojan_panel_port=8081 + + read -r -p "请输入数据库的IP地址(默认:本机数据库): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -e "create database if not exists trojan_panel_db;" &>/dev/null + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker pull jonssonyan/trojan-panel:2.1.4 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.1.4 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel后端安装完成" + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel后端安装成功" + echo_content yellow "MariaDB ${mariadb_user}的密码(请妥善保存): ${mariadb_pas}" + echo_content yellow "Redis的密码(请妥善保存): ${redis_pass}" + echo_content yellow "系统管理员 默认用户名: sysadmin 默认密码: 123456 请及时登陆管理面板修改密码" + echo_content yellow "Trojan Panel私钥和证书目录: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel后端安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel后端" + fi +} + +# 安装Trojan Panel内核 +install_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> 安装Trojan Panel内核" + + read -r -p "请输入Trojan Panel内核的服务端口(默认:8082): " trojan_panel_core_port + [[ -z "${trojan_panel_core_port}" ]] && trojan_panel_core_port=8082 + + read -r -p "请输入数据库的IP地址(默认:本机数据库): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + read -r -p "请输入数据库名称(默认:trojan_panel_db): " database + [[ -z "${database}" ]] && database="trojan_panel_db" + read -r -p "请输入数据库的用户表名称(默认:account): " account_table + [[ -z "${account_table}" ]] && account_table="account" + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + read -r -p "请输入API的端口(默认:8100): " grpc_port + [[ -z "${grpc_port}" ]] && grpc_port=8100 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.1.1 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.1.1 + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel内核安装完成" + else + echo_content red "---> Trojan Panel内核安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel内核" + fi +} + +# 更新Trojan Panel数据结构 +update_trojan_panel_database() { + echo_content skyBlue "---> 更新Trojan Panel数据结构" + + echo_content skyBlue "---> Trojan Panel数据结构更新完成" +} + +# 更新Trojan Panel内核数据结构 +update_trojan_panel_core_database() { + echo_content skyBlue "---> 更新Trojan Panel内核数据结构" + + echo_content skyBlue "---> Trojan Panel内核数据结构更新完成" +} + +# 更新Trojan Panel前端 +update_trojan_panel_ui() { + # 判断Trojan Panel前端是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content red "---> 请先安装Trojan Panel前端" + exit 0 + fi + + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + if [[ -z "${trojan_panel_ui_current_version}" || ! "${trojan_panel_ui_current_version}" =~ ^v.* ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel前端(trojan-panel-ui)当前版本为 ${trojan_panel_ui_current_version} 最新版本为 ${trojan_panel_ui_latest_version}" + + if [[ "${trojan_panel_ui_current_version}" != "${trojan_panel_ui_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel前端" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.5 + + docker pull jonssonyan/trojan-panel-ui:2.1.5 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.5 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel前端更新完成" + else + echo_content red "---> Trojan Panel前端更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel前端已经是最新版" + fi +} + +# 更新Trojan Panel后端 +update_trojan_panel() { + # 判断Trojan Panel后端是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content red "---> 请先安装Trojan Panel后端" + exit 0 + fi + + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + if [[ -z "${trojan_panel_current_version}" || ! "${trojan_panel_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_current_version}" "v2.1.4") ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel后端(trojan-panel)当前版本为 ${trojan_panel_current_version} 最新版本为 ${trojan_panel_latest_version}" + + if [[ "${trojan_panel_current_version}" != "${trojan_panel_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel后端" + + mariadb_ip=$(get_ini_value ${trojan_panel_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + trojan_panel_port=$(get_ini_value ${trojan_panel_config_path} server.port) + + update_trojan_panel_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.1.4 + + docker pull jonssonyan/trojan-panel:2.1.4 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.1.4 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel后端更新完成" + else + echo_content red "---> Trojan Panel后端更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel后端已经是最新版" + fi +} + +# 更新Trojan Panel内核 +update_trojan_panel_core() { + # 判断Trojan Panel内核是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content red "---> 请先安装Trojan Panel内核" + exit 0 + fi + + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + if [[ -z "${trojan_panel_core_current_version}" || ! "${trojan_panel_core_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_core_current_version}" "v2.1.1") ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel内核(trojan-panel-core)当前版本为 ${trojan_panel_core_current_version} 最新版本为 ${trojan_panel_core_latest_version}" + + if [[ "${trojan_panel_core_current_version}" != "${trojan_panel_core_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel内核" + + mariadb_ip=$(get_ini_value ${trojan_panel_core_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_core_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_core_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_core_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_core_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_core_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_core_config_path} redis.password) + grpc_port=$(get_ini_value ${trojan_panel_core_config_path} grpc.port) + trojan_panel_core_port=$(get_ini_value ${trojan_panel_core_config_path} server.port) + + update_trojan_panel_core_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.1.1 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.1.1 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.1.1 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel内核更新完成" + else + echo_content red "---> Trojan Panel内核更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel内核已经是最新版" + fi +} + +# 卸载Caddy2 +uninstall_caddy2() { + # 判断Caddy2是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> 卸载Caddy2" + + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_DATA} + + echo_content skyBlue "---> Caddy2卸载完成" + else + echo_content red "---> 请先安装Caddy2" + fi +} + +# 卸载Nginx +uninstall_nginx() { + # 判断Caddy2是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx") ]]; then + echo_content green "---> 卸载Nginx" + + docker rm -f trojan-panel-nginx && + rm -rf ${NGINX_DATA} + + echo_content skyBlue "---> Nginx卸载完成" + else + echo_content red "---> 请先安装Nginx" + fi +} + +# 卸载MariaDB +uninstall_mariadb() { + # 判断MariaDB是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> 卸载MariaDB" + + docker rm -f trojan-panel-mariadb && + rm -rf ${MARIA_DATA} + + echo_content skyBlue "---> MariaDB卸载完成" + else + echo_content red "---> 请先安装MariaDB" + fi +} + +# 卸载Redis +uninstall_redis() { + # 判断Redis是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> 卸载Redis" + + docker rm -f trojan-panel-redis && + rm -rf ${REDIS_DATA} + + echo_content skyBlue "---> Redis卸载完成" + else + echo_content red "---> 请先安装Redis" + fi +} + +# 卸载Trojan Panel前端 +uninstall_trojan_panel_ui() { + # 判断Trojan Panel前端是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> 卸载Trojan Panel前端" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.5 && + rm -rf ${TROJAN_PANEL_UI_DATA} + + echo_content skyBlue "---> Trojan Panel前端卸载完成" + else + echo_content red "---> 请先安装Trojan Panel前端" + fi +} + +# 卸载Trojan Panel后端 +uninstall_trojan_panel() { + # 判断Trojan Panel后端是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> 卸载Trojan Panel后端" + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.1.4 && + rm -rf ${TROJAN_PANEL_DATA} + + echo_content skyBlue "---> Trojan Panel后端卸载完成" + else + echo_content red "---> 请先安装Trojan Panel后端" + fi +} + +# 卸载Trojan Panel内核 +uninstall_trojan_panel_core() { + # 判断Trojan Panel内核是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> 卸载Trojan Panel内核" + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.1.1 && + rm -rf ${TROJAN_PANEL_CORE_DATA} + + echo_content skyBlue "---> Trojan Panel内核卸载完成" + else + echo_content red "---> 请先安装Trojan Panel内核" + fi +} + +# 卸载全部Trojan Panel相关的容器 +uninstall_all() { + echo_content green "---> 卸载全部Trojan Panel相关的容器" + + docker rm -f $(docker ps -a -q -f "name=^trojan-panel") + docker rmi -f $(docker images | grep "^jonssonyan/trojan-panel" | awk '{print $3}') + rm -rf ${TP_DATA} + + echo_content skyBlue "---> 卸载全部Trojan Panel相关的容器完成" +} + +# 修改Trojan Panel前端端口 +update_trojan_panel_ui_port() { + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content green "---> 修改Trojan Panel前端端口" + + trojan_panel_ui_port=$(grep 'listen.*ssl' ${UI_NGINX_CONFIG} | awk '{print $2}') + if [[ -z "${trojan_panel_ui_port}" ]]; then + ui_https=0 + trojan_panel_ui_port=$(grep -oP 'listen\s+\K\d+' ${UI_NGINX_CONFIG} | awk 'NR==1') + fi + if [[ -z "${trojan_panel_ui_port}" ]]; then + echo_content red "---> 未查询到Trojan Panel前端的端口" + exit 0 + fi + echo_content yellow "提示:Trojan Panel前端(trojan-panel-ui)当前端口为 ${trojan_panel_ui_port}" + + read -r -p "请输入Trojan Panel前端新端口(默认:8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + + if [[ ${ui_https} == 0 ]]; then + # http + sed -i "s/listen.*;/listen ${trojan_panel_ui_port};/g" ${UI_NGINX_CONFIG} && + sed -i "s/http:\/\/\$host:.*\$request_uri;/http:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + else + # https + sed -i "s/listen.*ssl;/listen ${trojan_panel_ui_port} ssl;/g" ${UI_NGINX_CONFIG} && + sed -i "s/https:\/\/\$host:.*\$request_uri;/https:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + fi + + if [[ "$?" == "0" ]]; then + echo_content skyBlue "---> Trojan Panel前端端口修改完成" + else + echo_content red "---> Trojan Panel前端端口修改失败" + fi + else + echo_content red "---> Trojan Panel前端未安装或运行异常,请修复或卸载重装后重试" + fi +} + +# 刷新Redis缓存 +redis_flush_all() { + # 判断Redis是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content red "---> 请先安装Redis" + exit 0 + fi + + if [[ -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis运行异常" + exit 0 + fi + + echo_content green "---> 刷新Redis缓存" + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + echo_content skyBlue "---> Redis缓存刷新完成" +} + +# 更换证书 +change_cert() { + domain_1=$(cat "${DOMAIN_FILE}") + + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_LOG}* && + echo "" >${CADDY_CONFIG} && + rm -rf ${WEB_PATH}* + fi + + rm -rf ${CERT_PATH}* && + echo "" >${DOMAIN_FILE} + + install_cert + + domain_2=$(cat "${DOMAIN_FILE}") + if [[ -n "${domain_2}" ]]; then + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${NGINX_CONFIG} && + docker restart trojan-panel-nginx + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${UI_NGINX_DATA} && + docker restart trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + find /tpdata/trojan-panel-core/bin/ -type f -exec sed -i "s/${domain_1}/${domain_2}/g" {} + && + sed -i "s/${domain_1}/${domain_2}/g" ${trojan_panel_core_config_path} && + docker restart trojan-panel-core + fi + fi +} + +# 故障检测 +failure_testing() { + echo_content green "---> 故障检测开始" + if [[ ! $(docker -v 2>/dev/null) ]]; then + echo_content red "---> Docker运行异常" + else + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + if [[ -z $(docker ps -q -f "name=^trojan-panel-caddy$" -f "status=running") ]]; then + echo_content red "---> Caddy2运行异常 错误日志如下:" + docker logs trojan-panel-caddy + fi + domain=$(cat "${DOMAIN_FILE}") + if [[ -z ${domain} || ! -d "${CERT_PATH}" || ! -f "${CERT_PATH}${domain}.crt" ]]; then + echo_content red "---> 证书申请异常,请尝试 1.换个子域名重新搭建 2.重启服务器将重新申请证书 3.重新搭建选择自定义证书选项 日志如下:" + if [[ -f ${CADDY_LOG}error.log ]]; then + tail -n 20 ${CADDY_LOG}error.log | grep error + else + docker logs trojan-panel-caddy + fi + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") && -z $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content red "---> MariaDB运行异常 日志如下:" + docker logs trojan-panel-mariadb + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") && -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis运行异常 日志如下:" + docker logs trojan-panel-redis + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -z $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel后端运行异常 日志如下:" + if [[ -f ${TROJAN_PANEL_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -z $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel前端运行异常 日志如下:" + docker logs trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -z $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel内核运行异常 日志如下:" + if [[ -f ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel-core + fi + fi + fi + echo_content green "---> 故障检测结束" +} + +log_query() { + while :; do + echo_content skyBlue "可以查询日志的应用如下:" + echo_content yellow "1. Trojan Panel后端" + echo_content yellow "2. Trojan Panel内核" + echo_content yellow "3. 退出" + read -r -p "请选择应用(默认:1): " select_log_query_type + [[ -z "${select_log_query_type}" ]] && select_log_query_type=1 + + case ${select_log_query_type} in + 1) + log_file_path=${TROJAN_PANEL_LOGS}trojan-panel.log + ;; + 2) + log_file_path=${TROJAN_PANEL_CORE_LOGS}trojan-panel-core.log + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + + read -r -p "请输入查询的行数(默认:20): " select_log_query_line_type + [[ -z "${select_log_query_line_type}" ]] && select_log_query_line_type=20 + + if [[ -f ${log_file_path} ]]; then + echo_content skyBlue "日志如下:" + tail -n ${select_log_query_line_type} ${log_file_path} + else + echo_content red "不存在日志文件" + fi + done +} + +version_query() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + echo_content yellow "Trojan Panel前端(trojan-panel-ui)当前版本为 ${trojan_panel_ui_current_version} 最新版本为 ${trojan_panel_ui_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + echo_content yellow "Trojan Panel后端(trojan-panel)当前版本为 ${trojan_panel_current_version} 最新版本为 ${trojan_panel_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + echo_content yellow "Trojan Panel内核(trojan-panel-core)当前版本为 ${trojan_panel_core_current_version} 最新版本为 ${trojan_panel_core_latest_version}" + fi +} + +main() { + cd "$HOME" || exit 0 + init_var + mkdir_tools + check_sys + depend_install + clear + echo_content red "\n==============================================================" + echo_content skyBlue "System Required: CentOS 7+/Ubuntu 18+/Debian 10+" + echo_content skyBlue "Version: v2.1.6" + echo_content skyBlue "Description: One click Install Trojan Panel server" + echo_content skyBlue "Author: jonssonyan " + echo_content skyBlue "Github: https://github.com/trojanpanel" + echo_content skyBlue "Docs: https://trojanpanel.github.io" + echo_content red "\n==============================================================" + echo_content yellow "1. 安装Trojan Panel前端" + echo_content yellow "2. 安装Trojan Panel后端" + echo_content yellow "3. 安装Trojan Panel内核" + echo_content yellow "4. 安装Caddy2" + echo_content yellow "5. 安装Nginx" + echo_content yellow "6. 安装MariaDB" + echo_content yellow "7. 安装Redis" + echo_content green "\n==============================================================" + echo_content yellow "8. 更新Trojan Panel前端" + echo_content yellow "9. 更新Trojan Panel后端" + echo_content yellow "10. 更新Trojan Panel内核" + echo_content green "\n==============================================================" + echo_content yellow "11. 卸载Trojan Panel前端" + echo_content yellow "12. 卸载Trojan Panel后端" + echo_content yellow "13. 卸载Trojan Panel内核" + echo_content yellow "14. 卸载Caddy2" + echo_content yellow "15. 卸载Nginx" + echo_content yellow "16. 卸载MariaDB" + echo_content yellow "17. 卸载Redis" + echo_content yellow "18. 卸载全部Trojan Panel相关的应用" + echo_content green "\n==============================================================" + echo_content yellow "19. 修改Trojan Panel前端端口" + echo_content yellow "20. 刷新Redis缓存" + echo_content yellow "21. 更换证书" + echo_content green "\n==============================================================" + echo_content yellow "22. 故障检测" + echo_content yellow "23. 日志查询" + echo_content yellow "24. 版本查询" + read -r -p "请选择:" selectInstall_type + case ${selectInstall_type} in + 1) + install_docker + install_cert + install_trojan_panel_ui + ;; + 2) + install_docker + install_mariadb + install_redis + install_trojan_panel + ;; + 3) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_core + ;; + 4) + install_docker + install_caddy2 + ;; + 5) + install_docker + install_nginx + ;; + 6) + install_docker + install_mariadb + ;; + 7) + install_docker + install_redis + ;; + 8) + update_trojan_panel_ui + ;; + 9) + update_trojan_panel + ;; + 10) + update_trojan_panel_core + ;; + 11) + uninstall_trojan_panel_ui + ;; + 12) + uninstall_trojan_panel + ;; + 13) + uninstall_trojan_panel_core + ;; + 14) + uninstall_caddy2 + ;; + 15) + uninstall_nginx + ;; + 16) + uninstall_mariadb + ;; + 17) + uninstall_redis + ;; + 18) + uninstall_all + ;; + 19) + update_trojan_panel_ui_port + ;; + 20) + redis_flush_all + ;; + 21) + change_cert + ;; + 22) + failure_testing + ;; + 23) + log_query + ;; + 24) + version_query + ;; + *) + echo_content red "没有这个选项" + ;; + esac +} + +main diff --git a/lib/archive/install_script_v2.1.7.sh b/lib/archive/install_script_v2.1.7.sh new file mode 100644 index 0000000..766ab5d --- /dev/null +++ b/lib/archive/install_script_v2.1.7.sh @@ -0,0 +1,1974 @@ +#!/usr/bin/env bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +# System Required: CentOS 7+/Ubuntu 18+/Debian 10+ +# Version: v2.1.7 +# Description: One click Install Trojan Panel server +# Author: jonssonyan +# Github: https://github.com/trojanpanel/install-script + +init_var() { + ECHO_TYPE="echo -e" + + package_manager="" + release="" + get_arch="" + can_google=0 + + # Docker + DOCKER_MIRROR='"https://hub-mirror.c.163.com","https://ccr.ccs.tencentyun.com","https://mirror.baidubce.com","https://dockerproxy.com"' + + # 项目目录 + TP_DATA="/tpdata/" + + STATIC_HTML="https://github.com/trojanpanel/install-script/releases/download/v1.0/html.tar.gz" + + # web + WEB_PATH="/tpdata/web/" + + # cert + CERT_PATH="/tpdata/cert/" + DOMAIN_FILE="/tpdata/domain.lock" + domain="" + crt_path="" + key_path="" + + # Caddy + CADDY_DATA="/tpdata/caddy/" + CADDY_CONFIG="${CADDY_DATA}config.json" + CADDY_LOG="${CADDY_DATA}logs/" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + caddy_port=80 + caddy_remote_port=8863 + your_email="" + ssl_option=1 + ssl_module_type=1 + ssl_module="acme" + + # Nginx + NGINX_DATA="/tpdata/nginx/" + NGINX_CONFIG="${NGINX_DATA}default.conf" + nginx_port=80 + nginx_remote_port=8863 + nginx_https=1 + + # MariaDB + MARIA_DATA="/tpdata/mariadb/" + mariadb_ip="127.0.0.1" + mariadb_port=9507 + mariadb_user="root" + mariadb_pas="" + + #Redis + REDIS_DATA="/tpdata/redis/" + redis_host="127.0.0.1" + redis_port=6378 + redis_pass="" + + # Trojan Panel前端 + TROJAN_PANEL_UI_DATA="/tpdata/trojan-panel-ui/" + # Nginx + UI_NGINX_DATA="${TROJAN_PANEL_UI_DATA}nginx/" + UI_NGINX_CONFIG="${UI_NGINX_DATA}default.conf" + trojan_panel_ui_port=8888 + ui_https=1 + trojan_panel_ip="127.0.0.1" + trojan_panel_server_port=8081 + + # Trojan Panel后端 + TROJAN_PANEL_DATA="/tpdata/trojan-panel/" + TROJAN_PANEL_WEBFILE="${TROJAN_PANEL_DATA}webfile/" + TROJAN_PANEL_LOGS="${TROJAN_PANEL_DATA}logs/" + TROJAN_PANEL_CONFIG="${TROJAN_PANEL_DATA}config/" + trojan_panel_config_path="${TROJAN_PANEL_DATA}config/config.ini" + trojan_panel_port=8081 + + # Trojan Panel内核 + TROJAN_PANEL_CORE_DATA="/tpdata/trojan-panel-core/" + TROJAN_PANEL_CORE_LOGS="${TROJAN_PANEL_CORE_DATA}logs/" + TROJAN_PANEL_CORE_CONFIG="${TROJAN_PANEL_CORE_DATA}config/" + trojan_panel_core_config_path="${TROJAN_PANEL_CORE_DATA}config/config.ini" + database="trojan_panel_db" + account_table="account" + grpc_port=8100 + trojan_panel_core_port=8082 + + # Update + trojan_panel_ui_current_version="" + trojan_panel_ui_latest_version="v2.1.5" + trojan_panel_current_version="" + trojan_panel_latest_version="v2.1.4" + trojan_panel_core_current_version="" + trojan_panel_core_latest_version="v2.1.1" + + # SQL +} + +echo_content() { + case $1 in + "red") + ${ECHO_TYPE} "\033[31m$2\033[0m" + ;; + "green") + ${ECHO_TYPE} "\033[32m$2\033[0m" + ;; + "yellow") + ${ECHO_TYPE} "\033[33m$2\033[0m" + ;; + "blue") + ${ECHO_TYPE} "\033[34m$2\033[0m" + ;; + "purple") + ${ECHO_TYPE} "\033[35m$2\033[0m" + ;; + "skyBlue") + ${ECHO_TYPE} "\033[36m$2\033[0m" + ;; + "white") + ${ECHO_TYPE} "\033[37m$2\033[0m" + ;; + esac +} + +mkdir_tools() { + # 项目目录 + mkdir -p ${TP_DATA} + + # web + mkdir -p ${WEB_PATH} + + # cert + mkdir -p ${CERT_PATH} + touch ${DOMAIN_FILE} + + # Caddy + mkdir -p ${CADDY_DATA} + touch ${CADDY_CONFIG} + mkdir -p ${CADDY_LOG} + + # Nginx + mkdir -p ${NGINX_DATA} + touch ${NGINX_CONFIG} + + # MariaDB + mkdir -p ${MARIA_DATA} + + # Redis + mkdir -p ${REDIS_DATA} + + # Trojan Panel前端 + mkdir -p ${TROJAN_PANEL_UI_DATA} + # # Nginx + mkdir -p ${UI_NGINX_DATA} + touch ${UI_NGINX_CONFIG} + + # Trojan Panel后端 + mkdir -p ${TROJAN_PANEL_DATA} + mkdir -p ${TROJAN_PANEL_LOGS} + + # Trojan Panel内核 + mkdir -p ${TROJAN_PANEL_CORE_DATA} + mkdir -p ${TROJAN_PANEL_CORE_LOGS} +} + +can_connect() { + ping -c2 -i0.3 -W1 "$1" &>/dev/null + if [[ "$?" == "0" ]]; then + return 0 + else + return 1 + fi +} + +get_ini_value() { + local config_file="$1" + local key="$2" + local section="" + local section_flag=0 + + # 拆分组名和键名 + IFS='.' read -r group_name key_name <<<"$key" + + while IFS='=' read -r name val; do + # 处理节名称 + if [[ $name =~ ^\[(.*)\]$ ]]; then + section="${BASH_REMATCH[1]}" + if [[ $section == $group_name ]]; then + section_flag=1 + else + section_flag=0 + fi + continue + fi + + # 提取配置项的值 + if [[ $section_flag -eq 1 && $name == $key_name ]]; then + echo "$val" + return + fi + done <"$config_file" +} + +# Version number comparison greater than or equal to +version_ge() { + local v1=${1#v} + local v2=${2#v} + + local v1_parts=(${v1//./ }) + local v2_parts=(${v2//./ }) + + for ((i = 0; i < 3; i++)); do + if ((${v1_parts[i]} < ${v2_parts[i]})); then + echo false + return 0 + elif ((${v1_parts[i]} > ${v2_parts[i]})); then + echo true + return 0 + fi + done + echo true +} + +check_sys() { + if [[ $(command -v yum) ]]; then + package_manager='yum' + elif [[ $(command -v dnf) ]]; then + package_manager='dnf' + elif [[ $(command -v apt) ]]; then + package_manager='apt' + elif [[ $(command -v apt-get) ]]; then + package_manager='apt-get' + fi + + if [[ -z "${package_manager}" ]]; then + echo_content red "暂不支持该系统" + exit 0 + fi + + if [[ -n $(find /etc -name "redhat-release") ]] || grep /dev/null) ]]; then + echo_content green "---> 安装Docker" + + # 关闭防火墙 + if [[ "${release}" == "centos" ]]; then + systemctl disable firewalld + elif [[ "${release}" == "debian" || "${release}" == "ubuntu" ]]; then + sudo ufw disable + fi + + # 时区 + timedatectl set-timezone Asia/Shanghai + + if [[ ${can_google} == 0 ]]; then + sh <(curl -sL https://get.docker.com) --mirror Aliyun + # 设置Docker国内源 + mkdir -p /etc/docker && + cat >/etc/docker/daemon.json </etc/docker/daemon.json </dev/null) ]]; then + echo_content skyBlue "---> Docker安装完成" + else + echo_content red "---> Docker安装失败" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Docker" + fi +} + +# 安装Caddy2 +install_caddy2() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> 安装Caddy2" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "请输入Caddy的端口(默认:80): " caddy_port + [[ -z "${caddy_port}" ]] && caddy_port=80 + read -r -p "请输入Caddy的转发端口(默认:8863): " caddy_remote_port + [[ -z "${caddy_remote_port}" ]] && caddy_remote_port=8863 + + echo_content yellow "提示:请确认域名已经解析到本机 否则可能安装失败" + while read -r -p "请输入你的域名(必填): " domain; do + if [[ -z "${domain}" ]]; then + echo_content red "域名不能为空" + else + break + fi + done + + read -r -p "请输入你的邮箱(可选): " your_email + + while read -r -p "请选择设置证书的方式?(1/自动申请和续签证书 2/手动设置证书路径 默认:1/自动申请和续签证书): " ssl_option; do + if [[ -z ${ssl_option} || ${ssl_option} == 1 ]]; then + while read -r -p "请选择申请证书的方式(1/acme 2/zerossl 默认:1/acme): " ssl_module_type; do + if [[ -z "${ssl_module_type}" || ${ssl_module_type} == 1 ]]; then + ssl_module="acme" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + break + elif [[ ${ssl_module_type} == 2 ]]; then + ssl_module="zerossl" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme.zerossl.com-v2-dv90/" + break + else + echo_content red "不可以输入除1和2之外的其他字符" + fi + done + + cat >${CADDY_CONFIG} <${CADDY_CONFIG} <${DOMAIN_FILE} < Caddy安装完成" + else + echo_content red "---> Caddy安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Caddy" + fi +} + +# 安装Nginx +install_nginx() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + echo_content green "---> 安装Nginx" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "请输入Nginx的端口(默认:80): " nginx_port + [[ -z "${nginx_port}" ]] && nginx_port=80 + read -r -p "请输入Nginx的转发端口(默认:8863): " nginx_remote_port + [[ -z "${nginx_remote_port}" ]] && nginx_remote_port=8863 + + while read -r -p "请选择Nginx是否开启https?(0/关闭 1/开启 默认:1/开启): " nginx_https; do + if [[ -z ${nginx_https} || ${nginx_https} == 1 ]]; then + install_custom_cert "custom_cert" + domain=$(cat "${DOMAIN_FILE}") + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + return 301 http://\$host:${nginx_remote_port}\$request_uri; +} + +server { + listen ${nginx_remote_port} ssl; + server_name localhost; + + #强制ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + #缓存有效期 + ssl_session_timeout 5m; + #安全链接可选的加密协议 + ssl_protocols TLSv1.3; + #加密算法 + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + #使用服务器端的首选算法 + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${nginx_remote_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + else + if [[ ${nginx_https} != 0 ]]; then + echo_content red "不可以输入除0和1之外的其他字符" + else + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + error_page 497 http://\$host:${nginx_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + fi + fi + done + + docker pull nginx:1.20-alpine && + docker run -d --name trojan-panel-nginx --restart always \ + --network=host \ + -v "${NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + nginx:1.20-alpine + + if [[ -n $(docker ps -q -f "name=^trojan-panel-nginx$" -f "status=running") ]]; then + echo_content skyBlue "---> Nginx安装完成" + else + echo_content red "---> Nginx安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Nginx" + fi +} + +# 设置伪装Web +install_reverse_proxy() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$|^trojan-panel-nginx$") ]]; then + echo_content green "---> 设置伪装Web" + + while :; do + echo_content yellow "1. 安装Caddy 2(推荐)" + echo_content yellow "2. 安装Nginx" + echo_content yellow "3. 不设置" + read -r -p "请选择(默认:1): " whether_install_reverse_proxy + [[ -z "${whether_install_reverse_proxy}" ]] && whether_install_reverse_proxy=1 + + case ${whether_install_reverse_proxy} in + 1) + install_caddy2 + break + ;; + 2) + install_nginx + break + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + done + + echo_content skyBlue "---> 伪装Web设置完成" + fi +} + +install_custom_cert() { + while read -r -p "请输入证书的.crt文件路径(必填): " crt_path; do + if [[ -z "${crt_path}" ]]; then + echo_content red "路径不能为空" + else + if [[ ! -f "${crt_path}" ]]; then + echo_content red "证书的.crt文件路径不存在" + else + cp "${crt_path}" "${CERT_PATH}$1.crt" + break + fi + fi + done + while read -r -p "请输入证书的.key文件路径(必填): " key_path; do + if [[ -z "${key_path}" ]]; then + echo_content red "路径不能为空" + else + if [[ ! -f "${key_path}" ]]; then + echo_content red "证书的.key文件路径不存在" + else + cp "${key_path}" "${CERT_PATH}$1.key" + break + fi + fi + done + cat >${DOMAIN_FILE} < 设置证书" + + while :; do + echo_content yellow "1. 安装Caddy 2(自动申请/续签证书)" + echo_content yellow "2. 手动设置证书路径" + echo_content yellow "3. 不设置" + read -r -p "请选择(默认:1): " whether_install_cert + [[ -z "${whether_install_cert}" ]] && whether_install_cert=1 + + case ${whether_install_cert} in + 1) + install_caddy2 + break + ;; + 2) + install_custom_cert "custom_cert" + break + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + done + + echo_content green "---> 证书设置完成" + fi +} + +# 安装MariaDB +install_mariadb() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> 安装MariaDB" + + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + if [[ "${mariadb_user}" == "root" ]]; then + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + else + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e MYSQL_USER="${mariadb_user}" \ + -e MYSQL_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + fi + + if [[ -n $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content skyBlue "---> MariaDB安装完成" + echo_content yellow "---> MariaDB root的数据库密码(请妥善保存): ${mariadb_pas}" + if [[ "${mariadb_user}" != "root" ]]; then + echo_content yellow "---> MariaDB ${mariadb_user}的数据库密码(请妥善保存): ${mariadb_pas}" + fi + else + echo_content red "---> MariaDB安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了MariaDB" + fi +} + +# 安装Redis +install_redis() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> 安装Redis" + + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker pull redis:6.2.7 && + docker run -d --name trojan-panel-redis --restart always \ + --network=host \ + redis:6.2.7 \ + redis-server --requirepass "${redis_pass}" --port "${redis_port}" + + if [[ -n $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content skyBlue "---> Redis安装完成" + echo_content yellow "---> Redis的数据库密码(请妥善保存): ${redis_pass}" + else + echo_content red "---> Redis安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Redis" + fi +} + +# 安装Trojan Panel前端 +install_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> 安装Trojan Panel前端" + + read -r -p "请输入Trojan Panel后端的IP地址(默认:本机后端): " trojan_panel_ip + [[ -z "${trojan_panel_ip}" ]] && trojan_panel_ip="127.0.0.1" + read -r -p "请输入Trojan Panel后端的服务端口(默认:8081): " trojan_panel_server_port + [[ -z "${trojan_panel_server_port}" ]] && trojan_panel_server_port=8081 + + read -r -p "请输入Trojan Panel前端端口(默认:8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + while read -r -p "请选择Trojan Panel前端是否开启https?(0/关闭 1/开启 默认:1/开启): " ui_https; do + if [[ -z ${ui_https} || ${ui_https} == 1 ]]; then + install_cert + domain=$(cat "${DOMAIN_FILE}") + # 配置Nginx + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port} ssl; + server_name localhost; + + #强制ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + #缓存有效期 + ssl_session_timeout 5m; + #安全链接可选的加密协议 + ssl_protocols TLSv1.3; + #加密算法 + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + #使用服务器端的首选算法 + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${trojan_panel_ui_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + else + if [[ ${ui_https} != 0 ]]; then + echo_content red "不可以输入除0和1之外的其他字符" + else + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port}; + server_name localhost; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + error_page 497 http://\$host:${trojan_panel_ui_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + fi + fi + done + + docker pull jonssonyan/trojan-panel-ui:2.1.5 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.5 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel前端安装完成" + + https_flag=$([[ -z ${ui_https} || ${ui_https} == 1 ]] && echo "https" || echo "http") + domain_or_ip=$([[ -z ${domain} || "${domain}" == "custom_cert" ]] && echo "ip" || echo "${domain}") + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel前端安装成功" + echo_content yellow "管理面板地址: ${https_flag}://${domain_or_ip}:${trojan_panel_ui_port}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel前端安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel前端" + fi +} + +# 安装Trojan Panel后端 +install_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> 安装Trojan Panel后端" + + read -r -p "请输入Trojan Panel后端的服务端口(默认:8081): " trojan_panel_port + [[ -z "${trojan_panel_port}" ]] && trojan_panel_port=8081 + + read -r -p "请输入数据库的IP地址(默认:本机数据库): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -e "create database if not exists trojan_panel_db;" &>/dev/null + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker pull jonssonyan/trojan-panel:2.1.4 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.1.4 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel后端安装完成" + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel后端安装成功" + echo_content yellow "MariaDB ${mariadb_user}的密码(请妥善保存): ${mariadb_pas}" + echo_content yellow "Redis的密码(请妥善保存): ${redis_pass}" + echo_content yellow "系统管理员 默认用户名: sysadmin 默认密码: 123456 请及时登陆管理面板修改密码" + echo_content yellow "Trojan Panel私钥和证书目录: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel后端安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel后端" + fi +} + +# 安装Trojan Panel内核 +install_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> 安装Trojan Panel内核" + + read -r -p "请输入Trojan Panel内核的服务端口(默认:8082): " trojan_panel_core_port + [[ -z "${trojan_panel_core_port}" ]] && trojan_panel_core_port=8082 + + read -r -p "请输入数据库的IP地址(默认:本机数据库): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + read -r -p "请输入数据库名称(默认:trojan_panel_db): " database + [[ -z "${database}" ]] && database="trojan_panel_db" + read -r -p "请输入数据库的用户表名称(默认:account): " account_table + [[ -z "${account_table}" ]] && account_table="account" + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + read -r -p "请输入API的端口(默认:8100): " grpc_port + [[ -z "${grpc_port}" ]] && grpc_port=8100 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.1.1 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.1.1 + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel内核安装完成" + else + echo_content red "---> Trojan Panel内核安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel内核" + fi +} + +# 更新Trojan Panel数据结构 +update_trojan_panel_database() { + echo_content skyBlue "---> 更新Trojan Panel数据结构" + + echo_content skyBlue "---> Trojan Panel数据结构更新完成" +} + +# 更新Trojan Panel内核数据结构 +update_trojan_panel_core_database() { + echo_content skyBlue "---> 更新Trojan Panel内核数据结构" + + echo_content skyBlue "---> Trojan Panel内核数据结构更新完成" +} + +# 更新Trojan Panel前端 +update_trojan_panel_ui() { + # 判断Trojan Panel前端是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content red "---> 请先安装Trojan Panel前端" + exit 0 + fi + + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + if [[ -z "${trojan_panel_ui_current_version}" || ! "${trojan_panel_ui_current_version}" =~ ^v.* ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel前端(trojan-panel-ui)当前版本为 ${trojan_panel_ui_current_version} 最新版本为 ${trojan_panel_ui_latest_version}" + + if [[ "${trojan_panel_ui_current_version}" != "${trojan_panel_ui_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel前端" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.5 + + docker pull jonssonyan/trojan-panel-ui:2.1.5 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.5 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel前端更新完成" + else + echo_content red "---> Trojan Panel前端更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel前端已经是最新版" + fi +} + +# 更新Trojan Panel后端 +update_trojan_panel() { + # 判断Trojan Panel后端是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content red "---> 请先安装Trojan Panel后端" + exit 0 + fi + + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + if [[ -z "${trojan_panel_current_version}" || ! "${trojan_panel_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_current_version}" "v2.1.4") ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel后端(trojan-panel)当前版本为 ${trojan_panel_current_version} 最新版本为 ${trojan_panel_latest_version}" + + if [[ "${trojan_panel_current_version}" != "${trojan_panel_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel后端" + + mariadb_ip=$(get_ini_value ${trojan_panel_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + trojan_panel_port=$(get_ini_value ${trojan_panel_config_path} server.port) + + update_trojan_panel_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.1.4 + + docker pull jonssonyan/trojan-panel:2.1.4 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.1.4 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel后端更新完成" + else + echo_content red "---> Trojan Panel后端更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel后端已经是最新版" + fi +} + +# 更新Trojan Panel内核 +update_trojan_panel_core() { + # 判断Trojan Panel内核是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content red "---> 请先安装Trojan Panel内核" + exit 0 + fi + + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + if [[ -z "${trojan_panel_core_current_version}" || ! "${trojan_panel_core_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_core_current_version}" "v2.1.1") ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel内核(trojan-panel-core)当前版本为 ${trojan_panel_core_current_version} 最新版本为 ${trojan_panel_core_latest_version}" + + if [[ "${trojan_panel_core_current_version}" != "${trojan_panel_core_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel内核" + + mariadb_ip=$(get_ini_value ${trojan_panel_core_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_core_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_core_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_core_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_core_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_core_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_core_config_path} redis.password) + grpc_port=$(get_ini_value ${trojan_panel_core_config_path} grpc.port) + trojan_panel_core_port=$(get_ini_value ${trojan_panel_core_config_path} server.port) + + update_trojan_panel_core_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.1.1 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.1.1 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.1.1 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel内核更新完成" + else + echo_content red "---> Trojan Panel内核更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel内核已经是最新版" + fi +} + +# 卸载Caddy2 +uninstall_caddy2() { + # 判断Caddy2是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> 卸载Caddy2" + + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_DATA} + + echo_content skyBlue "---> Caddy2卸载完成" + else + echo_content red "---> 请先安装Caddy2" + fi +} + +# 卸载Nginx +uninstall_nginx() { + # 判断Caddy2是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx") ]]; then + echo_content green "---> 卸载Nginx" + + docker rm -f trojan-panel-nginx && + rm -rf ${NGINX_DATA} + + echo_content skyBlue "---> Nginx卸载完成" + else + echo_content red "---> 请先安装Nginx" + fi +} + +# 卸载MariaDB +uninstall_mariadb() { + # 判断MariaDB是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> 卸载MariaDB" + + docker rm -f trojan-panel-mariadb && + rm -rf ${MARIA_DATA} + + echo_content skyBlue "---> MariaDB卸载完成" + else + echo_content red "---> 请先安装MariaDB" + fi +} + +# 卸载Redis +uninstall_redis() { + # 判断Redis是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> 卸载Redis" + + docker rm -f trojan-panel-redis && + rm -rf ${REDIS_DATA} + + echo_content skyBlue "---> Redis卸载完成" + else + echo_content red "---> 请先安装Redis" + fi +} + +# 卸载Trojan Panel前端 +uninstall_trojan_panel_ui() { + # 判断Trojan Panel前端是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> 卸载Trojan Panel前端" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.5 && + rm -rf ${TROJAN_PANEL_UI_DATA} + + echo_content skyBlue "---> Trojan Panel前端卸载完成" + else + echo_content red "---> 请先安装Trojan Panel前端" + fi +} + +# 卸载Trojan Panel后端 +uninstall_trojan_panel() { + # 判断Trojan Panel后端是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> 卸载Trojan Panel后端" + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.1.4 && + rm -rf ${TROJAN_PANEL_DATA} + + echo_content skyBlue "---> Trojan Panel后端卸载完成" + else + echo_content red "---> 请先安装Trojan Panel后端" + fi +} + +# 卸载Trojan Panel内核 +uninstall_trojan_panel_core() { + # 判断Trojan Panel内核是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> 卸载Trojan Panel内核" + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.1.1 && + rm -rf ${TROJAN_PANEL_CORE_DATA} + + echo_content skyBlue "---> Trojan Panel内核卸载完成" + else + echo_content red "---> 请先安装Trojan Panel内核" + fi +} + +# 卸载全部Trojan Panel相关的容器 +uninstall_all() { + echo_content green "---> 卸载全部Trojan Panel相关的容器" + + docker rm -f $(docker ps -a -q -f "name=^trojan-panel") + docker rmi -f $(docker images | grep "^jonssonyan/trojan-panel" | awk '{print $3}') + rm -rf ${TP_DATA} + + echo_content skyBlue "---> 卸载全部Trojan Panel相关的容器完成" +} + +# 修改Trojan Panel前端端口 +update_trojan_panel_ui_port() { + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content green "---> 修改Trojan Panel前端端口" + + trojan_panel_ui_port=$(grep 'listen.*ssl' ${UI_NGINX_CONFIG} | awk '{print $2}') + if [[ -z "${trojan_panel_ui_port}" ]]; then + ui_https=0 + trojan_panel_ui_port=$(grep -oP 'listen\s+\K\d+' ${UI_NGINX_CONFIG} | awk 'NR==1') + fi + if [[ -z "${trojan_panel_ui_port}" ]]; then + echo_content red "---> 未查询到Trojan Panel前端的端口" + exit 0 + fi + echo_content yellow "提示:Trojan Panel前端(trojan-panel-ui)当前端口为 ${trojan_panel_ui_port}" + + read -r -p "请输入Trojan Panel前端新端口(默认:8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + + if [[ ${ui_https} == 0 ]]; then + # http + sed -i "s/listen.*;/listen ${trojan_panel_ui_port};/g" ${UI_NGINX_CONFIG} && + sed -i "s/http:\/\/\$host:.*\$request_uri;/http:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + else + # https + sed -i "s/listen.*ssl;/listen ${trojan_panel_ui_port} ssl;/g" ${UI_NGINX_CONFIG} && + sed -i "s/https:\/\/\$host:.*\$request_uri;/https:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + fi + + if [[ "$?" == "0" ]]; then + echo_content skyBlue "---> Trojan Panel前端端口修改完成" + else + echo_content red "---> Trojan Panel前端端口修改失败" + fi + else + echo_content red "---> Trojan Panel前端未安装或运行异常,请修复或卸载重装后重试" + fi +} + +# 刷新Redis缓存 +redis_flush_all() { + # 判断Redis是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content red "---> 请先安装Redis" + exit 0 + fi + + if [[ -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis运行异常" + exit 0 + fi + + echo_content green "---> 刷新Redis缓存" + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + echo_content skyBlue "---> Redis缓存刷新完成" +} + +# 更换证书 +change_cert() { + domain_1=$(cat "${DOMAIN_FILE}") + + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_LOG}* && + echo "" >${CADDY_CONFIG} && + rm -rf ${WEB_PATH}* + fi + + rm -rf ${CERT_PATH}* && + echo "" >${DOMAIN_FILE} + + install_cert + + domain_2=$(cat "${DOMAIN_FILE}") + if [[ -n "${domain_1}" && -n "${domain_2}" ]]; then + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${NGINX_CONFIG} && + docker restart trojan-panel-nginx + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${UI_NGINX_DATA} && + docker restart trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + find /tpdata/trojan-panel-core/bin/ -type f -exec sed -i "s/${domain_1}/${domain_2}/g" {} + && + sed -i "s/${domain_1}/${domain_2}/g" ${trojan_panel_core_config_path} && + docker restart trojan-panel-core + fi + fi +} + +forget_pass() { + while :; do + echo_content yellow "1. 查询MariaDB密码" + echo_content yellow "2. 查询Redis密码" + echo_content yellow "3. 重设管理面板系统管理员用户名和密码" + echo_content yellow "4. 退出" + read -r -p "请选择(默认:4): " forget_pass_option + [[ -z "${forget_pass_option}" ]] && forget_pass_option=4 + case ${forget_pass_option} in + 1) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + echo_content red "\n==============================================================" + echo_content yellow "MariaDB ${mariadb_user}的密码(请妥善保存): ${mariadb_pas}" + echo_content red "\n==============================================================" + else + echo_content red "---> 请先安装Trojan Panel后端" + fi + ;; + 2) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + echo_content red "\n==============================================================" + echo_content yellow "Redis的密码(请妥善保存): ${redis_pass}" + echo_content red "\n==============================================================" + else + echo_content red "---> 请先安装Trojan Panel后端" + fi + ;; + 3) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + read -r -p "请输入数据库的IP地址(默认:本机数据库): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "update account set username = 'sysadmin',pass = 'tFjD2X1F6i9FfWp2GDU5Vbi1conuaChDKIYbw9zMFrqvMoSz',hash='4366294571b8b267d9cf15b56660f0a70659568a86fc270a52fdc9e5' where id = 1 limit 1" + if [[ "$?" == "0" ]]; then + echo_content red "\n==============================================================" + echo_content yellow "系统管理员 默认用户名: sysadmin 默认密码: 123456 请及时登陆管理面板修改密码" + echo_content red "\n==============================================================" + else + echo_content red "管理面板系统管理员用户名和密码重设失败" + fi + else + echo_content red "---> 请先安装MariaDB" + fi + ;; + 4) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + done +} + +# 故障检测 +failure_testing() { + echo_content green "---> 故障检测开始" + if [[ ! $(docker -v 2>/dev/null) ]]; then + echo_content red "---> Docker运行异常" + else + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + if [[ -z $(docker ps -q -f "name=^trojan-panel-caddy$" -f "status=running") ]]; then + echo_content red "---> Caddy2运行异常 错误日志如下:" + docker logs trojan-panel-caddy + fi + domain=$(cat "${DOMAIN_FILE}") + if [[ -z ${domain} || ! -d "${CERT_PATH}" || ! -f "${CERT_PATH}${domain}.crt" ]]; then + echo_content red "---> 证书申请异常,请尝试 1.换个子域名重新搭建 2.重启服务器将重新申请证书 3.重新搭建选择自定义证书选项 日志如下:" + if [[ -f ${CADDY_LOG}error.log ]]; then + tail -n 20 ${CADDY_LOG}error.log | grep error + else + docker logs trojan-panel-caddy + fi + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") && -z $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content red "---> MariaDB运行异常 日志如下:" + docker logs trojan-panel-mariadb + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") && -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis运行异常 日志如下:" + docker logs trojan-panel-redis + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -z $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel后端运行异常 日志如下:" + if [[ -f ${TROJAN_PANEL_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -z $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel前端运行异常 日志如下:" + docker logs trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -z $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel内核运行异常 日志如下:" + if [[ -f ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel-core + fi + fi + fi + echo_content green "---> 故障检测结束" +} + +log_query() { + while :; do + echo_content skyBlue "可以查询日志的应用如下:" + echo_content yellow "1. Trojan Panel后端" + echo_content yellow "2. Trojan Panel内核" + echo_content yellow "3. 退出" + read -r -p "请选择应用(默认:1): " select_log_query_type + [[ -z "${select_log_query_type}" ]] && select_log_query_type=1 + + case ${select_log_query_type} in + 1) + log_file_path=${TROJAN_PANEL_LOGS}trojan-panel.log + ;; + 2) + log_file_path=${TROJAN_PANEL_CORE_LOGS}trojan-panel-core.log + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + + read -r -p "请输入查询的行数(默认:20): " select_log_query_line_type + [[ -z "${select_log_query_line_type}" ]] && select_log_query_line_type=20 + + if [[ -f ${log_file_path} ]]; then + echo_content skyBlue "日志如下:" + tail -n ${select_log_query_line_type} ${log_file_path} + else + echo_content red "不存在日志文件" + fi + done +} + +version_query() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + echo_content yellow "Trojan Panel前端(trojan-panel-ui)当前版本为 ${trojan_panel_ui_current_version} 最新版本为 ${trojan_panel_ui_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + echo_content yellow "Trojan Panel后端(trojan-panel)当前版本为 ${trojan_panel_current_version} 最新版本为 ${trojan_panel_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + echo_content yellow "Trojan Panel内核(trojan-panel-core)当前版本为 ${trojan_panel_core_current_version} 最新版本为 ${trojan_panel_core_latest_version}" + fi +} + +main() { + cd "$HOME" || exit 0 + init_var + mkdir_tools + check_sys + depend_install + clear + echo_content red "\n==============================================================" + echo_content skyBlue "System Required: CentOS 7+/Ubuntu 18+/Debian 10+" + echo_content skyBlue "Version: v2.1.7" + echo_content skyBlue "Description: One click Install Trojan Panel server" + echo_content skyBlue "Author: jonssonyan " + echo_content skyBlue "Github: https://github.com/trojanpanel" + echo_content skyBlue "Docs: https://trojanpanel.github.io" + echo_content red "\n==============================================================" + echo_content yellow "1. 安装Trojan Panel前端" + echo_content yellow "2. 安装Trojan Panel后端" + echo_content yellow "3. 安装Trojan Panel内核" + echo_content yellow "4. 安装Caddy2" + echo_content yellow "5. 安装Nginx" + echo_content yellow "6. 安装MariaDB" + echo_content yellow "7. 安装Redis" + echo_content green "\n==============================================================" + echo_content yellow "8. 更新Trojan Panel前端" + echo_content yellow "9. 更新Trojan Panel后端" + echo_content yellow "10. 更新Trojan Panel内核" + echo_content green "\n==============================================================" + echo_content yellow "11. 卸载Trojan Panel前端" + echo_content yellow "12. 卸载Trojan Panel后端" + echo_content yellow "13. 卸载Trojan Panel内核" + echo_content yellow "14. 卸载Caddy2" + echo_content yellow "15. 卸载Nginx" + echo_content yellow "16. 卸载MariaDB" + echo_content yellow "17. 卸载Redis" + echo_content yellow "18. 卸载全部Trojan Panel相关的应用" + echo_content green "\n==============================================================" + echo_content yellow "19. 修改Trojan Panel前端端口" + echo_content yellow "20. 刷新Redis缓存" + echo_content yellow "21. 更换证书" + echo_content yellow "22. 忘记密码" + echo_content green "\n==============================================================" + echo_content yellow "23. 故障检测" + echo_content yellow "24. 日志查询" + echo_content yellow "25. 版本查询" + read -r -p "请选择:" selectInstall_type + case ${selectInstall_type} in + 1) + install_docker + install_cert + install_trojan_panel_ui + ;; + 2) + install_docker + install_mariadb + install_redis + install_trojan_panel + ;; + 3) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_core + ;; + 4) + install_docker + install_caddy2 + ;; + 5) + install_docker + install_nginx + ;; + 6) + install_docker + install_mariadb + ;; + 7) + install_docker + install_redis + ;; + 8) + update_trojan_panel_ui + ;; + 9) + update_trojan_panel + ;; + 10) + update_trojan_panel_core + ;; + 11) + uninstall_trojan_panel_ui + ;; + 12) + uninstall_trojan_panel + ;; + 13) + uninstall_trojan_panel_core + ;; + 14) + uninstall_caddy2 + ;; + 15) + uninstall_nginx + ;; + 16) + uninstall_mariadb + ;; + 17) + uninstall_redis + ;; + 18) + uninstall_all + ;; + 19) + update_trojan_panel_ui_port + ;; + 20) + redis_flush_all + ;; + 21) + change_cert + ;; + 22) + forget_pass + ;; + 23) + failure_testing + ;; + 24) + log_query + ;; + 25) + version_query + ;; + *) + echo_content red "没有这个选项" + ;; + esac +} + +main diff --git a/lib/archive/install_script_v2.1.8.sh b/lib/archive/install_script_v2.1.8.sh new file mode 100644 index 0000000..22aa292 --- /dev/null +++ b/lib/archive/install_script_v2.1.8.sh @@ -0,0 +1,1980 @@ +#!/usr/bin/env bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +# System Required: CentOS 7+/Ubuntu 18+/Debian 10+ +# Version: v2.1.8 +# Description: One click Install Trojan Panel server +# Author: jonssonyan +# Github: https://github.com/trojanpanel/install-script + +init_var() { + ECHO_TYPE="echo -e" + + package_manager="" + release="" + get_arch="" + can_google=0 + + # Docker + DOCKER_MIRROR='"https://hub-mirror.c.163.com","https://ccr.ccs.tencentyun.com","https://mirror.baidubce.com","https://dockerproxy.com"' + + # 项目目录 + TP_DATA="/tpdata/" + + STATIC_HTML="https://github.com/trojanpanel/install-script/releases/download/v1.0/html.tar.gz" + + # web + WEB_PATH="/tpdata/web/" + + # cert + CERT_PATH="/tpdata/cert/" + DOMAIN_FILE="/tpdata/domain.lock" + domain="" + crt_path="" + key_path="" + + # Caddy + CADDY_DATA="/tpdata/caddy/" + CADDY_CONFIG="${CADDY_DATA}config.json" + CADDY_LOG="${CADDY_DATA}logs/" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + caddy_port=80 + caddy_remote_port=8863 + your_email="" + ssl_option=1 + ssl_module_type=1 + ssl_module="acme" + + # Nginx + NGINX_DATA="/tpdata/nginx/" + NGINX_CONFIG="${NGINX_DATA}default.conf" + nginx_port=80 + nginx_remote_port=8863 + nginx_https=1 + + # MariaDB + MARIA_DATA="/tpdata/mariadb/" + mariadb_ip="127.0.0.1" + mariadb_port=9507 + mariadb_user="root" + mariadb_pas="" + + #Redis + REDIS_DATA="/tpdata/redis/" + redis_host="127.0.0.1" + redis_port=6378 + redis_pass="" + + # Trojan Panel前端 + TROJAN_PANEL_UI_DATA="/tpdata/trojan-panel-ui/" + # Nginx + UI_NGINX_DATA="${TROJAN_PANEL_UI_DATA}nginx/" + UI_NGINX_CONFIG="${UI_NGINX_DATA}default.conf" + trojan_panel_ui_port=8888 + ui_https=1 + trojan_panel_ip="127.0.0.1" + trojan_panel_server_port=8081 + + # Trojan Panel后端 + TROJAN_PANEL_DATA="/tpdata/trojan-panel/" + TROJAN_PANEL_WEBFILE="${TROJAN_PANEL_DATA}webfile/" + TROJAN_PANEL_LOGS="${TROJAN_PANEL_DATA}logs/" + TROJAN_PANEL_CONFIG="${TROJAN_PANEL_DATA}config/" + trojan_panel_config_path="${TROJAN_PANEL_DATA}config/config.ini" + trojan_panel_port=8081 + + # Trojan Panel内核 + TROJAN_PANEL_CORE_DATA="/tpdata/trojan-panel-core/" + TROJAN_PANEL_CORE_LOGS="${TROJAN_PANEL_CORE_DATA}logs/" + TROJAN_PANEL_CORE_CONFIG="${TROJAN_PANEL_CORE_DATA}config/" + trojan_panel_core_config_path="${TROJAN_PANEL_CORE_DATA}config/config.ini" + database="trojan_panel_db" + account_table="account" + grpc_port=8100 + trojan_panel_core_port=8082 + + # Update + trojan_panel_ui_current_version="" + trojan_panel_ui_latest_version="v2.1.6" + trojan_panel_current_version="" + trojan_panel_latest_version="v2.1.5" + trojan_panel_core_current_version="" + trojan_panel_core_latest_version="v2.1.2" + + # SQL + sql_215="alter table account change validity_period preset_expire int unsigned default 0 not null comment '预设过期时长';alter table account add preset_quota bigint default 0 not null comment '预设配额' after preset_expire;update account set preset_quota = quota where last_login_time = 0;update account set quota = 0 where last_login_time = 0;alter table node add priority int default 100 not null comment '优先级' after port;INSERT INTO casbin_rule (p_type, v0, v1, v2, v3, v4, v5) VALUES ('p', 'sysadmin', '/api/account/clashSubscribeForSb', 'GET', 'default', 'default', 'default');alter table node_hysteria add server_name varchar(64) default '' not null comment '用于验证服务端证书的 hostname' after down_mbps;alter table node_hysteria add insecure tinyint(1) default 0 not null comment '忽略一切证书错误' after server_name;alter table node_hysteria add fast_open tinyint(1) default 0 not null comment '启用 Fast Open (降低连接建立延迟)' after insecure;" +} + +echo_content() { + case $1 in + "red") + ${ECHO_TYPE} "\033[31m$2\033[0m" + ;; + "green") + ${ECHO_TYPE} "\033[32m$2\033[0m" + ;; + "yellow") + ${ECHO_TYPE} "\033[33m$2\033[0m" + ;; + "blue") + ${ECHO_TYPE} "\033[34m$2\033[0m" + ;; + "purple") + ${ECHO_TYPE} "\033[35m$2\033[0m" + ;; + "skyBlue") + ${ECHO_TYPE} "\033[36m$2\033[0m" + ;; + "white") + ${ECHO_TYPE} "\033[37m$2\033[0m" + ;; + esac +} + +mkdir_tools() { + # 项目目录 + mkdir -p ${TP_DATA} + + # web + mkdir -p ${WEB_PATH} + + # cert + mkdir -p ${CERT_PATH} + touch ${DOMAIN_FILE} + + # Caddy + mkdir -p ${CADDY_DATA} + touch ${CADDY_CONFIG} + mkdir -p ${CADDY_LOG} + + # Nginx + mkdir -p ${NGINX_DATA} + touch ${NGINX_CONFIG} + + # MariaDB + mkdir -p ${MARIA_DATA} + + # Redis + mkdir -p ${REDIS_DATA} + + # Trojan Panel前端 + mkdir -p ${TROJAN_PANEL_UI_DATA} + # # Nginx + mkdir -p ${UI_NGINX_DATA} + touch ${UI_NGINX_CONFIG} + + # Trojan Panel后端 + mkdir -p ${TROJAN_PANEL_DATA} + mkdir -p ${TROJAN_PANEL_LOGS} + + # Trojan Panel内核 + mkdir -p ${TROJAN_PANEL_CORE_DATA} + mkdir -p ${TROJAN_PANEL_CORE_LOGS} +} + +can_connect() { + ping -c2 -i0.3 -W1 "$1" &>/dev/null + if [[ "$?" == "0" ]]; then + return 0 + else + return 1 + fi +} + +get_ini_value() { + local config_file="$1" + local key="$2" + local section="" + local section_flag=0 + + # 拆分组名和键名 + IFS='.' read -r group_name key_name <<<"$key" + + while IFS='=' read -r name val; do + # 处理节名称 + if [[ $name =~ ^\[(.*)\]$ ]]; then + section="${BASH_REMATCH[1]}" + if [[ $section == $group_name ]]; then + section_flag=1 + else + section_flag=0 + fi + continue + fi + + # 提取配置项的值 + if [[ $section_flag -eq 1 && $name == $key_name ]]; then + echo "$val" + return + fi + done <"$config_file" +} + +# Version number comparison greater than or equal to +version_ge() { + local v1=${1#v} + local v2=${2#v} + + local v1_parts=(${v1//./ }) + local v2_parts=(${v2//./ }) + + for ((i = 0; i < 3; i++)); do + if ((${v1_parts[i]} < ${v2_parts[i]})); then + echo false + return 0 + elif ((${v1_parts[i]} > ${v2_parts[i]})); then + echo true + return 0 + fi + done + echo true +} + +check_sys() { + if [[ $(command -v yum) ]]; then + package_manager='yum' + elif [[ $(command -v dnf) ]]; then + package_manager='dnf' + elif [[ $(command -v apt) ]]; then + package_manager='apt' + elif [[ $(command -v apt-get) ]]; then + package_manager='apt-get' + fi + + if [[ -z "${package_manager}" ]]; then + echo_content red "暂不支持该系统" + exit 0 + fi + + if [[ -n $(find /etc -name "redhat-release") ]] || grep /dev/null) ]]; then + echo_content green "---> 安装Docker" + + # 关闭防火墙 + if [[ "${release}" == "centos" ]]; then + systemctl disable firewalld + elif [[ "${release}" == "debian" || "${release}" == "ubuntu" ]]; then + sudo ufw disable + fi + + # 时区 + timedatectl set-timezone Asia/Shanghai + + if [[ ${can_google} == 0 ]]; then + sh <(curl -sL https://get.docker.com) --mirror Aliyun + # 设置Docker国内源 + mkdir -p /etc/docker && + cat >/etc/docker/daemon.json </etc/docker/daemon.json </dev/null) ]]; then + echo_content skyBlue "---> Docker安装完成" + else + echo_content red "---> Docker安装失败" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Docker" + fi +} + +# 安装Caddy2 +install_caddy2() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> 安装Caddy2" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "请输入Caddy的端口(默认:80): " caddy_port + [[ -z "${caddy_port}" ]] && caddy_port=80 + read -r -p "请输入Caddy的转发端口(默认:8863): " caddy_remote_port + [[ -z "${caddy_remote_port}" ]] && caddy_remote_port=8863 + + echo_content yellow "提示:请确认域名已经解析到本机 否则可能安装失败" + while read -r -p "请输入你的域名(必填): " domain; do + if [[ -z "${domain}" ]]; then + echo_content red "域名不能为空" + else + break + fi + done + + read -r -p "请输入你的邮箱(可选): " your_email + + while read -r -p "请选择设置证书的方式?(1/自动申请和续签证书 2/手动设置证书路径 默认:1/自动申请和续签证书): " ssl_option; do + if [[ -z ${ssl_option} || ${ssl_option} == 1 ]]; then + while read -r -p "请选择申请证书的方式(1/acme 2/zerossl 默认:1/acme): " ssl_module_type; do + if [[ -z "${ssl_module_type}" || ${ssl_module_type} == 1 ]]; then + ssl_module="acme" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + break + elif [[ ${ssl_module_type} == 2 ]]; then + ssl_module="zerossl" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme.zerossl.com-v2-dv90/" + break + else + echo_content red "不可以输入除1和2之外的其他字符" + fi + done + + cat >${CADDY_CONFIG} <${CADDY_CONFIG} <${DOMAIN_FILE} < Caddy安装完成" + else + echo_content red "---> Caddy安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Caddy" + fi +} + +# 安装Nginx +install_nginx() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + echo_content green "---> 安装Nginx" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "请输入Nginx的端口(默认:80): " nginx_port + [[ -z "${nginx_port}" ]] && nginx_port=80 + read -r -p "请输入Nginx的转发端口(默认:8863): " nginx_remote_port + [[ -z "${nginx_remote_port}" ]] && nginx_remote_port=8863 + + while read -r -p "请选择Nginx是否开启https?(0/关闭 1/开启 默认:1/开启): " nginx_https; do + if [[ -z ${nginx_https} || ${nginx_https} == 1 ]]; then + install_custom_cert "custom_cert" + domain=$(cat "${DOMAIN_FILE}") + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + return 301 http://\$host:${nginx_remote_port}\$request_uri; +} + +server { + listen ${nginx_remote_port} ssl; + server_name localhost; + + #强制ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + #缓存有效期 + ssl_session_timeout 5m; + #安全链接可选的加密协议 + ssl_protocols TLSv1.3; + #加密算法 + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + #使用服务器端的首选算法 + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${nginx_remote_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + else + if [[ ${nginx_https} != 0 ]]; then + echo_content red "不可以输入除0和1之外的其他字符" + else + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + error_page 497 http://\$host:${nginx_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + fi + fi + done + + docker pull nginx:1.20-alpine && + docker run -d --name trojan-panel-nginx --restart always \ + --network=host \ + -v "${NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + nginx:1.20-alpine + + if [[ -n $(docker ps -q -f "name=^trojan-panel-nginx$" -f "status=running") ]]; then + echo_content skyBlue "---> Nginx安装完成" + else + echo_content red "---> Nginx安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Nginx" + fi +} + +# 设置伪装Web +install_reverse_proxy() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$|^trojan-panel-nginx$") ]]; then + echo_content green "---> 设置伪装Web" + + while :; do + echo_content yellow "1. 安装Caddy 2(推荐)" + echo_content yellow "2. 安装Nginx" + echo_content yellow "3. 不设置" + read -r -p "请选择(默认:1): " whether_install_reverse_proxy + [[ -z "${whether_install_reverse_proxy}" ]] && whether_install_reverse_proxy=1 + + case ${whether_install_reverse_proxy} in + 1) + install_caddy2 + break + ;; + 2) + install_nginx + break + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + done + + echo_content skyBlue "---> 伪装Web设置完成" + fi +} + +install_custom_cert() { + while read -r -p "请输入证书的.crt文件路径(必填): " crt_path; do + if [[ -z "${crt_path}" ]]; then + echo_content red "路径不能为空" + else + if [[ ! -f "${crt_path}" ]]; then + echo_content red "证书的.crt文件路径不存在" + else + cp "${crt_path}" "${CERT_PATH}$1.crt" + break + fi + fi + done + while read -r -p "请输入证书的.key文件路径(必填): " key_path; do + if [[ -z "${key_path}" ]]; then + echo_content red "路径不能为空" + else + if [[ ! -f "${key_path}" ]]; then + echo_content red "证书的.key文件路径不存在" + else + cp "${key_path}" "${CERT_PATH}$1.key" + break + fi + fi + done + cat >${DOMAIN_FILE} < 设置证书" + + while :; do + echo_content yellow "1. 安装Caddy 2(自动申请/续签证书)" + echo_content yellow "2. 手动设置证书路径" + echo_content yellow "3. 不设置" + read -r -p "请选择(默认:1): " whether_install_cert + [[ -z "${whether_install_cert}" ]] && whether_install_cert=1 + + case ${whether_install_cert} in + 1) + install_caddy2 + break + ;; + 2) + install_custom_cert "custom_cert" + break + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + done + + echo_content green "---> 证书设置完成" + fi +} + +# 安装MariaDB +install_mariadb() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> 安装MariaDB" + + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + if [[ "${mariadb_user}" == "root" ]]; then + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + else + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e MYSQL_USER="${mariadb_user}" \ + -e MYSQL_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + fi + + if [[ -n $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content skyBlue "---> MariaDB安装完成" + echo_content yellow "---> MariaDB root的数据库密码(请妥善保存): ${mariadb_pas}" + if [[ "${mariadb_user}" != "root" ]]; then + echo_content yellow "---> MariaDB ${mariadb_user}的数据库密码(请妥善保存): ${mariadb_pas}" + fi + else + echo_content red "---> MariaDB安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了MariaDB" + fi +} + +# 安装Redis +install_redis() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> 安装Redis" + + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker pull redis:6.2.7 && + docker run -d --name trojan-panel-redis --restart always \ + --network=host \ + redis:6.2.7 \ + redis-server --requirepass "${redis_pass}" --port "${redis_port}" + + if [[ -n $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content skyBlue "---> Redis安装完成" + echo_content yellow "---> Redis的数据库密码(请妥善保存): ${redis_pass}" + else + echo_content red "---> Redis安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Redis" + fi +} + +# 安装Trojan Panel前端 +install_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> 安装Trojan Panel前端" + + read -r -p "请输入Trojan Panel后端的IP地址(默认:本机后端): " trojan_panel_ip + [[ -z "${trojan_panel_ip}" ]] && trojan_panel_ip="127.0.0.1" + read -r -p "请输入Trojan Panel后端的服务端口(默认:8081): " trojan_panel_server_port + [[ -z "${trojan_panel_server_port}" ]] && trojan_panel_server_port=8081 + + read -r -p "请输入Trojan Panel前端端口(默认:8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + while read -r -p "请选择Trojan Panel前端是否开启https?(0/关闭 1/开启 默认:1/开启): " ui_https; do + if [[ -z ${ui_https} || ${ui_https} == 1 ]]; then + install_cert + domain=$(cat "${DOMAIN_FILE}") + # 配置Nginx + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port} ssl; + server_name localhost; + + #强制ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + #缓存有效期 + ssl_session_timeout 5m; + #安全链接可选的加密协议 + ssl_protocols TLSv1.3; + #加密算法 + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + #使用服务器端的首选算法 + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${trojan_panel_ui_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + else + if [[ ${ui_https} != 0 ]]; then + echo_content red "不可以输入除0和1之外的其他字符" + else + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port}; + server_name localhost; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + error_page 497 http://\$host:${trojan_panel_ui_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF + break + fi + fi + done + + docker pull jonssonyan/trojan-panel-ui:2.1.6 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.6 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel前端安装完成" + + https_flag=$([[ -z ${ui_https} || ${ui_https} == 1 ]] && echo "https" || echo "http") + domain_or_ip=$([[ -z ${domain} || "${domain}" == "custom_cert" ]] && echo "ip" || echo "${domain}") + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel前端安装成功" + echo_content yellow "管理面板地址: ${https_flag}://${domain_or_ip}:${trojan_panel_ui_port}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel前端安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel前端" + fi +} + +# 安装Trojan Panel后端 +install_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> 安装Trojan Panel后端" + + read -r -p "请输入Trojan Panel后端的服务端口(默认:8081): " trojan_panel_port + [[ -z "${trojan_panel_port}" ]] && trojan_panel_port=8081 + + read -r -p "请输入数据库的IP地址(默认:本机数据库): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -e "create database if not exists trojan_panel_db;" &>/dev/null + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker pull jonssonyan/trojan-panel:2.1.5 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.1.5 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel后端安装完成" + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel后端安装成功" + echo_content yellow "MariaDB ${mariadb_user}的密码(请妥善保存): ${mariadb_pas}" + echo_content yellow "Redis的密码(请妥善保存): ${redis_pass}" + echo_content yellow "系统管理员 默认用户名: sysadmin 默认密码: 123456 请及时登陆管理面板修改密码" + echo_content yellow "Trojan Panel私钥和证书目录: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel后端安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel后端" + fi +} + +# 安装Trojan Panel内核 +install_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> 安装Trojan Panel内核" + + read -r -p "请输入Trojan Panel内核的服务端口(默认:8082): " trojan_panel_core_port + [[ -z "${trojan_panel_core_port}" ]] && trojan_panel_core_port=8082 + + read -r -p "请输入数据库的IP地址(默认:本机数据库): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + read -r -p "请输入数据库名称(默认:trojan_panel_db): " database + [[ -z "${database}" ]] && database="trojan_panel_db" + read -r -p "请输入数据库的用户表名称(默认:account): " account_table + [[ -z "${account_table}" ]] && account_table="account" + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + read -r -p "请输入API的端口(默认:8100): " grpc_port + [[ -z "${grpc_port}" ]] && grpc_port=8100 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.1.2 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.1.2 + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel内核安装完成" + else + echo_content red "---> Trojan Panel内核安装失败或运行异常,请尝试修复或卸载重装" + exit 0 + fi + else + echo_content skyBlue "---> 你已经安装了Trojan Panel内核" + fi +} + +# 更新Trojan Panel数据结构 +update_trojan_panel_database() { + echo_content skyBlue "---> 更新Trojan Panel数据结构" + + version_214_215=("v2.1.4") + if [[ "${version_214_215[*]}" =~ "${trojan_panel_current_version}" ]]; then + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "${sql_215}" &>/dev/null && + trojan_panel_current_version="v2.1.5" + fi + + echo_content skyBlue "---> Trojan Panel数据结构更新完成" +} + +# 更新Trojan Panel内核数据结构 +update_trojan_panel_core_database() { + echo_content skyBlue "---> 更新Trojan Panel内核数据结构" + + echo_content skyBlue "---> Trojan Panel内核数据结构更新完成" +} + +# 更新Trojan Panel前端 +update_trojan_panel_ui() { + # 判断Trojan Panel前端是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content red "---> 请先安装Trojan Panel前端" + exit 0 + fi + + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + if [[ -z "${trojan_panel_ui_current_version}" || ! "${trojan_panel_ui_current_version}" =~ ^v.* ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel前端(trojan-panel-ui)当前版本为 ${trojan_panel_ui_current_version} 最新版本为 ${trojan_panel_ui_latest_version}" + + if [[ "${trojan_panel_ui_current_version}" != "${trojan_panel_ui_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel前端" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.6 + + docker pull jonssonyan/trojan-panel-ui:2.1.6 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.6 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel前端更新完成" + else + echo_content red "---> Trojan Panel前端更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel前端已经是最新版" + fi +} + +# 更新Trojan Panel后端 +update_trojan_panel() { + # 判断Trojan Panel后端是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content red "---> 请先安装Trojan Panel后端" + exit 0 + fi + + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + if [[ -z "${trojan_panel_current_version}" || ! "${trojan_panel_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_current_version}" "v2.1.4") ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel后端(trojan-panel)当前版本为 ${trojan_panel_current_version} 最新版本为 ${trojan_panel_latest_version}" + + if [[ "${trojan_panel_current_version}" != "${trojan_panel_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel后端" + + mariadb_ip=$(get_ini_value ${trojan_panel_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + trojan_panel_port=$(get_ini_value ${trojan_panel_config_path} server.port) + + update_trojan_panel_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.1.5 + + docker pull jonssonyan/trojan-panel:2.1.5 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.1.5 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel后端更新完成" + else + echo_content red "---> Trojan Panel后端更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel后端已经是最新版" + fi +} + +# 更新Trojan Panel内核 +update_trojan_panel_core() { + # 判断Trojan Panel内核是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content red "---> 请先安装Trojan Panel内核" + exit 0 + fi + + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + if [[ -z "${trojan_panel_core_current_version}" || ! "${trojan_panel_core_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_core_current_version}" "v2.1.1") ]]; then + echo_content red "---> 当前版本不支持自动化更新" + exit 0 + fi + + echo_content yellow "提示:Trojan Panel内核(trojan-panel-core)当前版本为 ${trojan_panel_core_current_version} 最新版本为 ${trojan_panel_core_latest_version}" + + if [[ "${trojan_panel_core_current_version}" != "${trojan_panel_core_latest_version}" ]]; then + echo_content green "---> 更新Trojan Panel内核" + + mariadb_ip=$(get_ini_value ${trojan_panel_core_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_core_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_core_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_core_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_core_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_core_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_core_config_path} redis.password) + grpc_port=$(get_ini_value ${trojan_panel_core_config_path} grpc.port) + trojan_panel_core_port=$(get_ini_value ${trojan_panel_core_config_path} server.port) + + update_trojan_panel_core_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.1.2 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.1.2 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.1.2 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel内核更新完成" + else + echo_content red "---> Trojan Panel内核更新失败或运行异常,请尝试修复或卸载重装" + fi + else + echo_content skyBlue "---> 你安装的Trojan Panel内核已经是最新版" + fi +} + +# 卸载Caddy2 +uninstall_caddy2() { + # 判断Caddy2是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> 卸载Caddy2" + + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_DATA} + + echo_content skyBlue "---> Caddy2卸载完成" + else + echo_content red "---> 请先安装Caddy2" + fi +} + +# 卸载Nginx +uninstall_nginx() { + # 判断Caddy2是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx") ]]; then + echo_content green "---> 卸载Nginx" + + docker rm -f trojan-panel-nginx && + rm -rf ${NGINX_DATA} + + echo_content skyBlue "---> Nginx卸载完成" + else + echo_content red "---> 请先安装Nginx" + fi +} + +# 卸载MariaDB +uninstall_mariadb() { + # 判断MariaDB是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> 卸载MariaDB" + + docker rm -f trojan-panel-mariadb && + rm -rf ${MARIA_DATA} + + echo_content skyBlue "---> MariaDB卸载完成" + else + echo_content red "---> 请先安装MariaDB" + fi +} + +# 卸载Redis +uninstall_redis() { + # 判断Redis是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> 卸载Redis" + + docker rm -f trojan-panel-redis && + rm -rf ${REDIS_DATA} + + echo_content skyBlue "---> Redis卸载完成" + else + echo_content red "---> 请先安装Redis" + fi +} + +# 卸载Trojan Panel前端 +uninstall_trojan_panel_ui() { + # 判断Trojan Panel前端是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> 卸载Trojan Panel前端" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.6 && + rm -rf ${TROJAN_PANEL_UI_DATA} + + echo_content skyBlue "---> Trojan Panel前端卸载完成" + else + echo_content red "---> 请先安装Trojan Panel前端" + fi +} + +# 卸载Trojan Panel后端 +uninstall_trojan_panel() { + # 判断Trojan Panel后端是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> 卸载Trojan Panel后端" + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.1.5 && + rm -rf ${TROJAN_PANEL_DATA} + + echo_content skyBlue "---> Trojan Panel后端卸载完成" + else + echo_content red "---> 请先安装Trojan Panel后端" + fi +} + +# 卸载Trojan Panel内核 +uninstall_trojan_panel_core() { + # 判断Trojan Panel内核是否安装 + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> 卸载Trojan Panel内核" + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.1.2 && + rm -rf ${TROJAN_PANEL_CORE_DATA} + + echo_content skyBlue "---> Trojan Panel内核卸载完成" + else + echo_content red "---> 请先安装Trojan Panel内核" + fi +} + +# 卸载全部Trojan Panel相关的容器 +uninstall_all() { + echo_content green "---> 卸载全部Trojan Panel相关的容器" + + docker rm -f $(docker ps -a -q -f "name=^trojan-panel") + docker rmi -f $(docker images | grep "^jonssonyan/trojan-panel" | awk '{print $3}') + rm -rf ${TP_DATA} + + echo_content skyBlue "---> 卸载全部Trojan Panel相关的容器完成" +} + +# 修改Trojan Panel前端端口 +update_trojan_panel_ui_port() { + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content green "---> 修改Trojan Panel前端端口" + + trojan_panel_ui_port=$(grep 'listen.*ssl' ${UI_NGINX_CONFIG} | awk '{print $2}') + if [[ -z "${trojan_panel_ui_port}" ]]; then + ui_https=0 + trojan_panel_ui_port=$(grep -oP 'listen\s+\K\d+' ${UI_NGINX_CONFIG} | awk 'NR==1') + fi + if [[ -z "${trojan_panel_ui_port}" ]]; then + echo_content red "---> 未查询到Trojan Panel前端的端口" + exit 0 + fi + echo_content yellow "提示:Trojan Panel前端(trojan-panel-ui)当前端口为 ${trojan_panel_ui_port}" + + read -r -p "请输入Trojan Panel前端新端口(默认:8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + + if [[ ${ui_https} == 0 ]]; then + # http + sed -i "s/listen.*;/listen ${trojan_panel_ui_port};/g" ${UI_NGINX_CONFIG} && + sed -i "s/http:\/\/\$host:.*\$request_uri;/http:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + else + # https + sed -i "s/listen.*ssl;/listen ${trojan_panel_ui_port} ssl;/g" ${UI_NGINX_CONFIG} && + sed -i "s/https:\/\/\$host:.*\$request_uri;/https:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + fi + + if [[ "$?" == "0" ]]; then + echo_content skyBlue "---> Trojan Panel前端端口修改完成" + else + echo_content red "---> Trojan Panel前端端口修改失败" + fi + else + echo_content red "---> Trojan Panel前端未安装或运行异常,请修复或卸载重装后重试" + fi +} + +# 刷新Redis缓存 +redis_flush_all() { + # 判断Redis是否安装 + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content red "---> 请先安装Redis" + exit 0 + fi + + if [[ -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis运行异常" + exit 0 + fi + + echo_content green "---> 刷新Redis缓存" + + read -r -p "请输入Redis的IP地址(默认:本机Redis): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "请输入Redis的端口(默认:6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "请输入Redis的密码(必填): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + echo_content skyBlue "---> Redis缓存刷新完成" +} + +# 更换证书 +change_cert() { + domain_1=$(cat "${DOMAIN_FILE}") + + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_LOG}* && + echo "" >${CADDY_CONFIG} && + rm -rf ${WEB_PATH}* + fi + + rm -rf ${CERT_PATH}* && + echo "" >${DOMAIN_FILE} + + install_cert + + domain_2=$(cat "${DOMAIN_FILE}") + if [[ -n "${domain_1}" && -n "${domain_2}" ]]; then + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${NGINX_CONFIG} && + docker restart trojan-panel-nginx + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${UI_NGINX_DATA} && + docker restart trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + find /tpdata/trojan-panel-core/bin/ -type f -exec sed -i "s/${domain_1}/${domain_2}/g" {} + && + sed -i "s/${domain_1}/${domain_2}/g" ${trojan_panel_core_config_path} && + docker restart trojan-panel-core + fi + fi +} + +forget_pass() { + while :; do + echo_content yellow "1. 查询MariaDB密码" + echo_content yellow "2. 查询Redis密码" + echo_content yellow "3. 重设管理面板系统管理员用户名和密码" + echo_content yellow "4. 退出" + read -r -p "请选择(默认:4): " forget_pass_option + [[ -z "${forget_pass_option}" ]] && forget_pass_option=4 + case ${forget_pass_option} in + 1) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + echo_content red "\n==============================================================" + echo_content yellow "MariaDB ${mariadb_user}的密码(请妥善保存): ${mariadb_pas}" + echo_content red "\n==============================================================" + else + echo_content red "---> 请先安装Trojan Panel后端" + fi + ;; + 2) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + echo_content red "\n==============================================================" + echo_content yellow "Redis的密码(请妥善保存): ${redis_pass}" + echo_content red "\n==============================================================" + else + echo_content red "---> 请先安装Trojan Panel后端" + fi + ;; + 3) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + read -r -p "请输入数据库的IP地址(默认:本机数据库): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "请输入数据库的端口(默认:9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "请输入数据库的用户名(默认:root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "请输入数据库的密码(必填): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "密码不能为空" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "update account set username = 'sysadmin',pass = 'tFjD2X1F6i9FfWp2GDU5Vbi1conuaChDKIYbw9zMFrqvMoSz',hash='4366294571b8b267d9cf15b56660f0a70659568a86fc270a52fdc9e5' where id = 1 limit 1" + if [[ "$?" == "0" ]]; then + echo_content red "\n==============================================================" + echo_content yellow "系统管理员 默认用户名: sysadmin 默认密码: 123456 请及时登陆管理面板修改密码" + echo_content red "\n==============================================================" + else + echo_content red "管理面板系统管理员用户名和密码重设失败" + fi + else + echo_content red "---> 请先安装MariaDB" + fi + ;; + 4) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + done +} + +# 故障检测 +failure_testing() { + echo_content green "---> 故障检测开始" + if [[ ! $(docker -v 2>/dev/null) ]]; then + echo_content red "---> Docker运行异常" + else + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + if [[ -z $(docker ps -q -f "name=^trojan-panel-caddy$" -f "status=running") ]]; then + echo_content red "---> Caddy2运行异常 运行日志如下:" + docker logs trojan-panel-caddy + fi + domain=$(cat "${DOMAIN_FILE}") + if [[ -n ${domain} && ! -f "${CERT_PATH}${domain}.crt" ]]; then + echo_content red "---> 证书申请异常,请尝试 1.换个子域名重新搭建 2.重启服务器将重新申请证书 3.重新搭建选择自定义证书选项" + if [[ -f ${CADDY_LOG}error.log ]]; then + echo_content red "Caddy2错误日志如下:" + tail -n 20 ${CADDY_LOG}error.log | grep error + fi + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") && -z $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content red "---> MariaDB运行异常 日志如下:" + docker logs trojan-panel-mariadb + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") && -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis运行异常 日志如下:" + docker logs trojan-panel-redis + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -z $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel后端运行异常 日志如下:" + if [[ -f ${TROJAN_PANEL_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -z $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel前端运行异常 日志如下:" + docker logs trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -z $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content red "---> Trojan Panel内核运行异常 日志如下:" + if [[ -f ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel-core + fi + fi + fi + echo_content green "---> 故障检测结束" +} + +log_query() { + while :; do + echo_content skyBlue "可以查询日志的应用如下:" + echo_content yellow "1. Trojan Panel后端" + echo_content yellow "2. Trojan Panel内核" + echo_content yellow "3. 退出" + read -r -p "请选择应用(默认:1): " select_log_query_type + [[ -z "${select_log_query_type}" ]] && select_log_query_type=1 + + case ${select_log_query_type} in + 1) + log_file_path=${TROJAN_PANEL_LOGS}trojan-panel.log + ;; + 2) + log_file_path=${TROJAN_PANEL_CORE_LOGS}trojan-panel-core.log + ;; + 3) + break + ;; + *) + echo_content red "没有这个选项" + continue + ;; + esac + + read -r -p "请输入查询的行数(默认:20): " select_log_query_line_type + [[ -z "${select_log_query_line_type}" ]] && select_log_query_line_type=20 + + if [[ -f ${log_file_path} ]]; then + echo_content skyBlue "日志如下:" + tail -n ${select_log_query_line_type} ${log_file_path} + else + echo_content red "不存在日志文件" + fi + done +} + +version_query() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + echo_content yellow "Trojan Panel前端(trojan-panel-ui)当前版本为 ${trojan_panel_ui_current_version} 最新版本为 ${trojan_panel_ui_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + echo_content yellow "Trojan Panel后端(trojan-panel)当前版本为 ${trojan_panel_current_version} 最新版本为 ${trojan_panel_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + echo_content yellow "Trojan Panel内核(trojan-panel-core)当前版本为 ${trojan_panel_core_current_version} 最新版本为 ${trojan_panel_core_latest_version}" + fi +} + +main() { + cd "$HOME" || exit 0 + init_var + mkdir_tools + check_sys + depend_install + clear + echo_content red "\n==============================================================" + echo_content skyBlue "System Required: CentOS 7+/Ubuntu 18+/Debian 10+" + echo_content skyBlue "Version: v2.1.8" + echo_content skyBlue "Description: One click Install Trojan Panel server" + echo_content skyBlue "Author: jonssonyan " + echo_content skyBlue "Github: https://github.com/trojanpanel" + echo_content skyBlue "Docs: https://trojanpanel.github.io" + echo_content red "\n==============================================================" + echo_content yellow "1. 安装Trojan Panel前端" + echo_content yellow "2. 安装Trojan Panel后端" + echo_content yellow "3. 安装Trojan Panel内核" + echo_content yellow "4. 安装Caddy2" + echo_content yellow "5. 安装Nginx" + echo_content yellow "6. 安装MariaDB" + echo_content yellow "7. 安装Redis" + echo_content green "\n==============================================================" + echo_content yellow "8. 更新Trojan Panel前端" + echo_content yellow "9. 更新Trojan Panel后端" + echo_content yellow "10. 更新Trojan Panel内核" + echo_content green "\n==============================================================" + echo_content yellow "11. 卸载Trojan Panel前端" + echo_content yellow "12. 卸载Trojan Panel后端" + echo_content yellow "13. 卸载Trojan Panel内核" + echo_content yellow "14. 卸载Caddy2" + echo_content yellow "15. 卸载Nginx" + echo_content yellow "16. 卸载MariaDB" + echo_content yellow "17. 卸载Redis" + echo_content yellow "18. 卸载全部Trojan Panel相关的应用" + echo_content green "\n==============================================================" + echo_content yellow "19. 修改Trojan Panel前端端口" + echo_content yellow "20. 刷新Redis缓存" + echo_content yellow "21. 更换证书" + echo_content yellow "22. 忘记密码" + echo_content green "\n==============================================================" + echo_content yellow "23. 故障检测" + echo_content yellow "24. 日志查询" + echo_content yellow "25. 版本查询" + read -r -p "请选择:" selectInstall_type + case ${selectInstall_type} in + 1) + install_docker + install_cert + install_trojan_panel_ui + ;; + 2) + install_docker + install_mariadb + install_redis + install_trojan_panel + ;; + 3) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_core + ;; + 4) + install_docker + install_caddy2 + ;; + 5) + install_docker + install_nginx + ;; + 6) + install_docker + install_mariadb + ;; + 7) + install_docker + install_redis + ;; + 8) + update_trojan_panel_ui + ;; + 9) + update_trojan_panel + ;; + 10) + update_trojan_panel_core + ;; + 11) + uninstall_trojan_panel_ui + ;; + 12) + uninstall_trojan_panel + ;; + 13) + uninstall_trojan_panel_core + ;; + 14) + uninstall_caddy2 + ;; + 15) + uninstall_nginx + ;; + 16) + uninstall_mariadb + ;; + 17) + uninstall_redis + ;; + 18) + uninstall_all + ;; + 19) + update_trojan_panel_ui_port + ;; + 20) + redis_flush_all + ;; + 21) + change_cert + ;; + 22) + forget_pass + ;; + 23) + failure_testing + ;; + 24) + log_query + ;; + 25) + version_query + ;; + *) + echo_content red "没有这个选项" + ;; + esac +} + +main diff --git a/lib/archive/install_script_v2.2.0.sh b/lib/archive/install_script_v2.2.0.sh new file mode 100644 index 0000000..4bcd025 --- /dev/null +++ b/lib/archive/install_script_v2.2.0.sh @@ -0,0 +1,2005 @@ +#!/usr/bin/env bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +# System Required: CentOS 7+/Ubuntu 18+/Debian 10+ +# Version: v2.2.0 +# Description: One click Install Trojan Panel server +# Author: jonssonyan +# Github: https://github.com/trojanpanel/install-script + +init_var() { + ECHO_TYPE="echo -e" + + package_manager="" + release="" + get_arch="" + can_google=0 + + # Docker + DOCKER_MIRROR='"https://hub-mirror.c.163.com","https://ccr.ccs.tencentyun.com","https://mirror.baidubce.com","https://dockerproxy.com"' + + # Project directory + TP_DATA="/tpdata/" + + STATIC_HTML="https://github.com/trojanpanel/install-script/releases/download/v1.0/html.tar.gz" + + # Web + WEB_PATH="/tpdata/web/" + + # Cert + CERT_PATH="/tpdata/cert/" + DOMAIN_FILE="/tpdata/domain.lock" + domain="" + crt_path="" + key_path="" + + # Caddy2 + CADDY_DATA="/tpdata/caddy/" + CADDY_CONFIG="${CADDY_DATA}config.json" + CADDY_LOG="${CADDY_DATA}logs/" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + caddy_port=80 + caddy_remote_port=8863 + your_email="" + ssl_option=1 + ssl_module_type=1 + ssl_module="acme" + + # Nginx + NGINX_DATA="/tpdata/nginx/" + NGINX_CONFIG="${NGINX_DATA}default.conf" + nginx_port=80 + nginx_remote_port=8863 + nginx_https=1 + + # MariaDB + MARIA_DATA="/tpdata/mariadb/" + mariadb_ip="127.0.0.1" + mariadb_port=9507 + mariadb_user="root" + mariadb_pas="" + + # Redis + REDIS_DATA="/tpdata/redis/" + redis_host="127.0.0.1" + redis_port=6378 + redis_pass="" + + # Trojan Panel Frontend + TROJAN_PANEL_UI_DATA="/tpdata/trojan-panel-ui/" + # Nginx + UI_NGINX_DATA="${TROJAN_PANEL_UI_DATA}nginx/" + UI_NGINX_CONFIG="${UI_NGINX_DATA}default.conf" + trojan_panel_ui_port=8888 + ui_https=1 + trojan_panel_ip="127.0.0.1" + trojan_panel_server_port=8081 + + # Trojan Panel Backend + TROJAN_PANEL_DATA="/tpdata/trojan-panel/" + TROJAN_PANEL_WEBFILE="${TROJAN_PANEL_DATA}webfile/" + TROJAN_PANEL_LOGS="${TROJAN_PANEL_DATA}logs/" + TROJAN_PANEL_CONFIG="${TROJAN_PANEL_DATA}config/" + trojan_panel_config_path="${TROJAN_PANEL_DATA}config/config.ini" + trojan_panel_port=8081 + + # Trojan Panel Core + TROJAN_PANEL_CORE_DATA="/tpdata/trojan-panel-core/" + TROJAN_PANEL_CORE_LOGS="${TROJAN_PANEL_CORE_DATA}logs/" + TROJAN_PANEL_CORE_CONFIG="${TROJAN_PANEL_CORE_DATA}config/" + trojan_panel_core_config_path="${TROJAN_PANEL_CORE_DATA}config/config.ini" + database="trojan_panel_db" + account_table="account" + grpc_port=8100 + trojan_panel_core_port=8082 + + # Version + trojan_panel_ui_current_version="" + trojan_panel_ui_latest_version="v2.1.6" + trojan_panel_current_version="" + trojan_panel_latest_version="v2.2.0" + trojan_panel_core_current_version="" + trojan_panel_core_latest_version="v2.2.0" + + # SQL + sql_215="alter table account change validity_period preset_expire int unsigned default 0 not null comment '预设过期时长';alter table account add preset_quota bigint default 0 not null comment '预设配额' after preset_expire;update account set preset_quota = quota where last_login_time = 0;update account set quota = 0 where last_login_time = 0;alter table node add priority int default 100 not null comment '优先级' after port;INSERT INTO casbin_rule (p_type, v0, v1, v2, v3, v4, v5) VALUES ('p', 'sysadmin', '/api/account/clashSubscribeForSb', 'GET', 'default', 'default', 'default');alter table node_hysteria add server_name varchar(64) default '' not null comment '用于验证服务端证书的 hostname' after down_mbps;alter table node_hysteria add insecure tinyint(1) default 0 not null comment '忽略一切证书错误' after server_name;alter table node_hysteria add fast_open tinyint(1) default 0 not null comment '启用 Fast Open (降低连接建立延迟)' after insecure;" +} + +echo_content() { + case $1 in + "red") + ${ECHO_TYPE} "\033[31m$2\033[0m" + ;; + "green") + ${ECHO_TYPE} "\033[32m$2\033[0m" + ;; + "yellow") + ${ECHO_TYPE} "\033[33m$2\033[0m" + ;; + "blue") + ${ECHO_TYPE} "\033[34m$2\033[0m" + ;; + "purple") + ${ECHO_TYPE} "\033[35m$2\033[0m" + ;; + "skyBlue") + ${ECHO_TYPE} "\033[36m$2\033[0m" + ;; + "white") + ${ECHO_TYPE} "\033[37m$2\033[0m" + ;; + esac +} + +mkdir_tools() { + # Project directory + mkdir -p ${TP_DATA} + + # Web + mkdir -p ${WEB_PATH} + + # Cert + mkdir -p ${CERT_PATH} + touch ${DOMAIN_FILE} + + # Caddy2 + mkdir -p ${CADDY_DATA} + touch ${CADDY_CONFIG} + mkdir -p ${CADDY_LOG} + + # Nginx + mkdir -p ${NGINX_DATA} + touch ${NGINX_CONFIG} + + # MariaDB + mkdir -p ${MARIA_DATA} + + # Redis + mkdir -p ${REDIS_DATA} + + # Trojan Panel Frontend + mkdir -p ${TROJAN_PANEL_UI_DATA} + # Nginx + mkdir -p ${UI_NGINX_DATA} + touch ${UI_NGINX_CONFIG} + + # Trojan Panel Backend + mkdir -p ${TROJAN_PANEL_DATA} + mkdir -p ${TROJAN_PANEL_LOGS} + + # Trojan Panel Core + mkdir -p ${TROJAN_PANEL_CORE_DATA} + mkdir -p ${TROJAN_PANEL_CORE_LOGS} +} + +can_connect() { + ping -c2 -i0.3 -W1 "$1" &>/dev/null + if [[ "$?" == "0" ]]; then + return 0 + else + return 1 + fi +} + +# query .ini configuration file information +get_ini_value() { + local config_file="$1" + local key="$2" + local section="" + local section_flag=0 + + # split group and key names + IFS='.' read -r group_name key_name <<<"$key" + + while IFS='=' read -r name val; do + # processing section name + if [[ $name =~ ^\[(.*)\]$ ]]; then + section="${BASH_REMATCH[1]}" + if [[ $section == $group_name ]]; then + section_flag=1 + else + section_flag=0 + fi + continue + fi + + # extract the value of the configuration item + if [[ $section_flag -eq 1 && $name == $key_name ]]; then + echo "$val" + return + fi + done <"$config_file" +} + +# Version number comparison greater than or equal to +version_ge() { + local v1=${1#v} + local v2=${2#v} + + local v1_parts=(${v1//./ }) + local v2_parts=(${v2//./ }) + + for ((i = 0; i < 3; i++)); do + if ((${v1_parts[i]} < ${v2_parts[i]})); then + echo false + return 0 + elif ((${v1_parts[i]} > ${v2_parts[i]})); then + echo true + return 0 + fi + done + echo true +} + +check_sys() { + if [[ $(command -v yum) ]]; then + package_manager='yum' + elif [[ $(command -v dnf) ]]; then + package_manager='dnf' + elif [[ $(command -v apt) ]]; then + package_manager='apt' + elif [[ $(command -v apt-get) ]]; then + package_manager='apt-get' + fi + + if [[ -z "${package_manager}" ]]; then + echo_content red "The system is not currently supported" + exit 0 + fi + + if [[ -n $(find /etc -name "redhat-release") ]] || grep /dev/null) ]]; then + echo_content green "---> Install Docker" + + # turn off firewall + if [[ "${release}" == "centos" ]]; then + systemctl disable firewalld + elif [[ "${release}" == "debian" || "${release}" == "ubuntu" ]]; then + sudo ufw disable + fi + + # set time zone + timedatectl set-timezone Asia/Shanghai + + if [[ ${can_google} == 0 ]]; then + sh <(curl -sL https://get.docker.com) --mirror Aliyun + mkdir -p /etc/docker && + cat >/etc/docker/daemon.json </etc/docker/daemon.json </dev/null) ]]; then + echo_content skyBlue "---> Docker installation completed" + else + echo_content red "---> Docker installation failed" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Docker" + fi +} + +# Custom Settings Certificate +install_custom_cert() { + if [[ -z "$(cat "${DOMAIN_FILE}")" ]]; then + while read -r -p "Please enter the file path of the .crt certificate (required): " crt_path; do + if [[ -z "${crt_path}" ]]; then + echo_content red "Path cannot be empty" + else + if [[ ! -f "${crt_path}" ]]; then + echo_content red "The file path for the .crt certificate does not exist" + else + cp "${crt_path}" "${CERT_PATH}$1.crt" + break + fi + fi + done + while read -r -p "Please enter the file path of the .key certificate (required): " key_path; do + if [[ -z "${key_path}" ]]; then + echo_content red "Path cannot be empty" + else + if [[ ! -f "${key_path}" ]]; then + echo_content red "The file path for the .key certificate does not exist" + else + cp "${key_path}" "${CERT_PATH}$1.key" + break + fi + fi + done + cat >${DOMAIN_FILE} < Custom settings certificate installation completed" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + fi +} + +# Caddy2 https custom settings certificate configuration file +caddy2_https_config() { + domain=$1 + cat >${CADDY_CONFIG} <${CADDY_CONFIG} < Install Caddy2+https" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "Please enter the port of Caddy2 (default: 80): " caddy_port + [[ -z "${caddy_port}" ]] && caddy_port=80 + read -r -p "Please enter the forwarding port of Caddy2 (default: 8863): " caddy_remote_port + [[ -z "${caddy_remote_port}" ]] && caddy_remote_port=8863 + + echo_content yellow "Tip: Please confirm that the domain name has been resolved to this machine, otherwise the installation may fail" + while read -r -p "Please enter your domain name (required): " domain; do + if [[ -z "${domain}" ]]; then + echo_content red "Domain name cannot be empty" + else + break + fi + done + + read -r -p "Please enter your email (optional): " your_email + + while read -r -p "Please choose the way to set up the certificate? (1/automatically apply for and renew the certificate 2/manually set the certificate path default: 1: " ssl_option; do + if [[ -z ${ssl_option} || ${ssl_option} == 1 ]]; then + while read -r -p "Please choose the way to apply for the certificate (1/acme 2/zerossl default: 1: " ssl_module_type; do + if [[ -z "${ssl_module_type}" || ${ssl_module_type} == 1 ]]; then + ssl_module="acme" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + break + elif [[ ${ssl_module_type} == 2 ]]; then + ssl_module="zerossl" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme.zerossl.com-v2-dv90/" + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + caddy2_https_auto_config "${domain}" + break + elif [[ ${ssl_option} == 2 ]]; then + install_custom_cert "${domain}" + caddy2_https_config "${domain}" + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + # Caddy2 temporary listening port for automatic certificate application + if [[ -n $(lsof -i:${caddy_port},${caddy_remote_port} -t) ]]; then + kill -9 "$(lsof -i:${caddy_port},${caddy_remote_port} -t)" + fi + + docker pull caddy:2.6.2 && + docker run -d --name trojan-panel-caddy --restart always \ + --network=host \ + -v "${CADDY_CONFIG}":"${CADDY_CONFIG}" \ + -v ${CERT_PATH}:"${CADDY_CERT_DIR}${domain}/" \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v ${CADDY_LOG}:${CADDY_LOG} \ + caddy:2.6.2 caddy run --config ${CADDY_CONFIG} + + cat >${DOMAIN_FILE} < Caddy2+https installation completed" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> Caddy2+https installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Caddy2+https" + fi +} + +# Nginx http configuration file +nginx_http_config() { + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + error_page 497 http://\$host:${nginx_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Nginx https configuration file +nginx_https_config() { + domain=$1 + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + return 301 http://\$host:${nginx_remote_port}\$request_uri; +} + +server { + listen ${nginx_remote_port} ssl; + server_name localhost; + + # force ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + # cache validity period + ssl_session_timeout 5m; + # secure link optional encryption protocol + ssl_protocols TLSv1.3; + # encryption algorithm + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + # use server-side preferred algorithm + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${nginx_remote_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Install Nginx +install_nginx() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + echo_content green "---> Install Nginx" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "Please enter the port of Nginx (default: 80): " nginx_port + [[ -z "${nginx_port}" ]] && nginx_port=80 + read -r -p "Please enter the forwarding port of Nginx (default: 8863): " nginx_remote_port + [[ -z "${nginx_remote_port}" ]] && nginx_remote_port=8863 + + while read -r -p "Please choose whether to enable https in Nginx? (0/off 1/on default: 1): " nginx_https; do + if [[ -z ${nginx_https} || ${nginx_https} == 1 ]]; then + install_custom_cert "custom_cert" + nginx_https_config "custom_cert" + break + elif [[ ${nginx_https} == 0 ]]; then + nginx_http_config + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + docker pull nginx:1.20-alpine && + docker run -d --name trojan-panel-nginx --restart always \ + --network=host \ + -v "${NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + nginx:1.20-alpine + + if [[ -n $(docker ps -q -f "name=^trojan-panel-nginx$" -f "status=running") ]]; then + echo_content skyBlue "---> Nginx installation completed" + else + echo_content red "---> Nginx installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Nginx" + fi +} + +# Install a web server +install_reverse_proxy() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$|^trojan-panel-nginx$") ]]; then + echo_content green "---> Install a web server" + + while :; do + echo_content yellow "1. Install Caddy2+https (recommend)" + echo_content yellow "2. Install Nginx" + echo_content yellow "3. Not install" + read -r -p "Please select (default: 1): " whether_install_reverse_proxy + [[ -z "${whether_install_reverse_proxy}" ]] && whether_install_reverse_proxy=1 + + case ${whether_install_reverse_proxy} in + 1) + install_caddy2 + break + ;; + 2) + install_nginx + break + ;; + 3) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done + + echo_content skyBlue "---> Web server installation completed" + fi +} + +# Set certificate +install_cert() { + if [[ -z "$(cat "${DOMAIN_FILE}")" ]]; then + echo_content green "---> Set certificate" + + while :; do + echo_content yellow "1. Custom certificate" + echo_content yellow "2. Not set" + read -r -p "Please select (default: 1): " whether_install_cert + [[ -z "${whether_install_cert}" ]] && whether_install_cert=1 + + case ${whether_install_cert} in + 1) + install_custom_cert "custom_cert" + break + ;; + 2) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done + + echo_content green "---> Certificate setup completed" + fi +} + +# Install MariaDB +install_mariadb() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> Install MariaDB" + + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + if [[ "${mariadb_user}" == "root" ]]; then + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + else + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e MYSQL_USER="${mariadb_user}" \ + -e MYSQL_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + fi + + if [[ -n $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content skyBlue "---> MariaDB installation completed" + echo_content yellow "---> The MariaDB password of root (please keep it safe): ${mariadb_pas}" + if [[ "${mariadb_user}" != "root" ]]; then + echo_content yellow "---> The MariaDB password of ${mariadb_user} (please keep it safe): ${mariadb_pas}" + fi + else + echo_content red "---> MariaDB installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed MariaDB" + fi +} + +# Install Redis +install_redis() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> Install Redis" + + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker pull redis:6.2.7 && + docker run -d --name trojan-panel-redis --restart always \ + --network=host \ + redis:6.2.7 \ + redis-server --requirepass "${redis_pass}" --port "${redis_port}" + + if [[ -n $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content skyBlue "---> Redis installation completed" + echo_content yellow "---> Redis password (please keep it safe): ${redis_pass}" + else + echo_content red "---> Redis installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Redis" + fi +} + +# Trojan Panel Frontend Nginx http configuration file +ui_http_config() { + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port}; + server_name localhost; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + error_page 497 http://\$host:${trojan_panel_ui_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Trojan Panel Frontend Nginx https configuration file +ui_https_config() { + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port} ssl; + server_name localhost; + + # force ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + # cache validity period + ssl_session_timeout 5m; + # secure link optional encryption protocol + ssl_protocols TLSv1.3; + # encryption algorithm + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + # use server-side preferred algorithm + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${trojan_panel_ui_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Install Trojan Panel Frontend +install_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> Install Trojan Panel Frontend" + + read -r -p "Please enter the IP address of the Trojan Panel Backend (default: local host): " trojan_panel_ip + [[ -z "${trojan_panel_ip}" ]] && trojan_panel_ip="127.0.0.1" + read -r -p "Please enter the service port of the Trojan Panel Backend (default: 8081): " trojan_panel_server_port + [[ -z "${trojan_panel_server_port}" ]] && trojan_panel_server_port=8081 + + read -r -p "Please enter the port of the Trojan Panel Frontend (default: 8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + while read -r -p "Please choose whether to enable https on the Trojan Panel Frontend? (0/off 1/on default: 1): " ui_https; do + if [[ -z ${ui_https} || ${ui_https} == 1 ]]; then + install_custom_cert "custom_cert" + domain=$(cat "${DOMAIN_FILE}") + ui_https_config + break + elif [[ ${ui_https} == 0 ]]; then + ui_http_config + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + docker pull jonssonyan/trojan-panel-ui:2.1.6 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.6 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Frontend installation completed" + + https_flag=$([[ -z ${ui_https} || ${ui_https} == 1 ]] && echo "https" || echo "http") + domain_or_ip=$([[ -z ${domain} || "${domain}" == "custom_cert" ]] && echo "ip" || echo "${domain}") + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel Frontend installed successfully" + echo_content yellow "Web management panel address: ${https_flag}://${domain_or_ip}:${trojan_panel_ui_port}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel Frontend installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Frontend" + fi +} + +# Install Trojan Panel Backend +install_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> Install Trojan Panel Backend" + + read -r -p "Please enter the service port of the Trojan Panel Backend (default: 8081): " trojan_panel_port + [[ -z "${trojan_panel_port}" ]] && trojan_panel_port=8081 + + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -e "create database if not exists trojan_panel_db;" &>/dev/null + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker pull jonssonyan/trojan-panel:2.2.0 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.2.0 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Backend installation completed" + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel Backend installed successfully" + echo_content yellow "MariaDB ${mariadb_user} password (please keep it safe): ${mariadb_pas}" + echo_content yellow "Redis password (please keep it safe): ${redis_pass}" + echo_content yellow "System administrator Default username: sysadmin Default password: 123456" + echo_content yellow "Please log in to the management panel to change the password in time" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel Backend installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Backend" + fi +} + +# Install Trojan Panel Core +install_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> Install Trojan Panel Core" + + read -r -p "Please enter the service port of the Trojan Panel Core (default: 8082): " trojan_panel_core_port + [[ -z "${trojan_panel_core_port}" ]] && trojan_panel_core_port=8082 + + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + read -r -p "Please enter the database name (default: trojan_panel_db): " database + [[ -z "${database}" ]] && database="trojan_panel_db" + read -r -p "Please enter the user table name of the database (default: account): " account_table + [[ -z "${account_table}" ]] && account_table="account" + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + read -r -p "Please enter the API port (default: 8100): " grpc_port + [[ -z "${grpc_port}" ]] && grpc_port=8100 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.2.0 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.2.0 + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Core installation completed" + else + echo_content red "---> Trojan Panel Core installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Core" + fi +} + +# Update Trojan Panel database structure +update_trojan_panel_database() { + echo_content skyBlue "---> Update Trojan Panel database structure" + + version_214_215=("v2.1.4") + if [[ "${version_214_215[*]}" =~ "${trojan_panel_current_version}" ]]; then + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "${sql_215}" &>/dev/null && + trojan_panel_current_version="v2.1.5" + fi + + echo_content skyBlue "---> Trojan Panel database structure update completed" +} + +# Update Trojan Panel Core database structure +update_trojan_panel_core_database() { + echo_content skyBlue "---> Update Trojan Panel Core database structure" + + echo_content skyBlue "---> Trojan Panel Core database structure update completed" +} + +# Update Trojan Panel Frontend +update_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content red "---> Please install the Trojan Panel Frontend first" + exit 0 + fi + + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + if [[ -z "${trojan_panel_ui_current_version}" || ! "${trojan_panel_ui_current_version}" =~ ^v.* ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Frontend (trojan-panel-ui) is ${trojan_panel_ui_current_version} the latest version is ${trojan_panel_ui_latest_version}" + + if [[ "${trojan_panel_ui_current_version}" != "${trojan_panel_ui_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Frontend" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.6 + + docker pull jonssonyan/trojan-panel-ui:2.1.6 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.6 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Frontend update completed" + else + echo_content red "---> Trojan Panel Frontend update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Frontend" + fi +} + +# Update Trojan Panel Backend +update_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content red "---> Please install the Trojan Panel Backend first" + exit 0 + fi + + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + if [[ -z "${trojan_panel_current_version}" || ! "${trojan_panel_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_current_version}" "v2.1.4") ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Backend (trojan-panel) is ${trojan_panel_current_version} The latest version is ${trojan_panel_latest_version}" + + if [[ "${trojan_panel_current_version}" != "${trojan_panel_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Backend" + + mariadb_ip=$(get_ini_value ${trojan_panel_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + trojan_panel_port=$(get_ini_value ${trojan_panel_config_path} server.port) + + update_trojan_panel_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.2.0 + + docker pull jonssonyan/trojan-panel:2.2.0 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.2.0 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel backend update completed" + else + echo_content red "---> Trojan Panel Backend update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Backend" + fi +} + +# Update Trojan Panel Core +update_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content red "---> Please install the Trojan Panel Core first" + exit 0 + fi + + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + if [[ -z "${trojan_panel_core_current_version}" || ! "${trojan_panel_core_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_core_current_version}" "v2.1.1") ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Core (trojan-panel-core) is ${trojan_panel_core_current_version} The latest version is ${trojan_panel_core_latest_version}" + + if [[ "${trojan_panel_core_current_version}" != "${trojan_panel_core_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Core" + + mariadb_ip=$(get_ini_value ${trojan_panel_core_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_core_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_core_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_core_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_core_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_core_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_core_config_path} redis.password) + grpc_port=$(get_ini_value ${trojan_panel_core_config_path} grpc.port) + trojan_panel_core_port=$(get_ini_value ${trojan_panel_core_config_path} server.port) + + update_trojan_panel_core_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.2.0 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.2.0 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.2.0 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Core update completed" + else + echo_content red "---> Trojan Panel Core update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Core" + fi +} + +# Uninstall Caddy2+https +uninstall_caddy2() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> Uninstall Caddy2+https" + + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_DATA} + + echo_content skyBlue "---> Caddy2+https uninstallation completed" + else + echo_content red "---> Please install Caddy2+https first" + fi +} + +# Uninstall Nginx +uninstall_nginx() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx") ]]; then + echo_content green "---> Uninstall Nginx" + + docker rm -f trojan-panel-nginx && + rm -rf ${NGINX_DATA} + + echo_content skyBlue "---> Nginx uninstallation completed" + else + echo_content red "---> Please install Nginx first" + fi +} + +# Uninstall MariaDB +uninstall_mariadb() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> Uninstall MariaDB" + + docker rm -f trojan-panel-mariadb && + rm -rf ${MARIA_DATA} + + echo_content skyBlue "---> MariaDB uninstall completed" + else + echo_content red "---> Please install MariaDB first" + fi +} + +# Uninstall Redis +uninstall_redis() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> Uninstall Redis" + + docker rm -f trojan-panel-redis && + rm -rf ${REDIS_DATA} + + echo_content skyBlue "---> Redis uninstall completed" + else + echo_content red "---> Please install Redis first" + fi +} + +# Uninstall Trojan Panel Frontend +uninstall_trojan_panel_ui() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> Uninstall Trojan Panel Frontend" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.6 && + rm -rf ${TROJAN_PANEL_UI_DATA} + + echo_content skyBlue "---> Trojan Panel Frontend uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Frontend first" + fi +} + +# Uninstall Trojan Panel Backend +uninstall_trojan_panel() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> Uninstall Trojan Panel Backend" + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.2.0 && + rm -rf ${TROJAN_PANEL_DATA} + + echo_content skyBlue "---> Trojan Panel Backend uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Backend first" + fi +} + +# Uninstall Trojan Panel Core +uninstall_trojan_panel_core() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> Uninstall Trojan Panel Core" + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.2.0 && + rm -rf ${TROJAN_PANEL_CORE_DATA} + + echo_content skyBlue "---> Trojan Panel Core uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Core first" + fi +} + +# Uninstall all Trojan Panel related containers +uninstall_all() { + echo_content green "---> Uninstall all Trojan Panel related containers" + + docker rm -f $(docker ps -a -q -f "name=^trojan-panel") + docker rmi -f $(docker images | grep "^jonssonyan/trojan-panel" | awk '{print $3}') + rm -rf ${TP_DATA} + + echo_content skyBlue "---> Uninstall all Trojan Panel related containers completed" +} + +# Modify Trojan Panel Frontend port +update_trojan_panel_ui_port() { + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content green "---> Modify Trojan Panel Frontend port" + + trojan_panel_ui_port=$(grep 'listen.*ssl' ${UI_NGINX_CONFIG} | awk '{print $2}') + if [[ -z "${trojan_panel_ui_port}" ]]; then + ui_https=0 + trojan_panel_ui_port=$(grep -oP 'listen\s+\K\d+' ${UI_NGINX_CONFIG} | awk 'NR==1') + fi + if [[ -z "${trojan_panel_ui_port}" ]]; then + echo_content red "---> Trojan Panel Frontend port not queried" + exit 0 + fi + echo_content yellow "Tip: The current port of the Trojan Panel Frontend (trojan-panel-ui) is ${trojan_panel_ui_port}" + + read -r -p "Please enter the new port of the Trojan Panel Frontend (default: 8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + + if [[ ${ui_https} == 0 ]]; then + # http + sed -i "s/listen.*;/listen ${trojan_panel_ui_port};/g" ${UI_NGINX_CONFIG} && + sed -i "s/http:\/\/\$host:.*\$request_uri;/http:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + else + # https + sed -i "s/listen.*ssl;/listen ${trojan_panel_ui_port} ssl;/g" ${UI_NGINX_CONFIG} && + sed -i "s/https:\/\/\$host:.*\$request_uri;/https:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + fi + + if [[ "$?" == "0" ]]; then + echo_content skyBlue "---> Trojan Panel Frontend port modification completed" + else + echo_content red "---> Trojan Panel Frontend port modification failed" + fi + else + echo_content red "---> The Trojan Panel Frontend is not installed or is running abnormally, please repair or uninstall and reinstall and try again" + fi +} + +# Refresh Redis cache +redis_flush_all() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content red "---> Please install Redis first" + exit 0 + fi + + if [[ -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis is running abnormally" + exit 0 + fi + + echo_content green "---> Refresh Redis cache" + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + echo_content skyBlue "---> Redis cache refresh completed" +} + +# Replace certificate +change_cert() { + domain_1=$(cat "${DOMAIN_FILE}") + + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_LOG}* && + echo "" >${CADDY_CONFIG} && + rm -rf ${WEB_PATH}* + fi + + rm -rf ${CERT_PATH}* && + echo "" >${DOMAIN_FILE} + + install_reverse_proxy + install_cert + + domain_2=$(cat "${DOMAIN_FILE}") + if [[ -n "${domain_1}" && -n "${domain_2}" ]]; then + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${NGINX_CONFIG} && + docker restart trojan-panel-nginx + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${UI_NGINX_DATA} && + docker restart trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + find /tpdata/trojan-panel-core/bin/ -type f -exec sed -i "s/${domain_1}/${domain_2}/g" {} + && + sed -i "s/${domain_1}/${domain_2}/g" ${trojan_panel_core_config_path} && + docker restart trojan-panel-core + fi + fi +} + +# Forgot sysadmin password +forget_pass() { + while :; do + echo_content yellow "1. Query MariaDB password" + echo_content yellow "2. Query Redis password" + echo_content yellow "3. Reset the username and password of the admin panel system administrator" + echo_content yellow "4. Quit" + read -r -p "Please choose (default: 4): " forget_pass_option + [[ -z "${forget_pass_option}" ]] && forget_pass_option=4 + case ${forget_pass_option} in + 1) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + echo_content red "\n==============================================================" + echo_content yellow "MariaDB ${mariadb_user} password (please keep it safe): ${mariadb_pas}" + echo_content red "\n==============================================================" + else + echo_content red "---> Please execute on the Trojan Panel backend server" + fi + ;; + 2) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + echo_content red "\n==============================================================" + echo_content yellow "Redis password (please keep it safe): ${redis_pass}" + echo_content red "\n==============================================================" + else + echo_content red "---> Please execute on the Trojan Panel backend server" + fi + ;; + 3) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "update account set username = 'sysadmin',pass = 'tFjD2X1F6i9FfWp2GDU5Vbi1conuaChDKIYbw9zMFrqvMoSz',hash='4366294571b8b267d9cf15b56660f0a70659568a86fc270a52fdc9e5' where id = 1 limit 1" + if [[ "$?" == "0" ]]; then + echo_content red "\n==============================================================" + echo_content yellow "System administrator Default username: sysadmin Default password: 123456" + echo_content yellow "Please log in to the management panel to change the password in time" + echo_content red "\n==============================================================" + else + echo_content red "Admin panel sysadmin username and password reset failed" + fi + else + echo_content red "---> Please execute on the MariaDB server" + fi + ;; + 4) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done +} + +# Fault detection +failure_testing() { + echo_content green "---> Start troubleshooting" + if [[ ! $(docker -v 2>/dev/null) ]]; then + echo_content red "---> Docker is running abnormally" + else + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + if [[ -z $(docker ps -q -f "name=^trojan-panel-caddy$" -f "status=running") ]]; then + echo_content red "---> Caddy2 is running abnormally and the running log is as follows:" + docker logs trojan-panel-caddy + fi + domain=$(cat "${DOMAIN_FILE}") + if [[ -n ${domain} && ! -f "${CERT_PATH}${domain}.crt" ]]; then + echo_content red "---> The certificate application is abnormal, please try 1. Change the sub-domain name to re-build 2. Restart the server to re-apply for the certificate 3. Re-build and select the custom certificate option" + if [[ -f ${CADDY_LOG}error.log ]]; then + echo_content red "Caddy2 error log is as follows:" + tail -n 20 ${CADDY_LOG}error.log | grep error + fi + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") && -z $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content red "---> The MariaDB is running abnormally and the running log is as follows:" + docker logs trojan-panel-mariadb + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") && -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> The Redis is running abnormally and the running log is as follows:" + docker logs trojan-panel-redis + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -z $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Backend is running abnormally and the running log is as follows:" + if [[ -f ${TROJAN_PANEL_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -z $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Frontend is running abnormally and the running log is as follows:" + docker logs trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -z $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Core is running abnormally and the running log is as follows:" + if [[ -f ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel-core + fi + fi + fi + echo_content green "---> Troubleshooting ended" +} + +log_query() { + while :; do + echo_content skyBlue "Applications that can query logs are as follows:" + echo_content yellow "1. Trojan Panel Backend" + echo_content yellow "2. Trojan Panel Frontend" + echo_content yellow "3. Quit" + read -r -p "Please select an application (default: 3): " select_log_query_type + [[ -z "${select_log_query_type}" ]] && select_log_query_type=3 + + case ${select_log_query_type} in + 1) + log_file_path=${TROJAN_PANEL_LOGS}trojan-panel.log + ;; + 2) + log_file_path=${TROJAN_PANEL_CORE_LOGS}trojan-panel-core.log + ;; + 3) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + + read -r -p "Please enter the number of rows to query (default: 20): " select_log_query_line_type + [[ -z "${select_log_query_line_type}" ]] && select_log_query_line_type=20 + + if [[ -f ${log_file_path} ]]; then + echo_content skyBlue "The log is as follows:" + tail -n ${select_log_query_line_type} ${log_file_path} + else + echo_content red "No log file exists" + fi + done +} + +version_query() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + echo_content yellow "The current version of Trojan Panel Frontend(trojan-panel-ui) is ${trojan_panel_ui_current_version} the latest version is ${trojan_panel_ui_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + echo_content yellow "The current version of Trojan Panel Backend(trojan-panel) is ${trojan_panel_current_version} the latest version is ${trojan_panel_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + echo_content yellow "The current version of Trojan Panel Core(trojan-panel-core) is ${trojan_panel_core_current_version} the latest version is ${trojan_panel_core_latest_version}" + fi +} + +main() { + cd "$HOME" || exit 0 + init_var + mkdir_tools + check_sys + depend_install + clear + echo_content red "\n==============================================================" + echo_content skyBlue "System Required: CentOS 7+/Ubuntu 18+/Debian 10+" + echo_content skyBlue "Version: v2.2.0" + echo_content skyBlue "Description: One click Install Trojan Panel server" + echo_content skyBlue "Author: jonssonyan " + echo_content skyBlue "Github: https://github.com/trojanpanel" + echo_content skyBlue "Docs: https://trojanpanel.github.io" + echo_content red "\n==============================================================" + echo_content yellow "1. Install Trojan Panel Frontend" + echo_content yellow "2. Install Trojan Panel Backend" + echo_content yellow "3. Install Trojan Panel Core" + echo_content yellow "4. Install Caddy2+https" + echo_content yellow "5. Install Nginx" + echo_content yellow "6. Install MariaDB" + echo_content yellow "7. Install Redis" + echo_content green "\n==============================================================" + echo_content yellow "8. Update Trojan Panel Frontend" + echo_content yellow "9. Update Trojan Panel Backend" + echo_content yellow "10. Update Trojan Panel Core" + echo_content green "\n==============================================================" + echo_content yellow "11. Uninstall Trojan Panel Frontend" + echo_content yellow "12. Uninstall Trojan Panel Backend" + echo_content yellow "13. Uninstall Trojan Panel Core" + echo_content yellow "14. Uninstall Caddy2+https" + echo_content yellow "15. Uninstall Nginx" + echo_content yellow "16. Uninstall MariaDB" + echo_content yellow "17. Uninstall Redis" + echo_content yellow "18. Uninstall all Trojan Panel related containers" + echo_content green "\n==============================================================" + echo_content yellow "19. Modify Trojan Panel Frontend port" + echo_content yellow "20. Refresh Redis cache" + echo_content yellow "21. Replace certificate" + echo_content yellow "22. Forgot sysadmin password" + echo_content green "\n==============================================================" + echo_content yellow "23. Fault detection" + echo_content yellow "24. Log query" + echo_content yellow "25. Version query" + read -r -p "Please choose: " selectInstall_type + case ${selectInstall_type} in + 1) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_ui + ;; + 2) + install_docker + install_mariadb + install_redis + install_trojan_panel + ;; + 3) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_core + ;; + 4) + install_docker + install_caddy2 + ;; + 5) + install_docker + install_nginx + ;; + 6) + install_docker + install_mariadb + ;; + 7) + install_docker + install_redis + ;; + 8) + update_trojan_panel_ui + ;; + 9) + update_trojan_panel + ;; + 10) + update_trojan_panel_core + ;; + 11) + uninstall_trojan_panel_ui + ;; + 12) + uninstall_trojan_panel + ;; + 13) + uninstall_trojan_panel_core + ;; + 14) + uninstall_caddy2 + ;; + 15) + uninstall_nginx + ;; + 16) + uninstall_mariadb + ;; + 17) + uninstall_redis + ;; + 18) + uninstall_all + ;; + 19) + update_trojan_panel_ui_port + ;; + 20) + redis_flush_all + ;; + 21) + change_cert + ;; + 22) + forget_pass + ;; + 23) + failure_testing + ;; + 24) + log_query + ;; + 25) + version_query + ;; + *) + echo_content red "No such option" + ;; + esac +} + +main diff --git a/lib/archive/install_script_v2.2.1.sh b/lib/archive/install_script_v2.2.1.sh new file mode 100644 index 0000000..3095f8b --- /dev/null +++ b/lib/archive/install_script_v2.2.1.sh @@ -0,0 +1,2005 @@ +#!/usr/bin/env bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +# System Required: CentOS 7+/Ubuntu 18+/Debian 10+ +# Version: v2.2.1 +# Description: One click Install Trojan Panel server +# Author: jonssonyan +# Github: https://github.com/trojanpanel/install-script + +init_var() { + ECHO_TYPE="echo -e" + + package_manager="" + release="" + get_arch="" + can_google=0 + + # Docker + DOCKER_MIRROR='"https://hub-mirror.c.163.com","https://ccr.ccs.tencentyun.com","https://mirror.baidubce.com","https://dockerproxy.com"' + + # Project directory + TP_DATA="/tpdata/" + + STATIC_HTML="https://github.com/trojanpanel/install-script/releases/download/v1.0/html.tar.gz" + + # Web + WEB_PATH="/tpdata/web/" + + # Cert + CERT_PATH="/tpdata/cert/" + DOMAIN_FILE="/tpdata/domain.lock" + domain="" + crt_path="" + key_path="" + + # Caddy2 + CADDY_DATA="/tpdata/caddy/" + CADDY_CONFIG="${CADDY_DATA}config.json" + CADDY_LOG="${CADDY_DATA}logs/" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + caddy_port=80 + caddy_remote_port=8863 + your_email="" + ssl_option=1 + ssl_module_type=1 + ssl_module="acme" + + # Nginx + NGINX_DATA="/tpdata/nginx/" + NGINX_CONFIG="${NGINX_DATA}default.conf" + nginx_port=80 + nginx_remote_port=8863 + nginx_https=1 + + # MariaDB + MARIA_DATA="/tpdata/mariadb/" + mariadb_ip="127.0.0.1" + mariadb_port=9507 + mariadb_user="root" + mariadb_pas="" + + # Redis + REDIS_DATA="/tpdata/redis/" + redis_host="127.0.0.1" + redis_port=6378 + redis_pass="" + + # Trojan Panel Frontend + TROJAN_PANEL_UI_DATA="/tpdata/trojan-panel-ui/" + # Nginx + UI_NGINX_DATA="${TROJAN_PANEL_UI_DATA}nginx/" + UI_NGINX_CONFIG="${UI_NGINX_DATA}default.conf" + trojan_panel_ui_port=8888 + ui_https=1 + trojan_panel_ip="127.0.0.1" + trojan_panel_server_port=8081 + + # Trojan Panel Backend + TROJAN_PANEL_DATA="/tpdata/trojan-panel/" + TROJAN_PANEL_WEBFILE="${TROJAN_PANEL_DATA}webfile/" + TROJAN_PANEL_LOGS="${TROJAN_PANEL_DATA}logs/" + TROJAN_PANEL_CONFIG="${TROJAN_PANEL_DATA}config/" + trojan_panel_config_path="${TROJAN_PANEL_DATA}config/config.ini" + trojan_panel_port=8081 + + # Trojan Panel Core + TROJAN_PANEL_CORE_DATA="/tpdata/trojan-panel-core/" + TROJAN_PANEL_CORE_LOGS="${TROJAN_PANEL_CORE_DATA}logs/" + TROJAN_PANEL_CORE_CONFIG="${TROJAN_PANEL_CORE_DATA}config/" + trojan_panel_core_config_path="${TROJAN_PANEL_CORE_DATA}config/config.ini" + database="trojan_panel_db" + account_table="account" + grpc_port=8100 + trojan_panel_core_port=8082 + + # Version + trojan_panel_ui_current_version="" + trojan_panel_ui_latest_version="v2.1.6" + trojan_panel_current_version="" + trojan_panel_latest_version="v2.2.0" + trojan_panel_core_current_version="" + trojan_panel_core_latest_version="v2.2.1" + + # SQL + sql_215="alter table account change validity_period preset_expire int unsigned default 0 not null comment '预设过期时长';alter table account add preset_quota bigint default 0 not null comment '预设配额' after preset_expire;update account set preset_quota = quota where last_login_time = 0;update account set quota = 0 where last_login_time = 0;alter table node add priority int default 100 not null comment '优先级' after port;INSERT INTO casbin_rule (p_type, v0, v1, v2, v3, v4, v5) VALUES ('p', 'sysadmin', '/api/account/clashSubscribeForSb', 'GET', 'default', 'default', 'default');alter table node_hysteria add server_name varchar(64) default '' not null comment '用于验证服务端证书的 hostname' after down_mbps;alter table node_hysteria add insecure tinyint(1) default 0 not null comment '忽略一切证书错误' after server_name;alter table node_hysteria add fast_open tinyint(1) default 0 not null comment '启用 Fast Open (降低连接建立延迟)' after insecure;" +} + +echo_content() { + case $1 in + "red") + ${ECHO_TYPE} "\033[31m$2\033[0m" + ;; + "green") + ${ECHO_TYPE} "\033[32m$2\033[0m" + ;; + "yellow") + ${ECHO_TYPE} "\033[33m$2\033[0m" + ;; + "blue") + ${ECHO_TYPE} "\033[34m$2\033[0m" + ;; + "purple") + ${ECHO_TYPE} "\033[35m$2\033[0m" + ;; + "skyBlue") + ${ECHO_TYPE} "\033[36m$2\033[0m" + ;; + "white") + ${ECHO_TYPE} "\033[37m$2\033[0m" + ;; + esac +} + +mkdir_tools() { + # Project directory + mkdir -p ${TP_DATA} + + # Web + mkdir -p ${WEB_PATH} + + # Cert + mkdir -p ${CERT_PATH} + touch ${DOMAIN_FILE} + + # Caddy2 + mkdir -p ${CADDY_DATA} + touch ${CADDY_CONFIG} + mkdir -p ${CADDY_LOG} + + # Nginx + mkdir -p ${NGINX_DATA} + touch ${NGINX_CONFIG} + + # MariaDB + mkdir -p ${MARIA_DATA} + + # Redis + mkdir -p ${REDIS_DATA} + + # Trojan Panel Frontend + mkdir -p ${TROJAN_PANEL_UI_DATA} + # Nginx + mkdir -p ${UI_NGINX_DATA} + touch ${UI_NGINX_CONFIG} + + # Trojan Panel Backend + mkdir -p ${TROJAN_PANEL_DATA} + mkdir -p ${TROJAN_PANEL_LOGS} + + # Trojan Panel Core + mkdir -p ${TROJAN_PANEL_CORE_DATA} + mkdir -p ${TROJAN_PANEL_CORE_LOGS} +} + +can_connect() { + ping -c2 -i0.3 -W1 "$1" &>/dev/null + if [[ "$?" == "0" ]]; then + return 0 + else + return 1 + fi +} + +# query .ini configuration file information +get_ini_value() { + local config_file="$1" + local key="$2" + local section="" + local section_flag=0 + + # split group and key names + IFS='.' read -r group_name key_name <<<"$key" + + while IFS='=' read -r name val; do + # processing section name + if [[ $name =~ ^\[(.*)\]$ ]]; then + section="${BASH_REMATCH[1]}" + if [[ $section == $group_name ]]; then + section_flag=1 + else + section_flag=0 + fi + continue + fi + + # extract the value of the configuration item + if [[ $section_flag -eq 1 && $name == $key_name ]]; then + echo "$val" + return + fi + done <"$config_file" +} + +# Version number comparison greater than or equal to +version_ge() { + local v1=${1#v} + local v2=${2#v} + + local v1_parts=(${v1//./ }) + local v2_parts=(${v2//./ }) + + for ((i = 0; i < 3; i++)); do + if ((${v1_parts[i]} < ${v2_parts[i]})); then + echo false + return 0 + elif ((${v1_parts[i]} > ${v2_parts[i]})); then + echo true + return 0 + fi + done + echo true +} + +check_sys() { + if [[ $(command -v yum) ]]; then + package_manager='yum' + elif [[ $(command -v dnf) ]]; then + package_manager='dnf' + elif [[ $(command -v apt) ]]; then + package_manager='apt' + elif [[ $(command -v apt-get) ]]; then + package_manager='apt-get' + fi + + if [[ -z "${package_manager}" ]]; then + echo_content red "The system is not currently supported" + exit 0 + fi + + if [[ -n $(find /etc -name "redhat-release") ]] || grep /dev/null) ]]; then + echo_content green "---> Install Docker" + + # turn off firewall + if [[ "${release}" == "centos" ]]; then + systemctl disable firewalld + elif [[ "${release}" == "debian" || "${release}" == "ubuntu" ]]; then + sudo ufw disable + fi + + # set time zone + timedatectl set-timezone Asia/Shanghai + + if [[ ${can_google} == 0 ]]; then + sh <(curl -sL https://get.docker.com) --mirror Aliyun + mkdir -p /etc/docker && + cat >/etc/docker/daemon.json </etc/docker/daemon.json </dev/null) ]]; then + echo_content skyBlue "---> Docker installation completed" + else + echo_content red "---> Docker installation failed" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Docker" + fi +} + +# Custom Settings Certificate +install_custom_cert() { + if [[ -z "$(cat "${DOMAIN_FILE}")" ]]; then + while read -r -p "Please enter the file path of the .crt certificate (required): " crt_path; do + if [[ -z "${crt_path}" ]]; then + echo_content red "Path cannot be empty" + else + if [[ ! -f "${crt_path}" ]]; then + echo_content red "The file path for the .crt certificate does not exist" + else + cp "${crt_path}" "${CERT_PATH}$1.crt" + break + fi + fi + done + while read -r -p "Please enter the file path of the .key certificate (required): " key_path; do + if [[ -z "${key_path}" ]]; then + echo_content red "Path cannot be empty" + else + if [[ ! -f "${key_path}" ]]; then + echo_content red "The file path for the .key certificate does not exist" + else + cp "${key_path}" "${CERT_PATH}$1.key" + break + fi + fi + done + cat >${DOMAIN_FILE} < Custom settings certificate installation completed" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + fi +} + +# Caddy2 https custom settings certificate configuration file +caddy2_https_config() { + domain=$1 + cat >${CADDY_CONFIG} <${CADDY_CONFIG} < Install Caddy2+https" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "Please enter the port of Caddy2 (default: 80): " caddy_port + [[ -z "${caddy_port}" ]] && caddy_port=80 + read -r -p "Please enter the forwarding port of Caddy2 (default: 8863): " caddy_remote_port + [[ -z "${caddy_remote_port}" ]] && caddy_remote_port=8863 + + echo_content yellow "Tip: Please confirm that the domain name has been resolved to this machine, otherwise the installation may fail" + while read -r -p "Please enter your domain name (required): " domain; do + if [[ -z "${domain}" ]]; then + echo_content red "Domain name cannot be empty" + else + break + fi + done + + read -r -p "Please enter your email (optional): " your_email + + while read -r -p "Please choose the way to set up the certificate? (1/automatically apply for and renew the certificate 2/manually set the certificate path default: 1: " ssl_option; do + if [[ -z ${ssl_option} || ${ssl_option} == 1 ]]; then + while read -r -p "Please choose the way to apply for the certificate (1/acme 2/zerossl default: 1: " ssl_module_type; do + if [[ -z "${ssl_module_type}" || ${ssl_module_type} == 1 ]]; then + ssl_module="acme" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + break + elif [[ ${ssl_module_type} == 2 ]]; then + ssl_module="zerossl" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme.zerossl.com-v2-dv90/" + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + caddy2_https_auto_config "${domain}" + break + elif [[ ${ssl_option} == 2 ]]; then + install_custom_cert "${domain}" + caddy2_https_config "${domain}" + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + # Caddy2 temporary listening port for automatic certificate application + if [[ -n $(lsof -i:${caddy_port},${caddy_remote_port} -t) ]]; then + kill -9 "$(lsof -i:${caddy_port},${caddy_remote_port} -t)" + fi + + docker pull caddy:2.6.2 && + docker run -d --name trojan-panel-caddy --restart always \ + --network=host \ + -v "${CADDY_CONFIG}":"${CADDY_CONFIG}" \ + -v ${CERT_PATH}:"${CADDY_CERT_DIR}${domain}/" \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v ${CADDY_LOG}:${CADDY_LOG} \ + caddy:2.6.2 caddy run --config ${CADDY_CONFIG} + + cat >${DOMAIN_FILE} < Caddy2+https installation completed" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> Caddy2+https installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Caddy2+https" + fi +} + +# Nginx http configuration file +nginx_http_config() { + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + error_page 497 http://\$host:${nginx_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Nginx https configuration file +nginx_https_config() { + domain=$1 + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + return 301 http://\$host:${nginx_remote_port}\$request_uri; +} + +server { + listen ${nginx_remote_port} ssl; + server_name localhost; + + # force ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + # cache validity period + ssl_session_timeout 5m; + # secure link optional encryption protocol + ssl_protocols TLSv1.3; + # encryption algorithm + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + # use server-side preferred algorithm + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${nginx_remote_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Install Nginx +install_nginx() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + echo_content green "---> Install Nginx" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "Please enter the port of Nginx (default: 80): " nginx_port + [[ -z "${nginx_port}" ]] && nginx_port=80 + read -r -p "Please enter the forwarding port of Nginx (default: 8863): " nginx_remote_port + [[ -z "${nginx_remote_port}" ]] && nginx_remote_port=8863 + + while read -r -p "Please choose whether to enable https in Nginx? (0/off 1/on default: 1): " nginx_https; do + if [[ -z ${nginx_https} || ${nginx_https} == 1 ]]; then + install_custom_cert "custom_cert" + nginx_https_config "custom_cert" + break + elif [[ ${nginx_https} == 0 ]]; then + nginx_http_config + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + docker pull nginx:1.20-alpine && + docker run -d --name trojan-panel-nginx --restart always \ + --network=host \ + -v "${NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + nginx:1.20-alpine + + if [[ -n $(docker ps -q -f "name=^trojan-panel-nginx$" -f "status=running") ]]; then + echo_content skyBlue "---> Nginx installation completed" + else + echo_content red "---> Nginx installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Nginx" + fi +} + +# Install a web server +install_reverse_proxy() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$|^trojan-panel-nginx$") ]]; then + echo_content green "---> Install a web server" + + while :; do + echo_content yellow "1. Install Caddy2+https (recommend)" + echo_content yellow "2. Install Nginx" + echo_content yellow "3. Not install" + read -r -p "Please select (default: 1): " whether_install_reverse_proxy + [[ -z "${whether_install_reverse_proxy}" ]] && whether_install_reverse_proxy=1 + + case ${whether_install_reverse_proxy} in + 1) + install_caddy2 + break + ;; + 2) + install_nginx + break + ;; + 3) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done + + echo_content skyBlue "---> Web server installation completed" + fi +} + +# Set certificate +install_cert() { + if [[ -z "$(cat "${DOMAIN_FILE}")" ]]; then + echo_content green "---> Set certificate" + + while :; do + echo_content yellow "1. Custom certificate" + echo_content yellow "2. Not set" + read -r -p "Please select (default: 1): " whether_install_cert + [[ -z "${whether_install_cert}" ]] && whether_install_cert=1 + + case ${whether_install_cert} in + 1) + install_custom_cert "custom_cert" + break + ;; + 2) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done + + echo_content green "---> Certificate setup completed" + fi +} + +# Install MariaDB +install_mariadb() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> Install MariaDB" + + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + if [[ "${mariadb_user}" == "root" ]]; then + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + else + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e MYSQL_USER="${mariadb_user}" \ + -e MYSQL_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + fi + + if [[ -n $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content skyBlue "---> MariaDB installation completed" + echo_content yellow "---> The MariaDB password of root (please keep it safe): ${mariadb_pas}" + if [[ "${mariadb_user}" != "root" ]]; then + echo_content yellow "---> The MariaDB password of ${mariadb_user} (please keep it safe): ${mariadb_pas}" + fi + else + echo_content red "---> MariaDB installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed MariaDB" + fi +} + +# Install Redis +install_redis() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> Install Redis" + + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker pull redis:6.2.7 && + docker run -d --name trojan-panel-redis --restart always \ + --network=host \ + redis:6.2.7 \ + redis-server --requirepass "${redis_pass}" --port "${redis_port}" + + if [[ -n $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content skyBlue "---> Redis installation completed" + echo_content yellow "---> Redis password (please keep it safe): ${redis_pass}" + else + echo_content red "---> Redis installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Redis" + fi +} + +# Trojan Panel Frontend Nginx http configuration file +ui_http_config() { + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port}; + server_name localhost; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + error_page 497 http://\$host:${trojan_panel_ui_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Trojan Panel Frontend Nginx https configuration file +ui_https_config() { + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port} ssl; + server_name localhost; + + # force ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + # cache validity period + ssl_session_timeout 5m; + # secure link optional encryption protocol + ssl_protocols TLSv1.3; + # encryption algorithm + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + # use server-side preferred algorithm + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${trojan_panel_ui_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Install Trojan Panel Frontend +install_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> Install Trojan Panel Frontend" + + read -r -p "Please enter the IP address of the Trojan Panel Backend (default: local host): " trojan_panel_ip + [[ -z "${trojan_panel_ip}" ]] && trojan_panel_ip="127.0.0.1" + read -r -p "Please enter the service port of the Trojan Panel Backend (default: 8081): " trojan_panel_server_port + [[ -z "${trojan_panel_server_port}" ]] && trojan_panel_server_port=8081 + + read -r -p "Please enter the port of the Trojan Panel Frontend (default: 8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + while read -r -p "Please choose whether to enable https on the Trojan Panel Frontend? (0/off 1/on default: 1): " ui_https; do + if [[ -z ${ui_https} || ${ui_https} == 1 ]]; then + install_custom_cert "custom_cert" + domain=$(cat "${DOMAIN_FILE}") + ui_https_config + break + elif [[ ${ui_https} == 0 ]]; then + ui_http_config + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + docker pull jonssonyan/trojan-panel-ui:2.1.6 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.6 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Frontend installation completed" + + https_flag=$([[ -z ${ui_https} || ${ui_https} == 1 ]] && echo "https" || echo "http") + domain_or_ip=$([[ -z ${domain} || "${domain}" == "custom_cert" ]] && echo "ip" || echo "${domain}") + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel Frontend installed successfully" + echo_content yellow "Web management panel address: ${https_flag}://${domain_or_ip}:${trojan_panel_ui_port}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel Frontend installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Frontend" + fi +} + +# Install Trojan Panel Backend +install_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> Install Trojan Panel Backend" + + read -r -p "Please enter the service port of the Trojan Panel Backend (default: 8081): " trojan_panel_port + [[ -z "${trojan_panel_port}" ]] && trojan_panel_port=8081 + + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -e "create database if not exists trojan_panel_db;" &>/dev/null + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker pull jonssonyan/trojan-panel:2.2.0 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.2.0 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Backend installation completed" + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel Backend installed successfully" + echo_content yellow "MariaDB ${mariadb_user} password (please keep it safe): ${mariadb_pas}" + echo_content yellow "Redis password (please keep it safe): ${redis_pass}" + echo_content yellow "System administrator Default username: sysadmin Default password: 123456" + echo_content yellow "Please log in to the management panel to change the password in time" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel Backend installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Backend" + fi +} + +# Install Trojan Panel Core +install_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> Install Trojan Panel Core" + + read -r -p "Please enter the service port of the Trojan Panel Core (default: 8082): " trojan_panel_core_port + [[ -z "${trojan_panel_core_port}" ]] && trojan_panel_core_port=8082 + + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + read -r -p "Please enter the database name (default: trojan_panel_db): " database + [[ -z "${database}" ]] && database="trojan_panel_db" + read -r -p "Please enter the user table name of the database (default: account): " account_table + [[ -z "${account_table}" ]] && account_table="account" + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + read -r -p "Please enter the API port (default: 8100): " grpc_port + [[ -z "${grpc_port}" ]] && grpc_port=8100 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.2.1 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.2.1 + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Core installation completed" + else + echo_content red "---> Trojan Panel Core installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Core" + fi +} + +# Update Trojan Panel database structure +update_trojan_panel_database() { + echo_content skyBlue "---> Update Trojan Panel database structure" + + version_214_215=("v2.1.4") + if [[ "${version_214_215[*]}" =~ "${trojan_panel_current_version}" ]]; then + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "${sql_215}" &>/dev/null && + trojan_panel_current_version="v2.1.5" + fi + + echo_content skyBlue "---> Trojan Panel database structure update completed" +} + +# Update Trojan Panel Core database structure +update_trojan_panel_core_database() { + echo_content skyBlue "---> Update Trojan Panel Core database structure" + + echo_content skyBlue "---> Trojan Panel Core database structure update completed" +} + +# Update Trojan Panel Frontend +update_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content red "---> Please install the Trojan Panel Frontend first" + exit 0 + fi + + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + if [[ -z "${trojan_panel_ui_current_version}" || ! "${trojan_panel_ui_current_version}" =~ ^v.* ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Frontend (trojan-panel-ui) is ${trojan_panel_ui_current_version} the latest version is ${trojan_panel_ui_latest_version}" + + if [[ "${trojan_panel_ui_current_version}" != "${trojan_panel_ui_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Frontend" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.6 + + docker pull jonssonyan/trojan-panel-ui:2.1.6 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.1.6 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Frontend update completed" + else + echo_content red "---> Trojan Panel Frontend update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Frontend" + fi +} + +# Update Trojan Panel Backend +update_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content red "---> Please install the Trojan Panel Backend first" + exit 0 + fi + + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + if [[ -z "${trojan_panel_current_version}" || ! "${trojan_panel_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_current_version}" "v2.1.4") ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Backend (trojan-panel) is ${trojan_panel_current_version} The latest version is ${trojan_panel_latest_version}" + + if [[ "${trojan_panel_current_version}" != "${trojan_panel_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Backend" + + mariadb_ip=$(get_ini_value ${trojan_panel_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + trojan_panel_port=$(get_ini_value ${trojan_panel_config_path} server.port) + + update_trojan_panel_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.2.0 + + docker pull jonssonyan/trojan-panel:2.2.0 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.2.0 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel backend update completed" + else + echo_content red "---> Trojan Panel Backend update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Backend" + fi +} + +# Update Trojan Panel Core +update_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content red "---> Please install the Trojan Panel Core first" + exit 0 + fi + + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + if [[ -z "${trojan_panel_core_current_version}" || ! "${trojan_panel_core_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_core_current_version}" "v2.1.1") ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Core (trojan-panel-core) is ${trojan_panel_core_current_version} The latest version is ${trojan_panel_core_latest_version}" + + if [[ "${trojan_panel_core_current_version}" != "${trojan_panel_core_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Core" + + mariadb_ip=$(get_ini_value ${trojan_panel_core_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_core_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_core_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_core_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_core_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_core_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_core_config_path} redis.password) + grpc_port=$(get_ini_value ${trojan_panel_core_config_path} grpc.port) + trojan_panel_core_port=$(get_ini_value ${trojan_panel_core_config_path} server.port) + + update_trojan_panel_core_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.2.1 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.2.1 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.2.1 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Core update completed" + else + echo_content red "---> Trojan Panel Core update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Core" + fi +} + +# Uninstall Caddy2+https +uninstall_caddy2() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> Uninstall Caddy2+https" + + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_DATA} + + echo_content skyBlue "---> Caddy2+https uninstallation completed" + else + echo_content red "---> Please install Caddy2+https first" + fi +} + +# Uninstall Nginx +uninstall_nginx() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx") ]]; then + echo_content green "---> Uninstall Nginx" + + docker rm -f trojan-panel-nginx && + rm -rf ${NGINX_DATA} + + echo_content skyBlue "---> Nginx uninstallation completed" + else + echo_content red "---> Please install Nginx first" + fi +} + +# Uninstall MariaDB +uninstall_mariadb() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> Uninstall MariaDB" + + docker rm -f trojan-panel-mariadb && + rm -rf ${MARIA_DATA} + + echo_content skyBlue "---> MariaDB uninstall completed" + else + echo_content red "---> Please install MariaDB first" + fi +} + +# Uninstall Redis +uninstall_redis() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> Uninstall Redis" + + docker rm -f trojan-panel-redis && + rm -rf ${REDIS_DATA} + + echo_content skyBlue "---> Redis uninstall completed" + else + echo_content red "---> Please install Redis first" + fi +} + +# Uninstall Trojan Panel Frontend +uninstall_trojan_panel_ui() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> Uninstall Trojan Panel Frontend" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.1.6 && + rm -rf ${TROJAN_PANEL_UI_DATA} + + echo_content skyBlue "---> Trojan Panel Frontend uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Frontend first" + fi +} + +# Uninstall Trojan Panel Backend +uninstall_trojan_panel() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> Uninstall Trojan Panel Backend" + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.2.0 && + rm -rf ${TROJAN_PANEL_DATA} + + echo_content skyBlue "---> Trojan Panel Backend uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Backend first" + fi +} + +# Uninstall Trojan Panel Core +uninstall_trojan_panel_core() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> Uninstall Trojan Panel Core" + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.2.1 && + rm -rf ${TROJAN_PANEL_CORE_DATA} + + echo_content skyBlue "---> Trojan Panel Core uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Core first" + fi +} + +# Uninstall all Trojan Panel related containers +uninstall_all() { + echo_content green "---> Uninstall all Trojan Panel related containers" + + docker rm -f $(docker ps -a -q -f "name=^trojan-panel") + docker rmi -f $(docker images | grep "^jonssonyan/trojan-panel" | awk '{print $3}') + rm -rf ${TP_DATA} + + echo_content skyBlue "---> Uninstall all Trojan Panel related containers completed" +} + +# Modify Trojan Panel Frontend port +update_trojan_panel_ui_port() { + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content green "---> Modify Trojan Panel Frontend port" + + trojan_panel_ui_port=$(grep 'listen.*ssl' ${UI_NGINX_CONFIG} | awk '{print $2}') + if [[ -z "${trojan_panel_ui_port}" ]]; then + ui_https=0 + trojan_panel_ui_port=$(grep -oP 'listen\s+\K\d+' ${UI_NGINX_CONFIG} | awk 'NR==1') + fi + if [[ -z "${trojan_panel_ui_port}" ]]; then + echo_content red "---> Trojan Panel Frontend port not queried" + exit 0 + fi + echo_content yellow "Tip: The current port of the Trojan Panel Frontend (trojan-panel-ui) is ${trojan_panel_ui_port}" + + read -r -p "Please enter the new port of the Trojan Panel Frontend (default: 8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + + if [[ ${ui_https} == 0 ]]; then + # http + sed -i "s/listen.*;/listen ${trojan_panel_ui_port};/g" ${UI_NGINX_CONFIG} && + sed -i "s/http:\/\/\$host:.*\$request_uri;/http:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + else + # https + sed -i "s/listen.*ssl;/listen ${trojan_panel_ui_port} ssl;/g" ${UI_NGINX_CONFIG} && + sed -i "s/https:\/\/\$host:.*\$request_uri;/https:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + fi + + if [[ "$?" == "0" ]]; then + echo_content skyBlue "---> Trojan Panel Frontend port modification completed" + else + echo_content red "---> Trojan Panel Frontend port modification failed" + fi + else + echo_content red "---> The Trojan Panel Frontend is not installed or is running abnormally, please repair or uninstall and reinstall and try again" + fi +} + +# Refresh Redis cache +redis_flush_all() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content red "---> Please install Redis first" + exit 0 + fi + + if [[ -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis is running abnormally" + exit 0 + fi + + echo_content green "---> Refresh Redis cache" + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + echo_content skyBlue "---> Redis cache refresh completed" +} + +# Replace certificate +change_cert() { + domain_1=$(cat "${DOMAIN_FILE}") + + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_LOG}* && + echo "" >${CADDY_CONFIG} && + rm -rf ${WEB_PATH}* + fi + + rm -rf ${CERT_PATH}* && + echo "" >${DOMAIN_FILE} + + install_reverse_proxy + install_cert + + domain_2=$(cat "${DOMAIN_FILE}") + if [[ -n "${domain_1}" && -n "${domain_2}" ]]; then + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${NGINX_CONFIG} && + docker restart trojan-panel-nginx + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${UI_NGINX_DATA} && + docker restart trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + find /tpdata/trojan-panel-core/bin/ -type f -exec sed -i "s/${domain_1}/${domain_2}/g" {} + && + sed -i "s/${domain_1}/${domain_2}/g" ${trojan_panel_core_config_path} && + docker restart trojan-panel-core + fi + fi +} + +# Forgot sysadmin password +forget_pass() { + while :; do + echo_content yellow "1. Query MariaDB password" + echo_content yellow "2. Query Redis password" + echo_content yellow "3. Reset the username and password of the admin panel system administrator" + echo_content yellow "4. Quit" + read -r -p "Please choose (default: 4): " forget_pass_option + [[ -z "${forget_pass_option}" ]] && forget_pass_option=4 + case ${forget_pass_option} in + 1) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + echo_content red "\n==============================================================" + echo_content yellow "MariaDB ${mariadb_user} password (please keep it safe): ${mariadb_pas}" + echo_content red "\n==============================================================" + else + echo_content red "---> Please execute on the Trojan Panel backend server" + fi + ;; + 2) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + echo_content red "\n==============================================================" + echo_content yellow "Redis password (please keep it safe): ${redis_pass}" + echo_content red "\n==============================================================" + else + echo_content red "---> Please execute on the Trojan Panel backend server" + fi + ;; + 3) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "update account set username = 'sysadmin',pass = 'tFjD2X1F6i9FfWp2GDU5Vbi1conuaChDKIYbw9zMFrqvMoSz',hash='4366294571b8b267d9cf15b56660f0a70659568a86fc270a52fdc9e5' where id = 1 limit 1" + if [[ "$?" == "0" ]]; then + echo_content red "\n==============================================================" + echo_content yellow "System administrator Default username: sysadmin Default password: 123456" + echo_content yellow "Please log in to the management panel to change the password in time" + echo_content red "\n==============================================================" + else + echo_content red "Admin panel sysadmin username and password reset failed" + fi + else + echo_content red "---> Please execute on the MariaDB server" + fi + ;; + 4) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done +} + +# Fault detection +failure_testing() { + echo_content green "---> Start troubleshooting" + if [[ ! $(docker -v 2>/dev/null) ]]; then + echo_content red "---> Docker is running abnormally" + else + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + if [[ -z $(docker ps -q -f "name=^trojan-panel-caddy$" -f "status=running") ]]; then + echo_content red "---> Caddy2 is running abnormally and the running log is as follows:" + docker logs trojan-panel-caddy + fi + domain=$(cat "${DOMAIN_FILE}") + if [[ -n ${domain} && ! -f "${CERT_PATH}${domain}.crt" ]]; then + echo_content red "---> The certificate application is abnormal, please try 1. Change the sub-domain name to re-build 2. Restart the server to re-apply for the certificate 3. Re-build and select the custom certificate option" + if [[ -f ${CADDY_LOG}error.log ]]; then + echo_content red "Caddy2 error log is as follows:" + tail -n 20 ${CADDY_LOG}error.log | grep error + fi + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") && -z $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content red "---> The MariaDB is running abnormally and the running log is as follows:" + docker logs trojan-panel-mariadb + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") && -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> The Redis is running abnormally and the running log is as follows:" + docker logs trojan-panel-redis + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -z $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Backend is running abnormally and the running log is as follows:" + if [[ -f ${TROJAN_PANEL_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -z $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Frontend is running abnormally and the running log is as follows:" + docker logs trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -z $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Core is running abnormally and the running log is as follows:" + if [[ -f ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel-core + fi + fi + fi + echo_content green "---> Troubleshooting ended" +} + +log_query() { + while :; do + echo_content skyBlue "Applications that can query logs are as follows:" + echo_content yellow "1. Trojan Panel Backend" + echo_content yellow "2. Trojan Panel Frontend" + echo_content yellow "3. Quit" + read -r -p "Please select an application (default: 3): " select_log_query_type + [[ -z "${select_log_query_type}" ]] && select_log_query_type=3 + + case ${select_log_query_type} in + 1) + log_file_path=${TROJAN_PANEL_LOGS}trojan-panel.log + ;; + 2) + log_file_path=${TROJAN_PANEL_CORE_LOGS}trojan-panel-core.log + ;; + 3) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + + read -r -p "Please enter the number of rows to query (default: 20): " select_log_query_line_type + [[ -z "${select_log_query_line_type}" ]] && select_log_query_line_type=20 + + if [[ -f ${log_file_path} ]]; then + echo_content skyBlue "The log is as follows:" + tail -n ${select_log_query_line_type} ${log_file_path} + else + echo_content red "No log file exists" + fi + done +} + +version_query() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + echo_content yellow "The current version of Trojan Panel Frontend(trojan-panel-ui) is ${trojan_panel_ui_current_version} the latest version is ${trojan_panel_ui_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + echo_content yellow "The current version of Trojan Panel Backend(trojan-panel) is ${trojan_panel_current_version} the latest version is ${trojan_panel_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + echo_content yellow "The current version of Trojan Panel Core(trojan-panel-core) is ${trojan_panel_core_current_version} the latest version is ${trojan_panel_core_latest_version}" + fi +} + +main() { + cd "$HOME" || exit 0 + init_var + mkdir_tools + check_sys + depend_install + clear + echo_content red "\n==============================================================" + echo_content skyBlue "System Required: CentOS 7+/Ubuntu 18+/Debian 10+" + echo_content skyBlue "Version: v2.2.1" + echo_content skyBlue "Description: One click Install Trojan Panel server" + echo_content skyBlue "Author: jonssonyan " + echo_content skyBlue "Github: https://github.com/trojanpanel" + echo_content skyBlue "Docs: https://trojanpanel.github.io" + echo_content red "\n==============================================================" + echo_content yellow "1. Install Trojan Panel Frontend" + echo_content yellow "2. Install Trojan Panel Backend" + echo_content yellow "3. Install Trojan Panel Core" + echo_content yellow "4. Install Caddy2+https" + echo_content yellow "5. Install Nginx" + echo_content yellow "6. Install MariaDB" + echo_content yellow "7. Install Redis" + echo_content green "\n==============================================================" + echo_content yellow "8. Update Trojan Panel Frontend" + echo_content yellow "9. Update Trojan Panel Backend" + echo_content yellow "10. Update Trojan Panel Core" + echo_content green "\n==============================================================" + echo_content yellow "11. Uninstall Trojan Panel Frontend" + echo_content yellow "12. Uninstall Trojan Panel Backend" + echo_content yellow "13. Uninstall Trojan Panel Core" + echo_content yellow "14. Uninstall Caddy2+https" + echo_content yellow "15. Uninstall Nginx" + echo_content yellow "16. Uninstall MariaDB" + echo_content yellow "17. Uninstall Redis" + echo_content yellow "18. Uninstall all Trojan Panel related containers" + echo_content green "\n==============================================================" + echo_content yellow "19. Modify Trojan Panel Frontend port" + echo_content yellow "20. Refresh Redis cache" + echo_content yellow "21. Replace certificate" + echo_content yellow "22. Forgot sysadmin password" + echo_content green "\n==============================================================" + echo_content yellow "23. Fault detection" + echo_content yellow "24. Log query" + echo_content yellow "25. Version query" + read -r -p "Please choose: " selectInstall_type + case ${selectInstall_type} in + 1) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_ui + ;; + 2) + install_docker + install_mariadb + install_redis + install_trojan_panel + ;; + 3) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_core + ;; + 4) + install_docker + install_caddy2 + ;; + 5) + install_docker + install_nginx + ;; + 6) + install_docker + install_mariadb + ;; + 7) + install_docker + install_redis + ;; + 8) + update_trojan_panel_ui + ;; + 9) + update_trojan_panel + ;; + 10) + update_trojan_panel_core + ;; + 11) + uninstall_trojan_panel_ui + ;; + 12) + uninstall_trojan_panel + ;; + 13) + uninstall_trojan_panel_core + ;; + 14) + uninstall_caddy2 + ;; + 15) + uninstall_nginx + ;; + 16) + uninstall_mariadb + ;; + 17) + uninstall_redis + ;; + 18) + uninstall_all + ;; + 19) + update_trojan_panel_ui_port + ;; + 20) + redis_flush_all + ;; + 21) + change_cert + ;; + 22) + forget_pass + ;; + 23) + failure_testing + ;; + 24) + log_query + ;; + 25) + version_query + ;; + *) + echo_content red "No such option" + ;; + esac +} + +main diff --git a/lib/archive/install_script_v2.3.0.sh b/lib/archive/install_script_v2.3.0.sh new file mode 100644 index 0000000..b323583 --- /dev/null +++ b/lib/archive/install_script_v2.3.0.sh @@ -0,0 +1,2013 @@ +#!/usr/bin/env bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +# System Required: CentOS 7+/Ubuntu 18+/Debian 10+ +# Version: v2.3.0 +# Description: One click Install Trojan Panel server +# Author: jonssonyan +# Github: https://github.com/trojanpanel/install-script + +init_var() { + ECHO_TYPE="echo -e" + + package_manager="" + release="" + get_arch="" + can_google=0 + + # Docker + DOCKER_MIRROR='"https://hub-mirror.c.163.com","https://ccr.ccs.tencentyun.com","https://mirror.baidubce.com","https://dockerproxy.com"' + + # Project directory + TP_DATA="/tpdata/" + + STATIC_HTML="https://github.com/trojanpanel/install-script/releases/download/v1.0/html.tar.gz" + + # Web + WEB_PATH="/tpdata/web/" + + # Cert + CERT_PATH="/tpdata/cert/" + DOMAIN_FILE="/tpdata/domain.lock" + domain="" + crt_path="" + key_path="" + + # Caddy2 + CADDY_DATA="/tpdata/caddy/" + CADDY_CONFIG="${CADDY_DATA}config.json" + CADDY_LOG="${CADDY_DATA}logs/" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + caddy_port=80 + caddy_remote_port=8863 + your_email="" + ssl_option=1 + ssl_module_type=1 + ssl_module="acme" + + # Nginx + NGINX_DATA="/tpdata/nginx/" + NGINX_CONFIG="${NGINX_DATA}default.conf" + nginx_port=80 + nginx_remote_port=8863 + nginx_https=1 + + # MariaDB + MARIA_DATA="/tpdata/mariadb/" + mariadb_ip="127.0.0.1" + mariadb_port=9507 + mariadb_user="root" + mariadb_pas="" + + # Redis + REDIS_DATA="/tpdata/redis/" + redis_host="127.0.0.1" + redis_port=6378 + redis_pass="" + + # Trojan Panel Frontend + TROJAN_PANEL_UI_DATA="/tpdata/trojan-panel-ui/" + # Nginx + UI_NGINX_DATA="${TROJAN_PANEL_UI_DATA}nginx/" + UI_NGINX_CONFIG="${UI_NGINX_DATA}default.conf" + trojan_panel_ui_port=8888 + ui_https=1 + trojan_panel_ip="127.0.0.1" + trojan_panel_server_port=8081 + + # Trojan Panel Backend + TROJAN_PANEL_DATA="/tpdata/trojan-panel/" + TROJAN_PANEL_WEBFILE="${TROJAN_PANEL_DATA}webfile/" + TROJAN_PANEL_LOGS="${TROJAN_PANEL_DATA}logs/" + TROJAN_PANEL_CONFIG="${TROJAN_PANEL_DATA}config/" + trojan_panel_config_path="${TROJAN_PANEL_DATA}config/config.ini" + trojan_panel_port=8081 + + # Trojan Panel Core + TROJAN_PANEL_CORE_DATA="/tpdata/trojan-panel-core/" + TROJAN_PANEL_CORE_LOGS="${TROJAN_PANEL_CORE_DATA}logs/" + TROJAN_PANEL_CORE_CONFIG="${TROJAN_PANEL_CORE_DATA}config/" + trojan_panel_core_config_path="${TROJAN_PANEL_CORE_DATA}config/config.ini" + database="trojan_panel_db" + account_table="account" + grpc_port=8100 + trojan_panel_core_port=8082 + + # Version + trojan_panel_ui_current_version="" + trojan_panel_ui_latest_version="v2.2.0" + trojan_panel_current_version="" + trojan_panel_latest_version="v2.3.0" + trojan_panel_core_current_version="" + trojan_panel_core_latest_version="v2.3.0" + + # SQL + sql_215="alter table account change validity_period preset_expire int unsigned default 0 not null comment '预设过期时长';alter table account add preset_quota bigint default 0 not null comment '预设配额' after preset_expire;update account set preset_quota = quota where last_login_time = 0;update account set quota = 0 where last_login_time = 0;alter table node add priority int default 100 not null comment '优先级' after port;INSERT INTO casbin_rule (p_type, v0, v1, v2, v3, v4, v5) VALUES ('p', 'sysadmin', '/api/account/clashSubscribeForSb', 'GET', 'default', 'default', 'default');alter table node_hysteria add server_name varchar(64) default '' not null comment '用于验证服务端证书的 hostname' after down_mbps;alter table node_hysteria add insecure tinyint(1) default 0 not null comment '忽略一切证书错误' after server_name;alter table node_hysteria add fast_open tinyint(1) default 0 not null comment '启用 Fast Open (降低连接建立延迟)' after insecure;" + sql_230="CREATE TABLE node_hysteria2 ( id bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键', obfs_password varchar(64) NOT NULL DEFAULT '' COMMENT '混淆密码', up_mbps int(10) NOT NULL DEFAULT '100' COMMENT '单客户端最大上传速度 单位:Mbps', down_mbps int(10) NOT NULL DEFAULT '100' COMMENT '单客户端最大下载速度 单位:Mbps', server_name varchar(64) NOT NULL DEFAULT '' COMMENT '用于验证服务端证书的 hostname', insecure tinyint(1) NOT NULL DEFAULT '0' COMMENT '忽略一切证书错误', create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Hysteria2节点';INSERT INTO node_type (id, name, create_time, update_time) VALUES (5, 'hysteria2', '2022-04-01 00:00:00', '2022-04-01 00:00:00');" +} + +echo_content() { + case $1 in + "red") + ${ECHO_TYPE} "\033[31m$2\033[0m" + ;; + "green") + ${ECHO_TYPE} "\033[32m$2\033[0m" + ;; + "yellow") + ${ECHO_TYPE} "\033[33m$2\033[0m" + ;; + "blue") + ${ECHO_TYPE} "\033[34m$2\033[0m" + ;; + "purple") + ${ECHO_TYPE} "\033[35m$2\033[0m" + ;; + "skyBlue") + ${ECHO_TYPE} "\033[36m$2\033[0m" + ;; + "white") + ${ECHO_TYPE} "\033[37m$2\033[0m" + ;; + esac +} + +mkdir_tools() { + # Project directory + mkdir -p ${TP_DATA} + + # Web + mkdir -p ${WEB_PATH} + + # Cert + mkdir -p ${CERT_PATH} + touch ${DOMAIN_FILE} + + # Caddy2 + mkdir -p ${CADDY_DATA} + touch ${CADDY_CONFIG} + mkdir -p ${CADDY_LOG} + + # Nginx + mkdir -p ${NGINX_DATA} + touch ${NGINX_CONFIG} + + # MariaDB + mkdir -p ${MARIA_DATA} + + # Redis + mkdir -p ${REDIS_DATA} + + # Trojan Panel Frontend + mkdir -p ${TROJAN_PANEL_UI_DATA} + # Nginx + mkdir -p ${UI_NGINX_DATA} + touch ${UI_NGINX_CONFIG} + + # Trojan Panel Backend + mkdir -p ${TROJAN_PANEL_DATA} + mkdir -p ${TROJAN_PANEL_LOGS} + + # Trojan Panel Core + mkdir -p ${TROJAN_PANEL_CORE_DATA} + mkdir -p ${TROJAN_PANEL_CORE_LOGS} +} + +can_connect() { + ping -c2 -i0.3 -W1 "$1" &>/dev/null + if [[ "$?" == "0" ]]; then + return 0 + else + return 1 + fi +} + +# query .ini configuration file information +get_ini_value() { + local config_file="$1" + local key="$2" + local section="" + local section_flag=0 + + # split group and key names + IFS='.' read -r group_name key_name <<<"$key" + + while IFS='=' read -r name val; do + # processing section name + if [[ $name =~ ^\[(.*)\]$ ]]; then + section="${BASH_REMATCH[1]}" + if [[ $section == $group_name ]]; then + section_flag=1 + else + section_flag=0 + fi + continue + fi + + # extract the value of the configuration item + if [[ $section_flag -eq 1 && $name == $key_name ]]; then + echo "$val" + return + fi + done <"$config_file" +} + +# Version number comparison greater than or equal to +version_ge() { + local v1=${1#v} + local v2=${2#v} + + local v1_parts=(${v1//./ }) + local v2_parts=(${v2//./ }) + + for ((i = 0; i < 3; i++)); do + if ((${v1_parts[i]} < ${v2_parts[i]})); then + echo false + return 0 + elif ((${v1_parts[i]} > ${v2_parts[i]})); then + echo true + return 0 + fi + done + echo true +} + +check_sys() { + if [[ $(command -v yum) ]]; then + package_manager='yum' + elif [[ $(command -v dnf) ]]; then + package_manager='dnf' + elif [[ $(command -v apt) ]]; then + package_manager='apt' + elif [[ $(command -v apt-get) ]]; then + package_manager='apt-get' + fi + + if [[ -z "${package_manager}" ]]; then + echo_content red "The system is not currently supported" + exit 0 + fi + + if [[ -n $(find /etc -name "redhat-release") ]] || grep /dev/null) ]]; then + echo_content green "---> Install Docker" + + # turn off firewall + if [[ "${release}" == "centos" ]]; then + systemctl disable firewalld + elif [[ "${release}" == "debian" || "${release}" == "ubuntu" ]]; then + sudo ufw disable + fi + + # set time zone + timedatectl set-timezone Asia/Shanghai + + if [[ ${can_google} == 0 ]]; then + sh <(curl -sL https://get.docker.com) --mirror Aliyun + mkdir -p /etc/docker && + cat >/etc/docker/daemon.json </etc/docker/daemon.json </dev/null) ]]; then + echo_content skyBlue "---> Docker installation completed" + else + echo_content red "---> Docker installation failed" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Docker" + fi +} + +# Custom Settings Certificate +install_custom_cert() { + if [[ -z "$(cat "${DOMAIN_FILE}")" ]]; then + while read -r -p "Please enter the file path of the .crt certificate (required): " crt_path; do + if [[ -z "${crt_path}" ]]; then + echo_content red "Path cannot be empty" + else + if [[ ! -f "${crt_path}" ]]; then + echo_content red "The file path for the .crt certificate does not exist" + else + cp "${crt_path}" "${CERT_PATH}$1.crt" + break + fi + fi + done + while read -r -p "Please enter the file path of the .key certificate (required): " key_path; do + if [[ -z "${key_path}" ]]; then + echo_content red "Path cannot be empty" + else + if [[ ! -f "${key_path}" ]]; then + echo_content red "The file path for the .key certificate does not exist" + else + cp "${key_path}" "${CERT_PATH}$1.key" + break + fi + fi + done + cat >${DOMAIN_FILE} < Custom settings certificate installation completed" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + fi +} + +# Caddy2 https custom settings certificate configuration file +caddy2_https_config() { + domain=$1 + cat >${CADDY_CONFIG} <${CADDY_CONFIG} < Install Caddy2+https" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "Please enter the port of Caddy2 (default: 80): " caddy_port + [[ -z "${caddy_port}" ]] && caddy_port=80 + read -r -p "Please enter the forwarding port of Caddy2 (default: 8863): " caddy_remote_port + [[ -z "${caddy_remote_port}" ]] && caddy_remote_port=8863 + + echo_content yellow "Tip: Please confirm that the domain name has been resolved to this machine, otherwise the installation may fail" + while read -r -p "Please enter your domain name (required): " domain; do + if [[ -z "${domain}" ]]; then + echo_content red "Domain name cannot be empty" + else + break + fi + done + + read -r -p "Please enter your email (optional): " your_email + + while read -r -p "Please choose the way to set up the certificate? (1/automatically apply for and renew the certificate 2/manually set the certificate path default: 1: " ssl_option; do + if [[ -z ${ssl_option} || ${ssl_option} == 1 ]]; then + while read -r -p "Please choose the way to apply for the certificate (1/acme 2/zerossl default: 1: " ssl_module_type; do + if [[ -z "${ssl_module_type}" || ${ssl_module_type} == 1 ]]; then + ssl_module="acme" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme-v02.api.letsencrypt.org-directory/" + break + elif [[ ${ssl_module_type} == 2 ]]; then + ssl_module="zerossl" + CADDY_CERT_DIR="${CERT_PATH}certificates/acme.zerossl.com-v2-dv90/" + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + caddy2_https_auto_config "${domain}" + break + elif [[ ${ssl_option} == 2 ]]; then + install_custom_cert "${domain}" + caddy2_https_config "${domain}" + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + # Caddy2 temporary listening port for automatic certificate application + if [[ -n $(lsof -i:${caddy_port},${caddy_remote_port} -t) ]]; then + kill -9 "$(lsof -i:${caddy_port},${caddy_remote_port} -t)" + fi + + docker pull caddy:2.6.2 && + docker run -d --name trojan-panel-caddy --restart always \ + --network=host \ + -v "${CADDY_CONFIG}":"${CADDY_CONFIG}" \ + -v ${CERT_PATH}:"${CADDY_CERT_DIR}${domain}/" \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v ${CADDY_LOG}:${CADDY_LOG} \ + caddy:2.6.2 caddy run --config ${CADDY_CONFIG} + + cat >${DOMAIN_FILE} < Caddy2+https installation completed" + echo_content yellow "Certificate Directory: ${CERT_PATH}" + echo_content red "\n==============================================================" + else + echo_content red "---> Caddy2+https installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Caddy2+https" + fi +} + +# Nginx http configuration file +nginx_http_config() { + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + error_page 497 http://\$host:${nginx_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Nginx https configuration file +nginx_https_config() { + domain=$1 + cat >${NGINX_CONFIG} <<-EOF +server { + listen ${nginx_port}; + server_name localhost; + + return 301 http://\$host:${nginx_remote_port}\$request_uri; +} + +server { + listen ${nginx_remote_port} ssl; + server_name localhost; + + # force ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + # cache validity period + ssl_session_timeout 5m; + # secure link optional encryption protocol + ssl_protocols TLSv1.3; + # encryption algorithm + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + # use server-side preferred algorithm + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${WEB_PATH}; + index index.html index.htm; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${nginx_remote_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Install Nginx +install_nginx() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + echo_content green "---> Install Nginx" + + wget --no-check-certificate -O ${WEB_PATH}html.tar.gz -N ${STATIC_HTML} && + tar -zxvf ${WEB_PATH}html.tar.gz -k -C ${WEB_PATH} + + read -r -p "Please enter the port of Nginx (default: 80): " nginx_port + [[ -z "${nginx_port}" ]] && nginx_port=80 + read -r -p "Please enter the forwarding port of Nginx (default: 8863): " nginx_remote_port + [[ -z "${nginx_remote_port}" ]] && nginx_remote_port=8863 + + while read -r -p "Please choose whether to enable https in Nginx? (0/off 1/on default: 1): " nginx_https; do + if [[ -z ${nginx_https} || ${nginx_https} == 1 ]]; then + install_custom_cert "custom_cert" + nginx_https_config "custom_cert" + break + elif [[ ${nginx_https} == 0 ]]; then + nginx_http_config + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + docker pull nginx:1.20-alpine && + docker run -d --name trojan-panel-nginx --restart always \ + --network=host \ + -v "${NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + nginx:1.20-alpine + + if [[ -n $(docker ps -q -f "name=^trojan-panel-nginx$" -f "status=running") ]]; then + echo_content skyBlue "---> Nginx installation completed" + else + echo_content red "---> Nginx installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Nginx" + fi +} + +# Install a web server +install_reverse_proxy() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-caddy$|^trojan-panel-nginx$") ]]; then + echo_content green "---> Install a web server" + + while :; do + echo_content yellow "1. Install Caddy2+https (recommend)" + echo_content yellow "2. Install Nginx" + echo_content yellow "3. Not install" + read -r -p "Please select (default: 1): " whether_install_reverse_proxy + [[ -z "${whether_install_reverse_proxy}" ]] && whether_install_reverse_proxy=1 + + case ${whether_install_reverse_proxy} in + 1) + install_caddy2 + break + ;; + 2) + install_nginx + break + ;; + 3) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done + + echo_content skyBlue "---> Web server installation completed" + fi +} + +# Set certificate +install_cert() { + if [[ -z "$(cat "${DOMAIN_FILE}")" ]]; then + echo_content green "---> Set certificate" + + while :; do + echo_content yellow "1. Custom certificate" + echo_content yellow "2. Not set" + read -r -p "Please select (default: 1): " whether_install_cert + [[ -z "${whether_install_cert}" ]] && whether_install_cert=1 + + case ${whether_install_cert} in + 1) + install_custom_cert "custom_cert" + break + ;; + 2) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done + + echo_content green "---> Certificate setup completed" + fi +} + +# Install MariaDB +install_mariadb() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> Install MariaDB" + + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + if [[ "${mariadb_user}" == "root" ]]; then + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + else + docker pull mariadb:10.7.3 && + docker run -d --name trojan-panel-mariadb --restart always \ + --network=host \ + -e MYSQL_DATABASE="trojan_panel_db" \ + -e MYSQL_ROOT_PASSWORD="${mariadb_pas}" \ + -e MYSQL_USER="${mariadb_user}" \ + -e MYSQL_PASSWORD="${mariadb_pas}" \ + -e TZ=Asia/Shanghai \ + mariadb:10.7.3 \ + --port ${mariadb_port} \ + --character-set-server=utf8mb4 \ + --collation-server=utf8mb4_unicode_ci + fi + + if [[ -n $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content skyBlue "---> MariaDB installation completed" + echo_content yellow "---> The MariaDB password of root (please keep it safe): ${mariadb_pas}" + if [[ "${mariadb_user}" != "root" ]]; then + echo_content yellow "---> The MariaDB password of ${mariadb_user} (please keep it safe): ${mariadb_pas}" + fi + else + echo_content red "---> MariaDB installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed MariaDB" + fi +} + +# Install Redis +install_redis() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> Install Redis" + + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker pull redis:6.2.7 && + docker run -d --name trojan-panel-redis --restart always \ + --network=host \ + redis:6.2.7 \ + redis-server --requirepass "${redis_pass}" --port "${redis_port}" + + if [[ -n $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content skyBlue "---> Redis installation completed" + echo_content yellow "---> Redis password (please keep it safe): ${redis_pass}" + else + echo_content red "---> Redis installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed Redis" + fi +} + +# Trojan Panel Frontend Nginx http configuration file +ui_http_config() { + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port}; + server_name localhost; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + error_page 497 http://\$host:${trojan_panel_ui_port}\$request_uri; + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Trojan Panel Frontend Nginx https configuration file +ui_https_config() { + cat >${UI_NGINX_CONFIG} <<-EOF +server { + listen ${trojan_panel_ui_port} ssl; + server_name localhost; + + # force ssl + ssl on; + ssl_certificate ${CERT_PATH}${domain}.crt; + ssl_certificate_key ${CERT_PATH}${domain}.key; + # cache validity period + ssl_session_timeout 5m; + # secure link optional encryption protocol + ssl_protocols TLSv1.3; + # encryption algorithm + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; + # use server-side preferred algorithm + ssl_prefer_server_ciphers on; + + #access_log /var/log/nginx/host.access.log main; + + location / { + root ${TROJAN_PANEL_UI_DATA}; + index index.html index.htm; + } + + location /api { + proxy_pass http://${trojan_panel_ip}:${trojan_panel_server_port}; + } + + #error_page 404 /404.html; + #497 http->https + error_page 497 https://\$host:${trojan_panel_ui_port}\$request_uri; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} +EOF +} + +# Install Trojan Panel Frontend +install_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> Install Trojan Panel Frontend" + + read -r -p "Please enter the IP address of the Trojan Panel Backend (default: local host): " trojan_panel_ip + [[ -z "${trojan_panel_ip}" ]] && trojan_panel_ip="127.0.0.1" + read -r -p "Please enter the service port of the Trojan Panel Backend (default: 8081): " trojan_panel_server_port + [[ -z "${trojan_panel_server_port}" ]] && trojan_panel_server_port=8081 + + read -r -p "Please enter the port of the Trojan Panel Frontend (default: 8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + while read -r -p "Please choose whether to enable https on the Trojan Panel Frontend? (0/off 1/on default: 1): " ui_https; do + if [[ -z ${ui_https} || ${ui_https} == 1 ]]; then + install_custom_cert "custom_cert" + domain=$(cat "${DOMAIN_FILE}") + ui_https_config + break + elif [[ ${ui_https} == 0 ]]; then + ui_http_config + break + else + echo_content red "Cannot enter other characters except 1 and 2" + fi + done + + docker pull jonssonyan/trojan-panel-ui:2.2.0 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.2.0 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Frontend installation completed" + + https_flag=$([[ -z ${ui_https} || ${ui_https} == 1 ]] && echo "https" || echo "http") + domain_or_ip=$([[ -z ${domain} || "${domain}" == "custom_cert" ]] && echo "ip" || echo "${domain}") + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel Frontend installed successfully" + echo_content yellow "Web management panel address: ${https_flag}://${domain_or_ip}:${trojan_panel_ui_port}" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel Frontend installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Frontend" + fi +} + +# Install Trojan Panel Backend +install_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> Install Trojan Panel Backend" + + read -r -p "Please enter the service port of the Trojan Panel Backend (default: 8081): " trojan_panel_port + [[ -z "${trojan_panel_port}" ]] && trojan_panel_port=8081 + + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -e "create database if not exists trojan_panel_db;" &>/dev/null + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker pull jonssonyan/trojan-panel:2.3.0 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.3.0 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Backend installation completed" + + echo_content red "\n==============================================================" + echo_content skyBlue "Trojan Panel Backend installed successfully" + echo_content yellow "MariaDB ${mariadb_user} password (please keep it safe): ${mariadb_pas}" + echo_content yellow "Redis password (please keep it safe): ${redis_pass}" + echo_content yellow "System administrator Default username: sysadmin Default password: 123456" + echo_content yellow "Please log in to the management panel to change the password in time" + echo_content red "\n==============================================================" + else + echo_content red "---> Trojan Panel Backend installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Backend" + fi +} + +# Install Trojan Panel Core +install_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> Install Trojan Panel Core" + + read -r -p "Please enter the service port of the Trojan Panel Core (default: 8082): " trojan_panel_core_port + [[ -z "${trojan_panel_core_port}" ]] && trojan_panel_core_port=8082 + + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + read -r -p "Please enter the database name (default: trojan_panel_db): " database + [[ -z "${database}" ]] && database="trojan_panel_db" + read -r -p "Please enter the user table name of the database (default: account): " account_table + [[ -z "${account_table}" ]] && account_table="account" + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + read -r -p "Please enter the API port (default: 8100): " grpc_port + [[ -z "${grpc_port}" ]] && grpc_port=8100 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.3.0 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria2/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria2/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.3.0 + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Core installation completed" + else + echo_content red "---> Trojan Panel Core installation fails or runs abnormally, please try to repair or uninstall and reinstall" + exit 0 + fi + else + echo_content skyBlue "---> You have installed the Trojan Panel Core" + fi +} + +# Update Trojan Panel database structure +update_trojan_panel_database() { + echo_content skyBlue "---> Update Trojan Panel database structure" + + version_214_215=("v2.1.4") + if [[ "${version_214_215[*]}" =~ "${trojan_panel_current_version}" ]]; then + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "${sql_215}" &>/dev/null && + trojan_panel_current_version="v2.1.5" + fi + version_215_230=("v2.1.5" "v2.1.6" "v2.1.7" "v2.1.8" "v2.2.0" "v2.2.1") + if [[ "${version_215_230[*]}" =~ "${trojan_panel_current_version}" ]]; then + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "${sql_230}" &>/dev/null && + trojan_panel_current_version="v2.3.0" + fi + + echo_content skyBlue "---> Trojan Panel database structure update completed" +} + +# Update Trojan Panel Core database structure +update_trojan_panel_core_database() { + echo_content skyBlue "---> Update Trojan Panel Core database structure" + + echo_content skyBlue "---> Trojan Panel Core database structure update completed" +} + +# Update Trojan Panel Frontend +update_trojan_panel_ui() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content red "---> Please install the Trojan Panel Frontend first" + exit 0 + fi + + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + if [[ -z "${trojan_panel_ui_current_version}" || ! "${trojan_panel_ui_current_version}" =~ ^v.* ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Frontend (trojan-panel-ui) is ${trojan_panel_ui_current_version} the latest version is ${trojan_panel_ui_latest_version}" + + if [[ "${trojan_panel_ui_current_version}" != "${trojan_panel_ui_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Frontend" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.2.0 + + docker pull jonssonyan/trojan-panel-ui:2.2.0 && + docker run -d --name trojan-panel-ui --restart always \ + --network=host \ + -v "${UI_NGINX_CONFIG}":"/etc/nginx/conf.d/default.conf" \ + -v ${CERT_PATH}:${CERT_PATH} \ + jonssonyan/trojan-panel-ui:2.2.0 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Frontend update completed" + else + echo_content red "---> Trojan Panel Frontend update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Frontend" + fi +} + +# Update Trojan Panel Backend +update_trojan_panel() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content red "---> Please install the Trojan Panel Backend first" + exit 0 + fi + + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + if [[ -z "${trojan_panel_current_version}" || ! "${trojan_panel_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_current_version}" "v2.1.4") ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Backend (trojan-panel) is ${trojan_panel_current_version} The latest version is ${trojan_panel_latest_version}" + + if [[ "${trojan_panel_current_version}" != "${trojan_panel_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Backend" + + mariadb_ip=$(get_ini_value ${trojan_panel_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + trojan_panel_port=$(get_ini_value ${trojan_panel_config_path} server.port) + + update_trojan_panel_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.3.0 + + docker pull jonssonyan/trojan-panel:2.3.0 && + docker run -d --name trojan-panel --restart always \ + --network=host \ + -v ${WEB_PATH}:${TROJAN_PANEL_WEBFILE} \ + -v ${TROJAN_PANEL_LOGS}:${TROJAN_PANEL_LOGS} \ + -v ${TROJAN_PANEL_CONFIG}:${TROJAN_PANEL_CONFIG} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "server_port=${trojan_panel_port}" \ + jonssonyan/trojan-panel:2.3.0 + + if [[ -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel backend update completed" + else + echo_content red "---> Trojan Panel Backend update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Backend" + fi +} + +# Update Trojan Panel Core +update_trojan_panel_core() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content red "---> Please install the Trojan Panel Core first" + exit 0 + fi + + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + if [[ -z "${trojan_panel_core_current_version}" || ! "${trojan_panel_core_current_version}" =~ ^v.* || ! $(version_ge "${trojan_panel_core_current_version}" "v2.1.1") ]]; then + echo_content red "---> The current version does not support online updates" + exit 0 + fi + + echo_content yellow "Tip: The current version of the Trojan Panel Core (trojan-panel-core) is ${trojan_panel_core_current_version} The latest version is ${trojan_panel_core_latest_version}" + + if [[ "${trojan_panel_core_current_version}" != "${trojan_panel_core_latest_version}" ]]; then + echo_content green "---> Update Trojan Panel Core" + + mariadb_ip=$(get_ini_value ${trojan_panel_core_config_path} mysql.host) + mariadb_port=$(get_ini_value ${trojan_panel_core_config_path} mysql.port) + mariadb_user=$(get_ini_value ${trojan_panel_core_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_core_config_path} mysql.password) + redis_host=$(get_ini_value ${trojan_panel_core_config_path} redis.host) + redis_port=$(get_ini_value ${trojan_panel_core_config_path} redis.port) + redis_pass=$(get_ini_value ${trojan_panel_core_config_path} redis.password) + grpc_port=$(get_ini_value ${trojan_panel_core_config_path} grpc.port) + trojan_panel_core_port=$(get_ini_value ${trojan_panel_core_config_path} server.port) + + update_trojan_panel_core_database + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.3.0 + + domain=$(cat "${DOMAIN_FILE}") + + docker pull jonssonyan/trojan-panel-core:2.3.0 && + docker run -d --name trojan-panel-core --restart always \ + --network=host \ + -v ${TROJAN_PANEL_CORE_DATA}bin/xray/config/:${TROJAN_PANEL_CORE_DATA}bin/xray/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/trojango/config/:${TROJAN_PANEL_CORE_DATA}bin/trojango/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/:${TROJAN_PANEL_CORE_DATA}bin/naiveproxy/config/ \ + -v ${TROJAN_PANEL_CORE_DATA}bin/hysteria2/config/:${TROJAN_PANEL_CORE_DATA}bin/hysteria2/config/ \ + -v ${TROJAN_PANEL_CORE_LOGS}:${TROJAN_PANEL_CORE_LOGS} \ + -v ${TROJAN_PANEL_CORE_CONFIG}:${TROJAN_PANEL_CORE_CONFIG} \ + -v ${CERT_PATH}:${CERT_PATH} \ + -v ${WEB_PATH}:${WEB_PATH} \ + -v /etc/localtime:/etc/localtime \ + -e GIN_MODE=release \ + -e "mariadb_ip=${mariadb_ip}" \ + -e "mariadb_port=${mariadb_port}" \ + -e "mariadb_user=${mariadb_user}" \ + -e "mariadb_pas=${mariadb_pas}" \ + -e "database=${database}" \ + -e "account-table=${account_table}" \ + -e "redis_host=${redis_host}" \ + -e "redis_port=${redis_port}" \ + -e "redis_pass=${redis_pass}" \ + -e "crt_path=${CERT_PATH}${domain}.crt" \ + -e "key_path=${CERT_PATH}${domain}.key" \ + -e "grpc_port=${grpc_port}" \ + -e "server_port=${trojan_panel_core_port}" \ + jonssonyan/trojan-panel-core:2.3.0 + + if [[ -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content skyBlue "---> Trojan Panel Core update completed" + else + echo_content red "---> Trojan Panel Core update fails or runs abnormally, please try to repair or uninstall and reinstall" + fi + else + echo_content skyBlue "---> You have installed the latest version of the Trojan Panel Core" + fi +} + +# Uninstall Caddy2+https +uninstall_caddy2() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + echo_content green "---> Uninstall Caddy2+https" + + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_DATA} + + echo_content skyBlue "---> Caddy2+https uninstallation completed" + else + echo_content red "---> Please install Caddy2+https first" + fi +} + +# Uninstall Nginx +uninstall_nginx() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx") ]]; then + echo_content green "---> Uninstall Nginx" + + docker rm -f trojan-panel-nginx && + rm -rf ${NGINX_DATA} + + echo_content skyBlue "---> Nginx uninstallation completed" + else + echo_content red "---> Please install Nginx first" + fi +} + +# Uninstall MariaDB +uninstall_mariadb() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + echo_content green "---> Uninstall MariaDB" + + docker rm -f trojan-panel-mariadb && + rm -rf ${MARIA_DATA} + + echo_content skyBlue "---> MariaDB uninstall completed" + else + echo_content red "---> Please install MariaDB first" + fi +} + +# Uninstall Redis +uninstall_redis() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content green "---> Uninstall Redis" + + docker rm -f trojan-panel-redis && + rm -rf ${REDIS_DATA} + + echo_content skyBlue "---> Redis uninstall completed" + else + echo_content red "---> Please install Redis first" + fi +} + +# Uninstall Trojan Panel Frontend +uninstall_trojan_panel_ui() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + echo_content green "---> Uninstall Trojan Panel Frontend" + + docker rm -f trojan-panel-ui && + docker rmi -f jonssonyan/trojan-panel-ui:2.2.0 && + rm -rf ${TROJAN_PANEL_UI_DATA} + + echo_content skyBlue "---> Trojan Panel Frontend uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Frontend first" + fi +} + +# Uninstall Trojan Panel Backend +uninstall_trojan_panel() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + echo_content green "---> Uninstall Trojan Panel Backend" + + docker rm -f trojan-panel && + docker rmi -f jonssonyan/trojan-panel:2.3.0 && + rm -rf ${TROJAN_PANEL_DATA} + + echo_content skyBlue "---> Trojan Panel Backend uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Backend first" + fi +} + +# Uninstall Trojan Panel Core +uninstall_trojan_panel_core() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + echo_content green "---> Uninstall Trojan Panel Core" + + docker rm -f trojan-panel-core && + docker rmi -f jonssonyan/trojan-panel-core:2.3.0 && + rm -rf ${TROJAN_PANEL_CORE_DATA} + + echo_content skyBlue "---> Trojan Panel Core uninstallation completed" + else + echo_content red "---> Please install the Trojan Panel Core first" + fi +} + +# Uninstall all Trojan Panel related containers +uninstall_all() { + echo_content green "---> Uninstall all Trojan Panel related containers" + + docker rm -f $(docker ps -a -q -f "name=^trojan-panel") + docker rmi -f $(docker images | grep "^jonssonyan/trojan-panel" | awk '{print $3}') + rm -rf ${TP_DATA} + + echo_content skyBlue "---> Uninstall all Trojan Panel related containers completed" +} + +# Modify Trojan Panel Frontend port +update_trojan_panel_ui_port() { + if [[ -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content green "---> Modify Trojan Panel Frontend port" + + trojan_panel_ui_port=$(grep 'listen.*ssl' ${UI_NGINX_CONFIG} | awk '{print $2}') + if [[ -z "${trojan_panel_ui_port}" ]]; then + ui_https=0 + trojan_panel_ui_port=$(grep -oP 'listen\s+\K\d+' ${UI_NGINX_CONFIG} | awk 'NR==1') + fi + if [[ -z "${trojan_panel_ui_port}" ]]; then + echo_content red "---> Trojan Panel Frontend port not queried" + exit 0 + fi + echo_content yellow "Tip: The current port of the Trojan Panel Frontend (trojan-panel-ui) is ${trojan_panel_ui_port}" + + read -r -p "Please enter the new port of the Trojan Panel Frontend (default: 8888): " trojan_panel_ui_port + [[ -z "${trojan_panel_ui_port}" ]] && trojan_panel_ui_port="8888" + + if [[ ${ui_https} == 0 ]]; then + # http + sed -i "s/listen.*;/listen ${trojan_panel_ui_port};/g" ${UI_NGINX_CONFIG} && + sed -i "s/http:\/\/\$host:.*\$request_uri;/http:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + else + # https + sed -i "s/listen.*ssl;/listen ${trojan_panel_ui_port} ssl;/g" ${UI_NGINX_CONFIG} && + sed -i "s/https:\/\/\$host:.*\$request_uri;/https:\/\/\$host:${trojan_panel_ui_port}\$request_uri;/g" ${UI_NGINX_CONFIG} && + docker restart trojan-panel-ui + fi + + if [[ "$?" == "0" ]]; then + echo_content skyBlue "---> Trojan Panel Frontend port modification completed" + else + echo_content red "---> Trojan Panel Frontend port modification failed" + fi + else + echo_content red "---> The Trojan Panel Frontend is not installed or is running abnormally, please repair or uninstall and reinstall and try again" + fi +} + +# Refresh Redis cache +redis_flush_all() { + if [[ -z $(docker ps -a -q -f "name=^trojan-panel-redis$") ]]; then + echo_content red "---> Please install Redis first" + exit 0 + fi + + if [[ -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> Redis is running abnormally" + exit 0 + fi + + echo_content green "---> Refresh Redis cache" + + read -r -p "Please enter the IP address of Redis (default: local host): " redis_host + [[ -z "${redis_host}" ]] && redis_host="127.0.0.1" + read -r -p "Please enter the port of Redis (default: 6378): " redis_port + [[ -z "${redis_port}" ]] && redis_port=6378 + while read -r -p "Please enter the Redis password (required): " redis_pass; do + if [[ -z "${redis_pass}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-redis redis-cli -h "${redis_host}" -p "${redis_port}" -a "${redis_pass}" -e "flushall" &>/dev/null + + echo_content skyBlue "---> Redis cache refresh completed" +} + +# Replace certificate +change_cert() { + domain_1=$(cat "${DOMAIN_FILE}") + + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + docker rm -f trojan-panel-caddy && + rm -rf ${CADDY_LOG}* && + echo "" >${CADDY_CONFIG} && + rm -rf ${WEB_PATH}* + fi + + rm -rf ${CERT_PATH}* && + echo "" >${DOMAIN_FILE} + + install_reverse_proxy + install_cert + + domain_2=$(cat "${DOMAIN_FILE}") + if [[ -n "${domain_1}" && -n "${domain_2}" ]]; then + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-nginx$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${NGINX_CONFIG} && + docker restart trojan-panel-nginx + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") ]]; then + sed -i "s/${domain_1}/${domain_2}/g" ${UI_NGINX_DATA} && + docker restart trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") ]]; then + find /tpdata/trojan-panel-core/bin/ -type f -exec sed -i "s/${domain_1}/${domain_2}/g" {} + && + sed -i "s/${domain_1}/${domain_2}/g" ${trojan_panel_core_config_path} && + docker restart trojan-panel-core + fi + fi +} + +# Forgot sysadmin password +forget_pass() { + while :; do + echo_content yellow "1. Query MariaDB password" + echo_content yellow "2. Query Redis password" + echo_content yellow "3. Reset the username and password of the admin panel system administrator" + echo_content yellow "4. Quit" + read -r -p "Please choose (default: 4): " forget_pass_option + [[ -z "${forget_pass_option}" ]] && forget_pass_option=4 + case ${forget_pass_option} in + 1) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + mariadb_user=$(get_ini_value ${trojan_panel_config_path} mysql.user) + mariadb_pas=$(get_ini_value ${trojan_panel_config_path} mysql.password) + echo_content red "\n==============================================================" + echo_content yellow "MariaDB ${mariadb_user} password (please keep it safe): ${mariadb_pas}" + echo_content red "\n==============================================================" + else + echo_content red "---> Please execute on the Trojan Panel backend server" + fi + ;; + 2) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") ]]; then + redis_pass=$(get_ini_value ${trojan_panel_config_path} redis.password) + echo_content red "\n==============================================================" + echo_content yellow "Redis password (please keep it safe): ${redis_pass}" + echo_content red "\n==============================================================" + else + echo_content red "---> Please execute on the Trojan Panel backend server" + fi + ;; + 3) + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") ]]; then + read -r -p "Please enter the IP address of MariaDB (default: local host): " mariadb_ip + [[ -z "${mariadb_ip}" ]] && mariadb_ip="127.0.0.1" + read -r -p "Please enter the port of MariaDB (default: 9507): " mariadb_port + [[ -z "${mariadb_port}" ]] && mariadb_port=9507 + read -r -p "Please enter the username of MariaDB (default: root): " mariadb_user + [[ -z "${mariadb_user}" ]] && mariadb_user="root" + while read -r -p "Please enter the password of MariaDB (required): " mariadb_pas; do + if [[ -z "${mariadb_pas}" ]]; then + echo_content red "Password can not be empty" + else + break + fi + done + + docker exec trojan-panel-mariadb mysql --default-character-set=utf8 -h"${mariadb_ip}" -P"${mariadb_port}" -u"${mariadb_user}" -p"${mariadb_pas}" -Dtrojan_panel_db -e "update account set username = 'sysadmin',pass = 'tFjD2X1F6i9FfWp2GDU5Vbi1conuaChDKIYbw9zMFrqvMoSz',hash='4366294571b8b267d9cf15b56660f0a70659568a86fc270a52fdc9e5' where id = 1 limit 1" + if [[ "$?" == "0" ]]; then + echo_content red "\n==============================================================" + echo_content yellow "System administrator Default username: sysadmin Default password: 123456" + echo_content yellow "Please log in to the management panel to change the password in time" + echo_content red "\n==============================================================" + else + echo_content red "Admin panel sysadmin username and password reset failed" + fi + else + echo_content red "---> Please execute on the MariaDB server" + fi + ;; + 4) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + done +} + +# Fault detection +failure_testing() { + echo_content green "---> Start troubleshooting" + if [[ ! $(docker -v 2>/dev/null) ]]; then + echo_content red "---> Docker is running abnormally" + else + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-caddy$") ]]; then + if [[ -z $(docker ps -q -f "name=^trojan-panel-caddy$" -f "status=running") ]]; then + echo_content red "---> Caddy2 is running abnormally and the running log is as follows:" + docker logs trojan-panel-caddy + fi + domain=$(cat "${DOMAIN_FILE}") + if [[ -n ${domain} && ! -f "${CERT_PATH}${domain}.crt" ]]; then + echo_content red "---> The certificate application is abnormal, please try 1. Change the sub-domain name to re-build 2. Restart the server to re-apply for the certificate 3. Re-build and select the custom certificate option" + if [[ -f ${CADDY_LOG}error.log ]]; then + echo_content red "Caddy2 error log is as follows:" + tail -n 20 ${CADDY_LOG}error.log | grep error + fi + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-mariadb$") && -z $(docker ps -q -f "name=^trojan-panel-mariadb$" -f "status=running") ]]; then + echo_content red "---> The MariaDB is running abnormally and the running log is as follows:" + docker logs trojan-panel-mariadb + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-redis$") && -z $(docker ps -q -f "name=^trojan-panel-redis$" -f "status=running") ]]; then + echo_content red "---> The Redis is running abnormally and the running log is as follows:" + docker logs trojan-panel-redis + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -z $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Backend is running abnormally and the running log is as follows:" + if [[ -f ${TROJAN_PANEL_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel + fi + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -z $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Frontend is running abnormally and the running log is as follows:" + docker logs trojan-panel-ui + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -z $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + echo_content red "---> The Trojan Panel Core is running abnormally and the running log is as follows:" + if [[ -f ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log ]]; then + tail -n 20 ${TROJAN_PANEL_CORE_LOGS}trojan-panel.log | grep error + else + docker logs trojan-panel-core + fi + fi + fi + echo_content green "---> Troubleshooting ended" +} + +log_query() { + while :; do + echo_content skyBlue "Applications that can query logs are as follows:" + echo_content yellow "1. Trojan Panel Backend" + echo_content yellow "2. Trojan Panel Frontend" + echo_content yellow "3. Quit" + read -r -p "Please select an application (default: 3): " select_log_query_type + [[ -z "${select_log_query_type}" ]] && select_log_query_type=3 + + case ${select_log_query_type} in + 1) + log_file_path=${TROJAN_PANEL_LOGS}trojan-panel.log + ;; + 2) + log_file_path=${TROJAN_PANEL_CORE_LOGS}trojan-panel-core.log + ;; + 3) + break + ;; + *) + echo_content red "No such option" + continue + ;; + esac + + read -r -p "Please enter the number of rows to query (default: 20): " select_log_query_line_type + [[ -z "${select_log_query_line_type}" ]] && select_log_query_line_type=20 + + if [[ -f ${log_file_path} ]]; then + echo_content skyBlue "The log is as follows:" + tail -n ${select_log_query_line_type} ${log_file_path} + else + echo_content red "No log file exists" + fi + done +} + +version_query() { + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-ui$") && -n $(docker ps -q -f "name=^trojan-panel-ui$" -f "status=running") ]]; then + trojan_panel_ui_current_version=$(docker exec trojan-panel-ui cat ${TROJAN_PANEL_UI_DATA}version) + echo_content yellow "The current version of Trojan Panel Frontend(trojan-panel-ui) is ${trojan_panel_ui_current_version} the latest version is ${trojan_panel_ui_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel$") && -n $(docker ps -q -f "name=^trojan-panel$" -f "status=running") ]]; then + trojan_panel_current_version=$(docker exec trojan-panel ./trojan-panel -version) + echo_content yellow "The current version of Trojan Panel Backend(trojan-panel) is ${trojan_panel_current_version} the latest version is ${trojan_panel_latest_version}" + fi + if [[ -n $(docker ps -a -q -f "name=^trojan-panel-core$") && -n $(docker ps -q -f "name=^trojan-panel-core$" -f "status=running") ]]; then + trojan_panel_core_current_version=$(docker exec trojan-panel-core ./trojan-panel-core -version) + echo_content yellow "The current version of Trojan Panel Core(trojan-panel-core) is ${trojan_panel_core_current_version} the latest version is ${trojan_panel_core_latest_version}" + fi +} + +main() { + cd "$HOME" || exit 0 + init_var + mkdir_tools + check_sys + depend_install + clear + echo_content red "\n==============================================================" + echo_content skyBlue "System Required: CentOS 7+/Ubuntu 18+/Debian 10+" + echo_content skyBlue "Version: v2.3.0" + echo_content skyBlue "Description: One click Install Trojan Panel server" + echo_content skyBlue "Author: jonssonyan " + echo_content skyBlue "Github: https://github.com/trojanpanel" + echo_content skyBlue "Docs: https://trojanpanel.github.io" + echo_content red "\n==============================================================" + echo_content yellow "1. Install Trojan Panel Frontend" + echo_content yellow "2. Install Trojan Panel Backend" + echo_content yellow "3. Install Trojan Panel Core" + echo_content yellow "4. Install Caddy2+https" + echo_content yellow "5. Install Nginx" + echo_content yellow "6. Install MariaDB" + echo_content yellow "7. Install Redis" + echo_content green "\n==============================================================" + echo_content yellow "8. Update Trojan Panel Frontend" + echo_content yellow "9. Update Trojan Panel Backend" + echo_content yellow "10. Update Trojan Panel Core" + echo_content green "\n==============================================================" + echo_content yellow "11. Uninstall Trojan Panel Frontend" + echo_content yellow "12. Uninstall Trojan Panel Backend" + echo_content yellow "13. Uninstall Trojan Panel Core" + echo_content yellow "14. Uninstall Caddy2+https" + echo_content yellow "15. Uninstall Nginx" + echo_content yellow "16. Uninstall MariaDB" + echo_content yellow "17. Uninstall Redis" + echo_content yellow "18. Uninstall all Trojan Panel related containers" + echo_content green "\n==============================================================" + echo_content yellow "19. Modify Trojan Panel Frontend port" + echo_content yellow "20. Refresh Redis cache" + echo_content yellow "21. Replace certificate" + echo_content yellow "22. Forgot sysadmin password" + echo_content green "\n==============================================================" + echo_content yellow "23. Fault detection" + echo_content yellow "24. Log query" + echo_content yellow "25. Version query" + read -r -p "Please choose: " selectInstall_type + case ${selectInstall_type} in + 1) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_ui + ;; + 2) + install_docker + install_mariadb + install_redis + install_trojan_panel + ;; + 3) + install_docker + install_reverse_proxy + install_cert + install_trojan_panel_core + ;; + 4) + install_docker + install_caddy2 + ;; + 5) + install_docker + install_nginx + ;; + 6) + install_docker + install_mariadb + ;; + 7) + install_docker + install_redis + ;; + 8) + update_trojan_panel_ui + ;; + 9) + update_trojan_panel + ;; + 10) + update_trojan_panel_core + ;; + 11) + uninstall_trojan_panel_ui + ;; + 12) + uninstall_trojan_panel + ;; + 13) + uninstall_trojan_panel_core + ;; + 14) + uninstall_caddy2 + ;; + 15) + uninstall_nginx + ;; + 16) + uninstall_mariadb + ;; + 17) + uninstall_redis + ;; + 18) + uninstall_all + ;; + 19) + update_trojan_panel_ui_port + ;; + 20) + redis_flush_all + ;; + 21) + change_cert + ;; + 22) + forget_pass + ;; + 23) + failure_testing + ;; + 24) + log_query + ;; + 25) + version_query + ;; + *) + echo_content red "No such option" + ;; + esac +} + +main