Files
hysteria2/install.sh

508 lines
14 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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