Добавить install.sh

This commit is contained in:
2026-02-23 19:49:12 +03:00
commit 91df8f5a26

508
install.sh Normal file
View 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