Добавить install.sh
This commit is contained in:
508
install.sh
Normal file
508
install.sh
Normal file
@@ -0,0 +1,508 @@
|
||||
#!/bin/bash
|
||||
|
||||
export LANG=ru_RU.UTF-8
|
||||
|
||||
RED="\033[31m"
|
||||
GREEN="\033[32m"
|
||||
YELLOW="\033[33m"
|
||||
PLAIN="\033[0m"
|
||||
|
||||
red(){
|
||||
echo -e "\033[31m\033[01m$1\033[0m"
|
||||
}
|
||||
|
||||
green(){
|
||||
echo -e "\033[32m\033[01m$1\033[0m"
|
||||
}
|
||||
|
||||
yellow(){
|
||||
echo -e "\033[33m\033[01m$1\033[0m"
|
||||
}
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
red "Внимание: Запустите скрипт от имени root пользователя"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CUSTOM_SNI=""
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--custom-sni=*)
|
||||
CUSTOM_SNI="${arg#*=}"
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
echo "Использование: $0 [--custom-sni=example.com]"
|
||||
echo ""
|
||||
echo "Опции:"
|
||||
echo " --custom-sni=HOSTNAME Указать свой SNI хост (по умолчанию: web.max.ru)"
|
||||
echo " --help Показать эту справку"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
REGEX=("debian" "ubuntu" "centos|red hat|kernel|oracle linux|alma|rocky" "'amazon linux'" "fedora" "alpine")
|
||||
RELEASE=("Debian" "Ubuntu" "CentOS" "CentOS" "Fedora" "Alpine")
|
||||
PACKAGE_UPDATE=("apt-get update" "apt-get update" "yum -y update" "yum -y update" "yum -y update" "apk update -f")
|
||||
PACKAGE_INSTALL=("apt -y install" "apt -y install" "yum -y install" "yum -y install" "yum -y install" "apk add -f")
|
||||
|
||||
CMD=("$(grep -i pretty_name /etc/os-release 2>/dev/null | cut -d \" -f2)" "$(hostnamectl 2>/dev/null | grep -i system | cut -d : -f2)" "$(lsb_release -sd 2>/dev/null)" "$(grep -i description /etc/lsb-release 2>/dev/null | cut -d \" -f2)" "$(grep . /etc/redhat-release 2>/dev/null)" "$(grep . /etc/issue 2>/dev/null | cut -d \\ -f1 | sed '/^[ ]*$/d')")
|
||||
|
||||
for i in "${CMD[@]}"; do
|
||||
SYS="$i" && [[ -n $SYS ]] && break
|
||||
done
|
||||
|
||||
for ((int = 0; int < ${#REGEX[@]}; int++)); do
|
||||
[[ $(echo "$SYS" | tr '[:upper:]' '[:lower:]') =~ ${REGEX[int]} ]] && SYSTEM="${RELEASE[int]}" && [[ -n $SYSTEM ]] && break
|
||||
done
|
||||
|
||||
[[ -z $SYSTEM ]] && red "Текущая система VPS не поддерживается, используйте основную операционную систему" && exit 1
|
||||
|
||||
if [[ -z $(type -P curl) ]]; then
|
||||
if [[ ! $SYSTEM == "CentOS" ]]; then
|
||||
${PACKAGE_UPDATE[int]}
|
||||
fi
|
||||
${PACKAGE_INSTALL[int]} curl
|
||||
fi
|
||||
|
||||
get_ip() {
|
||||
local ip=$(curl -s4m8 ip.sb -k) || ip=$(curl -s6m8 ip.sb -k)
|
||||
echo "$ip"
|
||||
}
|
||||
|
||||
install_server_core() {
|
||||
yellow "Установка Hysteria2..."
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_ARGS=("$@")
|
||||
|
||||
EXECUTABLE_INSTALL_PATH="/usr/local/bin/hysteria"
|
||||
|
||||
SYSTEMD_SERVICES_DIR="/etc/systemd/system"
|
||||
|
||||
CONFIG_DIR="/etc/hysteria"
|
||||
|
||||
REPO_URL="https://github.com/apernet/hysteria"
|
||||
|
||||
HY2_API_BASE_URL="https://api.hy2.io/v1"
|
||||
|
||||
CURL_FLAGS=(-L -f -q --retry 5 --retry-delay 10 --retry-max-time 60)
|
||||
|
||||
PACKAGE_MANAGEMENT_INSTALL="${PACKAGE_MANAGEMENT_INSTALL:-}"
|
||||
|
||||
OPERATING_SYSTEM="${OPERATING_SYSTEM:-}"
|
||||
|
||||
ARCHITECTURE="${ARCHITECTURE:-}"
|
||||
|
||||
HYSTERIA_USER="${HYSTERIA_USER:-}"
|
||||
|
||||
HYSTERIA_HOME_DIR="${HYSTERIA_HOME_DIR:-}"
|
||||
|
||||
OPERATION=
|
||||
|
||||
VERSION=
|
||||
|
||||
FORCE=
|
||||
|
||||
LOCAL_FILE=
|
||||
|
||||
has_command() {
|
||||
local _command=$1
|
||||
type -P "$_command" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
curl() {
|
||||
command curl "${CURL_FLAGS[@]}" "$@"
|
||||
}
|
||||
|
||||
mktemp() {
|
||||
command mktemp "$@" "/tmp/hyservinst.XXXXXXXXXX"
|
||||
}
|
||||
|
||||
note() {
|
||||
local _msg="$1"
|
||||
echo -e "$SCRIPT_NAME: $(tput bold)note: $_msg$(tput sgr0)"
|
||||
}
|
||||
|
||||
warning() {
|
||||
local _msg="$1"
|
||||
echo -e "$SCRIPT_NAME: $(tput setaf 3)warning: $_msg$(tput sgr0)"
|
||||
}
|
||||
|
||||
error() {
|
||||
local _msg="$1"
|
||||
echo -e "$SCRIPT_NAME: $(tput setaf 1)error: $_msg$(tput sgr0)"
|
||||
}
|
||||
|
||||
check_environment_operating_system() {
|
||||
if [[ -n "$OPERATING_SYSTEM" ]]; then
|
||||
warning "OPERATING_SYSTEM=$OPERATING_SYSTEM обнаружено, определение ОС выполняться не будет."
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ "x$(uname)" == "xLinux" ]]; then
|
||||
OPERATING_SYSTEM=linux
|
||||
return
|
||||
fi
|
||||
|
||||
error "Этот скрипт поддерживает только Linux."
|
||||
exit 95
|
||||
}
|
||||
|
||||
check_environment_architecture() {
|
||||
if [[ -n "$ARCHITECTURE" ]]; then
|
||||
warning "ARCHITECTURE=$ARCHITECTURE обнаружено, определение архитектуры выполняться не будет."
|
||||
return
|
||||
fi
|
||||
|
||||
case "$(uname -m)" in
|
||||
'i386' | 'i686')
|
||||
ARCHITECTURE='386'
|
||||
;;
|
||||
'amd64' | 'x86_64')
|
||||
ARCHITECTURE='amd64'
|
||||
;;
|
||||
'armv5tel' | 'armv6l' | 'armv7' | 'armv7l')
|
||||
ARCHITECTURE='arm'
|
||||
;;
|
||||
'armv8' | 'aarch64')
|
||||
ARCHITECTURE='arm64'
|
||||
;;
|
||||
'mips' | 'mipsle' | 'mips64' | 'mips64le')
|
||||
ARCHITECTURE='mipsle'
|
||||
;;
|
||||
's390x')
|
||||
ARCHITECTURE='s390x'
|
||||
;;
|
||||
*)
|
||||
error "Архитектура '$(uname -a)' не поддерживается."
|
||||
exit 8
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_environment_systemd() {
|
||||
if [[ -d "/run/systemd/system" ]] || grep -q systemd <(ls -l /sbin/init); then
|
||||
return
|
||||
fi
|
||||
|
||||
case "$FORCE_NO_SYSTEMD" in
|
||||
'1')
|
||||
warning "FORCE_NO_SYSTEMD=1, продолжим даже если systemd не обнаружен."
|
||||
;;
|
||||
'2')
|
||||
warning "FORCE_NO_SYSTEMD=2, продолжим но пропустим все команды связанные с systemd."
|
||||
;;
|
||||
*)
|
||||
error "Этот скрипт поддерживает только дистрибутивы Linux с systemd."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
update_packages() {
|
||||
${PACKAGE_UPDATE[int]}
|
||||
}
|
||||
|
||||
check_environment_curl() {
|
||||
if has_command curl; then
|
||||
return
|
||||
fi
|
||||
${PACKAGE_INSTALL[int]} curl
|
||||
}
|
||||
|
||||
check_environment_grep() {
|
||||
if has_command grep; then
|
||||
return
|
||||
fi
|
||||
${PACKAGE_INSTALL[int]} grep
|
||||
}
|
||||
|
||||
check_environment_qrencode() {
|
||||
if has_command qrencode; then
|
||||
return
|
||||
fi
|
||||
${PACKAGE_INSTALL[int]} qrencode
|
||||
}
|
||||
|
||||
check_environment() {
|
||||
update_packages
|
||||
check_environment_operating_system
|
||||
check_environment_architecture
|
||||
check_environment_systemd
|
||||
check_environment_curl
|
||||
check_environment_grep
|
||||
check_environment_qrencode
|
||||
}
|
||||
|
||||
install_content() {
|
||||
local _install_flags="$1"
|
||||
local _content="$2"
|
||||
local _destination="$3"
|
||||
local _overwrite="$4"
|
||||
|
||||
local _tmpfile="$(mktemp)"
|
||||
|
||||
echo -ne "Установка $_destination ... "
|
||||
echo "$_content" > "$_tmpfile"
|
||||
if [[ -z "$_overwrite" && -e "$_destination" ]]; then
|
||||
echo -e "существует"
|
||||
elif install "$_install_flags" "$_tmpfile" "$_destination"; then
|
||||
echo -e "ок"
|
||||
fi
|
||||
|
||||
rm -f "$_tmpfile"
|
||||
}
|
||||
|
||||
get_latest_version() {
|
||||
if [[ -n "$VERSION" ]]; then
|
||||
echo "$VERSION"
|
||||
return
|
||||
fi
|
||||
|
||||
local _tmpfile=$(mktemp)
|
||||
if ! curl -sS "$HY2_API_BASE_URL/update?cver=installscript&plat=${OPERATING_SYSTEM}&arch=${ARCHITECTURE}&chan=release&side=server" -o "$_tmpfile"; then
|
||||
error "Ошибка получения последней версии от Hysteria 2 API"
|
||||
exit 11
|
||||
fi
|
||||
|
||||
local _latest_version=$(grep -oP '"lver":\s*\K"v.*?"' "$_tmpfile" | head -1)
|
||||
_latest_version=${_latest_version#'"'}
|
||||
_latest_version=${_latest_version%'"'}
|
||||
|
||||
if [[ -n "$_latest_version" ]]; then
|
||||
echo "$_latest_version"
|
||||
fi
|
||||
|
||||
rm -f "$_tmpfile"
|
||||
}
|
||||
|
||||
download_hysteria() {
|
||||
local _version="$1"
|
||||
local _destination="$2"
|
||||
|
||||
local _download_url="$REPO_URL/releases/download/app/$_version/hysteria-$OPERATING_SYSTEM-$ARCHITECTURE"
|
||||
echo "Загрузка бинарного файла hysteria: $_download_url ..."
|
||||
if ! curl -R -H 'Cache-Control: no-cache' "$_download_url" -o "$_destination"; then
|
||||
error "Ошибка загрузки, проверьте ваше соединение и попробуйте снова."
|
||||
return 11
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
perform_install_hysteria_binary() {
|
||||
local _tmpfile=$(mktemp)
|
||||
local _version=$(get_latest_version)
|
||||
|
||||
if ! download_hysteria "$_version" "$_tmpfile"; then
|
||||
rm -f "$_tmpfile"
|
||||
exit 11
|
||||
fi
|
||||
|
||||
echo -ne "Установка исполняемого файла hysteria ... "
|
||||
if install -Dm755 "$_tmpfile" "$EXECUTABLE_INSTALL_PATH"; then
|
||||
echo "ок"
|
||||
else
|
||||
exit 13
|
||||
fi
|
||||
|
||||
rm -f "$_tmpfile"
|
||||
|
||||
mkdir -p /etc/hysteria
|
||||
}
|
||||
|
||||
perform_install_hysteria_systemd() {
|
||||
if [[ "x$FORCE_NO_SYSTEMD" == "x2" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local _service_content=$(cat << 'EOF'
|
||||
[Unit]
|
||||
Description=Hysteria Server Service (config.yaml)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/local/bin/hysteria server --config /etc/hysteria/config.yaml
|
||||
WorkingDirectory=~
|
||||
User=root
|
||||
Group=root
|
||||
Environment=HYSTERIA_LOG_LEVEL=info
|
||||
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW
|
||||
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_NET_RAW
|
||||
NoNewPrivileges=true
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
)
|
||||
install_content -Dm644 "$_service_content" "$SYSTEMD_SERVICES_DIR/hysteria-server.service" "1"
|
||||
|
||||
systemctl daemon-reload
|
||||
}
|
||||
|
||||
check_environment
|
||||
HYSTERIA_USER="root"
|
||||
HYSTERIA_HOME_DIR="/root"
|
||||
|
||||
perform_install_hysteria_binary
|
||||
perform_install_hysteria_systemd
|
||||
|
||||
green "Hysteria2 core успешно установлен!"
|
||||
}
|
||||
|
||||
configure_hysteria() {
|
||||
yellow "Настройка сервера Hysteria2..."
|
||||
|
||||
if [[ -n "$CUSTOM_SNI" ]]; then
|
||||
local sni_host="$CUSTOM_SNI"
|
||||
yellow "Используется кастомный SNI: $sni_host"
|
||||
else
|
||||
local sni_host="web.max.ru"
|
||||
fi
|
||||
|
||||
local masquerade_url="$sni_host"
|
||||
local port="443"
|
||||
|
||||
mkdir -p /etc/hysteria
|
||||
|
||||
local auth_pwd=$(date +%s%N | md5sum | cut -c 1-16)
|
||||
local obfs_pwd=$(date +%s%N | md5sum | cut -c 1-16)
|
||||
|
||||
openssl ecparam -genkey -name prime256v1 -out /etc/hysteria/private.key
|
||||
openssl req -new -x509 -days 36500 -key /etc/hysteria/private.key -out /etc/hysteria/cert.crt -subj "/CN=$sni_host"
|
||||
chmod 600 /etc/hysteria/cert.crt
|
||||
chmod 600 /etc/hysteria/private.key
|
||||
|
||||
cat << EOF > /etc/hysteria/config.yaml
|
||||
listen: :$port
|
||||
|
||||
tls:
|
||||
cert: /etc/hysteria/cert.crt
|
||||
key: /etc/hysteria/private.key
|
||||
|
||||
obfs:
|
||||
type: salamander
|
||||
salamander:
|
||||
password: $obfs_pwd
|
||||
|
||||
auth:
|
||||
type: password
|
||||
password: $auth_pwd
|
||||
|
||||
masquerade:
|
||||
type: proxy
|
||||
proxy:
|
||||
url: https://$masquerade_url
|
||||
rewriteHost: true
|
||||
|
||||
quic:
|
||||
initStreamReceiveWindow: 16777216
|
||||
maxStreamReceiveWindow: 16777216
|
||||
initConnReceiveWindow: 33554432
|
||||
maxConnReceiveWindow: 33554432
|
||||
EOF
|
||||
|
||||
local server_ip=$(get_ip)
|
||||
|
||||
cat << EOF > /root/hysteria2.txt
|
||||
hy2://$auth_pwd@$server_ip:$port?mport&security=tls&sni=$sni_host&allowInsecure=true&alpn&obfs=salamander&obfs-password=$obfs_pwd#Test
|
||||
EOF
|
||||
|
||||
green "Настройка завершена!"
|
||||
echo
|
||||
yellow "IP сервера: $server_ip"
|
||||
yellow "Порт: $port"
|
||||
yellow "SNI: $sni_host"
|
||||
yellow "Пароль аутентификации: $auth_pwd"
|
||||
yellow "Пароль обфускации: $obfs_pwd"
|
||||
yellow "Маскировка: https://$masquerade_url"
|
||||
echo
|
||||
|
||||
if [[ -n "$CUSTOM_SNI" ]]; then
|
||||
green "Использован кастомный SNI: $CUSTOM_SNI"
|
||||
fi
|
||||
}
|
||||
|
||||
start_service() {
|
||||
yellow "Запуск службы Hysteria2..."
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable hysteria-server
|
||||
systemctl start hysteria-server
|
||||
|
||||
sleep 2
|
||||
if systemctl is-active --quiet hysteria-server; then
|
||||
green "Служба Hysteria2 успешно запущена"
|
||||
else
|
||||
red "Ошибка запуска службы Hysteria2"
|
||||
systemctl status hysteria-server
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
show_config() {
|
||||
if command -v qrencode &> /dev/null; then
|
||||
green "=== QR Code ==="
|
||||
qrencode -t ANSIUTF8 "$(cat /root/hysteria2.txt)"
|
||||
else
|
||||
yellow "Установите qrencode для генерации QR кода: apt install qrencode / yum install qrencode"
|
||||
fi
|
||||
}
|
||||
|
||||
uninstall_hysteria() {
|
||||
red "Удаление Hysteria2..."
|
||||
|
||||
systemctl stop hysteria-server 2>/dev/null || true
|
||||
systemctl disable hysteria-server 2>/dev/null || true
|
||||
rm -f /etc/systemd/system/hysteria-server.service
|
||||
rm -f /usr/local/bin/hysteria
|
||||
rm -rf /etc/hysteria
|
||||
rm -f /root/hysteria2.txt
|
||||
systemctl daemon-reload
|
||||
|
||||
green "Hysteria2 полностью удален!"
|
||||
}
|
||||
|
||||
check_hysteria_installed() {
|
||||
[[ -f "/usr/local/bin/hysteria" ]]
|
||||
}
|
||||
|
||||
main() {
|
||||
if check_hysteria_installed; then
|
||||
red "Hysteria2 уже установлен!"
|
||||
echo
|
||||
read -p "Хотите переустановить? [y/N]: " reinstall
|
||||
case $reinstall in
|
||||
[yY]|[yY][eE][sS])
|
||||
uninstall_hysteria
|
||||
;;
|
||||
*)
|
||||
echo "Выход..."
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
install_server_core
|
||||
configure_hysteria
|
||||
start_service
|
||||
show_config
|
||||
|
||||
echo
|
||||
green "Установка Hysteria2 успешно завершена!"
|
||||
echo
|
||||
yellow "Конфиг клиента: /root/hysteria2.txt"
|
||||
yellow "Перезапуск службы: systemctl restart hysteria-server"
|
||||
yellow "Проверка статуса: systemctl status hysteria-server"
|
||||
echo
|
||||
yellow "Hysteria2 ключ:"
|
||||
cat /root/hysteria2.txt
|
||||
echo
|
||||
echo "Инструкции по настройке VPN приложений:"
|
||||
echo "https://github.com/YukiKras/wiki/blob/main/nastroikavpn.md"
|
||||
}
|
||||
|
||||
main
|
||||
Reference in New Issue
Block a user