1
1
mirror of https://github.com/angristan/wireguard-install.git synced 2024-06-05 04:50:49 +00:00
wireguard-install/wireguard-install.sh
Romanoidz 518e2e0ef2
Update wireguard-install.sh
Разукрасил вывод сообщений и перевел комментарии
2022-02-17 01:23:55 +03:00

458 lines
19 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
# Secure WireGuard server installer
# https://github.com/angristan/wireguard-install
WARN='\033[1;35m'
BOLD='\033[1;32m'
RED='\033[0;31m'
ORANGE='\033[0;33m'
NC='\033[0m'
function isRoot() {
if [ "${EUID}" -ne 0 ]; then
echo -e "${WARN}Вам нужно запустить этот скрипт от имени root-пользователя${NC}"
exit 1
fi
}
function checkVirt() {
if [ "$(systemd-detect-virt)" == "openvz" ]; then
echo -e "${WARN}OpenVZ не поддерживается${NC}"
exit 1
fi
if [ "$(systemd-detect-virt)" == "lxc" ]; then
echo -e "${WARN}LXC не поддерживается (пока).${NC}"
echo -e "${WARN}Технически WireGuard может работать в контейнере LXC,${NC}"
echo -e "${WARN}но модуль ядра должен быть установлен на хосте,${NC}"
echo -e "${WARN}контейнер должен быть запущен с некоторыми определенными параметрами${NC}"
echo -e "${WARN}и только инструменты должны быть установлены в контейнер.${NC}"
exit 1
fi
}
function checkOS() {
# Проверка операционной системы
if [[ -e /etc/debian_version ]]; then
source /etc/os-release
OS="${ID}" # debian или ubuntu
if [[ ${ID} == "debian" || ${ID} == "raspbian" ]]; then
if [[ ${VERSION_ID} -lt 10 ]]; then
echo -e "${WARN}Ваша версия Debian (${VERSION_ID}) не поддерживается. Пожалуйста, используйте Debian 10 Buster или более позднюю версию${NC}"
exit 1
fi
OS=debian # перезаписать, если raspbian
fi
elif [[ -e /etc/fedora-release ]]; then
source /etc/os-release
OS="${ID}"
elif [[ -e /etc/centos-release ]]; then
source /etc/os-release
OS=centos
elif [[ -e /etc/oracle-release ]]; then
source /etc/os-release
OS=oracle
elif [[ -e /etc/arch-release ]]; then
OS=arch
else
echo -e "${WARN}Похоже, вы не запускаете этот установщик в системе Debian, Ubuntu, Fedora, CentOS, Oracle или Arch Linux${NC}"
exit 1
fi
}
function initialCheck() {
isRoot
checkVirt
checkOS
}
function installQuestions() {
echo -e "${BOLD}Добро пожаловать в WireGuard installer!${NC}"
echo -e "${BOLD}Репозиторий git доступен по адресу: https://github.com/Romanoidz/wireguard-install ${NC}"
echo ""
echo -e "${BOLD}Мне нужно задать вам несколько вопросов, прежде чем приступить к настройке.${NC}"
echo -e "${BOLD}Вы можете оставить параметры по умолчанию и просто нажать Enter, если они вас устраивают.${NC}"
echo ""
# Detect public IPv4 or IPv6 address and pre-fill for the user
SERVER_PUB_IP=$(ip -4 addr | sed -ne 's|^.* inet \([^/]*\)/.* scope global.*$|\1|p' | awk '{print $1}' | head -1)
if [[ -z ${SERVER_PUB_IP} ]]; then
# Detect public IPv6 address
SERVER_PUB_IP=$(ip -6 addr | sed -ne 's|^.* inet6 \([^/]*\)/.* scope global.*$|\1|p' | head -1)
fi
read -rp "Публичный адрес IPv4 или IPv6: " -e -i "${SERVER_PUB_IP}" SERVER_PUB_IP
# Detect public interface and pre-fill for the user
SERVER_NIC="$(ip -4 route ls | grep default | grep -Po '(?<=dev )(\S+)' | head -1)"
until [[ ${SERVER_PUB_NIC} =~ ^[a-zA-Z0-9_]+$ ]]; do
read -rp "Общедоступный интерфейс: " -e -i "${SERVER_NIC}" SERVER_PUB_NIC
done
until [[ ${SERVER_WG_NIC} =~ ^[a-zA-Z0-9_]+$ && ${#SERVER_WG_NIC} -lt 16 ]]; do
read -rp "Имя интерфейса WireGuard: " -e -i wg0 SERVER_WG_NIC
done
until [[ ${SERVER_WG_IPV4} =~ ^([0-9]{1,3}\.){3} ]]; do
read -rp "Адрес сервера WireGuard IPv4: " -e -i 192.168.66.1 SERVER_WG_IPV4
done
until [[ ${SERVER_WG_IPV6} =~ ^([a-f0-9]{1,4}:){3,4}: ]]; do
read -rp "Адрес сервера WireGuard IPv6: " -e -i fd42:42:42::1 SERVER_WG_IPV6
done
# Генерировать случайное число в пределах диапазона частных портов
RANDOM_PORT=$(shuf -i49152-65535 -n1)
until [[ ${SERVER_PORT} =~ ^[0-9]+$ ]] && [ "${SERVER_PORT}" -ge 1 ] && [ "${SERVER_PORT}" -le 65535 ]; do
read -rp "Порт сервера WireGuard [1-65535]: " -e -i "${RANDOM_PORT}" SERVER_PORT
done
# По умолчанию Яндекс DNS серверы
until [[ ${CLIENT_DNS_1} =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; do
read -rp "1-й DNS-сервер, используемый для клиентов: " -e -i 77.88.8.8 CLIENT_DNS_1
done
until [[ ${CLIENT_DNS_2} =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$ ]]; do
read -rp "2-й DNS-сервер, используемый для клиентов: (опционально): " -e -i 77.88.8.1 CLIENT_DNS_2
if [[ ${CLIENT_DNS_2} == "" ]]; then
CLIENT_DNS_2="${CLIENT_DNS_1}"
fi
done
echo ""
echo -e "${BOLD}Необходимые данные получены. Теперь можно настроить ваш сервер WireGuard.${NC}"
echo -e "${BOLD}Настроить и создать Клиента можно в конце установки.${NC}"
read -n1 -r -p -e "${BOLD}Нажмите любую клавишу, чтобы продолжить...${NC}"
}
function installWireGuard() {
# Сначала выполните вопросы по настройке
installQuestions
# Установите инструменты и модуль для Wireguard
if [[ ${OS} == 'ubuntu' ]] || [[ ${OS} == 'debian' && ${VERSION_ID} -gt 10 ]]; then
apt-get update
apt-get install -y wireguard iptables resolvconf qrencode
elif [[ ${OS} == 'debian' ]]; then
if ! grep -rqs "^deb .* buster-backports" /etc/apt/; then
echo "deb http://deb.debian.org/debian buster-backports main" >/etc/apt/sources.list.d/backports.list
apt-get update
fi
apt update
apt-get install -y iptables resolvconf qrencode
apt-get install -y -t buster-backports wireguard
elif [[ ${OS} == 'fedora' ]]; then
if [[ ${VERSION_ID} -lt 32 ]]; then
dnf install -y dnf-plugins-core
dnf copr enable -y jdoss/wireguard
dnf install -y wireguard-dkms
fi
dnf install -y wireguard-tools iptables qrencode
elif [[ ${OS} == 'centos' ]]; then
yum -y install epel-release elrepo-release
if [[ ${VERSION_ID} -eq 7 ]]; then
yum -y install yum-plugin-elrepo
fi
yum -y install kmod-wireguard wireguard-tools iptables qrencode
elif [[ ${OS} == 'oracle' ]]; then
dnf install -y oraclelinux-developer-release-el8
dnf config-manager --disable -y ol8_developer
dnf config-manager --enable -y ol8_developer_UEKR6
dnf config-manager --save -y --setopt=ol8_developer_UEKR6.includepkgs='wireguard-tools*'
dnf install -y wireguard-tools qrencode iptables
elif [[ ${OS} == 'arch' ]]; then
pacman -S --needed --noconfirm wireguard-tools qrencode
fi
# Убедитесь, что каталог существует (похоже, это не относится к fedora)
mkdir /etc/wireguard >/dev/null 2>&1
chmod 600 -R /etc/wireguard/
SERVER_PRIV_KEY=$(wg genkey)
SERVER_PUB_KEY=$(echo "${SERVER_PRIV_KEY}" | wg pubkey)
# Сохранение настроек WireGuard
echo "SERVER_PUB_IP=${SERVER_PUB_IP}
SERVER_PUB_NIC=${SERVER_PUB_NIC}
SERVER_WG_NIC=${SERVER_WG_NIC}
SERVER_WG_IPV4=${SERVER_WG_IPV4}
SERVER_WG_IPV6=${SERVER_WG_IPV6}
SERVER_PORT=${SERVER_PORT}
SERVER_PRIV_KEY=${SERVER_PRIV_KEY}
SERVER_PUB_KEY=${SERVER_PUB_KEY}
CLIENT_DNS_1=${CLIENT_DNS_1}
CLIENT_DNS_2=${CLIENT_DNS_2}" >/etc/wireguard/params
# Добавить серверный интерфейс
echo "[Interface]
Address = ${SERVER_WG_IPV4}/24,${SERVER_WG_IPV6}/64
ListenPort = ${SERVER_PORT}
PrivateKey = ${SERVER_PRIV_KEY}" >"/etc/wireguard/${SERVER_WG_NIC}.conf"
if pgrep firewalld; then
FIREWALLD_IPV4_ADDRESS=$(echo "${SERVER_WG_IPV4}" | cut -d"." -f1-3)".0"
FIREWALLD_IPV6_ADDRESS=$(echo "${SERVER_WG_IPV6}" | sed 's/:[^:]*$/:0/')
echo "PostUp = firewall-cmd --add-port ${SERVER_PORT}/udp && firewall-cmd --add-rich-rule='rule family=ipv4 source address=${FIREWALLD_IPV4_ADDRESS}/24 masquerade' && firewall-cmd --add-rich-rule='rule family=ipv6 source address=${FIREWALLD_IPV6_ADDRESS}/24 masquerade'
PostDown = firewall-cmd --remove-port ${SERVER_PORT}/udp && firewall-cmd --remove-rich-rule='rule family=ipv4 source address=${FIREWALLD_IPV4_ADDRESS}/24 masquerade' && firewall-cmd --remove-rich-rule='rule family=ipv6 source address=${FIREWALLD_IPV6_ADDRESS}/24 masquerade'" >>"/etc/wireguard/${SERVER_WG_NIC}.conf"
else
echo "PostUp = iptables -A FORWARD -i ${SERVER_PUB_NIC} -o ${SERVER_WG_NIC} -j ACCEPT; iptables -A FORWARD -i ${SERVER_WG_NIC} -j ACCEPT; iptables -t nat -A POSTROUTING -o ${SERVER_PUB_NIC} -j MASQUERADE; ip6tables -A FORWARD -i ${SERVER_WG_NIC} -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ${SERVER_PUB_NIC} -j MASQUERADE
PostDown = iptables -D FORWARD -i ${SERVER_PUB_NIC} -o ${SERVER_WG_NIC} -j ACCEPT; iptables -D FORWARD -i ${SERVER_WG_NIC} -j ACCEPT; iptables -t nat -D POSTROUTING -o ${SERVER_PUB_NIC} -j MASQUERADE; ip6tables -D FORWARD -i ${SERVER_WG_NIC} -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ${SERVER_PUB_NIC} -j MASQUERADE" >>"/etc/wireguard/${SERVER_WG_NIC}.conf"
fi
# Включить маршрутизацию на сервере
echo "net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1" >/etc/sysctl.d/wg.conf
sysctl --system
systemctl start "wg-quick@${SERVER_WG_NIC}"
systemctl enable "wg-quick@${SERVER_WG_NIC}"
newClient
echo -e "${BOLD}Если вы хотите добавить больше клиентов, вам просто нужно запустить этот скрипт в еще раз!${NC}"
# Проверьте, работает ли WireGuard
systemctl is-active --quiet "wg-quick@${SERVER_WG_NIC}"
WG_RUNNING=$?
# WireGuard может не работать, если мы обновим ядро. Попросите пользователя перезагрузиться
if [[ ${WG_RUNNING} -ne 0 ]]; then
echo -e "\n${RED}ПРЕДУПРЕЖДЕНИЕ: WireGuard, похоже, не работает.${NC}"
echo -e "${ORANGE}Вы можете проверить, работает ли WireGuard: systemctl status wg-quick@${SERVER_WG_NIC}${NC}"
echo -e "${ORANGE}Если вы получите что-то вроде \"Cannot find device ${SERVER_WG_NIC}\", пожалуйста, перезагрузитесь!${NC}"
fi
}
function newClient() {
ENDPOINT="${SERVER_PUB_IP}:${SERVER_PORT}"
echo ""
echo -e "${BOLD}Введите имя клиента.${NC}"
echo -e "${WARN}Имя должно состоять из буквенно-цифровых символов. Оно также может содержать подчеркивание или тире и не может превышать 15 символов.${NC}"
until [[ ${CLIENT_NAME} =~ ^[a-zA-Z0-9_-]+$ && ${CLIENT_EXISTS} == '0' && ${#CLIENT_NAME} -lt 16 ]]; do
read -rp "Имя клиента: " -e CLIENT_NAME
CLIENT_EXISTS=$(grep -c -E "^### Client ${CLIENT_NAME}\$" "/etc/wireguard/${SERVER_WG_NIC}.conf")
if [[ ${CLIENT_EXISTS} == '1' ]]; then
echo ""
echo -e "${ORANGE}Клиент с указанным именем уже создан, пожалуйста, выберите другое имя.${NC}"
echo ""
fi
done
for DOT_IP in {2..254}; do
DOT_EXISTS=$(grep -c "${SERVER_WG_IPV4::-1}${DOT_IP}" "/etc/wireguard/${SERVER_WG_NIC}.conf")
if [[ ${DOT_EXISTS} == '0' ]]; then
break
fi
done
if [[ ${DOT_EXISTS} == '1' ]]; then
echo ""
echo -e "${ORANGE}Настроенная подсеть поддерживает только 253 клиента.${NC}"
exit 1
fi
BASE_IP=$(echo "$SERVER_WG_IPV4" | awk -F '.' '{ print $1"."$2"."$3 }')
until [[ ${IPV4_EXISTS} == '0' ]]; do
read -rp "Клиент WireGuard IPv4: ${BASE_IP}." -e -i "${DOT_IP}" DOT_IP
CLIENT_WG_IPV4="${BASE_IP}.${DOT_IP}"
IPV4_EXISTS=$(grep -c "$CLIENT_WG_IPV4/24" "/etc/wireguard/${SERVER_WG_NIC}.conf")
if [[ ${IPV4_EXISTS} == '1' ]]; then
echo ""
echo -e "${ORANGE}Клиент с указанным IPv4 уже создан, пожалуйста, выберите другой IPv4.${NC}"
echo ""
fi
done
BASE_IP=$(echo "$SERVER_WG_IPV6" | awk -F '::' '{ print $1 }')
until [[ ${IPV6_EXISTS} == '0' ]]; do
read -rp "Клиент WireGuard IPv6: ${BASE_IP}::" -e -i "${DOT_IP}" DOT_IP
CLIENT_WG_IPV6="${BASE_IP}::${DOT_IP}"
IPV6_EXISTS=$(grep -c "${CLIENT_WG_IPV6}/64" "/etc/wireguard/${SERVER_WG_NIC}.conf")
if [[ ${IPV6_EXISTS} == '1' ]]; then
echo ""
echo -e "${ORANGE}Клиент с указанным IPv6 уже создан, пожалуйста, выберите другой IPv6.${NC}"
echo ""
fi
done
# Создайте пару ключей для клиента
CLIENT_PRIV_KEY=$(wg genkey)
CLIENT_PUB_KEY=$(echo "${CLIENT_PRIV_KEY}" | wg pubkey)
CLIENT_PRE_SHARED_KEY=$(wg genpsk)
# Домашний каталог пользователя, в котором будет записана конфигурация клиента
if [ -e "/home/${CLIENT_NAME}" ]; then
# если $1 - это имя пользователя
HOME_DIR="/home/${CLIENT_NAME}"
elif [ "${SUDO_USER}" ]; then
# если нет, используйте SUDO_USER
if [ "${SUDO_USER}" == "root" ]; then
# При запуске sudo от имени root
HOME_DIR="/root"
else
HOME_DIR="/home/${SUDO_USER}"
fi
else
# если не SUDO_USER, используйте /root
HOME_DIR="/root"
fi
# Создайте клиентский файл и добавьте сервер в качестве однорангового узла
echo "[Interface]
PrivateKey = ${CLIENT_PRIV_KEY}
Address = ${CLIENT_WG_IPV4}/32,${CLIENT_WG_IPV6}/128
DNS = ${CLIENT_DNS_1},${CLIENT_DNS_2}
[Peer]
PublicKey = ${SERVER_PUB_KEY}
PresharedKey = ${CLIENT_PRE_SHARED_KEY}
Endpoint = ${ENDPOINT}
AllowedIPs = 0.0.0.0/0,::/0" >>"${HOME_DIR}/${SERVER_WG_NIC}-${SERVER_PUB_IP}-client-${CLIENT_NAME}.conf"
# Добавьте клиента в качестве однорангового узла к серверу
echo -e "\n### Client ${CLIENT_NAME}
[Peer]
PublicKey = ${CLIENT_PUB_KEY}
PresharedKey = ${CLIENT_PRE_SHARED_KEY}
AllowedIPs = ${CLIENT_WG_IPV4}/32,${CLIENT_WG_IPV6}/128" >>"/etc/wireguard/${SERVER_WG_NIC}.conf"
wg syncconf "${SERVER_WG_NIC}" <(wg-quick strip "${SERVER_WG_NIC}")
echo -e "${BOLD}\nВот файл конфигурации вашего клиента в виде QR-кода:${NC}"
qrencode -t ansiutf8 -l L <"${HOME_DIR}/${SERVER_WG_NIC}-${SERVER_PUB_IP}-client-${CLIENT_NAME}.conf"
echo "Он также доступен в ${HOME_DIR}/${SERVER_WG_NIC}-${SERVER_PUB_IP}-client-${CLIENT_NAME}.conf"
}
function revokeClient() {
NUMBER_OF_CLIENTS=$(grep -c -E "^### Client" "/etc/wireguard/${SERVER_WG_NIC}.conf")
if [[ ${NUMBER_OF_CLIENTS} == '0' ]]; then
echo ""
echo -e "${ORANGE}У вас нет существующих клиентов!${NC}"
exit 1
fi
echo ""
echo -e "${BOLD}Выберите существующего клиента, которого вы хотите отозвать${NC}"
grep -E "^### Client" "/etc/wireguard/${SERVER_WG_NIC}.conf" | cut -d ' ' -f 3 | nl -s ') '
until [[ ${CLIENT_NUMBER} -ge 1 && ${CLIENT_NUMBER} -le ${NUMBER_OF_CLIENTS} ]]; do
if [[ ${CLIENT_NUMBER} == '1' ]]; then
read -rp "Выберите одного клиента [1]: " CLIENT_NUMBER
else
read -rp "Выберите одного клиента [1-${NUMBER_OF_CLIENTS}]: " CLIENT_NUMBER
fi
done
# сопоставьте выбранный номер с именем клиента
CLIENT_NAME=$(grep -E "^### Client" "/etc/wireguard/${SERVER_WG_NIC}.conf" | cut -d ' ' -f 3 | sed -n "${CLIENT_NUMBER}"p)
# удалить [Peer] блок, соответствующий $CLIENT_NAME
sed -i "/^### Client ${CLIENT_NAME}\$/,/^$/d" "/etc/wireguard/${SERVER_WG_NIC}.conf"
# удалить сгенерированный файл клиента
rm -f "${HOME}/${SERVER_WG_NIC}-client-${CLIENT_NAME}.conf"
# перезапустите wireguard, чтобы применить изменения
wg syncconf "${SERVER_WG_NIC}" <(wg-quick strip "${SERVER_WG_NIC}")
}
function uninstallWg() {
echo ""
read -rp "Вы действительно хотите удалить WireGuard? [y/n]: " -e -i n REMOVE
if [[ $REMOVE == 'y' ]]; then
checkOS
systemctl stop "wg-quick@${SERVER_WG_NIC}"
systemctl disable "wg-quick@${SERVER_WG_NIC}"
if [[ ${OS} == 'ubuntu' ]]; then
apt-get autoremove --purge -y wireguard qrencode
elif [[ ${OS} == 'debian' ]]; then
apt-get autoremove --purge -y wireguard qrencode
elif [[ ${OS} == 'fedora' ]]; then
dnf remove -y wireguard-tools qrencode
if [[ ${VERSION_ID} -lt 32 ]]; then
dnf remove -y wireguard-dkms
dnf copr disable -y jdoss/wireguard
fi
dnf autoremove -y
elif [[ ${OS} == 'centos' ]]; then
yum -y remove kmod-wireguard wireguard-tools qrencode
yum -y autoremove
elif [[ ${OS} == 'oracle' ]]; then
yum -y remove wireguard-tools qrencode
yum -y autoremove
elif [[ ${OS} == 'arch' ]]; then
pacman -Rs --noconfirm wireguard-tools qrencode
fi
rm -rf /etc/wireguard
rm -f /etc/sysctl.d/wg.conf
# Перезагрузить sysctl
sysctl --system
# Проверьте, работает ли WireGuard
systemctl is-active --quiet "wg-quick@${SERVER_WG_NIC}"
WG_RUNNING=$?
if [[ ${WG_RUNNING} -eq 0 ]]; then
echo -e "${ORANGE}WireGuard не удалась удалить должным образом.${NC}"
exit 1
else
echo -e "${BOLD}WireGuard успешно удален.${NC}"
exit 0
fi
else
echo ""
echo -e "${ORANGE}Удаление прервано!${NC}"
fi
}
function manageMenu() {
echo -e "${BOLD}Добро пожаловать в установку WireGuard-сервера!${NC}"
echo -e "${BOLD}Репозиторий git доступен по адресу: https://github.com/Romanoidz/wireguard-install ${NC}"
echo ""
echo -e "${BOLD}Похоже WireGuard уже установлен.${NC}"
echo ""
echo -e "${BOLD}Что хотите сделать?${NC}"
echo -e "${BOLD} 1) Добавить нового пользователя${NC}"
echo -e "${BOLD} 2) Отозвать существующего пользователя${NC}"
echo -e "${BOLD} 3) Удалить WireGuard${NC}"
echo -e "${BOLD} 4) Выйти${NC}"
until [[ ${MENU_OPTION} =~ ^[1-4]$ ]]; do
read -rp "Выберите опцию [1-4]: " MENU_OPTION
done
case "${MENU_OPTION}" in
1)
newClient
;;
2)
revokeClient
;;
3)
uninstallWg
;;
4)
exit 0
;;
esac
}
# Проверьте наличие root, virt, ОС...
initialCheck
# Проверьте, установлен ли WireGuard, и загрузите параметры
if [[ -e /etc/wireguard/params ]]; then
source /etc/wireguard/params
manageMenu
else
installWireGuard
fi