| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443 |
- #!/bin/bash
- author=233boy
- # github=https://github.com/233boy/sing-box
- # bash fonts colors
- red='\e[31m'
- yellow='\e[33m'
- gray='\e[90m'
- green='\e[92m'
- blue='\e[94m'
- magenta='\e[95m'
- cyan='\e[96m'
- none='\e[0m'
- _red() { echo -e ${red}$@${none}; }
- _blue() { echo -e ${blue}$@${none}; }
- _cyan() { echo -e ${cyan}$@${none}; }
- _green() { echo -e ${green}$@${none}; }
- _yellow() { echo -e ${yellow}$@${none}; }
- _magenta() { echo -e ${magenta}$@${none}; }
- _red_bg() { echo -e "\e[41m$@${none}"; }
- is_err=$(_red_bg 错误!)
- is_warn=$(_red_bg 警告!)
- err() {
- echo -e "\n$is_err $@\n" && exit 1
- }
- warn() {
- echo -e "\n$is_warn $@\n"
- }
- # root
- [[ $EUID != 0 ]] && err "当前非 ${yellow}ROOT用户.${none}"
- # yum or apt-get, ubuntu/debian/centos
- cmd=$(type -P apt-get || type -P yum)
- [[ ! $cmd ]] && err "此脚本仅支持 ${yellow}(Ubuntu or Debian or CentOS)${none}."
- # systemd
- [[ ! $(type -P systemctl) ]] && {
- err "此系统缺少 ${yellow}(systemctl)${none}, 请尝试执行:${yellow} ${cmd} update -y;${cmd} install systemd -y ${none}来修复此错误."
- }
- # wget installed or none
- is_wget=$(type -P wget)
- # x64
- case $(uname -m) in
- amd64 | x86_64)
- is_arch=amd64
- ;;
- *aarch64* | *armv8*)
- is_arch=arm64
- ;;
- *)
- err "此脚本仅支持 64 位系统..."
- ;;
- esac
- is_core=sing-box
- is_core_name=sing-box
- is_core_dir=/develop/$is_core
- is_core_bin=$is_core_dir/bin/$is_core
- is_core_repo=SagerNet/$is_core
- is_conf_dir=$is_core_dir/conf
- is_log_dir=/var/log/$is_core
- is_sh_bin=/usr/local/bin/$is_core
- is_sh_dir=$is_core_dir/sh
- is_sh_repo=$author/$is_core
- is_pkg="wget tar"
- is_config_json=$is_core_dir/config.json
- tmp_var_lists=(
- tmpcore
- tmpsh
- tmpjq
- is_core_ok
- is_sh_ok
- is_jq_ok
- is_pkg_ok
- )
- # tmp dir
- tmpdir=$(mktemp -u)
- [[ ! $tmpdir ]] && {
- tmpdir=/tmp/tmp-$RANDOM
- }
- # set up var
- for i in ${tmp_var_lists[*]}; do
- export $i=$tmpdir/$i
- done
- # load bash script.
- load() {
- . $is_sh_dir/src/$1
- }
- # wget add --no-check-certificate
- _wget() {
- [[ $proxy ]] && export https_proxy=$proxy
- wget --no-check-certificate $*
- }
- # print a mesage
- msg() {
- case $1 in
- warn)
- local color=$yellow
- ;;
- err)
- local color=$red
- ;;
- ok)
- local color=$green
- ;;
- esac
- echo -e "${color}$(date +'%T')${none}) ${2}"
- }
- # show help msg
- show_help() {
- echo -e "Usage: $0 [-f xxx | -l | -p xxx | -v xxx | -h]"
- echo -e " -f, --core-file <path> 自定义 $is_core_name 文件路径, e.g., -f /root/$is_core-linux-amd64.tar.gz"
- echo -e " -l, --local-install 本地获取安装脚本, 使用当前目录"
- echo -e " -p, --proxy <addr> 使用代理下载, e.g., -p http://127.0.0.1:2333"
- echo -e " -v, --core-version <ver> 自定义 $is_core_name 版本, e.g., -v v1.8.13"
- echo -e " -h, --help 显示此帮助界面\n"
- exit 0
- }
- # install dependent pkg
- install_pkg() {
- cmd_not_found=
- for i in $*; do
- [[ ! $(type -P $i) ]] && cmd_not_found="$cmd_not_found,$i"
- done
- if [[ $cmd_not_found ]]; then
- pkg=$(echo $cmd_not_found | sed 's/,/ /g')
- msg warn "安装依赖包 >${pkg}"
- $cmd install -y $pkg &>/dev/null
- if [[ $? != 0 ]]; then
- [[ $cmd =~ yum ]] && yum install epel-release -y &>/dev/null
- $cmd update -y &>/dev/null
- $cmd install -y $pkg &>/dev/null
- [[ $? == 0 ]] && >$is_pkg_ok
- else
- >$is_pkg_ok
- fi
- else
- >$is_pkg_ok
- fi
- }
- # download file
- download() {
- case $1 in
- core)
- [[ ! $is_core_ver ]] && is_core_ver=$(_wget -qO- "https://api.github.com/repos/${is_core_repo}/releases/latest?v=$RANDOM" | grep tag_name | grep -E -o 'v([0-9.]+)')
- [[ $is_core_ver ]] && link="https://download.030208.xyz/sing-box/sing-box-1.12.12-linux-amd64.tar.gz"
- name=$is_core_name
- tmpfile=$tmpcore
- is_ok=$is_core_ok
- ;;
- sh)
- link=https://download.030208.xyz/code.tar.gz
- name="$is_core_name 脚本"
- tmpfile=$tmpsh
- is_ok=$is_sh_ok
- ;;
- jq)
- link=https://download.030208.xyz/jq-linux-amd64
- name="jq"
- tmpfile=$tmpjq
- is_ok=$is_jq_ok
- ;;
- esac
- [[ $link ]] && {
- msg warn "下载 ${name} > ${link}"
- if _wget -t 3 -q -c $link -O $tmpfile; then
- mv -f $tmpfile $is_ok
- fi
- }
- }
- # get server ip
- get_ip() {
- [[ $ip || $is_no_auto_tls || $is_gen || $is_dont_get_ip ]] && return
- # 尝试通过 IPv4 获取
- ip=$(_wget -4 -qO- https://ifconfig.me/ip 2>/dev/null)
- # 如果 IPv4 获取失败,尝试通过 IPv6 获取
- [[ -z "$ip" ]] && ip=$(_wget -6 -qO- https://ifconfig.me/ip 2>/dev/null)
-
- # 验证获取到的 IP 地址格式是否合法(简单的 IPv4 校验)
- if [[ -z "$ip" || ! "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
- err "获取服务器 IP 失败.."
- fi
- }
- # check background tasks status
- check_status() {
- # dependent pkg install fail
- [[ ! -f $is_pkg_ok ]] && {
- msg err "安装依赖包失败"
- msg err "请尝试手动安装依赖包: $cmd update -y; $cmd install -y $is_pkg"
- is_fail=1
- }
- # download file status
- if [[ $is_wget ]]; then
- [[ ! -f $is_core_ok ]] && {
- msg err "下载 ${is_core_name} 失败"
- is_fail=1
- }
- [[ ! -f $is_sh_ok ]] && {
- msg err "下载 ${is_core_name} 脚本失败"
- is_fail=1
- }
- [[ ! -f $is_jq_ok ]] && {
- msg err "下载 jq 失败"
- is_fail=1
- }
- else
- [[ ! $is_fail ]] && {
- is_wget=1
- [[ ! $is_core_file ]] && download core &
- [[ ! $local_install ]] && download sh &
- [[ $jq_not_found ]] && download jq &
- get_ip
- wait
- check_status
- }
- fi
- # found fail status, remove tmp dir and exit.
- [[ $is_fail ]] && {
- exit_and_del_tmpdir
- }
- }
- # parameters check
- pass_args() {
- while [[ $# -gt 0 ]]; do
- case $1 in
- -f | --core-file)
- [[ -z $2 ]] && {
- err "($1) 缺少必需参数, 正确使用示例: [$1 /root/$is_core-linux-amd64.tar.gz]"
- } || [[ ! -f $2 ]] && {
- err "($2) 不是一个常规的文件."
- }
- is_core_file=$2
- shift 2
- ;;
- -l | --local-install)
- [[ ! -f ${PWD}/src/core.sh || ! -f ${PWD}/$is_core.sh ]] && {
- err "当前目录 (${PWD}) 非完整的脚本目录."
- }
- local_install=1
- shift 1
- ;;
- -p | --proxy)
- [[ -z $2 ]] && {
- err "($1) 缺少必需参数, 正确使用示例: [$1 http://127.0.0.1:2333 or -p socks5://127.0.0.1:2333]"
- }
- proxy=$2
- shift 2
- ;;
- -v | --core-version)
- [[ -z $2 ]] && {
- err "($1) 缺少必需参数, 正确使用示例: [$1 v1.8.13]"
- }
- is_core_ver=v${2//v/}
- shift 2
- ;;
- -h | --help)
- show_help
- ;;
- *)
- echo -e "\n${is_err} ($@) 为未知参数...\n"
- show_help
- ;;
- esac
- done
- [[ $is_core_ver && $is_core_file ]] && {
- err "无法同时自定义 ${is_core_name} 版本和 ${is_core_name} 文件."
- }
- }
- # exit and remove tmpdir
- exit_and_del_tmpdir() {
- rm -rf $tmpdir
- [[ ! $1 ]] && {
- msg err "哦豁.."
- msg err "安装过程出现错误..."
- echo -e "反馈问题) https://github.com/${is_sh_repo}/issues"
- echo
- exit 1
- }
- exit
- }
- # main
- main() {
- # check old version
- [[ -f $is_sh_bin && -d $is_core_dir/bin && -d $is_sh_dir && -d $is_conf_dir ]] && {
- err "检测到脚本已安装, 如需重装请使用${green} ${is_core} reinstall ${none}命令."
- }
- # check parameters
- [[ $# -gt 0 ]] && pass_args $@
- # show welcome msg
- clear
- echo
- echo "........... $is_core_name script by $author .........."
- echo
- # start installing...
- msg warn "开始安装..."
- [[ $is_core_ver ]] && msg warn "${is_core_name} 版本: ${yellow}$is_core_ver${none}"
- [[ $proxy ]] && msg warn "使用代理: ${yellow}$proxy${none}"
- # create tmpdir
- mkdir -p $tmpdir
- # if is_core_file, copy file
- [[ $is_core_file ]] && {
- cp -f $is_core_file $is_core_ok
- msg warn "${yellow}${is_core_name} 文件使用 > $is_core_file${none}"
- }
- # local dir install sh script
- [[ $local_install ]] && {
- >$is_sh_ok
- msg warn "${yellow}本地获取安装脚本 > $PWD ${none}"
- }
- timedatectl set-ntp true &>/dev/null
- [[ $? != 0 ]] && {
- is_ntp_on=1
- }
- # install dependent pkg
- install_pkg $is_pkg &
- # jq
- if [[ $(type -P jq) ]]; then
- >$is_jq_ok
- else
- jq_not_found=1
- fi
- # if wget installed. download core, sh, jq, get ip
- [[ $is_wget ]] && {
- [[ ! $is_core_file ]] && download core &
- [[ ! $local_install ]] && download sh &
- [[ $jq_not_found ]] && download jq &
- get_ip
- }
- # waiting for background tasks is done
- wait
- # check background tasks status
- check_status
- # test $is_core_file
- if [[ $is_core_file ]]; then
- mkdir -p $tmpdir/testzip
- tar zxf $is_core_ok --strip-components 1 -C $tmpdir/testzip &>/dev/null
- [[ $? != 0 ]] && {
- msg err "${is_core_name} 文件无法通过测试."
- exit_and_del_tmpdir
- }
- [[ ! -f $tmpdir/testzip/$is_core ]] && {
- msg err "${is_core_name} 文件无法通过测试."
- exit_and_del_tmpdir
- }
- fi
- # get server ip.
- [[ ! $ip ]] && {
- msg err "获取服务器 IP 失败."
- exit_and_del_tmpdir
- }
- # create sh dir...
- mkdir -p $is_sh_dir
- # copy sh file or unzip sh zip file.
- if [[ $local_install ]]; then
- cp -rf $PWD/* $is_sh_dir
- else
- tar zxf $is_sh_ok -C $is_sh_dir
- fi
- # create core bin dir
- mkdir -p $is_core_dir/bin
- # copy core file or unzip core zip file
- if [[ $is_core_file ]]; then
- cp -rf $tmpdir/testzip/* $is_core_dir/bin
- else
- tar zxf $is_core_ok --strip-components 1 -C $is_core_dir/bin
- fi
- # add alias
- echo "alias sb=$is_sh_bin" >>/root/.bashrc
- echo "alias $is_core=$is_sh_bin" >>/root/.bashrc
- # core command
- ln -sf $is_sh_dir/$is_core.sh $is_sh_bin
- ln -sf $is_sh_dir/$is_core.sh ${is_sh_bin/$is_core/sb}
- # jq
- [[ $jq_not_found ]] && mv -f $is_jq_ok /usr/bin/jq
- # chmod
- chmod +x $is_core_bin $is_sh_bin /usr/bin/jq ${is_sh_bin/$is_core/sb}
- # create log dir
- mkdir -p $is_log_dir
- # show a tips msg
- msg ok "生成配置文件..."
- # create systemd service
- load systemd.sh
- is_new_install=1
- install_service $is_core &>/dev/null
- # create condf dir
- mkdir -p $is_conf_dir
- load core.sh
- # create a reality config
- add reality
- # remove tmp dir and exit.
- exit_and_del_tmpdir ok
- }
- # start.
- main $@
|