上传文件至 /

This commit is contained in:
asdf88 2024-09-29 23:33:25 +00:00
parent 0f48db90a4
commit 3af20678ba
2 changed files with 1762 additions and 0 deletions

1045
sa.sh Normal file
View File

@ -0,0 +1,1045 @@
#!/bin/bash
# singbox一键安装脚本
# Author: Slotheve<https://slotheve.com>
# 修复原脚本错误添加290291处脚本修改298处/usr/local/bin为/usr/local/bin/sing-box
cp /root/sa.sh /bin/sa && chmod +x /bin/sa
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
BLUE="\033[36m"
PLAIN='\033[0m'
CONFIG_FILE="/usr/local/etc/sing-box/config.json"
OS=`hostnamectl | grep -i system | cut -d: -f2`
stls_conf="/etc/systemd/system/shadowtls.service"
STLS="false"
IP=`curl -sL -4 ip.sb`
VMESS="false"
VLESS="false"
TROJAN="false"
SS="false"
SOCKS="false"
ciphers=(
aes-256-gcm
2022-blake3-aes-256-gcm
chacha20-ietf-poly1305
2022-blake3-chacha20-poly1305
none
)
domains=(
gateway.icloud.com
cn.bing.com
mp.weixin.qq.com
自定义
)
checkSystem() {
result=$(id | awk '{print $1}')
if [[ $result != "uid=0(root)" ]]; then
result=$(id | awk '{print $1}')
if [[ $result != "用户id=0(root)" ]]; then
colorEcho $RED " 请以root身份执行该脚本"
exit 1
fi
fi
res=`which yum 2>/dev/null`
if [[ "$?" != "0" ]]; then
res=`which apt 2>/dev/null`
if [[ "$?" != "0" ]]; then
colorEcho $RED " 不受支持的Linux系统"
exit 1
fi
PMT="apt"
CMD_INSTALL="apt install -y "
CMD_REMOVE="apt remove -y "
CMD_UPGRADE="apt update; apt upgrade -y; apt autoremove -y"
else
PMT="yum"
CMD_INSTALL="yum install -y "
CMD_REMOVE="yum remove -y "
CMD_UPGRADE="yum update -y"
fi
res=`which systemctl 2>/dev/null`
if [[ "$?" != "0" ]]; then
colorEcho $RED " 系统版本过低,请升级到最新版本"
exit 1
fi
}
colorEcho() {
echo -e "${1}${@:2}${PLAIN}"
}
config() {
local conf=`grep wsSettings $CONFIG_FILE`
if [[ -z "$conf" ]]; then
echo no
return
fi
echo yes
}
status() {
if [[ ! -f /usr/local/bin/sing-box ]]; then
echo 0
return
fi
if [[ ! -f $CONFIG_FILE ]]; then
echo 1
return
fi
port=`grep port $CONFIG_FILE| head -n 1| cut -d: -f2| tr -d \",' '`
res=`ss -nutlp| grep ${port} | grep -i sing-box`
if [[ -z "$res" ]]; then
echo 2
return
fi
if [[ `config` != "yes" ]]; then
echo 3
fi
}
Check_singbox() {
ress=`status`
if [[ "${ress}" = "0" || "${ress}" = "1" ]]; then
colorEcho $RED "未安装Singbox, 请先安装Singbox"
exit 1
fi
}
statusText() {
res=`status`
case $res in
2)
echo -e ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN}
;;
3)
echo -e ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN}
;;
*)
echo -e ${RED}未安装${PLAIN}
;;
esac
}
normalizeVersion() {
if [ -n "$1" ]; then
case "$1" in
v*)
echo "$1"
;;
http*)
echo "v1.2.5"
;;
*)
echo "v$1"
;;
esac
else
echo ""
fi
}
# 1: new Xray. 0: no. 1: yes. 2: not installed. 3: check failed.
getVersion() {
VER=v`/usr/local/bin/sing-box version|head -n1 | awk '{print $3}'`
RETVAL=$?
CUR_VER=v1.9.4
TAG_URL="https://ghproxy.lvedong.eu.org/https://api.github.com/repos/SagerNet/sing-box/releases/latest"
NEW_VER_V=v1.9.4
NEW_VER=1.9.4
if [[ $? -ne 0 ]] || [[ $NEW_VER_V == "" ]]; then
colorEcho $RED " 检查Sing-Box版本信息失败请检查网络"
return 3
elif [[ $RETVAL -ne 0 ]];then
return 2
elif [[ $NEW_VER_V != $CUR_VER ]];then
return 1
fi
return 0
}
selectciphers() {
for ((i=1;i<=${#ciphers[@]};i++ )); do
hint="${ciphers[$i-1]}"
echo -e "${green}${i}${plain}) ${hint}"
done
read -p " 你选择什么加密方式(默认: ${ciphers[0]}):" pick
[ -z "$pick" ] && pick=1
expr ${pick} + 1 &>/dev/null
if [ $? -ne 0 ]; then
echo -e "[${red}Error${plain}] Please enter a number"
continue
fi
if [[ "$pick" -lt 1 || "$pick" -gt ${#ciphers[@]} ]]; then
echo -e "${BLUE}[${PLAIN}${RED}Error${PLAIN}${BLUE}]${PLAIN} ${BLUE}请正确选择${PLAIN}"
exit 0
fi
METHOD=${ciphers[$pick-1]}
colorEcho $BLUE " 加密:${ciphers[$pick-1]}"
}
getData() {
read -p " 请输入SingBox监听端口[100-65535的一个数字]" PORT
[[ -z "${PORT}" ]] && PORT=`shuf -i200-65000 -n1`
if [[ "${PORT:0:1}" = "0" ]]; then
colorEcho ${RED} " 端口不能以0开头"
exit 1
fi
colorEcho ${BLUE} " SingBox端口$PORT"
if [[ "$TROJAN" = "true" ]]; then
echo ""
read -p " 请设置trojan密码不输则随机生成:" PASSWORD
[[ -z "$PASSWORD" ]] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1`
colorEcho $BLUE " 密码:$PASSWORD"
echo ""
read -p " 请设置trojan域名不输则随机生成:" DOMAIN
[[ -z "$DOMAIN" ]] && DOMAIN=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1`.xyz
colorEcho $BLUE " 域名:$DOMAIN"
echo ""
read -p " 请设置域名证书(不输默认生成):" KEY
[[ -z "$KEY" ]] && mkdir -pv /usr/local/etc/sing-box && openssl genrsa \
-out /usr/local/etc/sing-box/sing-box.key 2048 && chmod \
+x /usr/local/etc/sing-box/sing-box.key && KEY="/usr/local/etc/sing-box/sing-box.key"
colorEcho $BLUE " 密钥路径:$KEY"
echo ""
read -p " 请设置域名证书(不输默认生成):" CERT
[[ -z "$CERT" ]] && openssl req -new -x509 -days 3650 -key /usr/local/etc/sing-box/sing-box.key \
-out /usr/local/etc/sing-box/sing-box.crt -subj "/C=US/ST=LA/L=LAX/O=Xray/OU=Trojan/CN=&DOMAIN" \
&& chmod +x /usr/local/etc/sing-box/sing-box.crt && CERT="/usr/local/etc/sing-box/sing-box.crt"
colorEcho $BLUE " 证书路径:$CERT"
elif [[ "$SS" = "true" ]]; then
selectciphers
if [[ "$METHOD" = "2022-blake3-aes-256-gcm" || "$METHOD" = "2022-blake3-chacha20-poly1305" ]]; then
echo ""
read -p " 请设置ss2022密钥不会设置请默认生成:" PASSWORD
[[ -z "$PASSWORD" ]] && PASSWORD=`openssl rand -base64 32`
colorEcho $BLUE " 密码:$PASSWORD"
else
echo ""
read -p " 请设置ss密码不输则随机生成:" PASSWORD
[[ -z "$PASSWORD" ]] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1`
colorEcho $BLUE " 密码:$PASSWORD"
fi
elif [[ "$VLESS" = "true" ]]; then
echo ""
read -p " 请设置vless的UUID不输则随机生成:" UUID
[[ -z "$UUID" ]] && UUID="$(cat '/proc/sys/kernel/random/uuid')"
colorEcho $BLUE " UUID$UUID"
elif [[ "$SOCKS" = "true" ]]; then
echo ""
read -p " 请设置socks的用户名不输则随机生成:" USER
[[ -z "$USER" ]] && USER=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 6 | head -n 1`
colorEcho $BLUE " 用户名:$USER"
echo ""
read -p " 请设置socks的密码不输则随机生成:" PASSWORD
[[ -z "$PASSWORD" ]] && PASSWORD=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1`
colorEcho $BLUE " 密码:$PASSWORD"
elif [[ "$VMESS" = "true" ]]; then
echo ""
read -p " 请设置vmess的UUID不输则随机生成:" UUID
[[ -z "$UUID" ]] && UUID="$(cat '/proc/sys/kernel/random/uuid')"
colorEcho $BLUE " UUID$UUID"
fi
}
setSelinux() {
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
}
archAffix() {
case "$(uname -m)" in
x86_64|amd64)
ARCH="amd64"
CPU="x86_64"
;;
armv8|aarch64)
ARCH="arm64"
CPU="aarch64"
;;
*)
colorEcho $RED " 不支持的CPU架构"
exit 1
;;
esac
return 0
}
installSingBox() {
archAffix
rm -rf /tmp/sing-box
mkdir -p /tmp/sing-box
DOWNLOAD_LINK="https://codeberg.org/asdf88/s-box/raw/branch/main/core/sing-box-${NEW_VER}-linux-${ARCH}.tar.gz"
colorEcho $BLUE " 下载SingBox: ${DOWNLOAD_LINK}"
wget -O /tmp/sing-box/sing-box.tar.gz ${DOWNLOAD_LINK}
if [ $? != 0 ];then
colorEcho $RED " 下载SingBox文件失败请检查服务器网络设置"
exit 1
fi
systemctl stop sing-box
rm -rf /usr/local/bin
mkdir -p /usr/local/bin
mkdir -p /usr/local/etc/sing-box /usr/local/share/sing-box && \
tar -xvf /tmp/sing-box/sing-box.tar.gz -C /tmp/sing-box
cp /tmp/sing-box/sing-box-${NEW_VER}-linux-${ARCH}/sing-box /usr/local/bin/sing-box
chmod +x /usr/local/bin/sing-box || {
colorEcho $RED " SingBox安装失败"
exit 1
}
cat >/etc/systemd/system/sing-box.service<<-EOF
[Unit]
Description=sing-box Service
Documentation=https://sing-box.sagernet.org/
After=network.target nss-lookup.target
Wants=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/sing-box run -c ${CONFIG_FILE}
Restart=on-failure
RestartSec=30s
RestartPreventExitStatus=23
LimitNPROC=10000
LimitNOFILE=1000000
[Install]
WantedBy=multi-user.target
EOF
chmod 644 ${CONFIG_FILE}
systemctl daemon-reload
systemctl enable sing-box.service
}
Download_stls() {
rm -rf /usr/local/etc/sing-box/shadowtls
archAffix
TAG_URL="https://ghproxy.lvedong.eu.org/https://api.github.com/repos/ihciah/shadow-tls/releases/latest"
DOWN_VER=`curl -s "${TAG_URL}" --connect-timeout 10| grep -Eo '\"tag_name\"(.*?)\",' | cut -d\" -f4`
DOWNLOAD_LINK="https://ghproxy.lvedong.eu.org/https://github.com/ihciah/shadow-tls/releases/download/${DOWN_VER}/shadow-tls-${CPU}-unknown-linux-musl"
colorEcho $YELLOW "下载ShadowTLS: ${DOWNLOAD_LINK}"
curl -L -H "Cache-Control: no-cache" -o /usr/local/etc/sing-box/shadowtls ${DOWNLOAD_LINK}
chmod +x /usr/local/etc/sing-box/shadowtls
}
Generate_stls() {
Set_sport
Set_domain
Set_pass
}
Deploy_stls() {
cd /etc/systemd/system
cat > shadowtls.service<<-EOF
[Unit]
Description=Shadow-TLS Server Service
Documentation=man:sstls-server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/etc/sing-box/shadowtls --fastopen --v3 server --listen 0.0.0.0:$SPORT --server 127.0.0.1:$PORT --tls $DOMAIN --password $PASS
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=shadow-tls
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable shadowtls
systemctl restart shadowtls
colorEcho $BLUE "ShadowTLS安装完成"
}
Set_sport() {
read -p $'请输入协议端口 [1-65535]:' PORT
echo $((${PORT}+0)) &>/dev/null
if [[ $? -eq 0 ]]; then
if [[ ${PORT} -ge 1 ]] && [[ ${PORT} -le 65535 ]]; then
colorEcho $BLUE "协议端口: ${PORT}"
echo ""
else
colorEcho $RED "输入错误, 请输入正确的端口。"
echo ""
exit 1
fi
else
colorEcho $RED "输入错误, 请输入数字。"
echo ""
exit 1
fi
read -p $'请输入 ShadowTLS 端口 [1-65535]\n(默认: 9999回车):' SPORT
[[ -z "${SPORT}" ]] && SPORT="9999"
echo $((${SPORT}+0)) &>/dev/null
if [[ $? -eq 0 ]]; then
if [[ ${SPORT} -ge 1 ]] && [[ ${SPORT} -le 65535 ]]; then
colorEcho $BLUE "端口: ${SPORT}"
echo ""
else
colorEcho $RED "输入错误, 请输入正确的端口。"
echo ""
exit 1
fi
else
colorEcho $RED "输入错误, 请输入数字。"
echo ""
exit 1
fi
}
Set_domain() {
for ((i=1;i<=${#domains[@]};i++ )); do
hint="${domains[$i-1]}"
echo -e "${GREEN}${i}${PLAIN}) ${hint}"
done
read -p "请选择域名[1-4] (默认: ${domains[0]}):" pick
[ -z "$pick" ] && pick=1
expr ${pick} + 1 &>/dev/null
if [ $? -ne 0 ]; then
colorEcho $RED "错误, 请输入正确选项"
continue
fi
if [[ "$pick" -lt 1 || "$pick" -gt ${#domains[@]} ]]; then
echo -e "${red}错误, 请输入正确选项${plain}"
exit 0
fi
DOMAIN=${domains[$pick-1]}
if [[ "$pick" = "4" ]]; then
colorEcho $BLUE "已选择: ${domains[$pick-1]}"
echo ""
read -p $'请输入自定义域名: ' DOMAIN
if [[ -z "${DOMAIN}" ]]; then
colorEcho $RED "错误, 请输入正确的域名"
echo ""
exit 1
else
colorEcho $BLUE "域名:$DOMAIN"
echo ""
fi
else
colorEcho $BLUE "域名:${domains[$pick-1]}"
echo ""
fi
}
Set_pass() {
read -p $'请设置ShadowTLS的密码\n(默认随机生成, 回车):' PASS
[[ -z "$PASS" ]] && PASS=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1`
colorEcho $BLUE " 密码:$PASS"
echo ""
}
vmessConfig() {
cat > $CONFIG_FILE<<-EOF
{
"inbounds":[
{
"type": "vmess",
"listen":"0.0.0.0",
"listen_port":$PORT,
"tag":"VMessWS",
"users": [{
"uuid":"$UUID",
"alterId": 0
}],
"transport": {
"headers": {
"Host": [
"hnqywd.ha.189.cn"
]
},
"type": "ws",
"path": "/",
"max_early_data": 2048,
"early_data_header_name": "Sec-WebSocket-Protocol"
}
}
],
"outbounds": [{
"type": "direct"
}]
}
EOF
}
vlessConfig() {
cat > $CONFIG_FILE<<-EOF
{
"inbounds": [
{
"type": "vless",
"listen": "0.0.0.0",
"listen_port": $PORT,
"users": [{
"uuid": "$UUID",
"flow": ""
}],
"transport": {
"headers": {
"Host": [
"hnqywd.ha.189.cn"
]
},
"type": "ws",
"path": "",
"max_early_data": 2048,
"early_data_header_name": "Sec-WebSocket-Protocol"
}
}
],
"outbounds": [{
"type": "direct"
}
]
}
EOF
}
trojanConfig() {
cat > $CONFIG_FILE<<-EOF
{
"inbounds": [
{
"type": "trojan",
"listen": "0.0.0.0",
"listen_port": $PORT,
"domain_strategy": "prefer_ipv4",
"users": [{
"password": "$PASSWORD"
}],
"tcp_fast_open": true,
"udp_fragment": true,
"sniff": true,
"proxy_protocol": false,
"tls": {
"enabled": true,
"server_name": "$DOMAIN",
"certificate_path": "$CERT",
"key_path": "$KEY"
}
}
],
"outbounds": [{
"type": "direct"
}
]
}
EOF
}
ssConfig() {
cat > $CONFIG_FILE<<-EOF
{
"inbounds": [
{
"type": "shadowsocks",
"listen": "0.0.0.0",
"listen_port": $PORT,
"method": "$METHOD",
"password": "$PASSWORD",
"tcp_fast_open": true,
"udp_fragment": true,
"sniff": true,
"proxy_protocol": false
}
],
"outbounds": [{
"type": "direct"
}
]
}
EOF
}
socksConfig() {
cat > $CONFIG_FILE<<-EOF
{
"inbounds": [
{
"type": "socks",
"listen": "0.0.0.0",
"listen_port": $PORT,
"users": [{
"username": "$USER",
"password": "$PASSWORD"
}],
"tcp_fast_open": true,
"udp_fragment": true,
"sniff": true,
"proxy_protocol": false
}
],
"outbounds": [{
"type": "direct"
}
]
}
EOF
}
configSingBox() {
mkdir -p /usr/local/sing-box
if [[ "$VMESS" = "true" ]]; then
vmessConfig
elif [[ "$VLESS" = "true" ]]; then
vlessConfig
elif [[ "$TROJAN" = "true" ]]; then
trojanConfig
elif [[ "$SS" = "true" ]]; then
ssConfig
elif [[ "$SOCKS" = "true" ]]; then
socksConfig
fi
}
install() {
getData
$PMT clean all
[[ "$PMT" = "apt" ]] && $PMT update
$CMD_INSTALL wget vim tar openssl
$CMD_INSTALL net-tools
if [[ "$PMT" = "apt" ]]; then
$CMD_INSTALL libssl-dev
fi
colorEcho $BLUE " 安装SingBox..."
getVersion
RETVAL="$?"
if [[ $RETVAL == 0 ]]; then
colorEcho $BLUE " SingBox最新版 ${CUR_VER} 已经安装"
elif [[ $RETVAL == 3 ]]; then
exit 1
else
colorEcho $BLUE " 安装SingBox ${NEW_VER_V} ,架构$(archAffix)"
installSingBox
fi
configSingBox
setSelinux
start
showInfo
}
Install_stls() {
Check_singbox
Generate_stls
Download_stls
Deploy_stls
ShowInfo_stls
echo ""
echo -e " ${YELLOW}请将${PLAIN}${RED} 端口 ${PLAIN}${YELLOW}替换为${PLAIN}${RED} ${sport} ${PLAIN}"
}
update() {
res=`status`
if [[ $res -lt 2 ]]; then
colorEcho $RED " SingBox未安装请先安装"
return
fi
getVersion
RETVAL="$?"
if [[ $RETVAL == 0 ]]; then
colorEcho $BLUE " SingBox最新版 ${CUR_VER} 已经安装"
elif [[ $RETVAL == 3 ]]; then
exit 1
else
colorEcho $BLUE " 安装SingBox ${NEW_VER} ,架构$(archAffix)"
installXray
stop
start
colorEcho $GREEN " 最新版SingBox安装成功"
fi
}
uninstall() {
res=`status`
if [[ $res -lt 2 ]]; then
colorEcho $RED " SingBox未安装请先安装"
return
fi
echo ""
read -p " 确定卸载SingBox[y/n]" answer
if [[ "${answer,,}" = "y" ]]; then
if [[ -f "$stls_conf" ]]; then
stop
systemctl disable sing-box
systemctl stop shadowtls
systemctl disable shadowtls
rm -rf /etc/systemd/system/sing-box.service
rm -rf /etc/systemd/system/shadowtls.service
systemctl daemon-reload
rm -rf /usr/local/bin/sing-box
rm -rf /bin/sa
rm -rf /usr/local/etc/sing-box
colorEcho $GREEN " SingBox卸载成功"
else
stop
systemctl disable sing-box
rm -rf /etc/systemd/system/sing-box.service
systemctl daemon-reload
rm -rf /usr/local/bin/sing-box
rm -rf /usr/local/etc/sing-box
rm -rf /bin/sa
colorEcho $GREEN " SingBox卸载成功"
fi
elif [[ "${answer}" = "n" || -z "${answer}" ]]; then
colorEcho $BLUE " 取消卸载"
else
colorEcho $RED " 输入错误, 请输入正确操作。"
exit 1
fi
}
Uninstall_stls() {
read -p $' 是否卸载ShadowTLS[y/n]\n (默认n, 回车)' answer
if [[ "${answer}" = "y" ]]; then
systemctl stop shadowtls
systemctl disable shadowtls
rm -rf /etc/systemd/system/shadowtls.service
systemctl daemon-reload
colorEcho $BLUE " ShadowTLS已经卸载完毕"
elif [[ "${answer}" = "n" || -z "${answer}" ]]; then
colorEcho $BLUE " 取消卸载"
else
colorEcho $RED " 输入错误, 请输入正确操作。"
exit 1
fi
}
start() {
res=`status`
if [[ $res -lt 2 ]]; then
colorEcho $RED " SingBox未安装请先安装"
return
fi
systemctl restart sing-box
sleep 2
port=`grep listen_port $CONFIG_FILE| head -n 1| cut -d: -f2| tr -d \",' '`
res=`ss -nutlp| grep ${port} | grep -i sing-box`
if [[ "$res" = "" ]]; then
colorEcho $RED " SingBox启动失败请检查日志或查看端口是否被占用"
else
colorEcho $BLUE " SingBox启动成功"
fi
}
stop() {
systemctl stop sing-box
colorEcho $BLUE " SingBox停止成功"
}
restart() {
res=`status`
if [[ $res -lt 2 ]]; then
colorEcho $RED " SingBox未安装请先安装"
return
fi
stop
start
}
getConfigFileInfo() {
protocol="vmess"
network="ws"
port=`grep listen_port $CONFIG_FILE | cut -d: -f2 | tr -d \",' '`
uuid=`grep id $CONFIG_FILE | head -n1| cut -d: -f2 | tr -d \",' '`
alterid=`grep alterId $CONFIG_FILE | cut -d: -f2 | tr -d \",' '`
method=`grep method $CONFIG_FILE | cut -d: -f2 | tr -d \",' '`
username=`grep username $CONFIG_FILE | cut -d: -f2 | tr -d \",' '`
cert=`grep certificate_path $CONFIG_FILE | tail -n1| cut -d: -f2 | tr -d \",' '`
key=`grep key_path $CONFIG_FILE | tail -n1 | cut -d: -f2 | tr -d \",' '`
domain=`grep server_name $CONFIG_FILE | cut -d: -f2 | tr -d \",' '`
singbox=`grep type $CONFIG_FILE | head -n1 | cut -d: -f2 | tr -d \",' '`
password=`grep password $CONFIG_FILE | cut -d: -f2 | tr -d \",' '`
if [[ "$singbox" = "$protocol" ]]; then
protocol="vmess"
elif [[ "$VLESS" != "$protocol" ]]; then
protocol="$singbox"
fi
}
outputVmess() {
raw="{
\"v\":\"2\",
\"ps\":\"\",
\"add\":\"$IP\",
\"port\":\"${port}\",
\"id\":\"${uuid}\",
\"aid\":\"$alterid\",
\"net\":\"ws\",
\"type\":\"none\",
\"host\":\"hnqywd.ha.189.cn\",
\"path\":\"\",
\"tls\":\"\"
}"
link=`echo -n ${raw} | base64 -w 0`
link="vmess://${link}"
echo -e " ${BLUE}协议: ${PLAIN} ${RED}${protocol}${PLAIN}"
echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}"
echo -e " ${BLUE}端口(port)${PLAIN} ${RED}${port}${PLAIN}"
echo -e " ${BLUE}id(uuid)${PLAIN} ${RED}${uuid}${PLAIN}"
echo -e " ${BLUE}额外id(alterid)${PLAIN} ${RED}${alterid}${PLAIN}"
echo -e " ${BLUE}传输协议(network)${PLAIN} ${RED}ws${PLAIN}"
echo ""
echo -e " ${BLUE}vmess链接:${PLAIN} $RED$link$PLAIN"
}
outputVless() {
raw="${uuid}@$IP:${port}?encryption=none&type=ws&host=hnqywd.ha.189.cn&path=/"
link="vless://${raw}"
echo -e " ${BLUE}协议: ${PLAIN} ${RED}${protocol}${PLAIN}"
echo -e " ${BLUE}IP(address): ${PLAIN} ${RED}${IP}${PLAIN}"
echo -e " ${BLUE}端口(port)${PLAIN} ${RED}${port}${PLAIN}"
echo -e " ${BLUE}id(uuid)${PLAIN} ${RED}${uuid}${PLAIN}"
echo -e " ${BLUE}传输协议(network)${PLAIN} ${RED}ws${PLAIN}"
echo ""
echo -e " ${BLUE}vless链接:${PLAIN} $RED$link$PLAIN"
}
outputTrojan() {
raw="${password}@$IP:${port}?type=tcp&security=tls&sni=$domain&headerType=none"
link="trojan://${raw}"
echo -e " ${BLUE}协议: ${PLAIN} ${RED}${protocol}${PLAIN}"
echo -e " ${BLUE}IP/域名(address): ${PLAIN} ${RED}${IP}${PLAIN}"
echo -e " ${BLUE}端口(port)${PLAIN} ${RED}${port}${PLAIN}"
echo -e " ${BLUE}密码(password)${PLAIN} ${RED}${password}${PLAIN}"
echo -e " ${BLUE}传输协议(network)${PLAIN} ${RED}tcp${PLAIN}"
echo -e " ${BLUE}加密协议(security)${PLAIN} ${RED}tls${PLAIN}"
echo -e " ${BLUE}域名(domain)${PLAIN} ${RED}${domain}${PLAIN}"
echo -e " ${BLUE}证书路径(cert)${PLAIN} ${RED}${cert}${PLAIN}"
echo -e " ${BLUE}密钥路径(key)${PLAIN} ${RED}${key}${PLAIN}"
echo ""
echo -e " ${BLUE}trojan链接:${PLAIN} $RED$link$PLAIN"
echo -e " ${BLUE}非自定义证书路径请务必开启:${PLAIN} ${YELLOW}skip-cert-verify:${PLAIN} ${RED}true${PLAIN} ${YELLOW}(允许不安全连接)${PLAIN}"
}
outputSS() {
raw="${method}:${password}@$IP:${port}"
link=`echo -n ${raw} | base64 -w 0`
link="ss://${link}"
echo -e " ${BLUE}协议: ${PLAIN} ${RED}${protocol}${PLAIN}"
echo -e " ${BLUE}IP/域名(address): ${PLAIN} ${RED}${IP}${PLAIN}"
echo -e " ${BLUE}端口(port)${PLAIN} ${RED}${port}${PLAIN}"
echo -e " ${BLUE}密码(password)${PLAIN} ${RED}${password}${PLAIN}"
echo -e " ${BLUE}加密协议(method)${PLAIN} ${RED}${method}${PLAIN}"
echo -e " ${BLUE}传输协议(network)${PLAIN} ${RED}tcp${PLAIN}"
echo ""
echo -e " ${BLUE}ss链接:${PLAIN} $RED$link$PLAIN"
}
outputSocks() {
echo -e " ${BLUE}协议: ${PLAIN} ${RED}${protocol}${PLAIN}"
echo -e " ${BLUE}IP/域名(address): ${PLAIN} ${RED}${IP}${PLAIN}"
echo -e " ${BLUE}端口(port)${PLAIN} ${RED}${port}${PLAIN}"
echo -e " ${BLUE}用户名(username)${PLAIN} ${RED}${username}${PLAIN}"
echo -e " ${BLUE}密码(password)${PLAIN} ${RED}${password}${PLAIN}"
}
showInfo() {
res=`status`
if [[ $res -lt 2 ]]; then
colorEcho $RED " SingBox未安装请先安装"
return
fi
echo ""
echo -n -e " ${BLUE}SingBox运行状态${PLAIN}"
statusText
echo -e " ${BLUE}SingBox配置文件: ${PLAIN} ${RED}${CONFIG_FILE}${PLAIN}"
colorEcho $BLUE " SingBox配置信息"
getConfigFileInfo
if [[ "$protocol" = vmess ]]; then
outputVmess
elif [[ "$protocol" = vless ]]; then
outputVless
elif [[ "$protocol" = trojan ]]; then
outputTrojan
elif [[ "$protocol" = shadowsocks ]]; then
outputSS
elif [[ "$protocol" = socks ]]; then
outputSocks
fi
}
ShowInfo_stls() {
echo ""
colorEcho $BLUE " ShadowTLS配置信息"
GetConfig_stls
outputSTLS
}
GetConfig_stls() {
sport=`grep listen ${stls_conf} | cut -d- -f8 | cut -d: -f2`
pass=`grep password ${stls_conf} | cut -d " " -f12`
domain=`grep password ${stls_conf} | cut -d- -f12 | cut -d " " -f 2`
}
outputSTLS() {
echo -e " ${BLUE}端口(PORT)${PLAIN} ${RED}${sport}${PLAIN}"
echo -e " ${BLUE}密码(PASS)${PLAIN} ${RED}${pass}${PLAIN}"
echo -e " ${BLUE}域名(DOMAIN)${PLAIN} ${RED}${domain}${PLAIN}"
echo -e " ${BLUE}版本(VER)${PLAIN} ${RED}v3${PLAIN}"
}
showLog() {
res=`status`
if [[ $res -lt 2 ]]; then
colorEcho $RED " SingBox未安装请先安装"
return
fi
journalctl -xen -u sing-box --no-pager
}
menu() {
clear
echo "####################################################"
echo -e "# ${RED}SingBox一键安装脚本${PLAIN} #"
echo -e "# ${GREEN}作者${PLAIN}: 怠惰(Slotheve) #"
echo -e "# ${GREEN}网址${PLAIN}: https://slotheve.com #"
echo -e "# ${GREEN}频道${PLAIN}: https://t.me/SlothNews #"
echo "####################################################"
echo " -----------------------------------------------"
colorEcho $GREEN " 全协议支持UDP over TCP , 且ss/socks支持原生UDP"
echo " -----------------------------------------------"
echo -e " ${GREEN}1.${PLAIN} 安装vmess-ws"
echo -e " ${GREEN}2.${PLAIN} 安装vless-ws"
echo -e " ${GREEN}3.${PLAIN} 安装Trojan"
echo -e " ${GREEN}4.${PLAIN} 安装Shadowsocks"
echo -e " ${GREEN}5.${PLAIN} 安装Socks ${RED}不推荐${PLAIN}"
echo -e " ${GREEN}6.${PLAIN} ${YELLOW}切换Snell脚本${PLAIN}"
echo " --------------------"
echo -e " ${GREEN}7.${PLAIN} 安装ShadowTls"
echo -e " ${GREEN}8.${PLAIN} ${RED}卸载ShadowTls${PLAIN}"
echo " --------------------"
echo -e " ${GREEN}9.${PLAIN} 更新SingBox"
echo -e " ${GREEN}10.${PLAIN} ${RED}卸载SingBox${PLAIN}"
echo " --------------------"
echo -e " ${GREEN}11.${PLAIN} 启动SingBox"
echo -e " ${GREEN}12.${PLAIN} 重启SingBox"
echo -e " ${GREEN}13.${PLAIN} 停止SingBox"
echo " --------------------"
echo -e " ${GREEN}14.${PLAIN} 查看SingBox配置"
echo -e " ${GREEN}15.${PLAIN} 查看ShadowTls配置"
echo -e " ${GREEN}16.${PLAIN} 查看SingBox日志"
echo " --------------------"
echo -e " ${GREEN}0.${PLAIN} 退出"
echo ""
echo -n " 当前状态:"
statusText
echo
read -p " 请选择操作[0-16]" answer
case $answer in
0)
exit 0
;;
1)
VMESS="true"
install
;;
2)
VLESS="true"
install
;;
3)
TROJAN="true"
install
;;
4)
SS="true"
install
;;
5)
SOCKS="true"
install
;;
6)
bash <(curl -fsSL https://codeberg.org/asdf88/s-box/raw/branch/main/snell.sh)
;;
7)
Install_stls
;;
8)
Uninstall_stls
;;
9)
update
;;
10)
uninstall
;;
11)
start
;;
12)
restart
;;
13)
stop
;;
14)
showInfo
;;
15)
ShowInfo_stls
;;
16)
showLog
;;
*)
colorEcho $RED " 请选择正确的操作!"
exit 1
;;
esac
}
checkSystem
action=$1
[[ -z $1 ]] && action=menu
case "$action" in
menu|update|uninstall|start|restart|stop|showInfo|showLog)
${action}
;;
*)
echo " 参数错误"
echo " 用法: `basename $0` [menu|update|uninstall|start|restart|stop|showInfo|showLog]"
;;
esac

