#! /bin/bash Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m" Info="${Green_font_prefix}[信息]${Font_color_suffix}" Error="${Red_font_prefix}[错误]${Font_color_suffix}" Tip="${Green_font_prefix}[注意]${Font_color_suffix}" 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 else apt-get update apt-get install -y gzip 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() { 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.1" echo -e "${Error} gost 最新版本获取失败,正在下载v${ct_new_ver}版" # read -e -p "请输入版本号 [ 格式 x.x.xx , 如 0.8.21 ] :" ct_new_ver #[[ -z "${ct_new_ver}" ]] && echo "取消..." && exit 1 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 `rm -rf gost-linux-"$bit"-"$ct_new_ver".gz` `wget --no-check-certificate https://pan.jzv.me/GOST/gost-linux-amd64-2.11.1.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/Topcckin/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/Topcckin/EasyGost/master/config.json && mv config.json /etc/gost && chmod -R 777 /etc/gost` `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没有安装成功,可以在Github[EasyGost]中提交issue" `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() { `systemctl restart gost` echo "已重启" } function read_protocol() { echo -e "请问您要设置哪种转发协议: " echo -e "-----------------------------------" echo -e "[1] tcp+udp流量转发, 不加密" echo -e "说明: 一般设置在中转流量的机器上, 如国内机上" echo -e "-----------------------------------" echo -e "[2] relay+tls加密流量转发" echo -e "说明: (1)用于转发原本加密等级较低的流量, 一般设置在中转流量的机器上, 如国内机上" echo -e " (2)选择此协议意味着你还有一台机器用于接收此加密流量, 之后须在那台机器上配置协议[3]进行对接" echo -e "-----------------------------------" echo -e "[3] 解密由gost传输而来的流量并转发" echo -e "说明: 对于经由gost加密中转的流量, 通过此选项进行解密并转发给本机的其他服务端口或转发给其他远程机器, 一般设置在用于接收中转流量的国外机器上" echo -e "-----------------------------------" read -p "请选择转发协议: " numprotocol if [ "$numprotocol" = "1" ]; then flag_a="nonencrypt" elif [ "$numprotocol" = "2" ]; then flag_a="encrypt" elif [ "$numprotocol" = "3" ]; then flag_a="decrypt" else echo "type error, please try again" exit fi } function read_s_port() { echo -e "------------------------------------------------------------------" echo -e "------------------------------------------------------------------" echo -e "请问你要将本机哪个端口接收到的流量进行转发?" read -p "请输入: " flag_b } function read_d_ip() { echo -e "------------------------------------------------------------------" echo -e "------------------------------------------------------------------" echo -e "请问你要将本机从${flag_b}接收到的流量转发向哪个IP或域名?" echo -e "注: IP既可以是[远程机器/当前机器]的公网IP, 也可是以本机本地回环IP(即127.0.0.1)" echo -e " 具体IP地址的填写, 取决于接收该流量的服务正在监听的IP(详见: https://github.com/stsdust/EasyGost)" read -p "请输入: " flag_c } function read_d_port() { echo -e "------------------------------------------------------------------" echo -e "------------------------------------------------------------------" echo -e "请问你要将本机从${flag_b}接收到的流量转发向${flag_c}的哪个端口?" read -p "请输入: " flag_d } function writerawconf() { echo $flag_a"/"$flag_b"#"$flag_c"#"$flag_d >> $raw_conf_path } function rawconf() { read_protocol read_s_port 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 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" = "encrypt" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+tls://$d_ip:$d_port\"" >> $gost_conf_path elif [ "$is_encrypt" = "decrypt" ]; then echo " \"relay+tls://:$s_port/$d_ip:$d_port\"" >> $gost_conf_path 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" = "encrypt" ]; then echo " \"tcp://:$s_port\", \"udp://:$s_port\" ], \"ChainNodes\": [ \"relay+tls://$d_ip:$d_port\"" >> $gost_conf_path elif [ "$is_encrypt" = "decrypt" ]; then echo " \"relay+tls://:$s_port/$d_ip:$d_port\"" >> $gost_conf_path else echo "config error" fi 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="tcp+udp不加密" elif [ "$is_encrypt" = "encrypt" ]; then str="relay+tls加密" elif [ "$is_encrypt" = "decrypt" ]; then str="relay+tls解密" fi echo -e " $i |$str |$s_port\t|$d_ip:$d_port" echo -e "--------------------------------------------------------" done } echo && echo -e " gost 一键安装配置脚本 ----------- 由STSDUST制作 ----------- 原脚本来自 fiisi.com ----------- 特性: (1)本脚本采用systemd及gost配置文件对gost进行管理 (2)能够在不借助其他工具(如screen)的情况下实现多条转发规则同时生效 (3)脚本面向仅图省事的使用者,因此仅提供少数转发功能 功能: tcp+udp不加密转发, relay+tls加密转发, relay+tls解密对接转发 注意:首次使用本脚本安装完成后,需要再次运行以添加配置 ${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配置 ————————————" && 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 sed -i "${numdelete}d" $raw_conf_path rm -rf /etc/gost/config.json confstart writeconf conflast `systemctl restart gost` echo -e "配置已删除,服务已重启" ;; *) echo "请输入正确数字 [1-9]" ;; esac