diff --git a/install-release.sh b/install-release.sh new file mode 100644 index 0000000..68c5cb1 --- /dev/null +++ b/install-release.sh @@ -0,0 +1,474 @@ +#!/bin/bash + +# This file is accessible as https://install.direct/go.sh +# Original source is located at github.com/v2ray/v2ray-core/release/install-release.sh + +# If not specify, default meaning of return value: +# 0: Success +# 1: System error +# 2: Application error +# 3: Network error + +CUR_VER="" +NEW_VER="" +ARCH="" +VDIS="64" +ZIPFILE="/tmp/v2ray/v2ray.zip" +V2RAY_RUNNING=0 +VSRC_ROOT="/tmp/v2ray" +EXTRACT_ONLY=0 +ERROR_IF_UPTODATE=0 +DIST_SRC="github" + +CMD_INSTALL="" +CMD_UPDATE="" +SOFTWARE_UPDATED=0 + +SYSTEMCTL_CMD=$(command -v systemctl 2>/dev/null) +SERVICE_CMD=$(command -v service 2>/dev/null) + +CHECK="" +FORCE="" +HELP="" + +#######color code######## +RED="31m" # Error message +GREEN="32m" # Success message +YELLOW="33m" # Warning message +BLUE="36m" # Info message + + +######################### +while [[ $# > 0 ]];do + key="$1" + case $key in + -p|--proxy) + PROXY="-x ${2}" + shift # past argument + ;; + -h|--help) + HELP="1" + ;; + -f|--force) + FORCE="1" + ;; + -c|--check) + CHECK="1" + ;; + --remove) + REMOVE="1" + ;; + --version) + VERSION="$2" + shift + ;; + --extract) + VSRC_ROOT="$2" + shift + ;; + --extractonly) + EXTRACT_ONLY="1" + ;; + -l|--local) + LOCAL="$2" + LOCAL_INSTALL="1" + shift + ;; + --source) + DIST_SRC="$2" + shift + ;; + --errifuptodate) + ERROR_IF_UPTODATE="1" + ;; + *) + # unknown option + ;; + esac + shift # past argument or value +done + +############################### +colorEcho(){ + COLOR=$1 + echo -e "\033[${COLOR}${@:2}\033[0m" +} + +sysArch(){ + ARCH=$(uname -m) + if [[ "$ARCH" == "i686" ]] || [[ "$ARCH" == "i386" ]]; then + VDIS="32" + elif [[ "$ARCH" == *"armv7"* ]] || [[ "$ARCH" == "armv6l" ]]; then + VDIS="arm" + elif [[ "$ARCH" == *"armv8"* ]] || [[ "$ARCH" == "aarch64" ]]; then + VDIS="arm64" + elif [[ "$ARCH" == *"mips64le"* ]]; then + VDIS="mips64le" + elif [[ "$ARCH" == *"mips64"* ]]; then + VDIS="mips64" + elif [[ "$ARCH" == *"mipsle"* ]]; then + VDIS="mipsle" + elif [[ "$ARCH" == *"mips"* ]]; then + VDIS="mips" + elif [[ "$ARCH" == *"s390x"* ]]; then + VDIS="s390x" + elif [[ "$ARCH" == "ppc64le" ]]; then + VDIS="ppc64le" + elif [[ "$ARCH" == "ppc64" ]]; then + VDIS="ppc64" + fi + return 0 +} + +downloadV2Ray(){ + rm -rf /tmp/v2ray + mkdir -p /tmp/v2ray + if [[ "${DIST_SRC}" == "jsdelivr" ]]; then + DOWNLOAD_LINK="https://cdn.jsdelivr.net/gh/v2ray/dist/v2ray-linux-${VDIS}.zip" + else + DOWNLOAD_LINK="https://github.com/v2ray/v2ray-core/releases/download/${NEW_VER}/v2ray-linux-${VDIS}.zip" + fi + colorEcho ${BLUE} "Downloading V2Ray: ${DOWNLOAD_LINK}" + curl ${PROXY} -L -H "Cache-Control: no-cache" -o ${ZIPFILE} ${DOWNLOAD_LINK} + if [ $? != 0 ];then + colorEcho ${RED} "Failed to download! Please check your network or try again." + return 3 + fi + return 0 +} + +installSoftware(){ + COMPONENT=$1 + if [[ -n `command -v $COMPONENT` ]]; then + return 0 + fi + + getPMT + if [[ $? -eq 1 ]]; then + colorEcho ${RED} "The system package manager tool isn't APT or YUM, please install ${COMPONENT} manually." + return 1 + fi + if [[ $SOFTWARE_UPDATED -eq 0 ]]; then + colorEcho ${BLUE} "Updating software repo" + $CMD_UPDATE + SOFTWARE_UPDATED=1 + fi + + colorEcho ${BLUE} "Installing ${COMPONENT}" + $CMD_INSTALL $COMPONENT + if [[ $? -ne 0 ]]; then + colorEcho ${RED} "Failed to install ${COMPONENT}. Please install it manually." + return 1 + fi + return 0 +} + +# return 1: not apt, yum, or zypper +getPMT(){ + if [[ -n `command -v apt-get` ]];then + CMD_INSTALL="apt-get -y -qq install" + CMD_UPDATE="apt-get -qq update" + elif [[ -n `command -v yum` ]]; then + CMD_INSTALL="yum -y -q install" + CMD_UPDATE="yum -q makecache" + elif [[ -n `command -v zypper` ]]; then + CMD_INSTALL="zypper -y install" + CMD_UPDATE="zypper ref" + else + return 1 + fi + return 0 +} + +extract(){ + colorEcho ${BLUE}"Extracting V2Ray package to /tmp/v2ray." + mkdir -p /tmp/v2ray + unzip $1 -d ${VSRC_ROOT} + if [[ $? -ne 0 ]]; then + colorEcho ${RED} "Failed to extract V2Ray." + return 2 + fi + if [[ -d "/tmp/v2ray/v2ray-${NEW_VER}-linux-${VDIS}" ]]; then + VSRC_ROOT="/tmp/v2ray/v2ray-${NEW_VER}-linux-${VDIS}" + fi + return 0 +} + + +# 1: new V2Ray. 0: no. 2: not installed. 3: check failed. 4: don't check. +getVersion(){ + if [[ -n "$VERSION" ]]; then + NEW_VER="$VERSION" + if [[ ${NEW_VER} != v* ]]; then + NEW_VER=v${NEW_VER} + fi + return 4 + else + VER=`/usr/bin/v2ray/v2ray -version 2>/dev/null` + RETVAL="$?" + CUR_VER=`echo $VER | head -n 1 | cut -d " " -f2` + if [[ ${CUR_VER} != v* ]]; then + CUR_VER=v${CUR_VER} + fi + TAG_URL="https://api.github.com/repos/v2ray/v2ray-core/releases/latest" + NEW_VER=`curl ${PROXY} -s ${TAG_URL} --connect-timeout 10| grep 'tag_name' | cut -d\" -f4` + if [[ ${NEW_VER} != v* ]]; then + NEW_VER=v${NEW_VER} + fi + if [[ $? -ne 0 ]] || [[ $NEW_VER == "" ]]; then + colorEcho ${RED} "Failed to fetch release information. Please check your network or try again." + return 3 + elif [[ $RETVAL -ne 0 ]];then + return 2 + elif [[ $NEW_VER != $CUR_VER ]];then + return 1 + fi + return 0 + fi +} + +stopV2ray(){ + colorEcho ${BLUE} "Shutting down V2Ray service." + if [[ -n "${SYSTEMCTL_CMD}" ]] || [[ -f "/lib/systemd/system/v2ray.service" ]] || [[ -f "/etc/systemd/system/v2ray.service" ]]; then + ${SYSTEMCTL_CMD} stop v2ray + elif [[ -n "${SERVICE_CMD}" ]] || [[ -f "/etc/init.d/v2ray" ]]; then + ${SERVICE_CMD} v2ray stop + fi + if [[ $? -ne 0 ]]; then + colorEcho ${YELLOW} "Failed to shutdown V2Ray service." + return 2 + fi + return 0 +} + +startV2ray(){ + if [ -n "${SYSTEMCTL_CMD}" ] && [ -f "/lib/systemd/system/v2ray.service" ]; then + ${SYSTEMCTL_CMD} start v2ray + elif [ -n "${SYSTEMCTL_CMD}" ] && [ -f "/etc/systemd/system/v2ray.service" ]; then + ${SYSTEMCTL_CMD} start v2ray + elif [ -n "${SERVICE_CMD}" ] && [ -f "/etc/init.d/v2ray" ]; then + ${SERVICE_CMD} v2ray start + fi + if [[ $? -ne 0 ]]; then + colorEcho ${YELLOW} "Failed to start V2Ray service." + return 2 + fi + return 0 +} + +copyFile() { + NAME=$1 + if [[ "${NAME}" == v2ray ]] || [[ "${NAME}" == v2ctl ]]; then + ERROR=`cp "${VSRC_ROOT}/${NAME}" "/usr/local/bin/$NAME"` + elif [[ "${NAME}" == geoip.dat ]] || [[ "${NAME}" == geosite.dat ]]; then + ERROR=`cp "${VSRC_ROOT}/${NAME}" "/usr/local/lib/v2ray/$NAME"` + fi + if [[ $? -ne 0 ]]; then + colorEcho ${YELLOW} "${ERROR}" + return 1 + fi + return 0 +} + +makeExecutable() { + chmod +x "/usr/local/bin/$1" +} + +installV2Ray(){ + # Install V2Ray binary to /usr/local/bin and /usr/local/lib/v2ray + copyFile v2ray + if [[ $? -ne 0 ]]; then + colorEcho ${RED} "Failed to copy V2Ray binary and resources." + return 1 + fi + makeExecutable v2ray + copyFile v2ctl && makeExecutable v2ctl + mkdir /usr/local/lib/v2ray + copyFile geoip.dat + copyFile geosite.dat + + # Install V2Ray server config to /etc/v2ray + if [[ ! -f "/usr/local/etc/v2ray/config.json" ]]; then + mkdir -p /usr/local/etc/v2ray + mkdir -p /var/log/v2ray + cp "${VSRC_ROOT}/vpoint_vmess_freedom.json" "/usr/local/etc/v2ray/config.json" + if [[ $? -ne 0 ]]; then + colorEcho ${YELLOW} "Failed to create V2Ray configuration file. Please create it manually." + return 1 + fi + let PORT=$RANDOM+10000 + UUID=$(cat /proc/sys/kernel/random/uuid) + + sed -i "s/10086/${PORT}/g" "/usr/local/etc/v2ray/config.json" + sed -i "s/23ad6b10-8d1a-40f7-8ad0-e3e35cd38297/${UUID}/g" "/usr/local/etc/v2ray/config.json" + + colorEcho ${BLUE} "PORT:${PORT}" + colorEcho ${BLUE} "UUID:${UUID}" + fi + return 0 +} + + +installInitScript(){ + if [[ -n "${SYSTEMCTL_CMD}" ]];then + if [[ ! -f "/etc/systemd/system/v2ray.service" ]]; then + if [[ ! -f "/lib/systemd/system/v2ray.service" ]]; then + curl -o "${VSRC_ROOT}/systemd/v2ray.service" https://raw.githubusercontent.workers.dev/v2fly/fhs-install-v2ray/master/systemd/v2ray.service + cp "${VSRC_ROOT}/systemd/v2ray.service" "/etc/systemd/system/" + systemctl enable v2ray.service + fi + fi + return + elif [[ -n "${SERVICE_CMD}" ]] && [[ ! -f "/etc/init.d/v2ray" ]]; then + installSoftware "daemon" || return $? + curl -o "${VSRC_ROOT}/systemv/v2ray" https://raw.githubusercontent.workers.dev/v2fly/fhs-install-v2ray/master/systemv/v2ray + cp "${VSRC_ROOT}/systemv/v2ray" "/etc/init.d/v2ray" + chmod +x "/etc/init.d/v2ray" + update-rc.d v2ray defaults + fi + return +} + +Help(){ + echo "./install-release.sh [-h] [-c] [--remove] [-p proxy] [-f] [--version vx.y.z] [-l file]" + echo " -h, --help Show help" + echo " -p, --proxy To download through a proxy server, use -p socks5://127.0.0.1:1080 or -p http://127.0.0.1:3128 etc" + echo " -f, --force Force install" + echo " --version Install a particular version, use --version v3.15" + echo " -l, --local Install from a local file" + echo " --remove Remove installed V2Ray" + echo " -c, --check Check for update" + return 0 +} + +remove(){ + if [[ -n "${SYSTEMCTL_CMD}" ]] && [[ -f "/etc/systemd/system/v2ray.service" ]];then + if pgrep "v2ray" > /dev/null ; then + stopV2ray + fi + systemctl disable v2ray.service + rm -rf "/usr/bin/v2ray" "/etc/systemd/system/v2ray.service" + if [[ $? -ne 0 ]]; then + colorEcho ${RED} "Failed to remove V2Ray." + return 0 + else + colorEcho ${GREEN} "Removed V2Ray successfully." + colorEcho ${BLUE} "If necessary, please remove configuration file and log file manually." + return 0 + fi + elif [[ -n "${SYSTEMCTL_CMD}" ]] && [[ -f "/lib/systemd/system/v2ray.service" ]];then + if pgrep "v2ray" > /dev/null ; then + stopV2ray + fi + systemctl disable v2ray.service + rm -rf "/usr/bin/v2ray" "/lib/systemd/system/v2ray.service" + if [[ $? -ne 0 ]]; then + colorEcho ${RED} "Failed to remove V2Ray." + return 0 + else + colorEcho ${GREEN} "Removed V2Ray successfully." + colorEcho ${BLUE} "If necessary, please remove configuration file and log file manually." + return 0 + fi + elif [[ -n "${SERVICE_CMD}" ]] && [[ -f "/etc/init.d/v2ray" ]]; then + if pgrep "v2ray" > /dev/null ; then + stopV2ray + fi + rm -rf "/usr/bin/v2ray" "/etc/init.d/v2ray" + if [[ $? -ne 0 ]]; then + colorEcho ${RED} "Failed to remove V2Ray." + return 0 + else + colorEcho ${GREEN} "Removed V2Ray successfully." + colorEcho ${BLUE} "If necessary, please remove configuration file and log file manually." + return 0 + fi + else + colorEcho ${YELLOW} "V2Ray not found." + return 0 + fi +} + +checkUpdate(){ + echo "Checking for update." + VERSION="" + getVersion + RETVAL="$?" + if [[ $RETVAL -eq 1 ]]; then + colorEcho ${BLUE} "Found new version ${NEW_VER} for V2Ray.(Current version:$CUR_VER)" + elif [[ $RETVAL -eq 0 ]]; then + colorEcho ${BLUE} "No new version. Current version is ${NEW_VER}." + elif [[ $RETVAL -eq 2 ]]; then + colorEcho ${YELLOW} "No V2Ray installed." + colorEcho ${BLUE} "The newest version for V2Ray is ${NEW_VER}." + fi + return 0 +} + +main(){ + #helping information + [[ "$HELP" == "1" ]] && Help && return + [[ "$CHECK" == "1" ]] && checkUpdate && return + [[ "$REMOVE" == "1" ]] && remove && return + + sysArch + # extract local file + if [[ $LOCAL_INSTALL -eq 1 ]]; then + colorEcho ${YELLOW} "Installing V2Ray via local file. Please make sure the file is a valid V2Ray package, as we are not able to determine that." + NEW_VER=local + installSoftware unzip || return $? + rm -rf /tmp/v2ray + extract $LOCAL || return $? + #FILEVDIS=`ls /tmp/v2ray |grep v2ray-v |cut -d "-" -f4` + #SYSTEM=`ls /tmp/v2ray |grep v2ray-v |cut -d "-" -f3` + #if [[ ${SYSTEM} != "linux" ]]; then + # colorEcho ${RED} "The local V2Ray can not be installed in linux." + # return 1 + #elif [[ ${FILEVDIS} != ${VDIS} ]]; then + # colorEcho ${RED} "The local V2Ray can not be installed in ${ARCH} system." + # return 1 + #else + # NEW_VER=`ls /tmp/v2ray |grep v2ray-v |cut -d "-" -f2` + #fi + else + # download via network and extract + installSoftware "curl" || return $? + getVersion + RETVAL="$?" + if [[ $RETVAL == 0 ]] && [[ "$FORCE" != "1" ]]; then + colorEcho ${BLUE} "Latest version ${CUR_VER} is already installed." + if [[ "${ERROR_IF_UPTODATE}" == "1" ]]; then + return 10 + fi + return + elif [[ $RETVAL == 3 ]]; then + return 3 + else + colorEcho ${BLUE} "Installing V2Ray ${NEW_VER} on ${ARCH}" + downloadV2Ray || return $? + installSoftware unzip || return $? + extract ${ZIPFILE} || return $? + fi + fi + + if [[ "${EXTRACT_ONLY}" == "1" ]]; then + colorEcho ${GREEN} "V2Ray extracted to ${VSRC_ROOT}, and exiting..." + return 0 + fi + + if pgrep "v2ray" > /dev/null ; then + V2RAY_RUNNING=1 + stopV2ray + fi + installV2Ray || return $? + installInitScript || return $? + if [[ ${V2RAY_RUNNING} -eq 1 ]];then + colorEcho ${BLUE} "Restarting V2Ray service." + startV2ray + fi + colorEcho ${GREEN} "V2Ray ${NEW_VER} is installed." + rm -rf /tmp/v2ray + return 0 +} + +main diff --git a/systemd/v2ray.service b/systemd/v2ray.service new file mode 100644 index 0000000..56c707c --- /dev/null +++ b/systemd/v2ray.service @@ -0,0 +1,20 @@ +[Unit] +Description=V2Ray Service +After=network.target +Wants=network.target + +[Service] +# This service runs as root. You may consider to run it as another user for security concerns. +# By uncommenting the following two lines, this service will run as user v2ray/v2ray. +# More discussion at https://github.com/v2ray/v2ray-core/issues/1011 +# User=v2ray +# Group=v2ray +Type=simple +PIDFile=/run/v2ray.pid +ExecStart=/usr/local/bin/v2ray -config /usr/local/etc/v2ray/config.json +Restart=on-failure +# Don't restart in the case of configuration error +RestartPreventExitStatus=23 + +[Install] +WantedBy=multi-user.target diff --git a/systemv/v2ray b/systemv/v2ray new file mode 100644 index 0000000..64f8e61 --- /dev/null +++ b/systemv/v2ray @@ -0,0 +1,150 @@ +#!/bin/sh +### BEGIN INIT INFO +# Provides: v2ray +# Required-Start: $network $local_fs $remote_fs +# Required-Stop: $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: V2Ray proxy services +# Description: V2Ray proxy services +### END INIT INFO + +# Acknowledgements: Isulew Li + +DESC=v2ray +NAME=v2ray +DAEMON=/usr/local/bin/v2ray +PIDFILE=/var/run/$NAME.pid +SCRIPTNAME=/etc/init.d/$NAME + +DAEMON_OPTS="-config /usr/local/etc/v2ray/config.json" + +# Exit if the package is not installed +[ -x $DAEMON ] || exit 0 + +# Read configuration variable file if it is present +[ -r /etc/default/$NAME ] && . /etc/default/$NAME + +# Load the VERBOSE setting and other rcS variables +. /lib/init/vars.sh + +# Define LSB log_* functions. +# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. +. /lib/lsb/init-functions + +# +# Function that starts the daemon/service +# +do_start() +{ + mkdir -p /var/log/v2ray + # Return + # 0 if daemon has been started + # 1 if daemon was already running + # 2 if daemon could not be started + # 3 if configuration file not ready for daemon + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --background -m -- $DAEMON_OPTS \ + || return 2 + # Add code here, if necessary, that waits for the process to be ready + # to handle requests from services started subsequently which depend + # on this one. As a last resort, sleep for some time. +} + +# +# Function that stops the daemon/service +# +do_stop() +{ + # Return + # 0 if daemon has been stopped + # 1 if daemon was already stopped + # 2 if daemon could not be stopped + # other if a failure occurred + start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE + RETVAL="$?" + [ "$RETVAL" = 2 ] && return 2 + # Wait for children to finish too if this is a daemon that forks + # and if the daemon is only ever run from this initscript. + # If the above conditions are not satisfied then add some other code + # that waits for the process to drop all resources that could be + # needed by services started subsequently. A last resort is to + # sleep for some time. + start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON + [ "$?" = 2 ] && return 2 + # Many daemons don't delete their pidfiles when they exit. + rm -f $PIDFILE + return "$RETVAL" +} + +# +# Function that sends a SIGHUP to the daemon/service +# +do_reload() { + # + # If the daemon can reload its configuration without + # restarting (for example, when it is sent a SIGHUP), + # then implement that here. + # + start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE + return 0 +} + +case "$1" in + start) + [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME" + do_start + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + stop) + [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" + do_stop + case "$?" in + 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; + 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; + esac + ;; + status) + status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? + ;; + reload|force-reload) + # + # If do_reload() is not implemented then leave this commented out + # and leave 'force-reload' as an alias for 'restart'. + # + log_daemon_msg "Reloading $DESC" "$NAME" + do_reload + log_end_msg $? + ;; + restart|force-reload) + # + # If the "reload" option is implemented then remove the + # 'force-reload' alias + # + log_daemon_msg "Restarting $DESC" "$NAME" + do_stop + case "$?" in + 0|1) + do_start + case "$?" in + 0) log_end_msg 0 ;; + 1) log_end_msg 1 ;; # Old process is still running + *) log_end_msg 1 ;; # Failed to start + esac + ;; + *) + # Failed to stop + log_end_msg 1 + ;; + esac + ;; + *) + #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 + echo "Usage: $SCRIPTNAME {start|stop|status|reload|restart|force-reload}" >&2 + exit 3 + ;; +esac