717
snell.sh Normal file
View File

@ -0,0 +1,717 @@
#!/bin/bash
# Author: Slotheve<https://slotheve.com>
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
BLUE="\033[36m"
PLAIN='\033[0m'
IP4=`curl -sL -4 ip.sb`
IP6=`curl -sL -6 ip.sb`
CPU=`uname -m`
snell_conf="/etc/snell/snell-server.conf"
stls_conf="/etc/systemd/system/shadowtls.service"
colorEcho() {
echo -e "${1}${@:2}${PLAIN}"
}
versions=(
v1
v2
v3
v4
)
domains=(
gateway.icloud.com
cn.bing.com
mp.weixin.qq.com
自定义
)
archAffix(){
if [[ "$CPU" = "x86_64" ]] || [[ "$CPU" = "amd64" ]]; then
CPU="amd64"
ARCH="x86_64"
elif [[ "$CPU" = "armv8" ]] || [[ "$CPU" = "aarch64" ]]; then
CPU="arm64"
ARCH="aarch64"
else
colorEcho $RED " 不支持的CPU架构"
fi
}
checkSystem() {
result=$(id | awk '{print $1}')
if [[ $result != "uid=0(root)" ]]; then
result=$(id | awk '{print $1}')
if [[ $result != "用户id=0(root)" ]]; then
colorEcho $RED " 请以root身份执行该脚本"
exit 1
fi
fi
res=`which yum 2>/dev/null`
if [[ "$?" != "0" ]]; then
res=`which apt 2>/dev/null`
if [[ "$?" != "0" ]]; then
colorEcho $RED " 不受支持的Linux系统"
exit 1
fi
OS="apt"
else
OS="yum"
fi
res=`which systemctl 2>/dev/null`
if [[ "$?" != "0" ]]; then
colorEcho $RED " 系统版本过低,请升级到最新版本"
exit 1
fi
}
status() {
if [[ ! -f /etc/snell/snell ]]; then
echo 0
return
fi
if [[ ! -f $snell_conf ]]; then
echo 1
return
fi
tmp=`grep listen ${snell_conf} | awk -F '=' '{print $2}' | cut -d: -f2`
if [[ -z ${tmp} ]]; then
tmp=`grep listen ${snell_conf} | awk -F '=' '{print $2}' | cut -d: -f4`
fi
res=`ss -nutlp| grep ${tmp} | grep -i snell`
if [[ -z $res ]]; then
echo 2
else
echo 3
return
fi
}
status_stls() {
if [[ ! -f /etc/snell/shadowtls ]]; then
echo 0
return
fi
if [[ ! -f $stls_conf ]]; then
echo 1
return
fi
V6=`grep ipv6 ${snell_conf} | awk -F '= ' '{print $2}'`
if [[ $V6 = "true" ]]; then
tmp2=`grep listen ${stls_conf} | cut -d- -f7 | cut -d: -f4`
else
tmp2=`grep listen ${stls_conf} | cut -d- -f7 | cut -d: -f2`
fi
res2=`ss -nutlp| grep ${tmp2} | grep -i shadowtls`
if [[ -z $res2 ]]; then
echo 2
else
echo 3
return
fi
}
statusText() {
res=`status`
res2=`status_stls`
case ${res}${res2} in
22)
echo -e ${BLUE}Snell:${PLAIN} ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN}
echo -e " ${BLUE}ShadowTls:${PLAIN} ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN}"
;;
23)
echo -e ${BLUE}Snell:${PLAIN} ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN}
echo -e " ${BLUE}ShadowTls:${PLAIN} ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN}"
;;
32)
echo -e ${BLUE}Snell:${PLAIN} ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN}
echo -e " ${BLUE}ShadowTls:${PLAIN} ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN}"
;;
33)
echo -e ${BLUE}Snell:${PLAIN} ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN}
echo -e " ${BLUE}ShadowTls:${PLAIN} ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN}"
;;
20)
echo -e ${BLUE}Snell:${PLAIN} ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN}
echo -e " ${BLUE}ShadowTls:${PLAIN} ${RED}未安装${PLAIN}"
;;
21)
echo -e ${BLUE}Snell:${PLAIN} ${GREEN}已安装${PLAIN} ${RED}未运行${PLAIN}
echo -e " ${BLUE}ShadowTls:${PLAIN} ${RED}未安装${PLAIN}"
;;
30)
echo -e ${BLUE}Snell:${PLAIN} ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN}
echo -e " ${BLUE}ShadowTls:${PLAIN} ${RED}未安装${PLAIN}"
;;
31)
echo -e ${BLUE}Snell:${PLAIN} ${GREEN}已安装${PLAIN} ${GREEN}正在运行${PLAIN}
echo -e " ${BLUE}ShadowTls:${PLAIN} ${RED}未安装${PLAIN}"
;;
*)
echo -e ${BLUE}Snell:${PLAIN} ${RED}未安装${PLAIN}
echo -e " ${BLUE}ShadowTls:${PLAIN} ${RED}未安装${PLAIN}"
;;
esac
}
Install_dependency(){
if [[ ${OS} == "yum" ]]; then
echo ""
colorEcho $YELLOW "安装依赖中..."
yum install unzip wget -y >/dev/null 2>&1
echo ""
else
echo ""
colorEcho $YELLOW "安装依赖中..."
apt install unzip wget -y >/dev/null 2>&1
echo ""
fi
echo "net.ipv4.tcp_fastopen=3" >> /etc/sysctl.conf
sysctl -p >/dev/null 2>&1
}
selectversion() {
for ((i=1;i<=${#versions[@]};i++ )); do
hint="${versions[$i-1]}"
echo -e "${GREEN}${i}${PLAIN}) ${hint}"
done
read -p "请选择版本[1-4] (默认: ${versions[3]}):" pick
[ -z "$pick" ] && pick=4
expr ${pick} + 1 &>/dev/null
if [ $? -ne 0 ]; then
colorEcho $RED "错误, 请选择[1-4]"
selectversion
fi
if [[ "$pick" -lt 1 || "$pick" -gt ${#versions[@]} ]]; then
colorEcho $RED "错误, 请选择[1-4]"
selectversion
fi
vers=${versions[$pick-1]}
if [[ "$pick" = "4" ]]; then
VER="v4.0.1"
else
VER="v3.0.1"
fi
}
show_version() {
if [[ ! -z "${vers}" ]]; then
colorEcho $BLUE "版本: ${vers}"
echo ""
else
echo ""
return
fi
}
Download_snell(){
rm -rf /etc/snell /tmp/snell
mkdir -p /etc/snell /tmp/snell
archAffix
DOWNLOAD_LINK="https://ghproxy.lvedong.eu.org/https://raw.githubusercontent.com/Slotheve/Snell/main/snell-server-${VER}-linux-${CPU}.zip"
colorEcho $YELLOW "下载Snell: ${DOWNLOAD_LINK}"
curl -L -H "Cache-Control: no-cache" -o /tmp/snell/snell.zip ${DOWNLOAD_LINK}
unzip /tmp/snell/snell.zip -d /tmp/snell/
mv /tmp/snell/snell-server /etc/snell/snell
chmod +x /etc/snell/snell
}
Download_stls() {
rm -rf /etc/snell/shadowtls
archAffix
TAG_URL="https://ghproxy.lvedong.eu.org/https://api.github.com/repos/ihciah/shadow-tls/releases/latest"
DOWN_VER=`curl -s "${TAG_URL}" --connect-timeout 10| grep -Eo '\"tag_name\"(.*?)\",' | cut -d\" -f4`
DOWNLOAD_LINK="https://ghproxy.lvedong.eu.org/https://github.com/ihciah/shadow-tls/releases/download/${DOWN_VER}/shadow-tls-${ARCH}-unknown-linux-musl"
colorEcho $YELLOW "下载ShadowTLS: ${DOWNLOAD_LINK}"
curl -L -H "Cache-Control: no-cache" -o /etc/snell/shadowtls ${DOWNLOAD_LINK}
chmod +x /etc/snell/shadowtls
}
Generate_conf(){
show_version
Set_V6
Set_port
Set_psk
show_psk
Set_obfs
Set_tfo
}
Generate_stls() {
Decide_sv6
Set_sport
Set_domain
show_domain
Set_pass
}
Deploy_snell(){
cd /etc/systemd/system
cat > snell.service<<-EOF
[Unit]
Description=Snell Server
After=network.target
[Service]
ExecStart=/etc/snell/snell -c /etc/snell/snell-server.conf
Restart=on-failure
RestartSec=1s
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable snell
systemctl restart snell
echo "net.ipv4.tcp_fastopen = 3" >> /etc/sysctl.conf
sysctl -p
}
Deploy_stls() {
cd /etc/systemd/system
cat > shadowtls.service<<-EOF
[Unit]
Description=Shadow-TLS Server Service
Documentation=man:sstls-server
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/etc/snell/shadowtls --fastopen --v3 server --listen $SV6:$SPORT --server 127.0.0.1:$PORT --tls $DOMAIN --password $PASS
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=shadow-tls
[Install]
WantedBy=multi-user.target
# ${V6}
EOF
systemctl daemon-reload
systemctl enable shadowtls
systemctl restart shadowtls
}
Set_V6(){
read -p $'是否开启V6[y/n]\n(默认n, 回车): ' answer
if [[ "${answer}" = "y" ]]; then
if [[ $VER == "v3.0.1" ]]; then
LIP="[::]"
colorEcho $BLUE "启用V6"
echo ""
else
LIP="::0"
colorEcho $BLUE "启用V6"
echo ""
fi
V6="true"
elif [[ "${answer}" = "n" || -z "${answer}" ]]; then
colorEcho $BLUE "禁用V6"
echo ""
LIP="0.0.0.0"
V6="false"
else
colorEcho $RED "输入错误, 请输入 y/n"
Set_V6
fi
}
Set_port(){
read -p $'请输入 Snell 端口 [1-65535]\n(默认: 6666回车): ' PORT
[[ -z "${PORT}" ]] && PORT="6666"
echo $((${PORT}+0)) &>/dev/null
if [[ $? -eq 0 ]]; then
if [[ ${PORT} -ge 1 ]] && [[ ${PORT} -le 65535 ]]; then
colorEcho $BLUE "端口: ${PORT}"
echo ""
else
colorEcho $RED "输入错误, 请输入正确的端口。"
Set_port
fi
else
colorEcho $RED "输入错误, 请输入数字。"
Set_port
fi
}
Set_psk(){
read -p $'请输入 Snell PSK 密钥\n(推荐随机生成,直接回车): ' PSK
[[ -z "${PSK}" ]] && PSK=`tr -dc A-Za-z0-9 </dev/urandom | head -c 31`
if [[ "${#PSK}" != 31 ]]; then
colorEcho $RED "请输入正确的密匙31位字符。"
Set_psk
fi
}
show_psk() {
colorEcho $BLUE "PSK: ${PSK}"
echo ""
}
Set_obfs(){
read -p $'是否开启obfs[y/n]\n(默认n, 回车): ' answer
if [[ "${answer}" = "y" ]]; then
read -e -p "请输入 obfs 混淆 (tls/http): " OBFS
if [[ "${OBFS}" = "tls" || "${OBFS}" = "http" ]]; then
colorEcho $BLUE "obfs: ${OBFS}"
echo ""
else
colorEcho $RED "错误, 请输入 http/tls"
Set_obfs
fi
elif [[ "${answer}" = "n" || -z "${answer}" ]]; then
if [[ $VER == "v3.0.1" ]]; then
OBFS="none"
colorEcho $BLUE "禁用obfs"
echo ""
else
OBFS="off"
colorEcho $BLUE "禁用obfs"
echo ""
fi
else
colorEcho $RED "错误, 请输入 y/n"
Set_obfs
fi
}
Set_tfo(){
read -p $'是否开启TFO[y/n]\n(默认n, 回车): ' answer
if [[ "${answer}" = "y" ]]; then
TFO="true"
colorEcho $BLUE "启用TFO"
echo ""
elif [[ "${answer}" = "n" || -z "${answer}" ]]; then
TFO="false"
colorEcho $BLUE "禁用TFO"
echo ""
else
colorEcho $RED "错误, 请输入 y/n"
Set_tfo
fi
}
Decide_sv6() {
if [[ "${V6}" = "true" ]]; then
SV6="::0"
elif [[ "${V6}" = "false" ]]; then
SV6="0.0.0.0"
fi
}
Set_sport() {
read -p $'请输入 ShadowTLS 端口 [1-65535]\n(默认: 9999回车): ' SPORT
[[ -z "${SPORT}" ]] && SPORT="9999"
echo $((${SPORT}+0)) &>/dev/null
if [[ $? -eq 0 ]]; then
if [[ ${SPORT} -ge 1 ]] && [[ ${SPORT} -le 65535 ]]; then
colorEcho $BLUE "端口: ${SPORT}"
echo ""
else
colorEcho $RED "输入错误, 请输入正确的端口。"
Set_sport
fi
else
colorEcho $RED "输入错误, 请输入数字。"
Set_sport
fi
}
Set_domain() {
for ((i=1;i<=${#domains[@]};i++ )); do
hint="${domains[$i-1]}"
echo -e "${GREEN}${i}${PLAIN}) ${hint}"
done
read -p "请选择域名[1-4] (默认: ${domains[0]}):" pick
[ -z "$pick" ] && pick=1
expr ${pick} + 1 &>/dev/null
if [ $? -ne 0 ]; then
colorEcho $RED "错误, 请输入正确选项"
Set_domain
fi
if [[ "$pick" -lt 1 || "$pick" -gt ${#domains[@]} ]]; then
echo -e "${red}错误, 请输入正确选项${plain}"
Set_domain
fi
DOMAIN=${domains[$pick-1]}
if [[ "$pick" = "4" ]]; then
colorEcho $BLUE "已选择: ${domains[$pick-1]}"
echo ""
read -p $'请输入自定义域名: ' DOMAIN
if [[ -z "${DOMAIN}" ]]; then
colorEcho $RED "错误, 请输入正确的域名"
Set_domain
else
colorEcho $BLUE "域名:$DOMAIN"
echo ""
fi
fi
}
show_domain() {
colorEcho $BLUE "域名:${domains[$pick-1]}"
echo ""
}
Set_pass() {
read -p $'请设置ShadowTLS的密码\n(默认随机生成, 回车): ' PASS
[[ -z "$PASS" ]] && PASS=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1`
colorEcho $BLUE " 密码:$PASS"
echo ""
}
Write_config(){
cat > ${snell_conf}<<-EOF
[snell-server]
listen = ${LIP}:${PORT}
psk = ${PSK}
ipv6 = ${V6}
obfs = ${OBFS}
tfo = ${TFO}
# ${vers}
EOF
}
Install_snell(){
Install_dependency
selectversion
Generate_conf
Install_stls
colorEcho $BLUE "安装完成"
echo ""
ShowInfo
}
Install_stls() {
read -p $'是否安装ShadowTls[y/n]\n(默认n, 回车): ' answer
if [[ "${answer}" = "y" ]]; then
colorEcho $BLUE "安装ShadowTls"
echo ""
Generate_stls
Download_snell
Write_config
Deploy_snell
Download_stls
Deploy_stls
elif [[ "${answer}" = "n" || -z "${answer}" ]]; then
colorEcho $BLUE "不安装ShadowTls"
echo ""
Download_snell
Write_config
Deploy_snell
else
colorEcho $RED " 输入错误, 请输入[y/n]。"
Install_stls
fi
}
Restart_snell(){
systemctl restart snell
colorEcho $BLUE " Snell已启动"
}
Restart_stls(){
systemctl restart shadowtls
colorEcho $BLUE " ShadowTls已重启"
}
Stop_snell(){
systemctl stop snell
colorEcho $BLUE " Snell已停止"
}
Uninstall_snell(){
read -p $' 是否卸载Snell[y/n]\n (默认n, 回车): ' answer
if [[ "${answer}" = "y" ]]; then
if [[ -f "$stls_conf" ]]; then
systemctl stop snell shadowtls
systemctl disable snell shadowtls >/dev/null 2>&1
rm -rf /etc/systemd/system/snell.service
rm -rf /etc/systemd/system/shadowtls.service
rm -rf /etc/snell
systemctl daemon-reload
colorEcho $BLUE " Snell已经卸载完毕"
else
systemctl stop snell
systemctl disable snell >/dev/null 2>&1
rm -rf /etc/systemd/system/snell.service
rm -rf /etc/snell
systemctl daemon-reload
colorEcho $BLUE " Snell已经卸载完毕"
fi
else
colorEcho $BLUE " 取消卸载"
fi
}
ShowInfo() {
if [[ ! -f $snell_conf ]]; then
colorEcho $RED " Snell未安装"
exit 1
fi
echo ""
echo -e " ${BLUE}Snell配置文件: ${PLAIN} ${RED}${snell_conf}${PLAIN}"
colorEcho $BLUE " Snell配置信息"
GetConfig
outputSnell
if [[ -f $stls_conf ]]; then
GetConfig_stls
outputSTLS
echo ""
echo -e " ${BLUE}若要使用ShadowTls, 请将${PLAIN}${RED} 端口 ${PLAIN}${BLUE}替换为${PLAIN}${RED} ${sport} ${PLAIN}"
fi
}
GetConfig() {
port=`grep listen ${snell_conf} | awk -F '=' '{print $2}' | cut -d: -f2`
if [[ -z "${port}" ]]; then
port=`grep listen ${snell_conf} | awk -F '=' '{print $2}' | cut -d: -f4`
fi
psk=`grep psk ${snell_conf} | awk -F '= ' '{print $2}'`
ipv6=`grep ipv6 ${snell_conf} | awk -F '= ' '{print $2}'`
if [[ $ipv6 == "true" ]]; then
IP=${IP6}
else
IP=${IP4}
fi
obfs=`grep obfs ${snell_conf} | awk -F '= ' '{print $2}'`
tfo=`grep tfo ${snell_conf} | awk -F '= ' '{print $2}'`
ver=`grep '#' ${snell_conf} | awk -F '# ' '{print $2}'`
}
GetConfig_stls() {
V6=`grep ipv6 ${snell_conf} | awk -F '= ' '{print $2}'`
if [[ $V6 = "true" ]]; then
sport=`grep listen ${stls_conf} | cut -d- -f7 | cut -d: -f4`
else
sport=`grep listen ${stls_conf} | cut -d- -f7 | cut -d: -f2`
fi
pass=`grep password ${stls_conf} | cut -d- -f13 | cut -d " " -f 2`
domain=`grep password ${stls_conf} | cut -d- -f11 | cut -d " " -f 2`
}
outputSnell() {
echo -e " ${BLUE}协议: ${PLAIN} ${RED}snell${PLAIN}"
echo -e " ${BLUE}地址(IP): ${PLAIN} ${RED}${IP}${PLAIN}"
echo -e " ${BLUE}Snell端口(PORT)${PLAIN} ${RED}${port}${PLAIN}"
echo -e " ${BLUE}Snell密钥(PSK)${PLAIN} ${RED}${psk}${PLAIN}"
echo -e " ${BLUE}IPV6${PLAIN} ${RED}${ipv6}${PLAIN}"
echo -e " ${BLUE}混淆(OBFS)${PLAIN} ${RED}${obfs}${PLAIN}"
echo -e " ${BLUE}TCP记忆(TFO)${PLAIN} ${RED}${tfo}${PLAIN}"
echo -e " ${BLUE}Snell版本(VER)${PLAIN} ${RED}${ver}${PLAIN}"
}
outputSTLS() {
echo -e " ${BLUE}ShadowTls端口(PORT)${PLAIN} ${RED}${sport}${PLAIN}"
echo -e " ${BLUE}ShadowTls密码(PASS)${PLAIN} ${RED}${pass}${PLAIN}"
echo -e " ${BLUE}ShadowTls域名(DOMAIN)${PLAIN} ${RED}${domain}${PLAIN}"
echo -e " ${BLUE}ShadowTls版本(VER)${PLAIN} ${RED}v3${PLAIN}"
}
Change_snell(){
tmp3=`grep '#' ${snell_conf} | awk -F '# ' '{print $2}'`
Generate_conf
if [[ -f "$stls_conf" ]]; then
if [[ ${V6} = "true" ]]; then
SV6="::0"
SPORT=`grep listen ${stls_conf} | cut -d- -f7 | cut -d: -f2`
PASS=`grep password ${stls_conf} | cut -d- -f13 | cut -d " " -f 2`
DOMAIN=`grep password ${stls_conf} | cut -d- -f11 | cut -d " " -f 2`
else
SV6="0.0.0.0"
SPORT=`grep listen ${stls_conf} | cut -d- -f7 | cut -d: -f4`
PASS=`grep password ${stls_conf} | cut -d- -f13 | cut -d " " -f 2`
DOMAIN=`grep password ${stls_conf} | cut -d- -f11 | cut -d " " -f 2`
fi
Deploy_stls
fi
vers=$tmp3
Write_config
systemctl restart snell
colorEcho $BLUE " 修改配置成功"
ShowInfo
}
Change_stls() {
PORT=`grep listen ${snell_conf} | awk -F '=' '{print $2}' | cut -d: -f4`
if [[ -f "$stls_conf" ]]; then
V6=`grep ipv6 ${snell_conf} | awk -F '= ' '{print $2}'`
Generate_stls
Deploy_stls
colorEcho $BLUE " 修改配置成功"
ShowInfo
else
colorEcho $RED " 未安装ShadowTls"
fi
}
checkSystem
menu() {
clear
echo "################################"
echo -e "# ${RED}Snell一键安装脚本${PLAIN} #"
echo -e "# ${GREEN}作者${PLAIN}: 怠惰(Slotheve) #"
echo -e "# ${GREEN}网址${PLAIN}: https://slotheve.com #"
echo -e "# ${GREEN}频道${PLAIN}: https://t.me/SlothNews #"
echo "################################"
echo " ----------------------"
echo -e " ${GREEN}1.${PLAIN} 安装Snell"
echo -e " ${GREEN}2.${PLAIN} ${RED}卸载Snell${PLAIN}"
echo " ----------------------"
echo -e " ${GREEN}3.${PLAIN} 重启Snell"
echo -e " ${GREEN}4.${PLAIN} 重启ShadowTls"
echo -e " ${GREEN}5.${PLAIN} 停止Snell"
echo " ----------------------"
echo -e " ${GREEN}6.${PLAIN} 查看Snell配置"
echo -e " ${GREEN}7.${PLAIN} 修改Snell配置"
echo -e " ${GREEN}8.${PLAIN} 修改ShadowTLS配置"
echo " ----------------------"
echo -e " ${GREEN}0.${PLAIN} 退出"
echo ""
echo -n " 当前状态:"
statusText
echo
read -p " 请选择操作[0-11]" answer
case $answer in
0)
exit 0
;;
1)
Install_snell
;;
2)
Uninstall_snell
;;
3)
Restart_snell
;;
4)
Restart_stls
;;
5)
Stop_snell
;;
6)
ShowInfo
;;
7)
Change_snell
;;
8)
Change_stls
;;
*)
colorEcho $RED " 请选择正确的操作!"
sleep 2s
menu
;;
esac
}
menu