#/bin/bash set -e export GIT_BRANCH="main" export GIT_REPO="Akiyamov/xray-vps-setup" # Check if script started as root if [ "$EUID" -ne 0 ] then echo "Please run as root" exit fi # Install idn apt-get update apt-get install idn sudo dnsutils -y # Read domain input read -ep "Enter your domain:"$'\n' input_domain export VLESS_DOMAIN=$(echo $input_domain | idn) SERVER_IPS=($(hostname -I)) RESOLVED_IP=$(dig +short $VLESS_DOMAIN | tail -n1) if [ -z "$RESOLVED_IP" ]; then echo "Warning: Domain has no DNS record" read -ep "Are you sure? That domain has no DNS record. If you didn't add that you will have to restart xray and caddy by yourself [y/N]"$'\n' prompt_response if [[ "$prompt_response" =~ ^([yY])$ ]]; then echo "Ok, proceeding without DNS verification" else echo "Come back later" exit 1 fi else MATCH_FOUND=false for server_ip in "${SERVER_IPS[@]}"; do if [ "$RESOLVED_IP" == "$server_ip" ]; then MATCH_FOUND=true break fi done if [ "$MATCH_FOUND" = true ]; then echo "✓ DNS record points to this server ($RESOLVED_IP)" else echo "Warning: DNS record exists but points to different IP" echo " Domain resolves to: $RESOLVED_IP" echo " This server's IPs: ${SERVER_IPS[*]}" read -ep "Continue anyway? [y/N]"$'\n' prompt_response if [[ "$prompt_response" =~ ^([yY])$ ]]; then echo "Ok, proceeding" else echo "Come back later" exit 1 fi fi fi read -ep "Do you want to install marzban? [y/N] "$'\n' marzban_input read -ep "Do you want to configure server security? Do this on first run only. [y/N] "$'\n' configure_ssh_input if [[ ${configure_ssh_input,,} == "y" ]]; then # Read SSH port read -ep "Enter SSH port. Default 22, can't use ports: 80, 443 and 4123:"$'\n' input_ssh_port while [[ "$input_ssh_port" -eq "80" || "$input_ssh_port" -eq "443" || "$input_ssh_port" -eq "4123" ]]; do read -ep "No, ssh can't use $input_ssh_port as port, write again:"$'\n' input_ssh_port done # Read SSH Pubkey read -ep "Enter SSH public key:"$'\n' input_ssh_pbk echo "$input_ssh_pbk" > ./test_pbk ssh-keygen -l -f ./test_pbk PBK_STATUS=$(echo $?) if [ "$PBK_STATUS" -eq 255 ]; then echo "Can't verify the public key. Try again and make sure to include 'ssh-rsa' or 'ssh-ed25519' followed by 'user@pcname' at the end of the file." exit fi rm ./test_pbk fi read -ep "Do you want to install WARP and use it on russian websites? [y/N] "$'\n' configure_warp_input if [[ ${configure_warp_input,,} == "y" ]]; then if ! curl -I https://api.cloudflareclient.com --connect-timeout 10 > /dev/null 2>&1; then echo "Warp can't be used" configure_warp_input="n" fi fi # Check congestion protocol if sysctl net.ipv4.tcp_congestion_control | grep bbr; then echo "BBR is already used" else echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf sysctl -p > /dev/null echo "Enabled BBR" fi export ARCH=$(dpkg --print-architecture) yq_install() { wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_$ARCH -O /usr/bin/yq && chmod +x /usr/bin/yq } yq_install docker_install() { curl -fsSL https://get.docker.com | sh } if ! command -v docker 2>&1 >/dev/null; then docker_install fi # Generate values for XRay export SSH_USER=$(tr -dc A-Za-z0-9 ./docker-compose.yml yq eval \ '.services.marzban.image = "gozargah/marzban:v0.8.4" | .services.marzban.container_name = "marzban" | .services.marzban.restart = "always" | .services.marzban.env_file = "./marzban/.env" | .services.marzban.network_mode = "host" | .services.marzban.volumes[0] = "./marzban_lib:/var/lib/marzban" | .services.marzban.volumes[1] = "./marzban/xray_config.json:/code/xray_config.json" | .services.marzban.volumes[2] = "./marzban/templates:/var/lib/marzban/templates" | .services.caddy.volumes[2] = "./marzban_lib:/run/marzban"' -i /opt/xray-vps-setup/docker-compose.yml mkdir -p marzban caddy wget -qO- https://raw.githubusercontent.com/$GIT_REPO/refs/heads/$GIT_BRANCH/templates_for_script/marzban | envsubst > ./marzban/.env mkdir -p /opt/xray-vps-setup/marzban/templates/home wget -qO- https://raw.githubusercontent.com/$GIT_REPO/refs/heads/$GIT_BRANCH/templates_for_script/confluence_page | envsubst > ./marzban/templates/home/index.html export CADDY_REVERSE="reverse_proxy * unix//run/marzban/marzban.socket" wget -qO- "https://raw.githubusercontent.com/$GIT_REPO/refs/heads/$GIT_BRANCH/templates_for_script/caddy" | envsubst > ./caddy/Caddyfile wget -qO- "https://raw.githubusercontent.com/$GIT_REPO/refs/heads/$GIT_BRANCH/templates_for_script/xray" | envsubst > ./marzban/xray_config.json else wget -qO- https://raw.githubusercontent.com/$GIT_REPO/refs/heads/$GIT_BRANCH/templates_for_script/compose | envsubst > ./docker-compose.yml mkdir -p /opt/xray-vps-setup/caddy/templates yq eval \ '.services.xray.image = "ghcr.io/xtls/xray-core:25.6.8" | .services.xray.container_name = "xray" | .services.xray.user = "root" | .services.xray.command = "run -c /etc/xray/config.json" | .services.xray.restart = "always" | .services.xray.network_mode = "host" | .services.caddy.volumes[2] = "./caddy/templates:/srv" | .services.xray.volumes[0] = "./xray:/etc/xray"' -i /opt/xray-vps-setup/docker-compose.yml wget -qO- https://raw.githubusercontent.com/$GIT_REPO/refs/heads/$GIT_BRANCH/templates_for_script/confluence_page | envsubst > ./caddy/templates/index.html export CADDY_REVERSE="root * /srv file_server" mkdir -p xray caddy wget -qO- "https://raw.githubusercontent.com/$GIT_REPO/refs/heads/$GIT_BRANCH/templates_for_script/xray" | envsubst > ./xray/config.json wget -qO- "https://raw.githubusercontent.com/$GIT_REPO/refs/heads/$GIT_BRANCH/templates_for_script/caddy" | envsubst > ./caddy/Caddyfile fi } xray_setup sshd_edit() { grep -r Port /etc/ssh -l | xargs -n 1 sed -i -e "/Port /c\Port $SSH_PORT" grep -r PasswordAuthentication /etc/ssh -l | xargs -n 1 sed -i -e "/PasswordAuthentication /c\PasswordAuthentication no" grep -r PermitRootLogin /etc/ssh -l | xargs -n 1 sed -i -e "/PermitRootLogin /c\PermitRootLogin no" systemctl daemon-reload systemctl restart ssh } add_user() { useradd $SSH_USER -s /bin/bash usermod -aG sudo $SSH_USER echo $SSH_USER:$SSH_USER_PASS | chpasswd mkdir -p /home/$SSH_USER/.ssh touch /home/$SSH_USER/.ssh/authorized_keys echo $input_ssh_pbk >> /home/$SSH_USER/.ssh/authorized_keys chmod 700 /home/$SSH_USER/.ssh/ chmod 600 /home/$SSH_USER/.ssh/authorized_keys chown $SSH_USER:$SSH_USER -R /home/$SSH_USER usermod -aG docker $SSH_USER } debconf-set-selections <