#! /bin/bash Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Font_color_suffix="\033[0m" Info="${Green_font_prefix}[信息]${Font_color_suffix}" Error="${Red_font_prefix}[错误]${Font_color_suffix}" shell_version="1.1.1" ct_new_ver="2.11.2" gost_conf_path="/etc/gost/config.json" raw_conf_path="/etc/gost/rawconf" function checknew() { checknew=$(gost -V 2>&1 | awk '{print $2}') # check_new_ver echo "你的gost版本为:""$checknew""" echo -n 是否更新\(y/n\)\: read checknewnum if test $checknewnum = "y"; then cp -r /etc/gost /tmp/ Install_ct rm -rf /etc/gost mv /tmp/gost /etc/ systemctl restart gost else exit 0 fi } function check_sys() { if [[ -f /etc/redhat-release ]]; then release="centos" elif cat /etc/issue | grep -q -E -i "debian"; then release="debian" elif cat /etc/issue | grep -q -E -i "ubuntu"; then release="ubuntu" elif cat /etc/issue | grep -q -E -i "centos|red hat|redhat"; then release="centos" elif cat /proc/version | grep -q -E -i "debian"; then release="debian" elif cat /proc/version | grep -q -E -i "ubuntu"; then release="ubuntu" elif cat /proc/version | grep -q -E -i "centos|red hat|redhat"; then release="centos" fi bit=$(uname -m) if test "$bit" != "x86_64"; then echo "请输入你的芯片架构,/386/armv5/armv6/armv7/armv8" read bit else bit="amd64" fi } function Installation_dependency() { gzip_ver=$(gzip -V) if [[ -z ${gzip_ver} ]]; then if [[ ${release} == "centos" ]]; then yum update yum install -y gzip wget else apt-get update apt-get install -y gzip wget fi fi } function check_root() { [[ $EUID != 0 ]] && echo -e "${Error} 当前非ROOT账号(或没有ROOT权限),无法继续操作,请更换ROOT账号或使用 ${Green_background_prefix}sudo su${Font_color_suffix} 命令获取临时ROOT权限(执行后可能会提示输入当前账号的密码)。" && exit 1 } function check_new_ver() { # deprecated ct_new_ver=$(wget --no-check-certificate -qO- -t2 -T3 https://api.github.com/repos/ginuerzh/gost/releases/latest | grep "tag_name" | head -n 1 | awk -F ":" '{print $2}' | sed 's/\"//g;s/,//g;s/ //g;s/v//g') if [[ -z ${ct_new_ver} ]]; then ct_new_ver="2.11.2" echo -e "${Error} gost 最新版本获取失败,正在下载v${ct_new_ver}版" else echo -e "${Info} gost 目前最新版本为 ${ct_new_ver}" fi } function check_file() { if test ! -d "/usr/lib/systemd/system/"; then mkdir /usr/lib/systemd/system chmod -R 777 /usr/lib/systemd/system fi } function check_nor_file() { rm -rf "$(pwd)"/gost rm -rf "$(pwd)"/gost.service rm -rf "$(pwd)"/config.json rm -rf /etc/gost rm -rf /usr/lib/systemd/system/gost.service rm -rf /usr/bin/gost } function Install_ct() { check_root check_nor_file Installation_dependency check_file check_sys # check_new_ver echo -e "若为国内机器建议使用大陆镜像加速下载" read -e -p "是否使用?[y/n]:" addyn [[ -z ${addyn} ]] && addyn="n" if [[ ${addyn} == [Yy] ]]; then rm -rf gost-linux-"$bit"-"$ct_new_ver".gz wget --no-check-certificate https://gotunnel.oss-cn-shenzhen.aliyuncs.com/gost-linux-"$bit"-"$ct_new_ver".gz gunzip gost-linux-"$bit"-"$ct_new_ver".gz mv gost-linux-"$bit"-"$ct_new_ver" gost mv gost /usr/bin/gost chmod -R 777 /usr/bin/gost wget --no-check-certificate https://gotunnel.oss-cn-shenzhen.aliyuncs.com/gost.service && chmod -R 777 gost.service && mv gost.service /usr/lib/systemd/system mkdir /etc/gost && wget --no-check-certificate https://gotunnel.oss-cn-shenzhen.aliyuncs.com/config.json && mv config.json /etc/gost && chmod -R 777 /etc/gost else rm -rf gost-linux-"$bit"-"$ct_new_ver".gz wget --no-check-certificate https://github.com/ginuerzh/gost/releases/download/v"$ct_new_ver"/gost-linux-"$bit"-"$ct_new_ver".gz gunzip gost-linux-"$bit"-"$ct_new_ver".gz mv gost-linux-"$bit"-"$ct_new_ver" gost mv gost /usr/bin/gost chmod -R 777 /usr/bin/gost wget --no-check-certificate https://raw.githubusercontent.com/KANIKIG/Multi-EasyGost/master/gost.service && chmod -R 777 gost.service && mv gost.service /usr/lib/systemd/system mkdir /etc/gost && wget --no-check-certificate https://raw.githubusercontent.com/KANIKIG/Multi-EasyGost/master/config.json && mv config.json /etc/gost && chmod -R 777 /etc/gost fi systemctl enable gost && systemctl restart gost echo "------------------------------" if test -a /usr/bin/gost -a /usr/lib/systemctl/gost.service -a /etc/gost/config.json; then echo "gost安装成功" rm -rf "$(pwd)"/gost rm -rf "$(pwd)"/gost.service rm -rf "$(pwd)"/config.json else echo "gost没有安装成功" rm -rf "$(pwd)"/gost rm -rf "$(pwd)"/gost.service rm -rf "$(pwd)"/config.json rm -rf "$(pwd)"/gost.sh fi } function Uninstall_ct() { rm -rf /usr/bin/gost rm -rf /usr/lib/systemd/system/gost.service rm -rf /etc/gost rm -rf "$(pwd)"/gost.sh echo "gost已经成功删除" } function Start_ct() { systemctl start gost echo "已启动" } function Stop_ct() { systemctl stop gost echo "已停止" } function Restart_ct() { rm -rf /etc/gost/config.json confstart writeconf conflast systemctl restart gost echo "已重读配置并重启" } function read_protocol() { echo -e "请问您要设置哪种功能: " echo -e "-----------------------------------" echo -e "[1] tcp+udp流量转发, 不加密" echo -e "说明: 一般设置在国内中转机上" echo -e "-----------------------------------" echo -e "[2] 加密隧道流量转发" echo -e "说明: 用于转发原本加密等级较低的流量, 一般设置在国内中转机上" echo -e " 选择此协议意味着你还有一台机器用于接收此加密流量, 之后须在那台机器上配置协议[3]进行对接" echo -e "-----------------------------------" echo -e "[3] 解密由gost传输而来的流量并转发" echo -e "说明: 对于经由gost加密中转的流量, 通过此选项进行解密并转发给本机的代理服务端口或转发给其他远程机器" echo -e " 一般设置在用于接收中转流量的国外机器上" echo -e "-----------------------------------" read -p "请选择: " numprotocol if [ "$numprotocol" == "1" ]; then flag_a="nonencrypt" elif [ "$numprotocol" == "2" ]; then encrypt elif [ "$numprotocol" == "3" ]; then decrypt else echo "type error, please try again" exit fi } function read_d_ip() { echo -e "------------------------------------------------------------------" echo -e "请问你要将本机从${flag_b}接收到的流量转发向哪个IP或域名?" echo -e "注: IP既可以是[远程机器/当前机器]的公网IP, 也可是以本机本地回环IP(即127.0.0.1)" echo -e "具体IP地址的填写, 取决于接收该流量的服务正在监听的IP" if [[ ${is_cert} == [Yy] ]]; then echo -e "注意: 落地机开启自定义tls证书,务必填写${Red_font_prefix}域名${Font_color_suffix}" fi read -p "请输入: " flag_c } function read_d_port() { if [[ "$flag_a" == "peer"* ]]; then echo -e "------------------------------------------------------------------" echo -e "您要设置的均衡负载策略: " echo -e "-----------------------------------" echo -e "[1] round - 轮询" echo -e "[2] random - 随机" echo -e "[3] fifo - 自上而下" echo -e "-----------------------------------" read -p "请选择均衡负载类型: " numstra if [ "$numstra" == "1" ]; then flag_d="round" elif [ "$numstra" == "2" ]; then flag_d="random" elif [ "$numstra" == "3" ]; then flag_d="fifo" else echo "type error, please try again" exit fi else echo -e "------------------------------------------------------------------" echo -e "请问你要将本机从${flag_b}接收到的流量转发向${flag_c}的哪个端口?" read -p "请输入: " flag_d if [[ ${is_cert} == [Yy] ]]; then flag_d="$flag_d?secure=true" fi fi } function writerawconf() { echo $flag_a"/""$flag_b""#""$flag_c""#""$flag_d" >>$raw_conf_path } function rawconf() { read_protocol read_d_ip read_d_port writerawconf } function eachconf_retrieve() { d_server=${trans_conf#*#} d_port=${d_server#*#} d_ip=${d_server%#*} flag_s_port=${trans_conf%%#*} s_port=${flag_s_port#*/} is_encrypt=${flag_s_port%/*} } function confstart() { echo "{ \"Debug\": true, \"Retries\": 0, \"ServeNodes\": [" >>$gost_conf_path } function multiconfstart() { echo " { \"Retries\": 0, \"ServeNodes\": [" >>$gost_conf_path } function conflast() { echo " ] }" >>$gost_conf_path } function multiconflast() { if [ $i -eq $count_line ]; then echo " ] }" >>$gost_conf_path else echo " ] }," >>$gost_conf_path fi } function encrypt() { echo -e "请问您要设置的转发传输类型: " echo -e "-----------------------------------" echo -e "[1] tls隧道" echo -e "[2] ws隧道" echo -e "[3] wss隧道" echo -e "注意: 同一则转发,中转与落地传输类型必须对应!本脚本默认开启tcp+udp" echo -e "-----------------------------------" read -p "请选择转发传输类型: " numencrypt if [ "$numencrypt" == "1" ]; then flag_a="encrypttls" echo -e "注意: 选择 是 将针对落地的自定义证书开启证书校验保证安全性,稍后落地机务必填写${Red_font_prefix}域名${Font_color_suffix}" read -e -p "落地机是否开启了自定义tls证书?[y/n]:" is_cert elif [ "$numencrypt" == "2" ]; then flag_a="encryptws" elif [ "$numencrypt" == "3" ]; then flag_a="encryptwss" echo -e "注意: 选择 是 将针对落地的自定义证书开启证书校验保证安全性,稍后落地机务必填写${Red_font_prefix}域名${Font_color_suffix}" read -e -p "落地机是否开启了自定义tls证书?[y/n]:" is_cert else echo "type error, please try again" exit fi } function cert() { echo -e "-----------------------------------" echo -e "[1] 手动上传证书" echo -e "-----------------------------------" read -p "请选择证书生成方式: " numcert if [ "$numcert" == "1" ]; then if [ ! -d "$HOME/gost_cert" ]; then mkdir $HOME/gost_cert fi echo -e "-----------------------------------" echo -e "已在用户目录建立 ${Red_font_prefix}gost_cert${Font_color_suffix} 目录,请将证书文件 cert.pem 与秘钥文件 key.pem 上传到该目录" echo -e "证书与秘钥文件名必须与上述一致,目录名也请勿更改" echo -e "上传成功后,用脚本重启gost会自动启用,无需再设置; 删除 gost_cert 目录后用脚本重启,即重新启用gost内置证书" echo -e "-----------------------------------" else echo "type error, please try again" exit fi } function decrypt() { echo -e "请问您要设置的解密传输类型: " echo -e "-----------------------------------" echo -e "[1] tls" echo -e "[2] ws" echo -e "[3] wss" echo -e "注意: 同一则转发,中转与落地传输类型必须对应!本脚本默认开启tcp+udp" echo -e "-----------------------------------" read -p "请选择解密传输类型: " numdecrypt if [ "$numdecrypt" == "1" ]; then flag_a="decrypttls" elif [ "$numdecrypt" == "2" ]; then flag_a="decryptws" elif [ "$numdecrypt" == "3" ]; then flag_a="decryptwss" else echo "type error, please try again" exit fi } function method() { if [ $i -eq 1 ]; then if [ "$is_encrypt" == "nonencrypt" ]; then echo " \"tcp://:$s_port/$d_ip:$d_port\", \"udp://:$s_port/$d_ip:$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "cdnno" ]; then echo " \"tcp://:$s_port/$d_ip?host=$d_port\", \"udp://:$s_port/$d_ip?host=$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "peerno" ]; then echo " \"tcp://:$s_port?ip=/root/$d_ip.txt&strategy=$d_port\", \"udp://:$s_port?ip=/root/$d_ip.txt&strategy=$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "encrypttls" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+tls://$d_ip:$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "encryptws" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+ws://$d_ip:$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "encryptwss" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+wss://$d_ip:$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "peertls" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+tls://:?ip=/root/$d_ip.txt&strategy=$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "peerws" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+ws://:?ip=/root/$d_ip.txt&strategy=$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "peerwss" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+wss://:?ip=/root/$d_ip.txt&strategy=$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "decrypttls" ]; then if [ -d "$HOME/gost_cert" ]; then echo " \"relay+tls://:$s_port/$d_ip:$d_port?cert=/root/gost_cert/cert.pem&key=/root/gost_cert/key.pem\"" >>$gost_conf_path else echo " \"relay+tls://:$s_port/$d_ip:$d_port\"" >>$gost_conf_path fi elif [ "$is_encrypt" == "decryptws" ]; then echo " \"relay+ws://:$s_port/$d_ip:$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "decryptwss" ]; then if [ -d "$HOME/gost_cert" ]; then echo " \"relay+wss://:$s_port/$d_ip:$d_port?cert=/root/gost_cert/cert.pem&key=/root/gost_cert/key.pem\"" >>$gost_conf_path else echo " \"relay+wss://:$s_port/$d_ip:$d_port\"" >>$gost_conf_path fi else echo "config error" fi elif [ $i -gt 1 ]; then if [ "$is_encrypt" == "nonencrypt" ]; then echo " \"tcp://:$s_port/$d_ip:$d_port\", \"udp://:$s_port/$d_ip:$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "peerno" ]; then echo " \"tcp://:$s_port?ip=/root/$d_ip.txt&strategy=$d_port\", \"udp://:$s_port?ip=/root/$d_ip.txt&strategy=$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "cdnno" ]; then echo " \"tcp://:$s_port/$d_ip?host=$d_port\", \"udp://:$s_port/$d_ip?host=$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "encrypttls" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+tls://$d_ip:$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "encryptws" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+ws://$d_ip:$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "encryptwss" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+wss://$d_ip:$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "peertls" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+tls://:?ip=/root/$d_ip.txt&strategy=$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "peerws" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+ws://:?ip=/root/$d_ip.txt&strategy=$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "peerwss" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+wss://:?ip=/root/$d_ip.txt&strategy=$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "decrypttls" ]; then if [ -d "$HOME/gost_cert" ]; then echo " \"relay+tls://:$s_port/$d_ip:$d_port?cert=/root/gost_cert/cert.pem&key=/root/gost_cert/key.pem\"" >>$gost_conf_path else echo " \"relay+tls://:$s_port/$d_ip:$d_port\"" >>$gost_conf_path fi elif [ "$is_encrypt" == "decryptws" ]; then echo " \"relay+ws://:$s_port/$d_ip:$d_port\"" >>$gost_conf_path elif [ "$is_encrypt" == "decryptwss" ]; then if [ -d "$HOME/gost_cert" ]; then echo " \"relay+wss://:$s_port/$d_ip:$d_port?cert=/root/gost_cert/cert.pem&key=/root/gost_cert/key.pem\"" >>$gost_conf_path else echo " \"relay+wss://:$s_port/$d_ip:$d_port\"" >>$gost_conf_path fi else echo "config error" fi else echo "config error" exit fi } function writeconf() { count_line=$(awk 'END{print NR}' $raw_conf_path) for ((i = 1; i <= $count_line; i++)); do if [ $i -eq 1 ]; then trans_conf=$(sed -n "${i}p" $raw_conf_path) eachconf_retrieve method elif [ $i -gt 1 ]; then if [ $i -eq 2 ]; then echo " ], \"Routes\": [" >>$gost_conf_path trans_conf=$(sed -n "${i}p" $raw_conf_path) eachconf_retrieve multiconfstart method multiconflast else trans_conf=$(sed -n "${i}p" $raw_conf_path) eachconf_retrieve multiconfstart method multiconflast fi fi done } function show_all_conf() { echo -e " GOST 配置 " echo -e "--------------------------------------------------------" echo -e "序号|方法\t |本地端口\t|目的地地址:目的地端口" echo -e "--------------------------------------------------------" count_line=$(awk 'END{print NR}' $raw_conf_path) for ((i = 1; i <= $count_line; i++)); do trans_conf=$(sed -n "${i}p" $raw_conf_path) eachconf_retrieve if [ "$is_encrypt" == "nonencrypt" ]; then str="不加密中转" elif [ "$is_encrypt" == "encrypttls" ]; then str=" tls隧道 " elif [ "$is_encrypt" == "encryptws" ]; then str=" ws隧道 " elif [ "$is_encrypt" == "encryptwss" ]; then str=" wss隧道 " elif [ "$is_encrypt" == "peerno" ]; then str=" 不加密均衡负载 " elif [ "$is_encrypt" == "peertls" ]; then str=" tls隧道均衡负载 " elif [ "$is_encrypt" == "peerws" ]; then str=" ws隧道均衡负载 " elif [ "$is_encrypt" == "peerwss" ]; then str=" wss隧道均衡负载 " elif [ "$is_encrypt" == "decrypttls" ]; then str=" tls解密 " elif [ "$is_encrypt" == "decryptws" ]; then str=" ws解密 " elif [ "$is_encrypt" == "decryptwss" ]; then str=" wss解密 " else str="" fi echo -e " $i |$str |$s_port\t|$d_ip:$d_port" echo -e "--------------------------------------------------------" done } cron_restart() { echo -e "------------------------------------------------------------------" echo -e "gost定时重启任务: " echo -e "-----------------------------------" echo -e "[1] 配置gost定时重启任务" echo -e "[2] 删除gost定时重启任务" echo -e "-----------------------------------" read -p "请选择: " numcron if [ "$numcron" == "1" ]; then echo -e "------------------------------------------------------------------" echo -e "gost定时重启任务类型: " echo -e "-----------------------------------" echo -e "[1] 每?小时重启" echo -e "[2] 每日?点重启" echo -e "-----------------------------------" read -p "请选择: " numcrontype if [ "$numcrontype" == "1" ]; then echo -e "-----------------------------------" read -p "每?小时重启: " cronhr echo "0 0 */$cronhr * * ? * systemctl restart gost" >>/etc/crontab echo -e "定时重启设置成功!" elif [ "$numcrontype" == "2" ]; then echo -e "-----------------------------------" read -p "每日?点重启: " cronhr echo "0 0 $cronhr * * ? systemctl restart gost" >>/etc/crontab echo -e "定时重启设置成功!" else echo "type error, please try again" exit fi elif [ "$numcron" == "2" ]; then sed -i "/gost/d" /etc/crontab echo -e "定时重启任务删除完成!" else echo "type error, please try again" exit fi } echo && echo -e " gost 一键安装配置脚本"${Red_font_prefix}[${shell_version}]${Font_color_suffix}" ${Green_font_prefix}1.${Font_color_suffix} 安装 gost ${Green_font_prefix}2.${Font_color_suffix} 更新 gost ${Green_font_prefix}3.${Font_color_suffix} 卸载 gost ———————————— ${Green_font_prefix}4.${Font_color_suffix} 启动 gost ${Green_font_prefix}5.${Font_color_suffix} 停止 gost ${Green_font_prefix}6.${Font_color_suffix} 重启 gost ———————————— ${Green_font_prefix}7.${Font_color_suffix} 新增gost转发配置 ${Green_font_prefix}8.${Font_color_suffix} 查看现有gost配置 ${Green_font_prefix}9.${Font_color_suffix} 删除一则gost配置 ———————————— ${Green_font_prefix}10.${Font_color_suffix} gost定时重启配置 ${Green_font_prefix}11.${Font_color_suffix} 自定义TLS证书配置 ————————————" && echo read -e -p " 请输入数字 [1-9]:" num case "$num" in 1) Install_ct ;; 2) checknew ;; 3) Uninstall_ct ;; 4) Start_ct ;; 5) Stop_ct ;; 6) Restart_ct ;; 7) rawconf rm -rf /etc/gost/config.json confstart writeconf conflast systemctl restart gost echo -e "配置已生效,当前配置如下" echo -e "--------------------------------------------------------" show_all_conf ;; 8) show_all_conf ;; 9) show_all_conf read -p "请输入你要删除的配置编号:" numdelete if echo $numdelete | grep -q '[0-9]'; then sed -i "${numdelete}d" $raw_conf_path rm -rf /etc/gost/config.json confstart writeconf conflast systemctl restart gost echo -e "配置已删除,服务已重启" else echo "请输入正确数字" fi ;; 10) cron_restart ;; 11) cert ;; *) echo "请输入正确数字 [1-9]" ;; esac