Last active
August 23, 2020 02:16
-
-
Save wznpp1/47f44bfd710a5473ddcd98e963822883 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin | |
export PATH | |
#=================================================================# | |
# System Required: CentOS 7, Debian, Ubuntu # | |
# Description: Script of Install ShadowsocksR Native Server # | |
# Author: ssrlive # | |
#=================================================================# | |
proj_name="ShadowsocksR Native" | |
daemon_script_url="https://raw.githubusercontent.com/ShadowsocksR-Live/shadowsocksr-native/master/install/ssr-daemon.sh" | |
target_dir=/usr/bin | |
config_dir=/etc/ssr-native | |
service_dir=/lib/systemd/system | |
service_name=ssr-native | |
service_stub=/etc/init.d/${service_name} | |
bin_name=ssr-server | |
over_tls_mode=false | |
host_public_ip="" | |
client_connect_port=0 | |
shadowsocksport=13173 | |
shadowsockspwd="lzhrwwc1" | |
shadowsockscipher="chacha20" | |
shadowsockprotocol="auth_aes128_sha1" | |
shadowsockobfs="http_simple" | |
#Current folder | |
cur_dir=`pwd` | |
cmd_success=0 | |
cmd_failed=1 | |
# Stream Ciphers | |
ciphers=( | |
none | |
table | |
rc4 | |
rc4-md5-6 | |
rc4-md5 | |
aes-128-cfb | |
aes-192-cfb | |
aes-256-cfb | |
aes-128-ctr | |
aes-192-ctr | |
aes-256-ctr | |
bf-cfb | |
camellia-128-cfb | |
camellia-192-cfb | |
camellia-256-cfb | |
salsa20 | |
chacha20 | |
chacha20-ietf | |
) | |
# Reference URL: | |
# https://github.com/shadowsocksr-rm/shadowsocks-rss/blob/master/ssr.md | |
# Protocol | |
protocols=( | |
origin | |
auth_sha1_v4 | |
auth_aes128_md5 | |
auth_aes128_sha1 | |
auth_chain_a | |
auth_chain_b | |
auth_chain_c | |
auth_chain_d | |
auth_chain_e | |
auth_chain_f | |
) | |
# obfs | |
obfs=( | |
plain | |
http_simple | |
http_post | |
tls1.2_ticket_auth | |
tls1.2_ticket_fastauth | |
) | |
# Color | |
red='\033[0;31m' | |
green='\033[0;32m' | |
yellow='\033[0;33m' | |
plain='\033[0m' | |
# Disable selinux | |
function disable_selinux() { | |
if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then | |
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config | |
setenforce 0 | |
fi | |
} | |
#Check system | |
function check_sys() { | |
local checkType=${1} | |
local value=${2} | |
local release='' | |
local systemPackage='' | |
if [[ -f /etc/redhat-release ]]; then | |
release="centos" | |
systemPackage="yum" | |
elif grep -Eqi "debian" /etc/issue; then | |
release="debian" | |
systemPackage="apt" | |
elif grep -Eqi "ubuntu" /etc/issue; then | |
release="ubuntu" | |
systemPackage="apt" | |
elif grep -Eqi "centos|red hat|redhat" /etc/issue; then | |
release="centos" | |
systemPackage="yum" | |
elif grep -Eqi "debian" /proc/version; then | |
release="debian" | |
systemPackage="apt" | |
elif grep -Eqi "ubuntu" /proc/version; then | |
release="ubuntu" | |
systemPackage="apt" | |
elif grep -Eqi "centos|red hat|redhat" /proc/version; then | |
release="centos" | |
systemPackage="yum" | |
fi | |
if [[ "${checkType}" == "sysRelease" ]]; then | |
if [ "${value}" == "${release}" ]; then | |
return ${cmd_success} | |
else | |
return ${cmd_failed} | |
fi | |
elif [[ "${checkType}" == "packageManager" ]]; then | |
if [ "${value}" == "${systemPackage}" ]; then | |
return ${cmd_success} | |
else | |
return ${cmd_failed} | |
fi | |
fi | |
} | |
# Get version | |
function get_version() { | |
if [[ -s /etc/redhat-release ]]; then | |
grep -oE "[0-9.]+" /etc/redhat-release | |
else | |
grep -oE "[0-9.]+" /etc/issue | |
fi | |
} | |
# CentOS version | |
function centosversion() { | |
if check_sys sysRelease centos; then | |
local code=${1} | |
local version="$(get_version)" | |
local main_ver=${version%%.*} | |
if [ "${main_ver}" == "${code}" ]; then | |
return ${cmd_success} | |
else | |
return ${cmd_failed} | |
fi | |
else | |
return ${cmd_failed} | |
fi | |
} | |
# Get public IP address | |
function get_ip() { | |
local IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 ) | |
[ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipv4.icanhazip.com ) | |
[ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipinfo.io/ip ) | |
[ ! -z ${IP} ] && echo ${IP} || echo | |
} | |
function get_char() { | |
SAVEDSTTY=`stty -g` | |
stty -echo | |
stty cbreak | |
dd if=/dev/tty bs=1 count=1 2> /dev/null | |
stty -raw | |
stty echo | |
stty $SAVEDSTTY | |
} | |
function random_string_gen() { | |
local PASS="" | |
local MATRIX="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" # "~!@#$%^&*()_+=" | |
local LENGTH=$1 | |
[ -z $1 ] && LENGTH="16" | |
while [ "${n:=1}" -le "$LENGTH" ] | |
do | |
PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}" | |
let n+=1 | |
done | |
echo ${PASS} | |
} | |
# Pre-installation settings | |
function pre_install() { | |
if check_sys packageManager yum || check_sys packageManager apt; then | |
# Not support CentOS 5, 6 | |
if centosversion 5 || centosversion 6; then | |
echo -e "$[{red}Error${plain}] Not supported CentOS 5, 6, please change to CentOS 7+/Debian 7+/Ubuntu 12+ and try again." | |
exit 1 | |
fi | |
else | |
echo -e "[${red}Error${plain}] Your OS is not supported. please change OS to CentOS/Debian/Ubuntu and try again." | |
exit 1 | |
fi | |
# Set ShadowsocksR config password | |
echo "Please enter password for ${proj_name}:" | |
rnd_psw='lzhrwwc1' | |
read -p "(Default password: lzhrwwc1):" shadowsockspwd | |
[ -z "${shadowsockspwd}" ] && shadowsockspwd=${rnd_psw} | |
echo | |
echo "---------------------------" | |
echo "password = ${shadowsockspwd}" | |
echo "---------------------------" | |
echo | |
# Set ShadowsocksR config port | |
if [ ${over_tls_mode} = true ] ; then | |
shadowsocksport=${web_svr_reverse_proxy_port} | |
client_connect_port=${web_svr_listen_port} | |
else | |
local ssr_port=0 | |
while true; do | |
dport=13173 | |
echo -e "Please enter a port for ${proj_name} [1-65535]" | |
read -p "(Default port: 13173):" ssr_port | |
[ -z "${ssr_port}" ] && ssr_port=${dport} | |
expr ${ssr_port} + 1 &>/dev/null | |
if [ $? -eq 0 ]; then | |
if [ ${ssr_port} -ge 1 ] && [ ${ssr_port} -le 65535 ] && [ ${ssr_port:0:1} != 0 ]; then | |
break | |
fi | |
fi | |
echo -e "[${red}Error${plain}] Please enter a correct number [1-65535]" | |
done | |
echo | |
echo "---------------------------" | |
echo "port = ${ssr_port}" | |
echo "---------------------------" | |
echo | |
shadowsocksport=${ssr_port} | |
client_connect_port=${ssr_port} | |
fi | |
# Set shadowsocksR config stream ciphers | |
while true ; do | |
echo -e "Please select stream cipher for ${proj_name}:" | |
for (( i=1; i<=${#ciphers[@]}; i++ )); do | |
hint="${ciphers[$i-1]}" | |
# echo -e "${green}${i}${plain}) ${hint}" | |
printf "%2d) %s\n" ${i} ${hint} | |
done | |
read -p "Which cipher you'd select(Default: ${ciphers[16]}):" pick | |
[ -z "$pick" ] && pick=17 | |
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 "[${red}Error${plain}] Please enter a number between 1 and ${#ciphers[@]}" | |
continue | |
fi | |
shadowsockscipher=${ciphers[$pick-1]} | |
break | |
done | |
echo | |
echo "---------------------------" | |
echo "cipher = ${shadowsockscipher}" | |
echo "---------------------------" | |
echo | |
# Set shadowsocksR config protocol | |
while true ; do | |
echo -e "Please select protocol for ${proj_name}:" | |
for ((i=1;i<=${#protocols[@]};i++ )); do | |
hint="${protocols[$i-1]}" | |
# echo -e "${green}${i}${plain}) ${hint}" | |
printf "%2d) %s\n" ${i} ${hint} | |
done | |
read -p "Which protocol you'd select(Default: ${protocols[3]}):" protocol | |
[ -z "$protocol" ] && protocol=4 | |
expr ${protocol} + 1 &>/dev/null | |
if [ $? -ne 0 ]; then | |
echo -e "[${red}Error${plain}] Input error, please input a number" | |
continue | |
fi | |
if [[ "$protocol" -lt 1 || "$protocol" -gt ${#protocols[@]} ]]; then | |
echo -e "[${red}Error${plain}] Input error, please input a number between 1 and ${#protocols[@]}" | |
continue | |
fi | |
shadowsockprotocol=${protocols[$protocol-1]} | |
break | |
done | |
echo | |
echo "---------------------------" | |
echo "protocol = ${shadowsockprotocol}" | |
echo "---------------------------" | |
echo | |
# Set shadowsocksR config obfs | |
while true ; do | |
echo -e "Please select obfs for ${proj_name}:" | |
for ((i=1;i<=${#obfs[@]};i++ )); do | |
hint="${obfs[$i-1]}" | |
echo -e "${green}${i}${plain}) ${hint}" | |
done | |
read -p "Which obfs you'd select(Default: ${obfs[1]}):" r_obfs | |
[ -z "$r_obfs" ] && r_obfs=2 | |
expr ${r_obfs} + 1 &>/dev/null | |
if [ $? -ne 0 ]; then | |
echo -e "[${red}Error${plain}] Input error, please input a number" | |
continue | |
fi | |
if [[ "$r_obfs" -lt 1 || "$r_obfs" -gt ${#obfs[@]} ]]; then | |
echo -e "[${red}Error${plain}] Input error, please input a number between 1 and ${#obfs[@]}" | |
continue | |
fi | |
shadowsockobfs=${obfs[$r_obfs-1]} | |
break | |
done | |
echo | |
echo "---------------------------" | |
echo "obfs = ${shadowsockobfs}" | |
echo "---------------------------" | |
echo | |
} | |
function install_build_tools() { | |
if check_sys sysRelease debian ; then | |
apt-get remove upstart -y | |
apt-get remove udev -y | |
apt-get autoremove -y | |
fi | |
# Install necessary dependencies | |
if check_sys packageManager yum; then | |
yum install wget curl git gcc gcc-c++ gdb autoconf automake libtool make asciidoc xmlto -y | |
elif check_sys packageManager apt; then | |
apt-get -f install -y | |
apt-get -y update | |
apt-get -y upgrade | |
apt-get -y install --no-install-recommends build-essential autoconf libtool asciidoc xmlto | |
apt-get -y install git gcc g++ gdb wget curl automake | |
fi | |
curl https://cmake.org/files/v3.17/cmake-3.17.0-Linux-x86_64.sh -o cmake_pkg.sh | |
sh cmake_pkg.sh --prefix=/usr/ --exclude-subdir && rm -rf cmake_pkg.sh | |
} | |
function build_ssr_native() { | |
git clone https://github.com/ShadowsocksR-Live/shadowsocksr-native.git | |
cd shadowsocksr-native | |
git submodule update --init | |
git submodule foreach -q 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)' | |
# build ShadowsocksR-native | |
cmake . && make | |
cd .. | |
/bin/cp -rfa ./shadowsocksr-native/src/${bin_name} ${target_dir} | |
rm -rf shadowsocksr-native | |
} | |
# Firewall set | |
function firewall_settings() { | |
local target_port=$1 | |
echo -e "[${green}Info${plain}] firewall set start..." | |
if centosversion 6; then | |
/etc/init.d/iptables status > /dev/null 2>&1 | |
if [ $? -eq 0 ]; then | |
iptables -L -n | grep -i ${target_port} > /dev/null 2>&1 | |
if [ $? -ne 0 ]; then | |
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport ${target_port} -j ACCEPT | |
iptables -I INPUT -m state --state NEW -m udp -p udp --dport ${target_port} -j ACCEPT | |
/etc/init.d/iptables save | |
/etc/init.d/iptables restart | |
else | |
echo -e "[${green}Info${plain}] port ${target_port} has been set up." | |
fi | |
else | |
echo -e "[${yellow}Warning${plain}] iptables looks like shutdown or not installed, please manually set it if necessary." | |
fi | |
elif centosversion 7; then | |
systemctl status firewalld > /dev/null 2>&1 | |
if [ $? -eq 0 ]; then | |
firewall-cmd --permanent --zone=public --add-port=${target_port}/tcp | |
firewall-cmd --permanent --zone=public --add-port=${target_port}/udp | |
firewall-cmd --reload | |
else | |
echo -e "[${yellow}Warning${plain}] firewalld looks like not running or not installed, please enable port ${target_port} manually if necessary." | |
fi | |
fi | |
echo -e "[${green}Info${plain}] firewall set completed..." | |
} | |
# Config ShadowsocksR | |
function write_ssr_config() { | |
[ ! -d ${config_dir} ] && mkdir ${config_dir} | |
local ssr_ot_flag="false" | |
if [ ${over_tls_mode} = true ] ; then | |
ssr_ot_flag="true" | |
fi | |
cat > ${config_dir}/config.json <<-EOF | |
{ | |
"password": "${shadowsockspwd}", | |
"method": "${shadowsockscipher}", | |
"protocol": "${shadowsockprotocol}", | |
"protocol_param": "", | |
"obfs": "${shadowsockobfs}", | |
"obfs_param": "", | |
"udp": ${ssr_ot_flag}, | |
"idle_timeout": 300, | |
"connect_timeout": 6, | |
"udp_timeout": 6, | |
"server_settings": { | |
"listen_address": "0.0.0.0", | |
"listen_port": ${shadowsocksport} | |
}, | |
"client_settings": { | |
"server": "${host_public_ip}", | |
"server_port": ${client_connect_port}, | |
"listen_address": "0.0.0.0", | |
"listen_port": 1080 | |
}, | |
"over_tls_settings": { | |
"enable": ${ssr_ot_flag}, | |
"server_domain": "${web_svr_domain}", | |
"path": "/${reverse_proxy_location}/", | |
"root_cert_file": "" | |
} | |
} | |
EOF | |
} | |
function write_service_description_file() { | |
local svc_name=${1} | |
local svc_stub=${2} | |
cat > ${service_dir}/${svc_name}.service <<-EOF | |
[Unit] | |
Description=${svc_name} | |
After=network.target | |
[Service] | |
Type=forking | |
ExecStart=${svc_stub} start | |
ExecReload=${svc_stub} restart | |
ExecStop=${svc_stub} stop | |
PrivateTmp=true | |
Restart=on-failure | |
RestartSec=35s | |
LimitNOFILE=1000000 | |
LimitCORE=infinity | |
[Install] | |
WantedBy=multi-user.target | |
EOF | |
chmod 754 ${service_dir}/${svc_name}.service | |
} | |
# Install ShadowsocksR Native | |
function install_ssr_service() { | |
ldconfig | |
# Install ShadowsocksR Native | |
cd ${cur_dir} | |
if [ -f ${target_dir}/${bin_name} ]; then | |
# Download ShadowsocksR Native service script | |
if ! wget --no-check-certificate ${daemon_script_url} -O ${service_stub} ; then | |
echo -e "[${red}Error${plain}] Failed to download ${proj_name} Native chkconfig file!" | |
exit 1 | |
fi | |
chmod +x ${service_stub} | |
if check_sys packageManager yum; then | |
chkconfig --add ${service_name} | |
chkconfig ${service_name} on | |
elif check_sys packageManager apt; then | |
update-rc.d -f ${service_name} defaults | |
fi | |
write_service_description_file ${service_name} ${service_stub} | |
# ${service_stub} start | |
systemctl enable ${service_name}.service | |
systemctl start ${service_name}.service | |
if [ ${over_tls_mode} = true ] ; then | |
echo | |
echo "======== config.json ========" | |
echo | |
cat ${config_dir}/config.json | |
echo | |
echo "=============================" | |
echo | |
else | |
# clear | |
echo | |
echo -e "Congratulations, ${proj_name} server install completed!" | |
echo -e "Your Server IP : \033[41;37m ${host_public_ip} \033[0m" | |
echo -e "Your Server Port : \033[41;37m ${client_connect_port} \033[0m" | |
echo -e "Your Password : \033[41;37m ${shadowsockspwd} \033[0m" | |
echo -e "Your Protocol : \033[41;37m ${shadowsockprotocol} \033[0m" | |
echo -e "Your obfs : \033[41;37m ${shadowsockobfs} \033[0m" | |
echo -e "Your Encryption Method: \033[41;37m ${shadowsockscipher} \033[0m" | |
echo | |
echo "Enjoy it!" | |
echo | |
fi | |
else | |
echo "${proj_name} install failed, please contact @ssrlive" | |
exit 1 | |
fi | |
} | |
function do_uninstall_ssr_action() { | |
${service_stub} status > /dev/null 2>&1 | |
if [ $? -eq 0 ]; then | |
${service_stub} stop | |
fi | |
if check_sys packageManager yum; then | |
chkconfig --del ${service_name} | |
elif check_sys packageManager apt; then | |
update-rc.d -f ${service_name} remove | |
fi | |
systemctl stop ${service_name}.service | |
rm -rf ${config_dir} | |
rm -f ${service_stub} | |
rm -f ${target_dir}/${bin_name} | |
rm -f ${service_dir}/${service_name}.service | |
echo "ShadowsocksR uninstall success!" | |
} | |
# Uninstall ShadowsocksR | |
function uninstall_shadowsocksr() { | |
printf "Are you sure uninstall ${proj_name}? (y/n)\n" | |
read -p "(Default: y):" answer | |
[ -z ${answer} ] && answer="n" | |
if [ "${answer}" == "y" ] || [ "${answer}" == "Y" ]; then | |
do_uninstall_ssr_action | |
else | |
echo | |
echo "uninstall cancelled, nothing to do..." | |
echo | |
fi | |
} | |
# Install ShadowsocksR | |
function install_shadowsocksr() { | |
disable_selinux | |
pre_install | |
echo | |
echo "Press any key to start...or Press Ctrl+C to cancel" | |
char=`get_char` | |
cd ${cur_dir} | |
install_build_tools | |
do_uninstall_ssr_action | |
build_ssr_native | |
write_ssr_config | |
if check_sys packageManager yum; then | |
firewall_settings ${client_connect_port} | |
fi | |
install_ssr_service | |
} | |
function test_ssr_ot_mode() { | |
if [ ${ssr_ot_enabled} -a ${ssr_ot_enabled} = true ] ; then | |
echo "====>>>> SSRoT mode <<<<====" | |
if [ ! ${web_svr_domain} ] ; then | |
echo "[${red}Error${plain}] variable web_svr_domain missing!" | |
exit 5 | |
fi | |
if [ ! ${web_svr_local_ip_addr} ] ; then | |
echo "[${red}Error${plain}] variable web_svr_local_ip_addr missing!" | |
exit 5 | |
fi | |
if [ ! ${web_svr_listen_port} ] ; then | |
echo "[${red}Error${plain}] variable web_svr_listen_port missing!" | |
exit 5 | |
fi | |
if [ ! ${web_svr_reverse_proxy_port} ] ; then | |
echo "[${red}Error${plain}] variable web_svr_reverse_proxy_port missing!" | |
exit 5 | |
fi | |
if [ ! ${reverse_proxy_location} ] ; then | |
echo "[${red}Error${plain}] variable reverse_proxy_location missing!" | |
exit 5 | |
fi | |
over_tls_mode=true | |
fi | |
} | |
function main() { | |
# clear | |
echo | |
echo "####################################################################" | |
echo "# Script of Install ${proj_name} Server #" | |
echo "# Author: ssrlive #" | |
echo "# Github: https://github.com/ShadowsocksR-Live/shadowsocksr-native #" | |
echo "####################################################################" | |
echo | |
# Make sure only root can run our script | |
[[ $EUID -ne 0 ]] && echo -e "[${red}Error${plain}] This script must be run as root!" && exit 1 | |
test_ssr_ot_mode | |
if [ ${over_tls_mode} = true ]; then | |
host_public_ip=${web_svr_local_ip_addr} | |
else | |
host_public_ip=`get_ip` | |
fi | |
# Initialization step | |
local action=$1 | |
[ -z $1 ] && action=install | |
case "${action}" in | |
install|uninstall) | |
${action}_shadowsocksr | |
;; | |
*) | |
echo "Arguments error! [${action}]" | |
echo "Usage: `basename $0` [install|uninstall]" | |
;; | |
esac | |
exit 0 | |
} | |
#=================================================================# | |
# script begin entry # | |
#=================================================================# | |
main $1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment