fq
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
#!/bin/bash
|
||||
|
||||
red='\033[0;31m'
|
||||
green='\033[0;32m'
|
||||
blue='\033[0;34m'
|
||||
yellow='\033[0;33m'
|
||||
plain='\033[0m'
|
||||
|
||||
cur_dir=$(pwd)
|
||||
|
||||
# check root
|
||||
[[ $EUID -ne 0 ]] && echo -e "${red}Fatal error: ${plain} Please run this script with root privilege \n " && exit 1
|
||||
|
||||
# Check OS and set release variable
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
source /etc/os-release
|
||||
release=$ID
|
||||
elif [[ -f /usr/lib/os-release ]]; then
|
||||
source /usr/lib/os-release
|
||||
release=$ID
|
||||
else
|
||||
echo "Failed to check the system OS, please contact the author!" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "The OS release is: $release"
|
||||
|
||||
arch() {
|
||||
case "$(uname -m)" in
|
||||
x86_64 | x64 | amd64) echo 'amd64' ;;
|
||||
i*86 | x86) echo '386' ;;
|
||||
armv8* | armv8 | arm64 | aarch64) echo 'arm64' ;;
|
||||
armv7* | armv7 | arm) echo 'armv7' ;;
|
||||
armv6* | armv6) echo 'armv6' ;;
|
||||
armv5* | armv5) echo 'armv5' ;;
|
||||
s390x) echo 's390x' ;;
|
||||
*) echo -e "${green}Unsupported CPU architecture! ${plain}" && rm -f install.sh && exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo "Arch: $(arch)"
|
||||
|
||||
install_base() {
|
||||
case "${release}" in
|
||||
ubuntu | debian | armbian)
|
||||
apt-get update && apt-get install -y -q wget curl tar tzdata
|
||||
;;
|
||||
centos | rhel | almalinux | rocky | ol)
|
||||
yum -y update && yum install -y -q wget curl tar tzdata
|
||||
;;
|
||||
fedora | amzn | virtuozzo)
|
||||
dnf -y update && dnf install -y -q wget curl tar tzdata
|
||||
;;
|
||||
arch | manjaro | parch)
|
||||
pacman -Syu && pacman -Syu --noconfirm wget curl tar tzdata
|
||||
;;
|
||||
opensuse-tumbleweed)
|
||||
zypper refresh && zypper -q install -y wget curl tar timezone
|
||||
;;
|
||||
*)
|
||||
apt-get update && apt-get install -y -q wget curl tar tzdata
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
gen_random_string() {
|
||||
local length="$1"
|
||||
local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' </dev/urandom | fold -w "$length" | head -n 1)
|
||||
echo "$random_string"
|
||||
}
|
||||
|
||||
config_after_install() {
|
||||
local existing_hasDefaultCredential=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'hasDefaultCredential: .+' | awk '{print $2}')
|
||||
local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}')
|
||||
local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}')
|
||||
local URL_lists=(
|
||||
"https://api4.ipify.org"
|
||||
"https://ipv4.icanhazip.com"
|
||||
"https://v4.api.ipinfo.io/ip"
|
||||
"https://ipv4.myexternalip.com/raw"
|
||||
"https://4.ident.me"
|
||||
"https://check-host.net/ip"
|
||||
)
|
||||
local server_ip=""
|
||||
for ip_address in "${URL_lists[@]}"; do
|
||||
server_ip=$(curl -s --max-time 3 "${ip_address}" 2>/dev/null | tr -d '[:space:]')
|
||||
if [[ -n "${server_ip}" ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ${#existing_webBasePath} -lt 4 ]]; then
|
||||
if [[ "$existing_hasDefaultCredential" == "true" ]]; then
|
||||
local config_webBasePath=$(gen_random_string 18)
|
||||
local config_username=$(gen_random_string 10)
|
||||
local config_password=$(gen_random_string 10)
|
||||
|
||||
read -rp "Would you like to customize the Panel Port settings? (If not, a random port will be applied) [y/n]: " config_confirm
|
||||
if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then
|
||||
read -rp "Please set up the panel port: " config_port
|
||||
echo -e "${yellow}Your Panel Port is: ${config_port}${plain}"
|
||||
else
|
||||
local config_port=$(shuf -i 1024-62000 -n 1)
|
||||
echo -e "${yellow}Generated random port: ${config_port}${plain}"
|
||||
fi
|
||||
|
||||
/usr/local/x-ui/x-ui setting -username "${config_username}" -password "${config_password}" -port "${config_port}" -webBasePath "${config_webBasePath}"
|
||||
echo -e "This is a fresh installation, generating random login info for security concerns:"
|
||||
echo -e "###############################################"
|
||||
echo -e "${green}Username: ${config_username}${plain}"
|
||||
echo -e "${green}Password: ${config_password}${plain}"
|
||||
echo -e "${green}Port: ${config_port}${plain}"
|
||||
echo -e "${green}WebBasePath: ${config_webBasePath}${plain}"
|
||||
echo -e "${green}Access URL: http://${server_ip}:${config_port}/${config_webBasePath}${plain}"
|
||||
echo -e "###############################################"
|
||||
else
|
||||
local config_webBasePath=$(gen_random_string 18)
|
||||
echo -e "${yellow}WebBasePath is missing or too short. Generating a new one...${plain}"
|
||||
/usr/local/x-ui/x-ui setting -webBasePath "${config_webBasePath}"
|
||||
echo -e "${green}New WebBasePath: ${config_webBasePath}${plain}"
|
||||
echo -e "${green}Access URL: http://${server_ip}:${existing_port}/${config_webBasePath}${plain}"
|
||||
fi
|
||||
else
|
||||
if [[ "$existing_hasDefaultCredential" == "true" ]]; then
|
||||
local config_username=$(gen_random_string 10)
|
||||
local config_password=$(gen_random_string 10)
|
||||
|
||||
echo -e "${yellow}Default credentials detected. Security update required...${plain}"
|
||||
/usr/local/x-ui/x-ui setting -username "${config_username}" -password "${config_password}"
|
||||
echo -e "Generated new random login credentials:"
|
||||
echo -e "###############################################"
|
||||
echo -e "${green}Username: ${config_username}${plain}"
|
||||
echo -e "${green}Password: ${config_password}${plain}"
|
||||
echo -e "###############################################"
|
||||
else
|
||||
echo -e "${green}Username, Password, and WebBasePath are properly set. Exiting...${plain}"
|
||||
fi
|
||||
fi
|
||||
|
||||
/usr/local/x-ui/x-ui migrate
|
||||
}
|
||||
|
||||
install_x-ui() {
|
||||
cd /usr/local/
|
||||
|
||||
# Download resources
|
||||
if [ $# == 0 ]; then
|
||||
tag_version=$(curl -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
if [[ ! -n "$tag_version" ]]; then
|
||||
echo -e "${red}Failed to fetch x-ui version, it may be due to GitHub API restrictions, please try it later${plain}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..."
|
||||
wget -N -O /usr/local/x-ui-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${red}Downloading x-ui failed, please be sure that your server can access GitHub ${plain}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
tag_version=$1
|
||||
tag_version_numeric=${tag_version#v}
|
||||
min_version="2.3.5"
|
||||
|
||||
if [[ "$(printf '%s\n' "$min_version" "$tag_version_numeric" | sort -V | head -n1)" != "$min_version" ]]; then
|
||||
echo -e "${red}Please use a newer version (at least v2.3.5). Exiting installation.${plain}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
url="https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz"
|
||||
echo -e "Beginning to install x-ui $1"
|
||||
wget -N -O /usr/local/x-ui-linux-$(arch).tar.gz ${url}
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${red}Download x-ui $1 failed, please check if the version exists ${plain}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
wget -O /usr/bin/x-ui-temp https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh
|
||||
|
||||
# Stop x-ui service and remove old resources
|
||||
if [[ -e /usr/local/x-ui/ ]]; then
|
||||
systemctl stop x-ui
|
||||
rm /usr/local/x-ui/ -rf
|
||||
fi
|
||||
|
||||
# Extract resources and set permissions
|
||||
tar zxvf x-ui-linux-$(arch).tar.gz
|
||||
rm x-ui-linux-$(arch).tar.gz -f
|
||||
|
||||
cd x-ui
|
||||
chmod +x x-ui
|
||||
chmod +x x-ui.sh
|
||||
|
||||
# Check the system's architecture and rename the file accordingly
|
||||
if [[ $(arch) == "armv5" || $(arch) == "armv6" || $(arch) == "armv7" ]]; then
|
||||
mv bin/xray-linux-$(arch) bin/xray-linux-arm
|
||||
chmod +x bin/xray-linux-arm
|
||||
fi
|
||||
chmod +x x-ui bin/xray-linux-$(arch)
|
||||
|
||||
# Update x-ui cli and se set permission
|
||||
mv -f /usr/bin/x-ui-temp /usr/bin/x-ui
|
||||
chmod +x /usr/bin/x-ui
|
||||
config_after_install
|
||||
|
||||
cp -f x-ui.service /etc/systemd/system/
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl start x-ui
|
||||
echo -e "${green}x-ui ${tag_version}${plain} installation finished, it is running now..."
|
||||
echo -e ""
|
||||
echo -e "┌───────────────────────────────────────────────────────┐
|
||||
│ ${blue}x-ui control menu usages (subcommands):${plain} │
|
||||
│ │
|
||||
│ ${blue}x-ui${plain} - Admin Management Script │
|
||||
│ ${blue}x-ui start${plain} - Start │
|
||||
│ ${blue}x-ui stop${plain} - Stop │
|
||||
│ ${blue}x-ui restart${plain} - Restart │
|
||||
│ ${blue}x-ui status${plain} - Current Status │
|
||||
│ ${blue}x-ui settings${plain} - Current Settings │
|
||||
│ ${blue}x-ui enable${plain} - Enable Autostart on OS Startup │
|
||||
│ ${blue}x-ui disable${plain} - Disable Autostart on OS Startup │
|
||||
│ ${blue}x-ui log${plain} - Check logs │
|
||||
│ ${blue}x-ui banlog${plain} - Check Fail2ban ban logs │
|
||||
│ ${blue}x-ui update${plain} - Update │
|
||||
│ ${blue}x-ui legacy${plain} - legacy version │
|
||||
│ ${blue}x-ui install${plain} - Install │
|
||||
│ ${blue}x-ui uninstall${plain} - Uninstall │
|
||||
└───────────────────────────────────────────────────────┘"
|
||||
}
|
||||
|
||||
echo -e "${green}Running...${plain}"
|
||||
install_base
|
||||
install_x-ui $1
|
||||
+594
@@ -0,0 +1,594 @@
|
||||
#!/bin/bash
|
||||
|
||||
export LANG=en_US.UTF-8
|
||||
|
||||
RED="\033[31m"
|
||||
GREEN="\033[32m"
|
||||
YELLOW="\033[33m"
|
||||
PLAIN="\033[0m"
|
||||
|
||||
red(){
|
||||
echo -e "\033[31m\033[01m$1\033[0m"
|
||||
}
|
||||
|
||||
green(){
|
||||
echo -e "\033[32m\033[01m$1\033[0m"
|
||||
}
|
||||
|
||||
yellow(){
|
||||
echo -e "\033[33m\033[01m$1\033[0m"
|
||||
}
|
||||
|
||||
# 判断系统及定义系统安装依赖方式
|
||||
REGEX=("debian" "ubuntu" "centos|red hat|kernel|oracle linux|alma|rocky" "'amazon linux'" "fedora")
|
||||
RELEASE=("Debian" "Ubuntu" "CentOS" "CentOS" "Fedora")
|
||||
PACKAGE_UPDATE=("apt-get update" "apt-get update" "yum -y update" "yum -y update" "yum -y update")
|
||||
PACKAGE_INSTALL=("apt -y install" "apt -y install" "yum -y install" "yum -y install" "yum -y install")
|
||||
PACKAGE_REMOVE=("apt -y remove" "apt -y remove" "yum -y remove" "yum -y remove" "yum -y remove")
|
||||
PACKAGE_UNINSTALL=("apt -y autoremove" "apt -y autoremove" "yum -y autoremove" "yum -y autoremove" "yum -y autoremove")
|
||||
|
||||
[[ $EUID -ne 0 ]] && red "注意: 请在root用户下运行脚本" && exit 1
|
||||
|
||||
CMD=("$(grep -i pretty_name /etc/os-release 2>/dev/null | cut -d \" -f2)" "$(hostnamectl 2>/dev/null | grep -i system | cut -d : -f2)" "$(lsb_release -sd 2>/dev/null)" "$(grep -i description /etc/lsb-release 2>/dev/null | cut -d \" -f2)" "$(grep . /etc/redhat-release 2>/dev/null)" "$(grep . /etc/issue 2>/dev/null | cut -d \\ -f1 | sed '/^[ ]*$/d')")
|
||||
|
||||
for i in "${CMD[@]}"; do
|
||||
SYS="$i" && [[ -n $SYS ]] && break
|
||||
done
|
||||
|
||||
for ((int = 0; int < ${#REGEX[@]}; int++)); do
|
||||
[[ $(echo "$SYS" | tr '[:upper:]' '[:lower:]') =~ ${REGEX[int]} ]] && SYSTEM="${RELEASE[int]}" && [[ -n $SYSTEM ]] && break
|
||||
done
|
||||
|
||||
[[ -z $SYSTEM ]] && red "目前暂不支持你的VPS的操作系统!" && exit 1
|
||||
|
||||
if [[ -z $(type -P curl) ]]; then
|
||||
if [[ ! $SYSTEM == "CentOS" ]]; then
|
||||
${PACKAGE_UPDATE[int]}
|
||||
fi
|
||||
${PACKAGE_INSTALL[int]} curl
|
||||
fi
|
||||
|
||||
realip(){
|
||||
ip=$(curl -s4m8 ip.gs -k) || ip=$(curl -s6m8 ip.gs -k)
|
||||
}
|
||||
|
||||
inst_cert(){
|
||||
green "Hysteria 2 协议证书申请方式如下:"
|
||||
echo ""
|
||||
echo -e " ${GREEN}1.${PLAIN} 必应自签证书 ${YELLOW}(默认)${PLAIN}"
|
||||
echo -e " ${GREEN}2.${PLAIN} Acme 脚本自动申请"
|
||||
echo -e " ${GREEN}3.${PLAIN} 自定义证书路径"
|
||||
echo ""
|
||||
read -rp "请输入选项 [1-3]: " certInput
|
||||
if [[ $certInput == 2 ]]; then
|
||||
cert_path="/root/cert.crt"
|
||||
key_path="/root/private.key"
|
||||
|
||||
chmod -R 777 /root
|
||||
|
||||
chmod +rw /root/cert.crt
|
||||
chmod +rw /root/private.key
|
||||
|
||||
if [[ -f /root/cert.crt && -f /root/private.key ]] && [[ -s /root/cert.crt && -s /root/private.key ]] && [[ -f /root/ca.log ]]; then
|
||||
domain=$(cat /root/ca.log)
|
||||
green "检测到原有域名:$domain 的证书,正在应用"
|
||||
hy_domain=$domain
|
||||
else
|
||||
WARPv4Status=$(curl -s4m8 https://www.cloudflare.com/cdn-cgi/trace -k | grep warp | cut -d= -f2)
|
||||
WARPv6Status=$(curl -s6m8 https://www.cloudflare.com/cdn-cgi/trace -k | grep warp | cut -d= -f2)
|
||||
if [[ $WARPv4Status =~ on|plus ]] || [[ $WARPv6Status =~ on|plus ]]; then
|
||||
wg-quick down wgcf >/dev/null 2>&1
|
||||
systemctl stop warp-go >/dev/null 2>&1
|
||||
realip
|
||||
wg-quick up wgcf >/dev/null 2>&1
|
||||
systemctl start warp-go >/dev/null 2>&1
|
||||
else
|
||||
realip
|
||||
fi
|
||||
|
||||
read -p "请输入需要申请证书的域名:" domain
|
||||
[[ -z $domain ]] && red "未输入域名,无法执行操作!" && exit 1
|
||||
green "已输入的域名:$domain" && sleep 1
|
||||
domainIP=$(dig @8.8.8.8 +time=2 +short "$domain" 2>/dev/null)
|
||||
if echo $domainIP | grep -q "network unreachable\|timed out" || [[ -z $domainIP ]]; then
|
||||
domainIP=$(dig @2001:4860:4860::8888 +time=2 aaaa +short "$domain" 2>/dev/null)
|
||||
fi
|
||||
if echo $domainIP | grep -q "network unreachable\|timed out" || [[ -z $domainIP ]] ; then
|
||||
red "未解析出 IP,请检查域名是否输入有误"
|
||||
yellow "是否尝试强行匹配?"
|
||||
green "1. 是,将使用强行匹配"
|
||||
green "2. 否,退出脚本"
|
||||
read -p "请输入选项 [1-2]:" ipChoice
|
||||
if [[ $ipChoice == 1 ]]; then
|
||||
yellow "将尝试强行匹配以申请域名证书"
|
||||
else
|
||||
red "将退出脚本"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if [[ $domainIP == $ip ]]; then
|
||||
${PACKAGE_INSTALL[int]} curl wget sudo socat openssl
|
||||
if [[ $SYSTEM == "CentOS" ]]; then
|
||||
${PACKAGE_INSTALL[int]} cronie
|
||||
systemctl start crond
|
||||
systemctl enable crond
|
||||
else
|
||||
${PACKAGE_INSTALL[int]} cron
|
||||
systemctl start cron
|
||||
systemctl enable cron
|
||||
fi
|
||||
curl https://get.acme.sh | sh -s email=$(date +%s%N | md5sum | cut -c 1-16)@gmail.com
|
||||
source ~/.bashrc
|
||||
bash ~/.acme.sh/acme.sh --upgrade --auto-upgrade
|
||||
bash ~/.acme.sh/acme.sh --set-default-ca --server letsencrypt
|
||||
if [[ -n $(echo $ip | grep ":") ]]; then
|
||||
bash ~/.acme.sh/acme.sh --issue -d ${domain} --standalone -k ec-256 --listen-v6 --insecure
|
||||
else
|
||||
bash ~/.acme.sh/acme.sh --issue -d ${domain} --standalone -k ec-256 --insecure
|
||||
fi
|
||||
bash ~/.acme.sh/acme.sh --install-cert -d ${domain} --key-file /root/private.key --fullchain-file /root/cert.crt --ecc
|
||||
if [[ -f /root/cert.crt && -f /root/private.key ]] && [[ -s /root/cert.crt && -s /root/private.key ]]; then
|
||||
echo $domain > /root/ca.log
|
||||
sed -i '/--cron/d' /etc/crontab >/dev/null 2>&1
|
||||
echo "0 0 * * * root bash /root/.acme.sh/acme.sh --cron -f >/dev/null 2>&1" >> /etc/crontab
|
||||
green "证书申请成功! 脚本申请到的证书 (cert.crt) 和私钥 (private.key) 文件已保存到 /root 文件夹下"
|
||||
yellow "证书crt文件路径如下: /root/cert.crt"
|
||||
yellow "私钥key文件路径如下: /root/private.key"
|
||||
hy_domain=$domain
|
||||
fi
|
||||
else
|
||||
red "当前域名解析的IP与当前VPS使用的真实IP不匹配"
|
||||
green "建议如下:"
|
||||
yellow "1. 请确保CloudFlare小云朵为关闭状态(仅限DNS), 其他域名解析或CDN网站设置同理"
|
||||
yellow "2. 请检查DNS解析设置的IP是否为VPS的真实IP"
|
||||
yellow "3. 脚本可能跟不上时代, 建议截图发布到GitHub Issues、GitLab Issues、论坛或TG群询问"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
elif [[ $certInput == 3 ]]; then
|
||||
read -p "请输入公钥文件 crt 的路径:" cert_path
|
||||
yellow "公钥文件 crt 的路径:$cert_path "
|
||||
read -p "请输入密钥文件 key 的路径:" key_path
|
||||
yellow "密钥文件 key 的路径:$key_path "
|
||||
read -p "请输入证书的域名:" domain
|
||||
yellow "证书域名:$domain"
|
||||
hy_domain=$domain
|
||||
|
||||
chmod +rw $cert_path
|
||||
chmod +rw $key_path
|
||||
else
|
||||
green "将使用必应自签证书作为 Hysteria 2 的节点证书"
|
||||
|
||||
cert_path="/etc/hysteria/cert.crt"
|
||||
key_path="/etc/hysteria/private.key"
|
||||
openssl ecparam -genkey -name prime256v1 -out /etc/hysteria/private.key
|
||||
openssl req -new -x509 -days 36500 -key /etc/hysteria/private.key -out /etc/hysteria/cert.crt -subj "/CN=www.bing.com"
|
||||
chmod 777 /etc/hysteria/cert.crt
|
||||
chmod 777 /etc/hysteria/private.key
|
||||
hy_domain="www.bing.com"
|
||||
domain="www.bing.com"
|
||||
fi
|
||||
}
|
||||
|
||||
inst_port(){
|
||||
iptables -t nat -F PREROUTING >/dev/null 2>&1
|
||||
|
||||
read -p "设置 Hysteria 2 端口 [1-65535](回车则随机分配端口):" port
|
||||
[[ -z $port ]] && port=$(shuf -i 2000-65535 -n 1)
|
||||
until [[ -z $(ss -tunlp | grep -w udp | awk '{print $5}' | sed 's/.*://g' | grep -w "$port") ]]; do
|
||||
if [[ -n $(ss -tunlp | grep -w udp | awk '{print $5}' | sed 's/.*://g' | grep -w "$port") ]]; then
|
||||
echo -e "${RED} $port ${PLAIN} 端口已经被其他程序占用,请更换端口重试!"
|
||||
read -p "设置 Hysteria 2 端口 [1-65535](回车则随机分配端口):" port
|
||||
[[ -z $port ]] && port=$(shuf -i 2000-65535 -n 1)
|
||||
fi
|
||||
done
|
||||
|
||||
yellow "将在 Hysteria 2 节点使用的端口是:$port"
|
||||
inst_jump
|
||||
}
|
||||
|
||||
inst_jump(){
|
||||
green "Hysteria 2 端口使用模式如下:"
|
||||
echo ""
|
||||
echo -e " ${GREEN}1.${PLAIN} 单端口 ${YELLOW}(默认)${PLAIN}"
|
||||
echo -e " ${GREEN}2.${PLAIN} 端口跳跃"
|
||||
echo ""
|
||||
read -rp "请输入选项 [1-2]: " jumpInput
|
||||
if [[ $jumpInput == 2 ]]; then
|
||||
read -p "设置范围端口的起始端口 (建议10000-65535之间):" firstport
|
||||
read -p "设置一个范围端口的末尾端口 (建议10000-65535之间,一定要比上面起始端口大):" endport
|
||||
if [[ $firstport -ge $endport ]]; then
|
||||
until [[ $firstport -le $endport ]]; do
|
||||
if [[ $firstport -ge $endport ]]; then
|
||||
red "你设置的起始端口小于末尾端口,请重新输入起始和末尾端口"
|
||||
read -p "设置范围端口的起始端口 (建议10000-65535之间):" firstport
|
||||
read -p "设置一个范围端口的末尾端口 (建议10000-65535之间,一定要比上面起始端口大):" endport
|
||||
fi
|
||||
done
|
||||
fi
|
||||
iptables -t nat -A PREROUTING -p udp --dport $firstport:$endport -j DNAT --to-destination :$port
|
||||
ip6tables -t nat -A PREROUTING -p udp --dport $firstport:$endport -j DNAT --to-destination :$port
|
||||
netfilter-persistent save >/dev/null 2>&1
|
||||
else
|
||||
red "将继续使用单端口模式"
|
||||
fi
|
||||
}
|
||||
|
||||
inst_pwd(){
|
||||
read -p "设置 Hysteria 2 密码(回车跳过为随机字符):" auth_pwd
|
||||
[[ -z $auth_pwd ]] && auth_pwd=$(date +%s%N | md5sum | cut -c 1-8)
|
||||
yellow "使用在 Hysteria 2 节点的密码为:$auth_pwd"
|
||||
}
|
||||
|
||||
inst_site(){
|
||||
read -rp "请输入 Hysteria 2 的伪装网站地址 (去除https://) [回车世嘉maimai日本网站]:" proxysite
|
||||
[[ -z $proxysite ]] && proxysite="maimai.sega.jp"
|
||||
yellow "使用在 Hysteria 2 节点的伪装网站为:$proxysite"
|
||||
}
|
||||
|
||||
insthysteria(){
|
||||
warpv6=$(curl -s6m8 https://www.cloudflare.com/cdn-cgi/trace -k | grep warp | cut -d= -f2)
|
||||
warpv4=$(curl -s4m8 https://www.cloudflare.com/cdn-cgi/trace -k | grep warp | cut -d= -f2)
|
||||
if [[ $warpv4 =~ on|plus || $warpv6 =~ on|plus ]]; then
|
||||
wg-quick down wgcf >/dev/null 2>&1
|
||||
systemctl stop warp-go >/dev/null 2>&1
|
||||
realip
|
||||
systemctl start warp-go >/dev/null 2>&1
|
||||
wg-quick up wgcf >/dev/null 2>&1
|
||||
else
|
||||
realip
|
||||
fi
|
||||
|
||||
if [[ ! ${SYSTEM} == "CentOS" ]]; then
|
||||
${PACKAGE_UPDATE}
|
||||
fi
|
||||
${PACKAGE_INSTALL} curl wget sudo qrencode procps iptables-persistent netfilter-persistent
|
||||
|
||||
wget -N https://raw.githubusercontent.com/Misaka-blog/hysteria-install/main/hy2/install_server.sh
|
||||
bash install_server.sh
|
||||
rm -f install_server.sh
|
||||
|
||||
if [[ -f "/usr/local/bin/hysteria" ]]; then
|
||||
green "Hysteria 2 安装成功!"
|
||||
else
|
||||
red "Hysteria 2 安装失败!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 询问用户 Hysteria 配置
|
||||
inst_cert
|
||||
inst_port
|
||||
inst_pwd
|
||||
inst_site
|
||||
|
||||
# 设置 Hysteria 配置文件
|
||||
cat << EOF > /etc/hysteria/config.yaml
|
||||
listen: :$port
|
||||
|
||||
tls:
|
||||
cert: $cert_path
|
||||
key: $key_path
|
||||
|
||||
quic:
|
||||
initStreamReceiveWindow: 16777216
|
||||
maxStreamReceiveWindow: 16777216
|
||||
initConnReceiveWindow: 33554432
|
||||
maxConnReceiveWindow: 33554432
|
||||
|
||||
auth:
|
||||
type: password
|
||||
password: $auth_pwd
|
||||
|
||||
masquerade:
|
||||
type: proxy
|
||||
proxy:
|
||||
url: https://$proxysite
|
||||
rewriteHost: true
|
||||
EOF
|
||||
|
||||
# 确定最终入站端口范围
|
||||
if [[ -n $firstport ]]; then
|
||||
last_port="$port,$firstport-$endport"
|
||||
else
|
||||
last_port=$port
|
||||
fi
|
||||
|
||||
# 给 IPv6 地址加中括号
|
||||
if [[ -n $(echo $ip | grep ":") ]]; then
|
||||
last_ip="[$ip]"
|
||||
else
|
||||
last_ip=$ip
|
||||
fi
|
||||
|
||||
mkdir /root/hy
|
||||
cat << EOF > /root/hy/hy-client.yaml
|
||||
server: $last_ip:$last_port
|
||||
|
||||
auth: $auth_pwd
|
||||
|
||||
tls:
|
||||
sni: $hy_domain
|
||||
insecure: true
|
||||
|
||||
quic:
|
||||
initStreamReceiveWindow: 16777216
|
||||
maxStreamReceiveWindow: 16777216
|
||||
initConnReceiveWindow: 33554432
|
||||
maxConnReceiveWindow: 33554432
|
||||
|
||||
fastOpen: true
|
||||
|
||||
socks5:
|
||||
listen: 127.0.0.1:5080
|
||||
|
||||
transport:
|
||||
udp:
|
||||
hopInterval: 30s
|
||||
EOF
|
||||
cat << EOF > /root/hy/hy-client.json
|
||||
{
|
||||
"server": "$last_ip:$last_port",
|
||||
"auth": "$auth_pwd",
|
||||
"tls": {
|
||||
"sni": "$hy_domain",
|
||||
"insecure": true
|
||||
},
|
||||
"quic": {
|
||||
"initStreamReceiveWindow": 16777216,
|
||||
"maxStreamReceiveWindow": 16777216,
|
||||
"initConnReceiveWindow": 33554432,
|
||||
"maxConnReceiveWindow": 33554432
|
||||
},
|
||||
"fastOpen": true,
|
||||
"socks5": {
|
||||
"listen": "127.0.0.1:5080"
|
||||
},
|
||||
"transport": {
|
||||
"udp": {
|
||||
"hopInterval": "30s"
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
cat <<EOF > /root/hy/clash-meta.yaml
|
||||
mixed-port: 7890
|
||||
external-controller: 127.0.0.1:9090
|
||||
allow-lan: false
|
||||
mode: rule
|
||||
log-level: debug
|
||||
ipv6: true
|
||||
dns:
|
||||
enable: true
|
||||
listen: 0.0.0.0:53
|
||||
enhanced-mode: fake-ip
|
||||
nameserver:
|
||||
- 8.8.8.8
|
||||
- 1.1.1.1
|
||||
- 114.114.114.114
|
||||
proxies:
|
||||
- name: Misaka-Hysteria2
|
||||
type: hysteria2
|
||||
server: $last_ip
|
||||
port: $port
|
||||
password: $auth_pwd
|
||||
sni: $hy_domain
|
||||
skip-cert-verify: true
|
||||
proxy-groups:
|
||||
- name: Proxy
|
||||
type: select
|
||||
proxies:
|
||||
- Misaka-Hysteria2
|
||||
|
||||
rules:
|
||||
- GEOIP,CN,DIRECT
|
||||
- MATCH,Proxy
|
||||
EOF
|
||||
url="hysteria2://$auth_pwd@$last_ip:$last_port/?insecure=1&sni=$hy_domain#Misaka-Hysteria2"
|
||||
echo $url > /root/hy/url.txt
|
||||
nohopurl="hysteria2://$auth_pwd@$last_ip:$port/?insecure=1&sni=$hy_domain#Misaka-Hysteria2"
|
||||
echo $nohopurl > /root/hy/url-nohop.txt
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable hysteria-server
|
||||
systemctl start hysteria-server
|
||||
if [[ -n $(systemctl status hysteria-server 2>/dev/null | grep -w active) && -f '/etc/hysteria/config.yaml' ]]; then
|
||||
green "Hysteria 2 服务启动成功"
|
||||
else
|
||||
red "Hysteria 2 服务启动失败,请运行 systemctl status hysteria-server 查看服务状态并反馈,脚本退出" && exit 1
|
||||
fi
|
||||
red "======================================================================================"
|
||||
green "Hysteria 2 代理服务安装完成"
|
||||
yellow "Hysteria 2 客户端 YAML 配置文件 hy-client.yaml 内容如下,并保存到 /root/hy/hy-client.yaml"
|
||||
red "$(cat /root/hy/hy-client.yaml)"
|
||||
yellow "Hysteria 2 客户端 JSON 配置文件 hy-client.json 内容如下,并保存到 /root/hy/hy-client.json"
|
||||
red "$(cat /root/hy/hy-client.json)"
|
||||
yellow "Clash Meta 客户端配置文件已保存到 /root/hy/clash-meta.yaml"
|
||||
yellow "Hysteria 2 节点分享链接如下,并保存到 /root/hy/url.txt"
|
||||
red "$(cat /root/hy/url.txt)"
|
||||
yellow "Hysteria 2 节点单端口的分享链接如下,并保存到 /root/hy/url.txt"
|
||||
red "$(cat /root/hy/url-nohop.txt)"
|
||||
}
|
||||
|
||||
unsthysteria(){
|
||||
systemctl stop hysteria-server.service >/dev/null 2>&1
|
||||
systemctl disable hysteria-server.service >/dev/null 2>&1
|
||||
rm -f /lib/systemd/system/hysteria-server.service /lib/systemd/system/hysteria-server@.service
|
||||
rm -rf /usr/local/bin/hysteria /etc/hysteria /root/hy /root/hysteria.sh
|
||||
iptables -t nat -F PREROUTING >/dev/null 2>&1
|
||||
netfilter-persistent save >/dev/null 2>&1
|
||||
|
||||
green "Hysteria 2 已彻底卸载完成!"
|
||||
}
|
||||
|
||||
starthysteria(){
|
||||
systemctl start hysteria-server
|
||||
systemctl enable hysteria-server >/dev/null 2>&1
|
||||
}
|
||||
|
||||
stophysteria(){
|
||||
systemctl stop hysteria-server
|
||||
systemctl disable hysteria-server >/dev/null 2>&1
|
||||
}
|
||||
|
||||
hysteriaswitch(){
|
||||
yellow "请选择你需要的操作:"
|
||||
echo ""
|
||||
echo -e " ${GREEN}1.${PLAIN} 启动 Hysteria 2"
|
||||
echo -e " ${GREEN}2.${PLAIN} 关闭 Hysteria 2"
|
||||
echo -e " ${GREEN}3.${PLAIN} 重启 Hysteria 2"
|
||||
echo ""
|
||||
read -rp "请输入选项 [0-3]: " switchInput
|
||||
case $switchInput in
|
||||
1 ) starthysteria ;;
|
||||
2 ) stophysteria ;;
|
||||
3 ) stophysteria && starthysteria ;;
|
||||
* ) exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
changeport(){
|
||||
oldport=$(cat /etc/hysteria/config.yaml 2>/dev/null | sed -n 1p | awk '{print $2}' | awk -F ":" '{print $2}')
|
||||
|
||||
read -p "设置 Hysteria 2 端口[1-65535](回车则随机分配端口):" port
|
||||
[[ -z $port ]] && port=$(shuf -i 2000-65535 -n 1)
|
||||
|
||||
until [[ -z $(ss -tunlp | grep -w udp | awk '{print $5}' | sed 's/.*://g' | grep -w "$port") ]]; do
|
||||
if [[ -n $(ss -tunlp | grep -w udp | awk '{print $5}' | sed 's/.*://g' | grep -w "$port") ]]; then
|
||||
echo -e "${RED} $port ${PLAIN} 端口已经被其他程序占用,请更换端口重试!"
|
||||
read -p "设置 Hysteria 2 端口 [1-65535](回车则随机分配端口):" port
|
||||
[[ -z $port ]] && port=$(shuf -i 2000-65535 -n 1)
|
||||
fi
|
||||
done
|
||||
|
||||
sed -i "1s#$oldport#$port#g" /etc/hysteria/config.yaml
|
||||
sed -i "1s#$oldport#$port#g" /root/hy/hy-client.yaml
|
||||
sed -i "2s#$oldport#$port#g" /root/hy/hy-client.json
|
||||
|
||||
stophysteria && starthysteria
|
||||
|
||||
green "Hysteria 2 端口已成功修改为:$port"
|
||||
yellow "请手动更新客户端配置文件以使用节点"
|
||||
showconf
|
||||
}
|
||||
|
||||
changepasswd(){
|
||||
oldpasswd=$(cat /etc/hysteria/config.yaml 2>/dev/null | sed -n 15p | awk '{print $2}')
|
||||
|
||||
read -p "设置 Hysteria 2 密码(回车跳过为随机字符):" passwd
|
||||
[[ -z $passwd ]] && passwd=$(date +%s%N | md5sum | cut -c 1-8)
|
||||
|
||||
sed -i "1s#$oldpasswd#$passwd#g" /etc/hysteria/config.yaml
|
||||
sed -i "1s#$oldpasswd#$passwd#g" /root/hy/hy-client.yaml
|
||||
sed -i "3s#$oldpasswd#$passwd#g" /root/hy/hy-client.json
|
||||
|
||||
stophysteria && starthysteria
|
||||
|
||||
green "Hysteria 2 节点密码已成功修改为:$passwd"
|
||||
yellow "请手动更新客户端配置文件以使用节点"
|
||||
showconf
|
||||
}
|
||||
|
||||
change_cert(){
|
||||
old_cert=$(cat /etc/hysteria/config.yaml | grep cert | awk -F " " '{print $2}')
|
||||
old_key=$(cat /etc/hysteria/config.yaml | grep key | awk -F " " '{print $2}')
|
||||
old_hydomain=$(cat /root/hy/hy-client.yaml | grep sni | awk '{print $2}')
|
||||
|
||||
inst_cert
|
||||
|
||||
sed -i "s!$old_cert!$cert_path!g" /etc/hysteria/config.yaml
|
||||
sed -i "s!$old_key!$key_path!g" /etc/hysteria/config.yaml
|
||||
sed -i "6s/$old_hydomain/$hy_domain/g" /root/hy/hy-client.yaml
|
||||
sed -i "5s/$old_hydomain/$hy_domain/g" /root/hy/hy-client.json
|
||||
|
||||
stophysteria && starthysteria
|
||||
|
||||
green "Hysteria 2 节点证书类型已成功修改"
|
||||
yellow "请手动更新客户端配置文件以使用节点"
|
||||
showconf
|
||||
}
|
||||
|
||||
changeproxysite(){
|
||||
oldproxysite=$(cat /etc/hysteria/config.yaml | grep url | awk -F " " '{print $2}' | awk -F "https://" '{print $2}')
|
||||
|
||||
inst_site
|
||||
|
||||
sed -i "s#$oldproxysite#$proxysite#g" /etc/caddy/Caddyfile
|
||||
|
||||
stophysteria && starthysteria
|
||||
|
||||
green "Hysteria 2 节点伪装网站已成功修改为:$proxysite"
|
||||
}
|
||||
|
||||
changeconf(){
|
||||
green "Hysteria 2 配置变更选择如下:"
|
||||
echo -e " ${GREEN}1.${PLAIN} 修改端口"
|
||||
echo -e " ${GREEN}2.${PLAIN} 修改密码"
|
||||
echo -e " ${GREEN}3.${PLAIN} 修改证书类型"
|
||||
echo -e " ${GREEN}4.${PLAIN} 修改伪装网站"
|
||||
echo ""
|
||||
read -p " 请选择操作 [1-4]:" confAnswer
|
||||
case $confAnswer in
|
||||
1 ) changeport ;;
|
||||
2 ) changepasswd ;;
|
||||
3 ) change_cert ;;
|
||||
4 ) changeproxysite ;;
|
||||
* ) exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
showconf(){
|
||||
yellow "Hysteria 2 客户端 YAML 配置文件 hy-client.yaml 内容如下,并保存到 /root/hy/hy-client.yaml"
|
||||
red "$(cat /root/hy/hy-client.yaml)"
|
||||
yellow "Hysteria 2 客户端 JSON 配置文件 hy-client.json 内容如下,并保存到 /root/hy/hy-client.json"
|
||||
red "$(cat /root/hy/hy-client.json)"
|
||||
yellow "Clash Meta 客户端配置文件已保存到 /root/hy/clash-meta.yaml"
|
||||
yellow "Hysteria 2 节点分享链接如下,并保存到 /root/hy/url.txt"
|
||||
red "$(cat /root/hy/url.txt)"
|
||||
yellow "Hysteria 2 节点单端口的分享链接如下,并保存到 /root/hy/url.txt"
|
||||
red "$(cat /root/hy/url-nohop.txt)"
|
||||
}
|
||||
|
||||
update_core(){
|
||||
wget -N https://raw.githubusercontent.com/Misaka-blog/hysteria-install/main/hy2/install_server.sh
|
||||
bash install_server.sh
|
||||
|
||||
rm -f install_server.sh
|
||||
}
|
||||
|
||||
menu() {
|
||||
clear
|
||||
echo "#############################################################"
|
||||
echo -e "# ${RED}Hysteria 2 一键安装脚本${PLAIN} #"
|
||||
echo -e "# ${GREEN}作者${PLAIN}: MisakaNo の 小破站 #"
|
||||
echo -e "# ${GREEN}博客${PLAIN}: https://blog.misaka.cyou #"
|
||||
echo -e "# ${GREEN}GitHub 项目${PLAIN}: https://github.com/Misaka-blog #"
|
||||
echo -e "# ${GREEN}GitLab 项目${PLAIN}: https://gitlab.com/Misaka-blog #"
|
||||
echo -e "# ${GREEN}Telegram 频道${PLAIN}: https://t.me/misakanocchannel #"
|
||||
echo -e "# ${GREEN}Telegram 群组${PLAIN}: https://t.me/misakanoc #"
|
||||
echo -e "# ${GREEN}YouTube 频道${PLAIN}: https://www.youtube.com/@misaka-blog #"
|
||||
echo "#############################################################"
|
||||
echo ""
|
||||
echo -e " ${GREEN}1.${PLAIN} 安装 Hysteria 2"
|
||||
echo -e " ${GREEN}2.${PLAIN} ${RED}卸载 Hysteria 2${PLAIN}"
|
||||
echo " -------------"
|
||||
echo -e " ${GREEN}3.${PLAIN} 关闭、开启、重启 Hysteria 2"
|
||||
echo -e " ${GREEN}4.${PLAIN} 修改 Hysteria 2 配置"
|
||||
echo -e " ${GREEN}5.${PLAIN} 显示 Hysteria 2 配置文件"
|
||||
echo " -------------"
|
||||
echo -e " ${GREEN}6.${PLAIN} 更新 Hysteria 2 内核"
|
||||
echo " -------------"
|
||||
echo -e " ${GREEN}0.${PLAIN} 退出脚本"
|
||||
echo ""
|
||||
read -rp "请输入选项 [0-5]: " menuInput
|
||||
case $menuInput in
|
||||
1 ) insthysteria ;;
|
||||
2 ) unsthysteria ;;
|
||||
3 ) hysteriaswitch ;;
|
||||
4 ) changeconf ;;
|
||||
5 ) showconf ;;
|
||||
6 ) update_core ;;
|
||||
* ) exit 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
menu
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
#!/bin/bash
|
||||
|
||||
red='\033[0;31m'
|
||||
green='\033[0;32m'
|
||||
yellow='\033[0;33m'
|
||||
plain='\033[0m'
|
||||
|
||||
cur_dir=$(pwd)
|
||||
|
||||
# check root
|
||||
[[ $EUID -ne 0 ]] && echo -e "${red}错误:${plain} 必须使用root用户运行此脚本!\n" && exit 1
|
||||
|
||||
# check os
|
||||
if [[ -f /etc/redhat-release ]]; then
|
||||
release="centos"
|
||||
elif cat /etc/issue | grep -Eqi "debian"; then
|
||||
release="debian"
|
||||
elif cat /etc/issue | grep -Eqi "ubuntu"; then
|
||||
release="ubuntu"
|
||||
elif cat /etc/issue | grep -Eqi "centos|red hat|redhat"; then
|
||||
release="centos"
|
||||
elif cat /proc/version | grep -Eqi "debian"; then
|
||||
release="debian"
|
||||
elif cat /proc/version | grep -Eqi "ubuntu"; then
|
||||
release="ubuntu"
|
||||
elif cat /proc/version | grep -Eqi "centos|red hat|redhat"; then
|
||||
release="centos"
|
||||
else
|
||||
echo -e "${red}未检测到系统版本,请联系脚本作者!${plain}\n" && exit 1
|
||||
fi
|
||||
|
||||
arch=$(arch)
|
||||
|
||||
if [[ $arch == "i386" || $arch == "i686" ]]; then
|
||||
arch="386"
|
||||
elif [[ $arch == "x86_64" || $arch == "x64" || $arch == "amd64" ]]; then
|
||||
arch="amd64"
|
||||
elif [[ $arch == "aarch64" || $arch == "arm64" ]]; then
|
||||
arch="arm64"
|
||||
elif [[ $arch == "s390x" ]]; then
|
||||
arch="s390x"
|
||||
else
|
||||
arch="amd64"
|
||||
echo -e "${red}检测架构失败,使用默认架构: ${arch}${plain}"
|
||||
fi
|
||||
|
||||
echo "架构: ${arch}"
|
||||
|
||||
if [ $(getconf WORD_BIT) != '32' ] && [ $(getconf LONG_BIT) != '64' ]; then
|
||||
echo "本软件不支持 32 位系统(x86),请使用 64 位系统(x86_64),如果检测有误,请联系作者"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
os_version=""
|
||||
|
||||
# os version
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
os_version=$(awk -F'[= ."]' '/VERSION_ID/{print $3}' /etc/os-release)
|
||||
fi
|
||||
if [[ -z "$os_version" && -f /etc/lsb-release ]]; then
|
||||
os_version=$(awk -F'[= ."]+' '/DISTRIB_RELEASE/{print $2}' /etc/lsb-release)
|
||||
fi
|
||||
|
||||
if [[ x"${release}" == x"centos" ]]; then
|
||||
if [[ ${os_version} -le 6 ]]; then
|
||||
echo -e "${red}请使用 CentOS 7 或更高版本的系统!${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ x"${release}" == x"ubuntu" ]]; then
|
||||
if [[ ${os_version} -lt 16 ]]; then
|
||||
echo -e "${red}请使用 Ubuntu 16 或更高版本的系统!${plain}\n" && exit 1
|
||||
fi
|
||||
elif [[ x"${release}" == x"debian" ]]; then
|
||||
if [[ ${os_version} -lt 8 ]]; then
|
||||
echo -e "${red}请使用 Debian 8 或更高版本的系统!${plain}\n" && exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
install_base() {
|
||||
if [[ x"${release}" == x"centos" ]]; then
|
||||
yum install wget curl tar -y
|
||||
else
|
||||
apt-get update
|
||||
apt install wget curl tar -y
|
||||
fi
|
||||
}
|
||||
|
||||
#This function will be called when user installed x-ui out of sercurity
|
||||
config_after_install() {
|
||||
echo -e "${yellow}出于安全考虑,安装/更新完成后需要强制修改端口与账户密码${plain}"
|
||||
read -p "确认是否继续? [y/n]: " config_confirm
|
||||
if [[ x"${config_confirm}" == x"y" || x"${config_confirm}" == x"Y" ]]; then
|
||||
read -p "请设置您的账户名(如未填写则随机8位字符): " config_account
|
||||
[[ -z $config_account ]] && config_account=$(date +%s%N | md5sum | cut -c 1-8)
|
||||
echo -e "${yellow}您的账户名将设定为:${config_account}${plain}"
|
||||
read -p "请设置您的账户密码(如未填写则随机8位字符): " config_password
|
||||
[[ -z $config_password ]] && config_password=$(date +%s%N | md5sum | cut -c 1-8)
|
||||
echo -e "${yellow}您的账户密码将设定为:${config_password}${plain}"
|
||||
read -p "请设置面板访问端口(如未填写则随机端口号): " config_port
|
||||
[[ -z $config_port ]] && config_port=$(shuf -i 2000-65535 -n 1)
|
||||
until [[ -z $(ss -ntlp | awk '{print $4}' | sed 's/.*://g' | grep -w "$port") ]]; do
|
||||
if [[ -n $(ss -ntlp | awk '{print $4}' | sed 's/.*://g' | grep -w "$port") ]]; then
|
||||
echo -e "${red} $config_port ${plain} 端口已经其他程序占用,请更换面板端口号"
|
||||
read -p "请设置面板访问端口(如未填写则随机端口号): " config_port
|
||||
[[ -z $config_port ]] && config_port=$(shuf -i 2000-65535 -n 1)
|
||||
fi
|
||||
done
|
||||
echo -e "${yellow}您的面板访问端口将设定为:${config_port}${plain}"
|
||||
echo -e "${yellow}确认设定,设定中${plain}"
|
||||
/usr/local/x-ui/x-ui setting -username ${config_account} -password ${config_password}
|
||||
echo -e "${yellow}账户密码设定完成${plain}"
|
||||
/usr/local/x-ui/x-ui setting -port ${config_port}
|
||||
echo -e "${yellow}面板端口设定完成${plain}"
|
||||
else
|
||||
config_port=$(/usr/local/x-ui/x-ui setting -show | sed -n 4p | awk -F ": " '{print $2}')
|
||||
echo -e "${red}已取消, 所有设置项均为默认设置, 请及时修改${plain}"
|
||||
fi
|
||||
}
|
||||
|
||||
install_x-ui() {
|
||||
systemctl stop x-ui
|
||||
cd /usr/local/
|
||||
|
||||
if [ $# == 0 ]; then
|
||||
last_version=$(curl -Ls "https://api.github.com/repos/sing-web/x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
|
||||
if [[ ! -n "$last_version" ]]; then
|
||||
echo -e "${red}检测 x-ui 版本失败,可能是超出 Github API 限制,请稍后再试,或手动指定 x-ui 版本安装${plain}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "检测到 x-ui 最新版本:${last_version},开始安装"
|
||||
wget -N --no-check-certificate -O /usr/local/x-ui-linux-${arch}.tar.gz https://github.com/sing-web/x-ui/releases/download/${last_version}/x-ui-linux-${arch}.tar.gz
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${red}下载 x-ui 失败,请确保你的服务器能够下载 Github 的文件${plain}"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
last_version=$1
|
||||
url="https://github.com/sing-web/x-ui/releases/download/${last_version}/x-ui-linux-${arch}.tar.gz"
|
||||
echo -e "开始安装 x-ui $1"
|
||||
wget -N --no-check-certificate -O /usr/local/x-ui-linux-${arch}.tar.gz ${url}
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${red}下载 x-ui $1 失败,请确保此版本存在${plain}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -e /usr/local/x-ui/ ]]; then
|
||||
rm /usr/local/x-ui/ -rf
|
||||
fi
|
||||
|
||||
tar zxvf x-ui-linux-${arch}.tar.gz
|
||||
rm x-ui-linux-${arch}.tar.gz -f
|
||||
cd x-ui
|
||||
chmod +x x-ui bin/xray-linux-${arch}
|
||||
cp -f x-ui.service /etc/systemd/system/
|
||||
wget --no-check-certificate -O /usr/bin/x-ui https://raw.githubusercontent.com/sing-web/x-ui/main/x-ui_CN.sh
|
||||
chmod +x /usr/local/x-ui/x-ui.sh
|
||||
chmod +x /usr/bin/x-ui
|
||||
config_after_install
|
||||
#echo -e "如果是全新安装,默认网页端口为 ${green}54321${plain},用户名和密码默认都是 ${green}admin${plain}"
|
||||
#echo -e "请自行确保此端口没有被其他程序占用,${yellow}并且确保 54321 端口已放行${plain}"
|
||||
# echo -e "若想将 54321 修改为其它端口,输入 x-ui 命令进行修改,同样也要确保你修改的端口也是放行的"
|
||||
#echo -e ""
|
||||
#echo -e "如果是更新面板,则按你之前的方式访问面板"
|
||||
#echo -e ""
|
||||
systemctl daemon-reload
|
||||
systemctl enable x-ui
|
||||
systemctl start x-ui
|
||||
|
||||
systemctl stop warp-go >/dev/null 2>&1
|
||||
wg-quick down wgcf >/dev/null 2>&1
|
||||
ipv4=$(curl -s4m8 ip.p3terx.com -k | sed -n 1p)
|
||||
ipv6=$(curl -s6m8 ip.p3terx.com -k | sed -n 1p)
|
||||
systemctl start warp-go >/dev/null 2>&1
|
||||
wg-quick up wgcf >/dev/null 2>&1
|
||||
echo -e "${green}x-ui ${last_version}${plain} 安装完成,面板已启动"
|
||||
echo -e ""
|
||||
echo -e "x-ui 管理脚本使用方法: "
|
||||
echo -e "----------------------------------------------"
|
||||
echo -e "x-ui - 显示管理菜单 (功能更多)"
|
||||
echo -e "x-ui start - 启动 x-ui 面板"
|
||||
echo -e "x-ui stop - 停止 x-ui 面板"
|
||||
echo -e "x-ui restart - 重启 x-ui 面板"
|
||||
echo -e "x-ui status - 查看 x-ui 状态"
|
||||
echo -e "x-ui enable - 设置 x-ui 开机自启"
|
||||
echo -e "x-ui disable - 取消 x-ui 开机自启"
|
||||
echo -e "x-ui log - 查看 x-ui 日志"
|
||||
echo -e "x-ui update - 更新 x-ui 面板"
|
||||
echo -e "x-ui install - 安装 x-ui 面板"
|
||||
echo -e "x-ui uninstall - 卸载 x-ui 面板"
|
||||
echo -e "----------------------------------------------"
|
||||
echo ""
|
||||
if [[ -n $ipv4 ]]; then
|
||||
echo -e "${yellow}面板IPv4访问地址为:${plain} ${green}http://$ipv4:$config_port ${plain}"
|
||||
fi
|
||||
if [[ -n $ipv6 ]]; then
|
||||
echo -e "${yellow}面板IPv6访问地址为:${plain} ${green}http://[$ipv6]:$config_port ${plain}"
|
||||
fi
|
||||
echo -e "请自行确保此端口没有被其他程序占用,${yellow}并且确保${plain} ${red} $config_port ${plain} ${yellow}端口已放行${plain}"
|
||||
}
|
||||
|
||||
echo -e "${green}开始安装${plain}"
|
||||
install_base
|
||||
install_x-ui $1
|
||||
+417
@@ -0,0 +1,417 @@
|
||||
#!/bin/bash
|
||||
# MTProto一键安装脚本
|
||||
# Author: palm<https://tizi.blog>
|
||||
|
||||
RED="\033[31m" # Error message
|
||||
GREEN="\033[32m" # Success message
|
||||
YELLOW="\033[33m" # Warning message
|
||||
BLUE="\033[36m" # Info message
|
||||
PLAIN='\033[0m'
|
||||
|
||||
export MTG_CONFIG="${MTG_CONFIG:-$HOME/.config/mtg}"
|
||||
export MTG_ENV="$MTG_CONFIG/env"
|
||||
export MTG_SECRET="$MTG_CONFIG/secret"
|
||||
export MTG_CONTAINER="${MTG_CONTAINER:-mtg}"
|
||||
export MTG_IMAGENAME="${MTG_IMAGENAME:-nineseconds/mtg:1}"
|
||||
|
||||
DOCKER_CMD="$(command -v docker)"
|
||||
OSNAME=`hostnamectl | grep -i system | cut -d: -f2`
|
||||
|
||||
IP=`curl -sL -4 ip.sb`
|
||||
|
||||
colorEcho() {
|
||||
echo -e "${1}${@:2}${PLAIN}"
|
||||
}
|
||||
|
||||
checkSystem() {
|
||||
result=$(id | awk '{print $1}')
|
||||
if [[ $result != "uid=0(root)" ]]; then
|
||||
colorEcho $RED " 请以root身份执行该脚本"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
res=`which yum`
|
||||
if [[ "$?" != "0" ]]; then
|
||||
res=`which apt`
|
||||
if [ "$?" != "0" ]; then
|
||||
colorEcho $RED " 不受支持的Linux系统"
|
||||
exit 1
|
||||
fi
|
||||
res=`hostnamectl | grep -i ubuntu`
|
||||
if [[ "${res}" != "" ]]; then
|
||||
OS="ubuntu"
|
||||
else
|
||||
OS="debian"
|
||||
fi
|
||||
PMT="apt"
|
||||
CMD_INSTALL="apt install -y "
|
||||
CMD_REMOVE="apt remove -y "
|
||||
else
|
||||
OS="centos"
|
||||
PMT="yum"
|
||||
CMD_INSTALL="yum install -y "
|
||||
CMD_REMOVE="yum remove -y "
|
||||
fi
|
||||
res=`which systemctl`
|
||||
if [[ "$?" != "0" ]]; then
|
||||
colorEcho $RED " 系统版本过低,请升级到最新版本"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
status() {
|
||||
if [[ "$DOCKER_CMD" = "" ]]; then
|
||||
echo 0
|
||||
return
|
||||
elif [[ ! -f $MTG_ENV ]]; then
|
||||
echo 1
|
||||
return
|
||||
fi
|
||||
port=`grep MTG_PORT $MTG_ENV|cut -d= -f2`
|
||||
if [[ -z "$port" ]]; then
|
||||
echo 2
|
||||
return
|
||||
fi
|
||||
res=`ss -ntlp| grep ${port} | grep docker`
|
||||
if [[ -z "$res" ]]; then
|
||||
echo 3
|
||||
else
|
||||
echo 4
|
||||
fi
|
||||
}
|
||||
|
||||
statusText() {
|
||||
res=`status`
|
||||
case $res in
|
||||
3)
|
||||
echo -e ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN}
|
||||
;;
|
||||
4)
|
||||
echo -e ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN}
|
||||
;;
|
||||
*)
|
||||
echo -e ${RED}未安装${PLAIN}
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
getData() {
|
||||
read -p " 请输入MTProto端口[100-65535的一个数字]:" PORT
|
||||
[[ -z "${PORT}" ]] && {
|
||||
echo -e " ${RED}请输入MTProto端口!${PLAIN}"
|
||||
exit 1
|
||||
}
|
||||
if [[ "${PORT:0:1}" = "0" ]]; then
|
||||
echo -e " ${RED}端口不能以0开头${PLAIN}"
|
||||
exit 1
|
||||
fi
|
||||
MTG_PORT=$PORT
|
||||
mkdir -p $MTG_CONFIG
|
||||
echo "MTG_IMAGENAME=$MTG_IMAGENAME" > "$MTG_ENV"
|
||||
echo "MTG_PORT=$MTG_PORT" >> "$MTG_ENV"
|
||||
echo "MTG_CONTAINER=$MTG_CONTAINER" >> "$MTG_ENV"
|
||||
}
|
||||
|
||||
installDocker() {
|
||||
if [[ "$DOCKER_CMD" != "" ]]; then
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
selinux
|
||||
return
|
||||
fi
|
||||
|
||||
#$CMD_REMOVE docker docker-engine docker.io containerd runc
|
||||
$PMT clean all
|
||||
$CMD_INSTALL wget curl
|
||||
if [[ $PMT = "apt" ]]; then
|
||||
apt clean all
|
||||
apt-get -y install \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg-agent \
|
||||
software-properties-common
|
||||
curl -fsSL https://download.docker.com/linux/$OS/gpg | apt-key add -
|
||||
add-apt-repository \
|
||||
"deb [arch=amd64] https://download.docker.com/linux/$OS \
|
||||
$(lsb_release -cs) \
|
||||
stable"
|
||||
apt update
|
||||
else
|
||||
wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo
|
||||
yum clean all
|
||||
fi
|
||||
$CMD_INSTALL docker-ce docker-ce-cli containerd.io
|
||||
|
||||
DOCKER_CMD="$(command -v docker)"
|
||||
if [[ "$DOCKER_CMD" = "" ]]; then
|
||||
echo -e " ${RED}$OSNAME docker安装失败,请到https://tizi.blog反馈${PLAIN}"
|
||||
exit 1
|
||||
fi
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
|
||||
selinux
|
||||
}
|
||||
|
||||
pullImage() {
|
||||
if [[ "$DOCKER_CMD" = "" ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -a
|
||||
source "$MTG_ENV"
|
||||
set +a
|
||||
|
||||
$DOCKER_CMD pull "$MTG_IMAGENAME" > /dev/null
|
||||
}
|
||||
|
||||
selinux() {
|
||||
if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then
|
||||
sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config
|
||||
setenforce 0
|
||||
fi
|
||||
}
|
||||
|
||||
firewall() {
|
||||
port=$1
|
||||
systemctl status firewalld > /dev/null 2>&1
|
||||
if [[ $? -eq 0 ]];then
|
||||
firewall-cmd --permanent --add-port=$port/tcp
|
||||
firewall-cmd --reload
|
||||
else
|
||||
nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'`
|
||||
if [ "$nl" != "3" ]; then
|
||||
iptables -I INPUT -p tcp --dport=$port -j ACCEPT
|
||||
else
|
||||
res=`ufw status | grep -i inactive`
|
||||
if [ "$res" = "" ]; then
|
||||
ufw allow $port/tcp
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
start() {
|
||||
res=`status`
|
||||
if [[ $res -lt 3 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
set -a
|
||||
source "$MTG_ENV"
|
||||
set +a
|
||||
|
||||
if [[ ! -f "$MTG_SECRET" ]]; then
|
||||
$DOCKER_CMD run \
|
||||
--rm \
|
||||
"$MTG_IMAGENAME" \
|
||||
generate-secret tls -c "$(openssl rand -hex 16).com" \
|
||||
> "$MTG_SECRET"
|
||||
fi
|
||||
|
||||
$DOCKER_CMD ps --filter "Name=$MTG_CONTAINER" -aq | xargs -r $DOCKER_CMD rm -fv > /dev/null
|
||||
$DOCKER_CMD run \
|
||||
-d \
|
||||
--restart=unless-stopped \
|
||||
--name "$MTG_CONTAINER" \
|
||||
--ulimit nofile=51200:51200 \
|
||||
-p "$MTG_PORT:3128" \
|
||||
"$MTG_IMAGENAME" run "$(cat "$MTG_SECRET")" > /dev/null
|
||||
|
||||
sleep 3
|
||||
res=`ss -ntlp| grep ${MTG_PORT} | grep docker`
|
||||
if [[ "$res" = "" ]]; then
|
||||
docker logs $MTG_CONTAINER | tail
|
||||
echo -e " ${RED}$OSNAME 启动docker镜像失败,请到 https://tizi.blog 反馈${PLAIN}"
|
||||
exit 1
|
||||
else
|
||||
colorEcho $BLUE " MTProto启动成功!"
|
||||
fi
|
||||
}
|
||||
|
||||
stop() {
|
||||
res=`status`
|
||||
if [[ $res -lt 3 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
set -a
|
||||
source "$MTG_ENV"
|
||||
set +a
|
||||
|
||||
$DOCKER_CMD stop $MTG_CONTAINER >> /dev/null
|
||||
colorEcho $BLUE " MTProto停止成功!"
|
||||
}
|
||||
|
||||
showInfo() {
|
||||
res=`status`
|
||||
if [[ $res -lt 3 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
SECRET=$(cat "$MTG_SECRET")
|
||||
set -a
|
||||
source "$MTG_ENV"
|
||||
set +a
|
||||
|
||||
echo
|
||||
echo -e " ${RED}MTProto代理信息:${PLAIN}"
|
||||
echo
|
||||
echo -n -e " ${BLUE}当前状态:${PLAIN}"
|
||||
statusText
|
||||
echo -e " ${BLUE}IP:${PLAIN}${RED}$IP${PLAIN}"
|
||||
echo -e " ${BLUE}端口:${PLAIN}${RED}$MTG_PORT${PLAIN}"
|
||||
echo -e " ${BLUE}密钥:${PLAIN}${RED}$SECRET${PLAIN}"
|
||||
echo ""
|
||||
echo -e " 如需获取tg://proxy形式的链接,请打开telegrame关注${GREEN}@MTProxybot${PLAIN}生成"
|
||||
echo ""
|
||||
}
|
||||
|
||||
install() {
|
||||
getData
|
||||
installDocker
|
||||
pullImage
|
||||
start
|
||||
firewall $MTG_PORT
|
||||
showInfo
|
||||
}
|
||||
|
||||
update() {
|
||||
res=`status`
|
||||
if [[ $res -lt 2 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
pullImage
|
||||
stop
|
||||
start
|
||||
showInfo
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
echo ""
|
||||
read -p " 确定卸载MTProto?[y/n]:" answer
|
||||
if [[ "$answer" = "y" ]] || [[ "$answer" = "Y" ]]; then
|
||||
stop
|
||||
rm -rf $MTG_CONFIG
|
||||
docker system prune -af
|
||||
systemctl stop docker
|
||||
systemctl disable docker
|
||||
$CMD_REMOVE docker-ce docker-ce-cli containerd.io
|
||||
colorEcho $GREEN " 卸载成功"
|
||||
fi
|
||||
}
|
||||
|
||||
restart() {
|
||||
res=`status`
|
||||
if [[ $res -lt 3 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
reconfig()
|
||||
{
|
||||
res=`status`
|
||||
if [[ $res -lt 2 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
getData
|
||||
stop
|
||||
start
|
||||
firewall $MTG_PORT
|
||||
showInfo
|
||||
}
|
||||
|
||||
showLog() {
|
||||
res=`status`
|
||||
if [[ $res -lt 3 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
set -a
|
||||
source "$MTG_ENV"
|
||||
set +a
|
||||
|
||||
$DOCKER_CMD logs $MTG_CONTAINER | tail
|
||||
}
|
||||
|
||||
menu() {
|
||||
clear
|
||||
echo "#############################################################"
|
||||
echo -e "# ${RED}MTProto一键安装脚本${PLAIN} #"
|
||||
echo "#############################################################"
|
||||
echo ""
|
||||
|
||||
echo -e " ${GREEN}1.${PLAIN} 安装MTProto代理"
|
||||
echo -e " ${GREEN}2.${PLAIN} 更新MTProto代理"
|
||||
echo -e " ${GREEN}3.${PLAIN} 卸载MTProto代理"
|
||||
echo " -------------"
|
||||
echo -e " ${GREEN}4.${PLAIN} 启动MTProto代理"
|
||||
echo -e " ${GREEN}5.${PLAIN} 重启MTProto代理"
|
||||
echo -e " ${GREEN}6.${PLAIN} 停止MTProto代理"
|
||||
echo " -------------"
|
||||
echo -e " ${GREEN}7.${PLAIN} 查看MTProto信息"
|
||||
echo -e " ${GREEN}8.${PLAIN} 修改MTProto配置"
|
||||
echo -e " ${GREEN}9.${PLAIN} 查看MTProto日志"
|
||||
echo " -------------"
|
||||
echo -e " ${GREEN}0.${PLAIN} 退出"
|
||||
echo
|
||||
echo -n " 当前状态:"
|
||||
statusText
|
||||
echo
|
||||
|
||||
read -p " 请选择操作[0-9]:" answer
|
||||
case $answer in
|
||||
0)
|
||||
exit 0
|
||||
;;
|
||||
1)
|
||||
install
|
||||
;;
|
||||
2)
|
||||
update
|
||||
;;
|
||||
3)
|
||||
uninstall
|
||||
;;
|
||||
4)
|
||||
start
|
||||
;;
|
||||
5)
|
||||
restart
|
||||
;;
|
||||
6)
|
||||
stop
|
||||
;;
|
||||
7)
|
||||
showInfo
|
||||
;;
|
||||
8)
|
||||
reconfig
|
||||
;;
|
||||
9)
|
||||
showLog
|
||||
;;
|
||||
*)
|
||||
echo -e " ${RED}请选择正确的操作!${PLAIN}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
checkSystem
|
||||
|
||||
menu
|
||||
+417
@@ -0,0 +1,417 @@
|
||||
#!/bin/bash
|
||||
# MTProto一键安装脚本
|
||||
# Author: palm<https://tizi.blog>
|
||||
|
||||
RED="\033[31m" # Error message
|
||||
GREEN="\033[32m" # Success message
|
||||
YELLOW="\033[33m" # Warning message
|
||||
BLUE="\033[36m" # Info message
|
||||
PLAIN='\033[0m'
|
||||
|
||||
export MTG_CONFIG="${MTG_CONFIG:-$HOME/.config/mtg}"
|
||||
export MTG_ENV="$MTG_CONFIG/env"
|
||||
export MTG_SECRET="$MTG_CONFIG/secret"
|
||||
export MTG_CONTAINER="${MTG_CONTAINER:-mtg}"
|
||||
export MTG_IMAGENAME="${MTG_IMAGENAME:-nineseconds/mtg:1}"
|
||||
|
||||
DOCKER_CMD="$(command -v docker)"
|
||||
OSNAME=`hostnamectl | grep -i system | cut -d: -f2`
|
||||
|
||||
IP=`curl -sL -4 ip.sb`
|
||||
|
||||
colorEcho() {
|
||||
echo -e "${1}${@:2}${PLAIN}"
|
||||
}
|
||||
|
||||
checkSystem() {
|
||||
result=$(id | awk '{print $1}')
|
||||
if [[ $result != "uid=0(root)" ]]; then
|
||||
colorEcho $RED " 请以root身份执行该脚本"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
res=`which yum`
|
||||
if [[ "$?" != "0" ]]; then
|
||||
res=`which apt`
|
||||
if [ "$?" != "0" ]; then
|
||||
colorEcho $RED " 不受支持的Linux系统"
|
||||
exit 1
|
||||
fi
|
||||
res=`hostnamectl | grep -i ubuntu`
|
||||
if [[ "${res}" != "" ]]; then
|
||||
OS="ubuntu"
|
||||
else
|
||||
OS="debian"
|
||||
fi
|
||||
PMT="apt"
|
||||
CMD_INSTALL="apt install -y "
|
||||
CMD_REMOVE="apt remove -y "
|
||||
else
|
||||
OS="centos"
|
||||
PMT="yum"
|
||||
CMD_INSTALL="yum install -y "
|
||||
CMD_REMOVE="yum remove -y "
|
||||
fi
|
||||
res=`which systemctl`
|
||||
if [[ "$?" != "0" ]]; then
|
||||
colorEcho $RED " 系统版本过低,请升级到最新版本"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
status() {
|
||||
if [[ "$DOCKER_CMD" = "" ]]; then
|
||||
echo 0
|
||||
return
|
||||
elif [[ ! -f $MTG_ENV ]]; then
|
||||
echo 1
|
||||
return
|
||||
fi
|
||||
port=`grep MTG_PORT $MTG_ENV|cut -d= -f2`
|
||||
if [[ -z "$port" ]]; then
|
||||
echo 2
|
||||
return
|
||||
fi
|
||||
res=`ss -ntlp| grep ${port} | grep docker`
|
||||
if [[ -z "$res" ]]; then
|
||||
echo 3
|
||||
else
|
||||
echo 4
|
||||
fi
|
||||
}
|
||||
|
||||
statusText() {
|
||||
res=`status`
|
||||
case $res in
|
||||
3)
|
||||
echo -e ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN}
|
||||
;;
|
||||
4)
|
||||
echo -e ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN}
|
||||
;;
|
||||
*)
|
||||
echo -e ${RED}未安装${PLAIN}
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
getData() {
|
||||
read -p " 请输入MTProto端口[100-65535的一个数字]:" PORT
|
||||
[[ -z "${PORT}" ]] && {
|
||||
echo -e " ${RED}请输入MTProto端口!${PLAIN}"
|
||||
exit 1
|
||||
}
|
||||
if [[ "${PORT:0:1}" = "0" ]]; then
|
||||
echo -e " ${RED}端口不能以0开头${PLAIN}"
|
||||
exit 1
|
||||
fi
|
||||
MTG_PORT=$PORT
|
||||
mkdir -p $MTG_CONFIG
|
||||
echo "MTG_IMAGENAME=$MTG_IMAGENAME" > "$MTG_ENV"
|
||||
echo "MTG_PORT=$MTG_PORT" >> "$MTG_ENV"
|
||||
echo "MTG_CONTAINER=$MTG_CONTAINER" >> "$MTG_ENV"
|
||||
}
|
||||
|
||||
installDocker() {
|
||||
if [[ "$DOCKER_CMD" != "" ]]; then
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
selinux
|
||||
return
|
||||
fi
|
||||
|
||||
#$CMD_REMOVE docker docker-engine docker.io containerd runc
|
||||
$PMT clean all
|
||||
$CMD_INSTALL wget curl
|
||||
if [[ $PMT = "apt" ]]; then
|
||||
apt clean all
|
||||
apt-get -y install \
|
||||
apt-transport-https \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg-agent \
|
||||
software-properties-common
|
||||
curl -fsSL https://download.docker.com/linux/$OS/gpg | apt-key add -
|
||||
add-apt-repository \
|
||||
"deb [arch=amd64] https://download.docker.com/linux/$OS \
|
||||
$(lsb_release -cs) \
|
||||
stable"
|
||||
apt update
|
||||
else
|
||||
wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo
|
||||
yum clean all
|
||||
fi
|
||||
$CMD_INSTALL docker-ce docker-ce-cli containerd.io
|
||||
|
||||
DOCKER_CMD="$(command -v docker)"
|
||||
if [[ "$DOCKER_CMD" = "" ]]; then
|
||||
echo -e " ${RED}$OSNAME docker安装失败,请到https://tizi.blog反馈${PLAIN}"
|
||||
exit 1
|
||||
fi
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
|
||||
selinux
|
||||
}
|
||||
|
||||
pullImage() {
|
||||
if [[ "$DOCKER_CMD" = "" ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -a
|
||||
source "$MTG_ENV"
|
||||
set +a
|
||||
|
||||
$DOCKER_CMD pull "$MTG_IMAGENAME" > /dev/null
|
||||
}
|
||||
|
||||
selinux() {
|
||||
if [[ -s /etc/selinux/config ]] && grep 'SELINUX=enforcing' /etc/selinux/config; then
|
||||
sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config
|
||||
setenforce 0
|
||||
fi
|
||||
}
|
||||
|
||||
firewall() {
|
||||
port=$1
|
||||
systemctl status firewalld > /dev/null 2>&1
|
||||
if [[ $? -eq 0 ]];then
|
||||
firewall-cmd --permanent --add-port=$port/tcp
|
||||
firewall-cmd --reload
|
||||
else
|
||||
nl=`iptables -nL | nl | grep FORWARD | awk '{print $1}'`
|
||||
if [ "$nl" != "3" ]; then
|
||||
iptables -I INPUT -p tcp --dport=$port -j ACCEPT
|
||||
else
|
||||
res=`ufw status | grep -i inactive`
|
||||
if [ "$res" = "" ]; then
|
||||
ufw allow $port/tcp
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
start() {
|
||||
res=`status`
|
||||
if [[ $res -lt 3 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
set -a
|
||||
source "$MTG_ENV"
|
||||
set +a
|
||||
|
||||
if [[ ! -f "$MTG_SECRET" ]]; then
|
||||
$DOCKER_CMD run \
|
||||
--rm \
|
||||
"$MTG_IMAGENAME" \
|
||||
generate-secret tls -c "$(openssl rand -hex 16).com" \
|
||||
> "$MTG_SECRET"
|
||||
fi
|
||||
|
||||
$DOCKER_CMD ps --filter "Name=$MTG_CONTAINER" -aq | xargs -r $DOCKER_CMD rm -fv > /dev/null
|
||||
$DOCKER_CMD run \
|
||||
-d \
|
||||
--restart=unless-stopped \
|
||||
--name "$MTG_CONTAINER" \
|
||||
--ulimit nofile=51200:51200 \
|
||||
-p "$MTG_PORT:3128" \
|
||||
"$MTG_IMAGENAME" run "$(cat "$MTG_SECRET")" > /dev/null
|
||||
|
||||
sleep 3
|
||||
res=`ss -ntlp| grep ${MTG_PORT} | grep docker`
|
||||
if [[ "$res" = "" ]]; then
|
||||
docker logs $MTG_CONTAINER | tail
|
||||
echo -e " ${RED}$OSNAME 启动docker镜像失败,请到 https://tizi.blog 反馈${PLAIN}"
|
||||
exit 1
|
||||
else
|
||||
colorEcho $BLUE " MTProto启动成功!"
|
||||
fi
|
||||
}
|
||||
|
||||
stop() {
|
||||
res=`status`
|
||||
if [[ $res -lt 3 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
set -a
|
||||
source "$MTG_ENV"
|
||||
set +a
|
||||
|
||||
$DOCKER_CMD stop $MTG_CONTAINER >> /dev/null
|
||||
colorEcho $BLUE " MTProto停止成功!"
|
||||
}
|
||||
|
||||
showInfo() {
|
||||
res=`status`
|
||||
if [[ $res -lt 3 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
SECRET=$(cat "$MTG_SECRET")
|
||||
set -a
|
||||
source "$MTG_ENV"
|
||||
set +a
|
||||
|
||||
echo
|
||||
echo -e " ${RED}MTProto代理信息:${PLAIN}"
|
||||
echo
|
||||
echo -n -e " ${BLUE}当前状态:${PLAIN}"
|
||||
statusText
|
||||
echo -e " ${BLUE}IP:${PLAIN}${RED}$IP${PLAIN}"
|
||||
echo -e " ${BLUE}端口:${PLAIN}${RED}$MTG_PORT${PLAIN}"
|
||||
echo -e " ${BLUE}密钥:${PLAIN}${RED}$SECRET${PLAIN}"
|
||||
echo ""
|
||||
echo -e " 如需获取tg://proxy形式的链接,请打开telegrame关注${GREEN}@MTProxybot${PLAIN}生成"
|
||||
echo ""
|
||||
}
|
||||
|
||||
install() {
|
||||
getData
|
||||
installDocker
|
||||
pullImage
|
||||
start
|
||||
firewall $MTG_PORT
|
||||
showInfo
|
||||
}
|
||||
|
||||
update() {
|
||||
res=`status`
|
||||
if [[ $res -lt 2 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
pullImage
|
||||
stop
|
||||
start
|
||||
showInfo
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
echo ""
|
||||
read -p " 确定卸载MTProto?[y/n]:" answer
|
||||
if [[ "$answer" = "y" ]] || [[ "$answer" = "Y" ]]; then
|
||||
stop
|
||||
rm -rf $MTG_CONFIG
|
||||
docker system prune -af
|
||||
systemctl stop docker
|
||||
systemctl disable docker
|
||||
$CMD_REMOVE docker-ce docker-ce-cli containerd.io
|
||||
colorEcho $GREEN " 卸载成功"
|
||||
fi
|
||||
}
|
||||
|
||||
restart() {
|
||||
res=`status`
|
||||
if [[ $res -lt 3 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
reconfig()
|
||||
{
|
||||
res=`status`
|
||||
if [[ $res -lt 2 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
getData
|
||||
stop
|
||||
start
|
||||
firewall $MTG_PORT
|
||||
showInfo
|
||||
}
|
||||
|
||||
showLog() {
|
||||
res=`status`
|
||||
if [[ $res -lt 3 ]]; then
|
||||
echo -e " ${RED}MTProto未安装,请先安装!${PLAIN}"
|
||||
return
|
||||
fi
|
||||
|
||||
set -a
|
||||
source "$MTG_ENV"
|
||||
set +a
|
||||
|
||||
$DOCKER_CMD logs $MTG_CONTAINER | tail
|
||||
}
|
||||
|
||||
menu() {
|
||||
clear
|
||||
echo "#############################################################"
|
||||
echo -e "# ${RED}MTProto一键安装脚本${PLAIN} #"
|
||||
echo "#############################################################"
|
||||
echo ""
|
||||
|
||||
echo -e " ${GREEN}1.${PLAIN} 安装MTProto代理"
|
||||
echo -e " ${GREEN}2.${PLAIN} 更新MTProto代理"
|
||||
echo -e " ${GREEN}3.${PLAIN} 卸载MTProto代理"
|
||||
echo " -------------"
|
||||
echo -e " ${GREEN}4.${PLAIN} 启动MTProto代理"
|
||||
echo -e " ${GREEN}5.${PLAIN} 重启MTProto代理"
|
||||
echo -e " ${GREEN}6.${PLAIN} 停止MTProto代理"
|
||||
echo " -------------"
|
||||
echo -e " ${GREEN}7.${PLAIN} 查看MTProto信息"
|
||||
echo -e " ${GREEN}8.${PLAIN} 修改MTProto配置"
|
||||
echo -e " ${GREEN}9.${PLAIN} 查看MTProto日志"
|
||||
echo " -------------"
|
||||
echo -e " ${GREEN}0.${PLAIN} 退出"
|
||||
echo
|
||||
echo -n " 当前状态:"
|
||||
statusText
|
||||
echo
|
||||
|
||||
read -p " 请选择操作[0-9]:" answer
|
||||
case $answer in
|
||||
0)
|
||||
exit 0
|
||||
;;
|
||||
1)
|
||||
install
|
||||
;;
|
||||
2)
|
||||
update
|
||||
;;
|
||||
3)
|
||||
uninstall
|
||||
;;
|
||||
4)
|
||||
start
|
||||
;;
|
||||
5)
|
||||
restart
|
||||
;;
|
||||
6)
|
||||
stop
|
||||
;;
|
||||
7)
|
||||
showInfo
|
||||
;;
|
||||
8)
|
||||
reconfig
|
||||
;;
|
||||
9)
|
||||
showLog
|
||||
;;
|
||||
*)
|
||||
echo -e " ${RED}请选择正确的操作!${PLAIN}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
checkSystem
|
||||
|
||||
menu
|
||||
+4981
File diff suppressed because one or more lines are too long
+1867
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user