@@ -50,47 +50,120 @@ detect_legacy_linux() {
5050 ;;
5151 esac
5252}
53- select_release_artifact () {
53+ print_usage () {
54+ cat << 'USAGE '
55+ MasterDnsVPN Server Linux Installer
56+
57+ Usage:
58+ bash <(curl -Ls https://raw.githubusercontent.com/masterking32/MasterDnsVPN/main/server_linux_install.sh) [OPTIONS]
59+
60+ Options:
61+ -v, --version <VERSION> Install a specific MasterDnsVPN release (tag), e.g. v1.2.3.
62+ If omitted, the latest release is installed.
63+ -u, --uninstall Uninstall MasterDnsVPN: stop and remove the systemd
64+ service, drop kernel/limit tunings, and clean up
65+ binaries and config files in the install directory.
66+ -h, --help Show this help message and exit.
67+
68+ Examples:
69+ # Install the latest release (default behavior):
70+ bash <(curl -Ls https://raw.githubusercontent.com/masterking32/MasterDnsVPN/main/server_linux_install.sh)
71+
72+ # Install a specific release version:
73+ bash <(curl -Ls https://raw.githubusercontent.com/masterking32/MasterDnsVPN/main/server_linux_install.sh) --version v1.2.3
74+
75+ # Uninstall MasterDnsVPN:
76+ bash <(curl -Ls https://raw.githubusercontent.com/masterking32/MasterDnsVPN/main/server_linux_install.sh) --uninstall
77+ USAGE
78+ }select_release_artifact() {
5479 local arch=" $1 "
80+ local version=" ${2:- } "
5581 local legacy=0
5682 if detect_legacy_linux; then
5783 legacy=1
5884 log_info " Legacy system detected (broader Linux compatibility mode)."
5985 fi
6086
87+ local base_url
88+ if [[ -n " $version " ]]; then
89+ base_url=" https://github.com/masterking32/MasterDnsVPN/releases/download/${version} "
90+ log_info " Targeting MasterDnsVPN release: ${version} "
91+ else
92+ base_url=" https://github.com/masterking32/MasterDnsVPN/releases/latest/download"
93+ fi
94+
6195 case " $arch " in
6296 aarch64|arm64)
6397 if [[ $legacy -eq 1 ]]; then
64- URL=" https://github.com/masterking32/MasterDnsVPN/releases/latest/download/MasterDnsVPN_Server_Linux-Legacy_ARM64.zip"
6598 PREFIX=" MasterDnsVPN_Server_Linux-Legacy_ARM64"
6699 else
67- URL=" https://github.com/masterking32/MasterDnsVPN/releases/latest/download/MasterDnsVPN_Server_Linux_ARM64.zip"
68100 PREFIX=" MasterDnsVPN_Server_Linux_ARM64"
69101 fi
70102 ;;
71103 armv7l|armv7|armhf)
72- URL=" https://github.com/masterking32/MasterDnsVPN/releases/latest/download/MasterDnsVPN_Server_Linux_ARMV7.zip"
73104 PREFIX=" MasterDnsVPN_Server_Linux_ARMV7"
74105 ;;
75106 x86_64|amd64)
76107 if [[ $legacy -eq 1 ]]; then
77- URL=" https://github.com/masterking32/MasterDnsVPN/releases/latest/download/MasterDnsVPN_Server_Linux-Legacy_AMD64.zip"
78108 PREFIX=" MasterDnsVPN_Server_Linux-Legacy_AMD64"
79109 else
80- URL=" https://github.com/masterking32/MasterDnsVPN/releases/latest/download/MasterDnsVPN_Server_Linux_AMD64.zip"
81110 PREFIX=" MasterDnsVPN_Server_Linux_AMD64"
82111 fi
83112 ;;
84113 i386|i486|i586|i686|x86)
85- URL=" https://github.com/masterking32/MasterDnsVPN/releases/latest/download/MasterDnsVPN_Server_Linux_X86.zip"
86114 PREFIX=" MasterDnsVPN_Server_Linux_X86"
87115 ;;
88116 * )
89117 log_error " Unsupported architecture: $arch "
90118 ;;
91119 esac
120+
121+ URL=" ${base_url} /${PREFIX} .zip"
92122}
93123
124+ ACTION=" install"
125+ TARGET_VERSION=" "
126+ while [[ $# -gt 0 ]]; do
127+ case " $1 " in
128+ -v|--version)
129+ [[ $# -ge 2 ]] || { echo " Error: $1 requires a value" >&2 ; print_usage; exit 2; }
130+ TARGET_VERSION=" $2 "
131+ shift 2
132+ ;;
133+ --version=* )
134+ TARGET_VERSION=" ${1#* =} "
135+ shift
136+ ;;
137+ -u|--uninstall)
138+ ACTION=" uninstall"
139+ shift
140+ ;;
141+ -h|--help)
142+ print_usage
143+ exit 0
144+ ;;
145+ --)
146+ shift
147+ break
148+ ;;
149+ * )
150+ echo " Error: unknown option: $1 " >&2
151+ print_usage
152+ exit 2
153+ ;;
154+ esac
155+ done
156+
157+ if [[ " $ACTION " == " uninstall" && -n " $TARGET_VERSION " ]]; then
158+ echo " Error: --version cannot be combined with --uninstall" >&2
159+ exit 2
160+ fi
161+
162+ if [[ -n " $TARGET_VERSION " && ! " $TARGET_VERSION " =~ ^[A-Za-z0-9._+-]+$ ]]; then
163+ echo " Error: invalid version tag: $TARGET_VERSION " >&2
164+ exit 2
165+ fi
166+
94167if [[ " ${EUID} " -ne 0 ]]; then
95168 log_error " Run this script as root (sudo)."
96169fi
@@ -120,7 +193,11 @@ echo " | \ / | __ _ ___| |_ ___ _ __ | | | | \| | (___ "
120193echo " | |\/| |/ _\` / __| __/ _ \ '__|| | | | . \ |\___ \ "
121194echo " | | | | (_| \__ \ || __/ | | |__| | |\ |____) |"
122195echo " |_| |_|\__,_|___/\__\___|_| |_____/|_| \_|_____/ "
123- echo -e " MasterDnsVPN Server Auto-Installer${NC} "
196+ if [[ " $ACTION " == " uninstall" ]]; then
197+ echo -e " MasterDnsVPN Server Auto-Uninstaller${NC} "
198+ else
199+ echo -e " MasterDnsVPN Server Auto-Installer${NC} "
200+ fi
124201echo -e " ${CYAN} ------------------------------------------------------${NC} "
125202
126203TMP_LOG=" init_logs.tmp"
@@ -298,6 +375,85 @@ remove_port53_forward_rules() {
298375 remove_nft_port53_redirects
299376}
300377
378+ do_uninstall () {
379+ log_header " Uninstalling MasterDnsVPN"
380+
381+ if systemctl list-unit-files --all 2> /dev/null | grep -q ' ^masterdnsvpn\.service' ; then
382+ log_info " Stopping and disabling masterdnsvpn service..."
383+ systemctl stop masterdnsvpn 2> /dev/null || true
384+ systemctl disable masterdnsvpn > /dev/null 2>&1 || true
385+ systemctl reset-failed masterdnsvpn 2> /dev/null || true
386+ else
387+ log_info " No masterdnsvpn systemd unit found."
388+ fi
389+
390+ if [[ -f /etc/systemd/system/masterdnsvpn.service ]]; then
391+ rm -f /etc/systemd/system/masterdnsvpn.service
392+ log_success " Removed /etc/systemd/system/masterdnsvpn.service"
393+ fi
394+ systemctl daemon-reload 2> /dev/null || true
395+
396+ local pid cmdline
397+ while IFS= read -r pid; do
398+ [[ -z " $pid " ]] && continue
399+ cmdline=" $( ps -p " $pid " -o cmd= 2> /dev/null || true) "
400+ if echo " $cmdline " | grep -qiE ' masterdnsvpn' ; then
401+ log_warn " Terminating stray MasterDnsVPN process (PID: $pid )..."
402+ kill " $pid " 2> /dev/null || true
403+ sleep 1
404+ if kill -0 " $pid " 2> /dev/null; then
405+ kill -9 " $pid " 2> /dev/null || true
406+ fi
407+ fi
408+ done < <( pgrep -fi ' masterdnsvpn' 2> /dev/null || true)
409+
410+ if [[ -f /etc/sysctl.d/99-masterdnsvpn.conf ]]; then
411+ rm -f /etc/sysctl.d/99-masterdnsvpn.conf
412+ sysctl --system > /dev/null 2>&1 || true
413+ log_success " Removed kernel tuning (/etc/sysctl.d/99-masterdnsvpn.conf)."
414+ fi
415+ if [[ -f /etc/security/limits.d/99-masterdnsvpn.conf ]]; then
416+ rm -f /etc/security/limits.d/99-masterdnsvpn.conf
417+ log_success " Removed file descriptor limits (/etc/security/limits.d/99-masterdnsvpn.conf)."
418+ fi
419+
420+ if [[ -f /etc/systemd/resolved.conf.bak && -f /etc/systemd/resolved.conf ]]; then
421+ log_info " Restoring original /etc/systemd/resolved.conf from backup..."
422+ mv -f /etc/systemd/resolved.conf.bak /etc/systemd/resolved.conf
423+ systemctl restart systemd-resolved 2> /dev/null || true
424+ fi
425+
426+ log_header " Cleaning Install Directory"
427+ log_info " Install directory: $INSTALL_DIR "
428+ shopt -s nullglob
429+ local removed=0
430+ for f in \
431+ " $INSTALL_DIR " /MasterDnsVPN_Server_Linux* _v* \
432+ " $INSTALL_DIR " /server_config.toml \
433+ " $INSTALL_DIR " /server_config.toml.backup \
434+ " $INSTALL_DIR " /server_config.toml.bak \
435+ " $INSTALL_DIR " /server_config_* .toml \
436+ " $INSTALL_DIR " /encrypt_key.txt \
437+ " $INSTALL_DIR " /init_logs.tmp \
438+ " $INSTALL_DIR " /* .spec; do
439+ if [[ -e " $f " ]]; then
440+ rm -f -- " $f "
441+ log_info " Removed: $f "
442+ removed=1
443+ fi
444+ done
445+ shopt -u nullglob
446+ if [[ $removed -eq 0 ]]; then
447+ log_warn " No MasterDnsVPN files found in $INSTALL_DIR . If you installed elsewhere, run the uninstaller from that directory."
448+ fi
449+
450+ echo -e " \n${CYAN} ======================================================${NC} "
451+ echo -e " ${GREEN}${BOLD} MASTERDNSVPN UNINSTALL COMPLETED${NC} "
452+ echo -e " ${CYAN} ======================================================${NC} "
453+ echo -e " ${YELLOW} Note:${NC} Firewall rules for port 53 (UDP/TCP) were left in place."
454+ echo -e " Remove them manually if no longer needed."
455+ }
456+
301457stop_existing_masterdnsvpn_service () {
302458 local unit_present=0
303459 if systemctl list-unit-files --all 2> /dev/null | grep -q ' ^masterdnsvpn\.service' ; then
@@ -337,6 +493,11 @@ stop_existing_masterdnsvpn_service() {
337493 done <<< " $(get_port53_pids)"
338494}
339495
496+ if [[ " $ACTION " == " uninstall" ]]; then
497+ do_uninstall
498+ exit 0
499+ fi
500+
340501log_header " Stopping Existing MasterDnsVPN"
341502stop_existing_masterdnsvpn_service
342503
@@ -349,7 +510,9 @@ if check_port53; then
349510
350511 if systemctl is-active --quiet systemd-resolved; then
351512 log_info " Configuring systemd-resolved DNSStubListener=no ..."
352- backup_file_once /etc/systemd/resolved.conf
513+ if [[ -f /etc/systemd/resolved.conf && ! -f /etc/systemd/resolved.conf.bak ]]; then
514+ cp -a /etc/systemd/resolved.conf /etc/systemd/resolved.conf.bak
515+ fi
353516 if grep -q ' ^#\?DNSStubListener=' /etc/systemd/resolved.conf; then
354517 sed -i ' s/^#\?DNSStubListener=.*/DNSStubListener=no/' /etc/systemd/resolved.conf || true
355518 else
@@ -470,9 +633,13 @@ root hard nofile 1048576
470633EOF
471634log_success " Kernel and file descriptor limits configured."
472635
473- log_header " Fetching Latest Release"
636+ if [[ -n " $TARGET_VERSION " ]]; then
637+ log_header " Fetching Release ${TARGET_VERSION} "
638+ else
639+ log_header " Fetching Latest Release"
640+ fi
474641ARCH=" $( uname -m) "
475- select_release_artifact " $ARCH "
642+ select_release_artifact " $ARCH " " $TARGET_VERSION "
476643
477644if [[ -f " server_config.toml" ]]; then
478645 mv -f server_config.toml server_config.toml.backup
545712
546713log_header " Security Initialization"
547714log_info " Starting server once to generate encryption key..."
548- if ! ./" $EXECUTABLE " -genkey -nowait > " $TMP_LOG " 2>&1 ; then
549- log_warn " Initialization log tail:"
550- tail -n 20 " $TMP_LOG " || true
551- log_error " Could not verify key generation."
715+ EXECUTABLE_ARGS=" -genkey -nowait"
716+ KEY_GENERATED=false
717+
718+ # Try with -genkey -nowait (newest versions)
719+ if ./" $EXECUTABLE " $EXECUTABLE_ARGS > " $TMP_LOG " 2>&1 ; then
720+ log_success " Key generated!"
721+ KEY_GENERATED=true
722+ fi
723+
724+ # Try running normally to trigger key generation (older versions)
725+ if [[ " $KEY_GENERATED " != true ]]; then
726+ ./" $EXECUTABLE " > " $TMP_LOG " 2>&1 &
727+ APP_PID=$!
728+ READY=false
729+ for _ in {1..10}; do
730+ if grep -q " Active Encryption Key" " $TMP_LOG " 2> /dev/null; then
731+ READY=true
732+ break
733+ fi
734+ sleep 1
735+ done
736+ kill " $APP_PID " 2> /dev/null || true
737+ wait " $APP_PID " 2> /dev/null || true
738+
739+ if [[ " $READY " == true ]]; then
740+ log_success " Key generated."
741+ EXECUTABLE_ARGS=" "
742+ KEY_GENERATED=true
743+ else
744+ log_warn " Initialization log tail:"
745+ tail -n 20 " $TMP_LOG " || true
746+ log_error " Could not verify key generation."
747+ fi
552748fi
553749
554750echo -e " ${GREEN}${BOLD} ------------------------------------------------------"
@@ -567,7 +763,7 @@ StartLimitIntervalSec=0
567763[Service]
568764Type=simple
569765WorkingDirectory=$INSTALL_DIR
570- ExecStart=$INSTALL_DIR /$EXECUTABLE -nowait
766+ ExecStart=$INSTALL_DIR /$EXECUTABLE $EXECUTABLE_ARGS
571767Restart=always
572768RestartSec=3
573769User=root
0 commit comments