forked from FrenchToblerone54/GhostwireInstaller
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsetup.sh
More file actions
executable file
·762 lines (728 loc) · 26.6 KB
/
setup.sh
File metadata and controls
executable file
·762 lines (728 loc) · 26.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
#!/bin/bash
set -e
GITHUB_REPO="frenchtoblerone54/ghostwire"
GW_VERSION="latest"
RED="\033[0;31m"
GREEN="\033[0;32m"
YELLOW="\033[1;33m"
BLUE="\033[0;34m"
CYAN="\033[0;36m"
MAGENTA="\033[0;35m"
BOLD="\033[1m"
DIM="\033[2m"
NC="\033[0m"
INSTALL_MODE=""
p_banner() {
clear
echo -e "${CYAN}${BOLD}"
echo " ============================================================"
echo " 👻 GhostWire Easy Installer | Nasb-e Rahat "
echo " Anti-Censorship Reverse Tunnel | Tunnel Zed-e Sansor "
echo " ============================================================"
echo -e "${NC}"
echo -e " ${DIM}Source: github.com/${GITHUB_REPO}${NC}"
echo ""
}
p_step() {
echo -e "\n${BLUE}${BOLD}▶ $1${NC}"
}
p_ok() {
echo -e " ${GREEN}✓${NC} $1"
}
p_warn() {
echo -e " ${YELLOW}⚠${NC} $1"
}
p_err() {
echo -e " ${RED}✗${NC} $1" >&2
}
p_info() {
echo -e " ${CYAN}ℹ${NC} $1"
}
p_ask() {
echo -ne " ${MAGENTA}?${NC} $1"
}
p_sep() {
echo -e " ${DIM}------------------------------------------------------------${NC}"
}
p_token_box() {
local token="$1"
echo ""
echo -e " ${YELLOW}${BOLD}╔══════════════════════════════════════════════════════════╗${NC}"
echo -e " ${YELLOW}${BOLD}║ 🔑 TOKEN - IN RO SAVE KON! (Save this!) ║${NC}"
echo -e " ${YELLOW}${BOLD}║ ║${NC}"
echo -e " ${YELLOW}${BOLD}║ ${NC}${BOLD}${token}${NC}${YELLOW}${BOLD} ║${NC}"
echo -e " ${YELLOW}${BOLD}║ ║${NC}"
echo -e " ${YELLOW}${BOLD}║ ⚠ Baraye Client (Kharej server) lazem dari! ║${NC}"
echo -e " ${YELLOW}${BOLD}╚══════════════════════════════════════════════════════════╝${NC}"
echo ""
}
p_panel_box() {
local url="$1"
echo ""
echo -e " ${CYAN}${BOLD}╔══════════════════════════════════════════════════════════╗${NC}"
echo -e " ${CYAN}${BOLD}║ 🖥 Web Management Panel ║${NC}"
echo -e " ${CYAN}${BOLD}║ ║${NC}"
echo -e " ${CYAN}${BOLD}║ URL: ${NC}${url}${CYAN}${BOLD} ║${NC}"
echo -e " ${CYAN}${BOLD}║ ║${NC}"
echo -e " ${CYAN}${BOLD}║ In URL ro bookmark kon! (Bookmark this URL!) ║${NC}"
echo -e " ${CYAN}${BOLD}╚══════════════════════════════════════════════════════════╝${NC}"
echo ""
}
check_prerequisites() {
p_step "Pish-niaz-ha ro check mikonim... (Checking prerequisites)"
if [ "$EUID" -ne 0 ]; then
p_err "Bayad ba sudo ejra koni! Run with: sudo bash setup.sh"
exit 1
fi
p_ok "Root access: OK"
if [ "$(uname -m)" != "x86_64" ]; then
p_err "Faqat x86_64 (64-bit) support mishe! Nur x86_64 unterstützt."
exit 1
fi
p_ok "CPU: x86_64 - OK"
if [ "$(uname -s)" != "Linux" ]; then
p_err "Faqat Linux support mishe!"
exit 1
fi
p_ok "OS: Linux - OK"
if ! command -v curl &>/dev/null && ! command -v wget &>/dev/null; then
p_err "curl ya wget lazem dari! Nasb kon: apt-get install -y curl"
exit 1
fi
p_ok "curl/wget: OK"
}
fetch_url() {
local url="$1"
local out="$2"
if command -v curl &>/dev/null; then
curl -fsSL --max-time 10 "$url" -o "$out" 2>/dev/null
else
wget -q --timeout=10 "$url" -O "$out" 2>/dev/null
fi
}
fetch_text() {
local url="$1"
if command -v curl &>/dev/null; then
curl -s --max-time 8 "$url" 2>/dev/null || true
else
wget -qO- --timeout=8 "$url" 2>/dev/null || true
fi
}
detect_country() {
local country=""
p_info "IP-e shoma ro detect mikonim... (Detecting your location)"
country=$(fetch_text "https://ipapi.co/country_code/")
[ ${#country} -eq 2 ] && { echo "$country"; return; }
country=$(fetch_text "https://ipinfo.io/country" | tr -d '"' | tr -d ' ')
[ ${#country} -eq 2 ] && { echo "$country"; return; }
country=$(fetch_text "https://api.country.is/" | grep -o '"country":"[A-Z]*"' | grep -o '[A-Z]*"' | tr -d '"' || true)
[ ${#country} -eq 2 ] && { echo "$country"; return; }
local ip
ip=$(fetch_text "https://api.ipify.org")
[ -n "$ip" ] && country=$(fetch_text "https://ipapi.co/${ip}/country_code/")
[ ${#country} -eq 2 ] && { echo "$country"; return; }
echo "IR"
}
ask_location() {
local detected
detected=$(detect_country)
local suggested_mode="KHAREJ"
[ "$detected" = "IR" ] && suggested_mode="IRAN"
p_step "Server shoma kojast? (Where is your server?)"
p_sep
if [ "$detected" = "IR" ]; then
echo -e " ${BLUE}ℹ${NC} IP-e shoma az ${BLUE}${BOLD}IRAN${NC} detect shod. 🇮🇷"
echo -e " ${BLUE}ℹ${NC} Pishnahad: ${BLUE}${BOLD}Iran Server (Server Mode)${NC}"
else
echo -e " ${GREEN}ℹ${NC} IP-e shoma az ${GREEN}${BOLD}Kharej${NC} detect shod. 🌍 (Country: ${detected})"
echo -e " ${GREEN}ℹ${NC} Pishnahad: ${GREEN}${BOLD}Kharej Client (Client Mode)${NC}"
fi
p_sep
echo ""
echo -e " ${BOLD}Lotfan entekhab konid (Please choose):${NC}"
echo ""
echo -e " ${BLUE}${BOLD}1)${NC} 🇮🇷 ${BLUE}${BOLD}Iran Server${NC}"
echo -e " ${DIM}Server darun-e Iran - port-ha ro listen mikone${NC}"
echo -e " ${DIM}GhostWire inja nasb mishe va dar-e varoodi ro baz negah midare${NC}"
echo ""
echo -e " ${GREEN}${BOLD}2)${NC} 🌍 ${GREEN}${BOLD}Kharej Client (Abroad)${NC}"
echo -e " ${DIM}Server birun az Iran - be Iran vasl mishe, internet ro forwart mikone${NC}"
echo -e " ${DIM}GhostWire inja nasb mishe va traffic ro be internet miresone${NC}"
echo ""
local default_num="1"
[ "$suggested_mode" = "KHAREJ" ] && default_num="2"
local choice=""
while true; do
p_ask "Gozine-ye shoma (1 ya 2) [default: ${default_num}]: "
read -r choice
choice="${choice:-${default_num}}"
case "$choice" in
"1") INSTALL_MODE="IRAN"; break ;;
"2") INSTALL_MODE="KHAREJ"; break ;;
*) p_err "Lotfan 1 ya 2 bezan!" ;;
esac
done
echo ""
if [ "$INSTALL_MODE" = "IRAN" ]; then
echo -e " ${BLUE}✓${NC} Mode: ${BLUE}${BOLD}Iran Server${NC} - nasb mikonim... 🇮🇷"
else
echo -e " ${GREEN}✓${NC} Mode: ${GREEN}${BOLD}Kharej Client${NC} - nasb mikonim... 🌍"
fi
}
download_binary() {
local bin_name="$1"
local bin_url="https://github.com/${GITHUB_REPO}/releases/${GW_VERSION}/download/${bin_name}"
local sha_url="${bin_url}.sha256"
p_info "Daryaft: ${bin_name} (Downloading binary)"
if command -v wget &>/dev/null; then
wget -q --show-progress "$bin_url" -O "/tmp/${bin_name}"
wget -q "$sha_url" -O "/tmp/${bin_name}.sha256"
else
curl -L --progress-bar "$bin_url" -o "/tmp/${bin_name}"
curl -fsSL "$sha_url" -o "/tmp/${bin_name}.sha256"
fi
p_info "Hash-e file ro check mikonim... (Verifying checksum)"
cd /tmp && sha256sum -c "${bin_name}.sha256"
p_ok "File dorost darid - hash tamiz! (Checksum verified)"
install -m 755 "/tmp/${bin_name}" "/usr/local/bin/${bin_name}"
p_ok "Binary nasb shod dar: /usr/local/bin/${bin_name}"
}
install_systemd_service() {
local svc_name="$1"
local bin_path="/usr/local/bin/${svc_name}"
local conf_path="/etc/ghostwire/${svc_name##ghostwire-}.toml"
cat > "/etc/systemd/system/${svc_name}.service" <<EOF
[Unit]
Description=GhostWire ${svc_name}
After=network.target
[Service]
Type=simple
ExecStart=${bin_path} -c ${conf_path}
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
p_ok "Systemd service sakhte shod: ${svc_name}.service"
}
start_service() {
local svc_name="$1"
systemctl enable "$svc_name"
if systemctl is-active --quiet "$svc_name"; then
systemctl restart "$svc_name"
p_ok "Service restart shod: ${svc_name}"
else
systemctl start "$svc_name"
p_ok "Service shoru shod: ${svc_name}"
fi
}
configure_server() {
p_step "Tanzim-ate server (Server configuration)"
if [ -f /etc/ghostwire/server.toml ]; then
p_warn "Config ghablan vojod dasht: /etc/ghostwire/server.toml"
p_warn "Jadid nasazi - haman config ro negah midim."
return
fi
p_info "GhostWire yek token rand (tasadofi) mikhad baraye amniyat."
p_info "In token moshakhas mikone ke client-e kharej-e to-e!"
local token
token=$(/usr/local/bin/ghostwire-server --generate-token)
echo ""
p_sep
echo -e " ${BLUE}${BOLD}1. WebSocket Port - Dar-e Varoodi${NC}"
p_info "Kharej server az in port be Iran vasl mishe."
p_info "Agar nginx doshti: host = 127.0.0.1 (default, amniyat bishtar)"
p_info "Agar nginx nadori: host = 0.0.0.0 (direct connection)"
echo ""
p_ask "WebSocket listen host [127.0.0.1]: "
read -r WS_HOST
WS_HOST="${WS_HOST:-127.0.0.1}"
p_ask "WebSocket listen port [8443]: "
read -r WS_PORT
WS_PORT="${WS_PORT:-8443}"
p_ok "WebSocket: ${WS_HOST}:${WS_PORT}"
p_sep
echo ""
echo -e " ${BLUE}${BOLD}2. Port Mapping - Che Port-hai Forward Beshe?${NC}"
p_info "Misali: 8080=80 => Iran:8080 traffic ro be internet port 80 miresone"
p_info "Misali: 8443=443 => Iran:8443 traffic ro be internet port 443 miresone"
p_info "Misali: 8000-8100=80 => Port range forwarding"
p_info "Misali: 9000=1.2.3.4:443 => Be yek IP-e khas forward kone"
echo ""
p_info "Agar proxy (like V2Ray, Xray) daridal kharej:"
p_info " Oon proxy-e kharej port X ro listen mikone"
p_info " Inja bezan: 443=X (Iran 443 → kharej port X)"
echo ""
local tunnel_input=""
while true; do
p_ask "Port mapping-ha (ba comma joda kon) [8080=80,8443=443]: "
read -r tunnel_input
tunnel_input="${tunnel_input:-8080=80,8443=443}"
[ -n "$tunnel_input" ] && break
p_err "In ghole lazem-e!"
done
IFS="," read -ra TUNNELS <<< "$tunnel_input"
TUNNELS=("${TUNNELS[@]// /}")
p_sep
echo ""
echo -e " ${BLUE}${BOLD}3. Auto-Update - Be-roozresani Khodkar${NC}"
p_info "GhostWire az GitHub jadid-tarinha ro check mikone va khodesh update mishe."
p_ask "Auto-update ro faal koni? [Y/n]: "
read -r AUTO_UPDATE
AUTO_UPDATE="${AUTO_UPDATE:-y}"
if [[ "$AUTO_UPDATE" =~ ^[Yy]$ ]]; then
AUTO_UPDATE="true"
p_ok "Auto-update: Faal"
else
AUTO_UPDATE="false"
p_warn "Auto-update: Gheyr-e Faal"
fi
p_sep
echo ""
echo -e " ${BLUE}${BOLD}4. Web Panel - Pane-le Modiriyat${NC}"
p_info "Yek interface grafiki baraye monitoring, log va control-e service."
p_info "Amniyat: Faghat az localhost qabl dashreset (baraye nginx proxy)."
p_ask "Panel ro faal koni? [Y/n]: "
read -r ENABLE_PANEL
ENABLE_PANEL="${ENABLE_PANEL:-y}"
local PANEL_ENABLED="false"
local PANEL_HOST="127.0.0.1"
local PANEL_PORT="9090"
local PANEL_PATH=""
local PANEL_CONFIG=""
if [[ "$ENABLE_PANEL" =~ ^[Yy]$ ]]; then
PANEL_ENABLED="true"
p_ask "Panel host [127.0.0.1]: "
read -r PANEL_HOST
PANEL_HOST="${PANEL_HOST:-127.0.0.1}"
p_ask "Panel port [9090]: "
read -r PANEL_PORT
PANEL_PORT="${PANEL_PORT:-9090}"
PANEL_PATH=$(/usr/local/bin/ghostwire-server --generate-token)
PANEL_CONFIG="
[panel]
enabled=true
host=\"${PANEL_HOST}\"
port=${PANEL_PORT}
path=\"${PANEL_PATH}\"
threads=4"
p_ok "Panel: http://${PANEL_HOST}:${PANEL_PORT}/${PANEL_PATH}/"
fi
local TUNNEL_ARRAY
TUNNEL_ARRAY=$(printf ',"%s"' "${TUNNELS[@]}")
TUNNEL_ARRAY="[${TUNNEL_ARRAY:1}]"
p_sep
echo ""
echo -e " ${BLUE}${BOLD}Kholaseh-ye Config (Summary):${NC}"
p_info "WebSocket: ${WS_HOST}:${WS_PORT}"
p_info "Tunnels: ${TUNNEL_ARRAY}"
p_info "Auto-update: ${AUTO_UPDATE}"
[ "$PANEL_ENABLED" = "true" ] && p_info "Panel: http://${PANEL_HOST}:${PANEL_PORT}/${PANEL_PATH}/"
echo ""
p_ask "Confirm? Zakhire beshe? [Y/n]: "
read -r CONFIRM
CONFIRM="${CONFIRM:-y}"
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
p_err "Nasb cancel shod."
exit 1
fi
mkdir -p /etc/ghostwire
cat > /etc/ghostwire/server.toml <<EOF
[server]
protocol="websocket"
listen_host="${WS_HOST}"
listen_port=${WS_PORT}
listen_backlog=4096
websocket_path="/ws"
ping_interval=30
ping_timeout=60
ws_pool_enabled=true
ws_pool_children=8
ws_pool_min=2
ws_pool_stripe=false
udp_enabled=true
ws_send_batch_bytes=65536
auto_update=${AUTO_UPDATE}
update_check_interval=300
update_check_on_startup=true
[auth]
token="${token}"
[tunnels]
ports=${TUNNEL_ARRAY}
[logging]
level="info"
file="/var/log/ghostwire-server.log"${PANEL_CONFIG}
EOF
p_ok "Config zakhire shod: /etc/ghostwire/server.toml"
p_token_box "$token"
if [ "$PANEL_ENABLED" = "true" ]; then
p_panel_box "http://${PANEL_HOST}:${PANEL_PORT}/${PANEL_PATH}/"
fi
}
setup_nginx_server() {
p_step "Nginx Setup - Reverse Proxy (Optional)"
p_info "Nginx yek in-dari (reverse proxy) ast ke connection-ha ro be GhostWire miresone."
p_info "Fayde-ha: TLS/HTTPS, domain name, security bishtar."
p_info "Agar domain nadari ya direct mikhai, skip kon."
echo ""
p_ask "Nginx ro hazir koni? [y/N]: "
read -r -n 1 REPLY
echo ""
if [[ ! "$REPLY" =~ ^[Yy]$ ]]; then
p_info "Nginx skip shod. Direct connection mode."
p_info "Port WS-e server ro (${WS_PORT}) direct expose kon ya bad nasb kon."
return
fi
p_info "Nasb-e nginx va certbot..."
apt-get update -qq && apt-get install -y -qq nginx certbot python3-certbot-nginx
p_ok "nginx va certbot nasb shod."
if [ -f /etc/nginx/sites-available/ghostwire ]; then
rm -f /etc/nginx/sites-enabled/ghostwire /etc/nginx/sites-available/ghostwire
systemctl is-active --quiet nginx && systemctl reload nginx
fi
echo ""
p_ask "Domain-et ro bezan (meslan: tunnel.mysite.com): "
read -r DOMAIN
while [ -z "$DOMAIN" ]; do
p_err "Domain lazem-e!"
p_ask "Domain: "
read -r DOMAIN
done
cat > /etc/nginx/sites-available/ghostwire <<EOF
server {
listen 80;
server_name ${DOMAIN};
location /.well-known/acme-challenge/ {
root /var/www/html;
}
}
EOF
ln -sf /etc/nginx/sites-available/ghostwire /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
p_ok "Nginx config aval sakhte shod."
echo ""
p_ask "TLS certificate ba Let's Encrypt begiri? [y/N]: "
read -r -n 1 TLS_REPLY
echo ""
if [[ "$TLS_REPLY" =~ ^[Yy]$ ]]; then
certbot --nginx -d "$DOMAIN"
p_ok "TLS certificate gereft!"
fi
local WS_PORT_CURRENT
WS_PORT_CURRENT=$(grep "listen_port" /etc/ghostwire/server.toml | cut -d'=' -f2 | tr -d ' ')
WS_PORT_CURRENT="${WS_PORT_CURRENT:-8443}"
cat > /etc/nginx/sites-available/ghostwire <<EOF
server {
listen 80;
server_name ${DOMAIN};
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://\$server_name\$request_uri;
}
}
server {
listen 443 ssl http2;
server_name ${DOMAIN};
ssl_certificate /etc/letsencrypt/live/${DOMAIN}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${DOMAIN}/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location /ws {
proxy_pass http://127.0.0.1:${WS_PORT_CURRENT};
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_buffering off;
proxy_request_buffering off;
tcp_nodelay on;
}
location / {
root /var/www/html;
index index.html;
}
}
EOF
nginx -t && systemctl reload nginx
p_ok "Nginx config kamel shod baraye: ${DOMAIN}"
local PANEL_ENABLED_CHECK
PANEL_ENABLED_CHECK=$(grep "^enabled=true" /etc/ghostwire/server.toml 2>/dev/null | head -1 || true)
if [ -n "$PANEL_ENABLED_CHECK" ]; then
echo ""
p_ask "Baraye panel ham yek domain joda mikhahi? [y/N]: "
read -r -n 1 PANEL_DOMAIN_REPLY
echo ""
if [[ "$PANEL_DOMAIN_REPLY" =~ ^[Yy]$ ]]; then
p_ask "Panel domain: "
read -r PANEL_DOMAIN
local PANEL_PORT_CURRENT
PANEL_PORT_CURRENT=$(grep "^port=" /etc/ghostwire/server.toml 2>/dev/null | tail -1 | cut -d'=' -f2 || echo "9090")
rm -f /etc/nginx/sites-enabled/ghostwire-panel /etc/nginx/sites-available/ghostwire-panel
cat > /etc/nginx/sites-available/ghostwire-panel <<EOF
server {
listen 80;
server_name ${PANEL_DOMAIN};
location /.well-known/acme-challenge/ {
root /var/www/html;
}
}
EOF
ln -sf /etc/nginx/sites-available/ghostwire-panel /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
p_ask "TLS baraye panel domain? [y/N]: "
read -r -n 1 PANEL_TLS
echo ""
[[ "$PANEL_TLS" =~ ^[Yy]$ ]] && certbot --nginx -d "$PANEL_DOMAIN"
cat > /etc/nginx/sites-available/ghostwire-panel <<EOF
server {
listen 80;
server_name ${PANEL_DOMAIN};
location /.well-known/acme-challenge/ {
root /var/www/html;
}
location / {
return 301 https://\$server_name\$request_uri;
}
}
server {
listen 443 ssl http2;
server_name ${PANEL_DOMAIN};
ssl_certificate /etc/letsencrypt/live/${PANEL_DOMAIN}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${PANEL_DOMAIN}/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://127.0.0.1:${PANEL_PORT_CURRENT};
proxy_http_version 1.1;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
EOF
nginx -t && systemctl reload nginx
p_ok "Panel nginx config tamam shod: https://${PANEL_DOMAIN}"
fi
fi
}
install_server() {
p_sep
echo ""
echo -e " ${BLUE}${BOLD}🇮🇷 Iran Server Mode${NC}"
echo ""
p_info "In server DARUN-E IRAN nasb mishe."
p_info "Vazife: Port-haye local ro listen kone va traffic ro az tunel forwart kone."
p_info "Kharej (client) az kharej be IN server vasl mishe."
echo ""
p_sep
p_step "Gam 1: Daryaft va Nasb-e Binary (Step 1: Download & Install)"
download_binary "ghostwire-server"
p_step "Gam 2: Tanzim-e Config (Step 2: Configure)"
configure_server
p_step "Gam 3: Systemd Service (Step 3: Setup Service)"
p_info "Systemd service ye daemon-e ke GhostWire ro khodkar shoru mikone."
p_info "Agar server restart she, GhostWire khodesh shoru mishe."
install_systemd_service "ghostwire-server"
p_step "Gam 4: Nginx Setup (Step 4: Reverse Proxy)"
setup_nginx_server
p_step "Gam 5: Shoru-e Service (Step 5: Start Service)"
start_service "ghostwire-server"
p_step "Nasb Tamam Shod! (Installation Complete!) 🎉"
p_sep
echo ""
echo -e " ${BLUE}${BOLD}✓ GhostWire Server dar Iran nasb shod!${NC}"
echo ""
echo -e " ${BLUE}ℹ${NC} Config: /etc/ghostwire/server.toml"
echo -e " ${BLUE}ℹ${NC} Log file: /var/log/ghostwire-server.log"
echo ""
echo -e " ${BLUE}${BOLD}Dastorat (Useful Commands):${NC}"
echo ""
echo -e " ${BLUE}sudo systemctl status ghostwire-server${NC} - Status check"
echo -e " ${BLUE}sudo systemctl restart ghostwire-server${NC} - Restart kone"
echo -e " ${BLUE}sudo systemctl stop ghostwire-server${NC} - Stop kone"
echo -e " ${BLUE}sudo journalctl -u ghostwire-server -f${NC} - Live log"
echo -e " ${BLUE}sudo ghostwire-server update${NC} - Manual update"
echo ""
p_warn "Faramosh Nakoni: Token ro ke bala neshon dade shod, save kon!"
p_warn "Baraye nasb-e client-e kharej, token lazem dari."
echo ""
p_sep
echo ""
echo -e " ${BLUE}${BOLD}Gam Baadi (Next Step):${NC}"
echo -e " ${BLUE}ℹ${NC} Boro sar server-e kharej (Netherlands/Germany/etc)"
echo -e " ${BLUE}ℹ${NC} Inja ejra kon: sudo ./setup.sh"
echo -e " ${BLUE}ℹ${NC} Entekhab kon: Kharej Client"
echo -e " ${BLUE}ℹ${NC} URL server: wss://YOUR-IRAN-DOMAIN/ws (ya direct IP:PORT)"
echo -e " ${BLUE}ℹ${NC} Token: Hamoon chi ke bala save kardi"
echo ""
}
configure_client() {
p_step "Tanzim-ate client (Client configuration)"
if [ -f /etc/ghostwire/client.toml ]; then
p_warn "Config ghablan vojod dasht: /etc/ghostwire/client.toml"
p_warn "Jadid nasazi - haman config ro negah midim."
return
fi
p_sep
echo ""
echo -e " ${GREEN}${BOLD}1. URL-e Server-e Iran${NC}"
p_info "Inja URL-e server-e Iran ro mide. Chand shakl dare:"
p_info " wss://tunnel.mysite.com/ws (ba nginx + SSL)"
p_info " ws://1.2.3.4:8443/ws (direct, bedun-e SSL)"
p_info " https://tunnel.mysite.com/ws (ham kar mikone)"
echo ""
local server_url=""
while true; do
p_ask "URL-e server-e Iran: "
read -r server_url
[ -z "$server_url" ] && { p_err "URL lazem-e!"; continue; }
[[ "$server_url" =~ ^(wss?|https?):// ]] && break
p_err "URL bayad ba ws://, wss://, http://, ya https:// shoru she!"
done
p_ok "Server URL: ${server_url}"
p_sep
echo ""
echo -e " ${GREEN}${BOLD}2. Token-e Amniyati${NC}"
p_info "Hamoon token-i ke dar Iran server nasb kardin."
p_info "Agar yad dari, az server-e Iran copy kon:"
p_info " grep token /etc/ghostwire/server.toml"
echo ""
local auth_token=""
while true; do
p_ask "Token: "
read -r auth_token
[ -z "$auth_token" ] && { p_err "Token lazem-e!"; continue; }
break
done
p_ok "Token: ${auth_token:0:8}... (accepted)"
p_sep
echo ""
echo -e " ${GREEN}${BOLD}3. Auto-Update${NC}"
p_info "GhostWire khodesh az GitHub update mishe."
p_ask "Auto-update faal bashe? [Y/n]: "
read -r AU
AU="${AU:-y}"
local auto_update="true"
if [[ "$AU" =~ ^[Nn]$ ]]; then
auto_update="false"
p_warn "Auto-update: Gheyr-e Faal"
else
p_ok "Auto-update: Faal"
fi
p_sep
echo ""
echo -e " ${GREEN}${BOLD}Kholaseh (Summary):${NC}"
p_info "Server URL: ${server_url}"
p_info "Token: ${auth_token:0:8}..."
p_info "Auto-update: ${auto_update}"
echo ""
p_ask "Confirm? Zakhire beshe? [Y/n]: "
read -r CONFIRM
CONFIRM="${CONFIRM:-y}"
if [[ ! "$CONFIRM" =~ ^[Yy]$ ]]; then
p_err "Nasb cancel shod."
exit 1
fi
mkdir -p /etc/ghostwire
cat > /etc/ghostwire/client.toml <<EOF
[server]
protocol="websocket"
url="${server_url}"
token="${auth_token}"
ping_interval=30
ping_timeout=60
ws_send_batch_bytes=65536
auto_update=${auto_update}
update_check_interval=300
update_check_on_startup=true
[reconnect]
initial_delay=1
max_delay=60
multiplier=2
[cloudflare]
enabled=false
ips=[]
host=""
check_interval=300
max_connection_time=1740
[logging]
level="info"
file="/var/log/ghostwire-client.log"
EOF
p_ok "Config zakhire shod: /etc/ghostwire/client.toml"
}
install_client() {
p_sep
echo ""
echo -e " ${GREEN}${BOLD}🌍 Kharej Client Mode${NC}"
echo ""
p_info "In client BIRUN AZ IRAN nasb mishe."
p_info "Vazife: Be server-e Iran vasl she, traffic-e Iran ro be internet brigardone."
p_info "Client khodesh vasl mishe - Iran block nemikone chon inbound-e."
echo ""
p_sep
p_step "Gam 1: Daryaft va Nasb-e Binary (Step 1: Download & Install)"
download_binary "ghostwire-client"
p_step "Gam 2: Tanzim-e Config (Step 2: Configure)"
configure_client
p_step "Gam 3: Systemd Service (Step 3: Setup Service)"
p_info "Systemd service ye daemon-e ke GhostWire ro khodkar shoru mikone."
p_info "Agar server restart she, GhostWire khodesh vasl mishe."
install_systemd_service "ghostwire-client"
p_step "Gam 4: Shoru-e Service (Step 4: Start Service)"
start_service "ghostwire-client"
p_step "Nasb Tamam Shod! (Installation Complete!) 🎉"
p_sep
echo ""
echo -e " ${GREEN}${BOLD}✓ GhostWire Client dar Kharej nasb shod!${NC}"
echo ""
echo -e " ${GREEN}ℹ${NC} Config: /etc/ghostwire/client.toml"
echo -e " ${GREEN}ℹ${NC} Log file: /var/log/ghostwire-client.log"
echo ""
echo -e " ${GREEN}${BOLD}Dastorat (Useful Commands):${NC}"
echo ""
echo -e " ${GREEN}sudo systemctl status ghostwire-client${NC} - Status check"
echo -e " ${GREEN}sudo systemctl restart ghostwire-client${NC} - Restart kone"
echo -e " ${GREEN}sudo systemctl stop ghostwire-client${NC} - Stop kone"
echo -e " ${GREEN}sudo journalctl -u ghostwire-client -f${NC} - Live log"
echo -e " ${GREEN}sudo ghostwire-client update${NC} - Manual update"
echo ""
p_sep
echo ""
echo -e " ${GREEN}${BOLD}Test Kon (How to test):${NC}"
echo -e " ${GREEN}ℹ${NC} Boro sar yek mashine darun-e Iran"
echo -e " ${GREEN}ℹ${NC} Ports-haye tanimsaz-shode (masalan 8080, 8443) ro test kon"
echo -e " ${GREEN}ℹ${NC} curl -v http://IRAN_SERVER_IP:8080"
echo -e " ${GREEN}ℹ${NC} Agar tunel kar mikone, traffic ba internet-e kharej javoqb mide"
echo ""
p_warn "Agar Cloudflare dari: dar /etc/ghostwire/client.toml"
p_warn " cloudflare enabled=true set kon baraye paydari bishtar"
echo ""
}
main() {
p_banner
p_step "Salam! Khosh Amadid be GhostWire Easy Installer"
p_info "In script GhostWire ro gam-be-gam baraye to nasb mikone."
p_info "Kharej = Client (birun az Iran) | Iran = Server (darun-e Iran)"
echo ""
p_warn "Hame chiz ba sudo ejra mishe - baraye nasb-e software lazem-e."
echo ""
check_prerequisites
ask_location
if [ "$INSTALL_MODE" = "IRAN" ]; then
install_server
else
install_client
fi
echo ""
echo -e " ${GREEN}${BOLD}Kheyr! Movafagh bashi! 🎉${NC}"
echo ""
}
main