forked from ak47229527/Xray-TLS-Web-setup-script
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBluejerry-Xray-REALITY+Web.sh
4552 lines (4401 loc) · 174 KB
/
Bluejerry-Xray-REALITY+Web.sh
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
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
#系统信息
# 指令集(amd64、x86、arm64、armv7等)
unset arch
# 系统发行版名称(ubuntu、debian、fedora、centos、oracle、rhel等)
unset distro
# 发行版基于(debian/rhel)
unset distro_like
# 系统版本
unset system_version
# 包管理器(apt/yum/dnf/microdnf)
unset pkg
# CPU线程数
unset nproc
# 安装配置(nginx、openssl、PHP、cloudreve、xray的安装版本、位置等信息)
nginx_version="nginx-1.25.1"
openssl_version="openssl-openssl-3.1.3"
nginx_prefix="/usr/local/nginx"
nginx_config="${nginx_prefix}/conf.d/xray.conf"
nginx_service="/etc/systemd/system/nginx.service"
php_version="php-8.2.8"
# 此处(php_prefix)请使用绝对路径(安装imagick时有影响)
php_prefix="/usr/local/php"
php_service="/etc/systemd/system/php-fpm.service"
cloudreve_version="3.8.3"
nextcloud_url="https://download.nextcloud.com/server/releases/nextcloud-27.0.0.tar.bz2"
xray_config="/usr/local/etc/xray/config.json"
# 临时目录
temp_dir="/temp_install_xray_reality_web"
# 安装信息(是否已经安装)
unset is_installed
unset xray_is_installed
unset nginx_is_installed
unset php_is_installed
# 配置信息
# 域名列表,带www(如果对应domain_config_list为2,则不带www,和true_domain_list相同)
unset domain_list
# 域名列表,不带www
unset true_domain_list
# 域名配置类型:1:带www,2:不带www
unset domain_config_list
# 域名伪装类型:1:cloudreve,2:nextcloud,3:重定向至pretend_redirect_list对应的域名
unset pretend_list
# 重定向至什么域名,-代表不重定向
unset pretend_redirect_list
unset pretend_redirect_index_list
# TCP(REALITY):0 禁用;1 启用
unset protocol_1
# grpc: 0 禁用;1 VLESS;2 VMess
unset protocol_2
# WebSocket:0 禁用;1 VLESS;2 VMess
unset protocol_3
# TCP(REALITY) 的 uuid
unset xid_1
# TCP(REALITY) 的 公钥
unset reality_public_key
# TCP(REALITY) 的 私钥
unset reality_private_key
# grpc 的 uuid
unset xid_2
# grpc的serviceName
unset serviceName
# ws 的 uuid
unset xid_3
# ws的path
unset path
# 其它安装过程中的临时信息
# 现在有没有通过脚本启动swap
using_swap_now=0
# 在更新
update=0
# 在 install_update_xray_reality_web 函数中
in_install_update_xray_reality_web=0
script_url="https://github.com/bluejerry2021/Xray-script/raw/main/Xray-REALITY+Web.sh"
#功能性函数:
#定义几个颜色
purple() #紫
{
echo -e "\\033[35;1m${*}\\033[0m"
}
tyblue() #天依蓝
{
echo -e "\\033[36;1m${*}\\033[0m"
}
green() #绿
{
echo -e "\\033[32;1m${*}\\033[0m"
}
yellow() #黄
{
echo -e "\\033[33;1m${*}\\033[0m"
}
red() #红
{
echo -e "\\033[31;1m${*}\\033[0m"
}
blue() #蓝
{
echo -e "\\033[34;1m${*}\\033[0m"
}
# 使用英文运行命令
english_run()
{
local command
command="$(type -P "$1")"
if [ -z "${command}" ]; then
env -i LANG="C.UTF-8" "$@"
else
shift
env -i LANG="C.UTF-8" "${command}" "$@"
fi
return $?
}
#版本比较函数
version_ge()
{
if [[ "$1" =~ $'\n' ]] || [[ "$2" =~ $'\n' ]]; then
red "版本比较输入包含换行符!"
report_bug_exit
fi
test "$(sort -rV <<< "$1"$'\n'"$2" | head -n 1)" == "$1"
}
report_bug()
{
green "欢迎进行Bug report(https://github.com/kirin10000/Xray-script/issues),感谢您的支持"
yellow "按回车键继续或者Ctrl+c退出"
read -rs
}
report_bug_exit()
{
green "欢迎进行Bug report(https://github.com/kirin10000/Xray-script/issues),感谢您的支持"
exit 1
}
#进入工作目录
enter_temp_dir()
{
local temp_exit_code=0
if ! rm -rf "$temp_dir"; then
swapoff "${temp_dir}/swap"
rm -rf "$temp_dir" || temp_exit_code=1
fi
mkdir "$temp_dir" || temp_exit_code=1
cd "$temp_dir" || temp_exit_code=1
if [ $temp_exit_code -eq 1 ]; then
yellow "进入临时目录失败"
report_bug_exit
fi
}
check_temp_dir()
{
if ! [[ -d "${temp_dir}" ]]; then
red "异常行为:尚未创建临时目录!"
report_bug_exit
fi
}
ask_if()
{
local choice=""
while [ "$choice" != "y" ] && [ "$choice" != "n" ]
do
tyblue "$1"
read -r choice
done
[ "$choice" == y ] && return 0
return 1
}
check_base_command()
{
hash -r
local i
local temp_command_list=('bash' 'sh' 'command' 'type' 'hash' 'install' 'true' 'false' 'exit' 'echo' 'test' 'sort' 'sed' 'awk' 'grep' 'cut' 'cd' 'rm' 'cp' 'mv' 'head' 'tail' 'uname' 'tr' 'md5sum' 'cat' 'find' 'wc' 'ls' 'mktemp' 'swapon' 'swapoff' 'mkswap' 'chmod' 'chown' 'chgrp' 'export' 'tar' 'gzip' 'mkdir' 'arch' 'uniq' 'dd' 'env' 'mapfile' 'nproc' 'sleep' 'read')
for i in "${temp_command_list[@]}"
do
if ! command -V "${i}" > /dev/null; then
red "命令\"${i}\"未找到"
red "不是标准的Linux系统"
exit 1
fi
done
temp_command_list=('rm' 'mkdir' 'chmod' 'chown')
for i in "${temp_command_list[@]}"
do
if [ -z "$(type -P "$i")" ]; then
red "命令 $i 没有可执行文件"
red "不支持的系统!"
report_bug_exit
fi
done
}
check_sudo()
{
if [ "$SUDO_GID" ] && [ "$SUDO_COMMAND" ] && [ "$SUDO_USER" ] && [ "$SUDO_UID" ]; then
if [ "$SUDO_USER" = "root" ] && [ "$SUDO_UID" = "0" ]; then
#it's root using sudo, no matter it's using sudo or not, just fine
return 0
fi
if [ -n "$SUDO_COMMAND" ]; then
#it's a normal user doing "sudo su", or `sudo -i` or `sudo -s`, or `sudo su acmeuser1`
echo "$SUDO_COMMAND" | grep -- "/bin/su\$" >/dev/null 2>&1 || echo "$SUDO_COMMAND" | grep -- "/bin/su " >/dev/null 2>&1 || grep "^$SUDO_COMMAND\$" /etc/shells >/dev/null 2>&1
return $?
fi
#otherwise
return 1
fi
return 0
}
check_and_get_system_info()
{
check_base_command
if [ "$EUID" != "0" ]; then
red "请用root用户运行此脚本!!"
exit 1
fi
if ! check_sudo; then
yellow "检测到正在使用sudo!"
yellow "acme.sh不支持sudo,请使用root用户运行此脚本"
tyblue "详情请见:https://github.com/acmesh-official/acme.sh/wiki/sudo"
exit 1
fi
if [[ ! -f '/etc/os-release' ]]; then
red "/etc/os-release文件不存在!"
red "不支持的系统!"
exit 1
fi
if ! [[ -d /run ]]; then
red "/run 目录不存在!"
red "不支持的系统!"
exit 1
fi
if [[ -f /.dockerenv ]] || grep -q 'docker\|lxc' /proc/1/cgroup && [[ "$(type -P systemctl)" ]]; then
true
elif [[ -d /run/systemd/system ]] || grep -q systemd <(ls -l /sbin/init); then
true
else
red "仅支持使用systemd的系统!"
exit 1
fi
if [ -n "$(type -P apt)" ] || [ -n "$(type -P apt-get)" ]; then
if [ -n "$(type -P dnf)" ] || [ -n "$(type -P microdnf)" ] || [ -n "$(type -P yum)" ]; then
red "同时存在 apt/apt-get 和 dnf/microdnf/yum"
red "不支持的系统!"
exit 1
fi
distro_like="debian"
if [ -z "$(type -P apt)" ]; then
red "该系统仅支持apt-get,不支持apt"
tyblue "可能系统版本太老"
red "不支持的系统!"
exit 1
fi
pkg="apt"
if [ -z "$(type -P apt-mark)" ]; then
red "apt-mark命令不存在!"
red "不支持的系统!"
exit 1
fi
if [ -z "$(type -P dpkg)" ]; then
red "dpkg命令不存在!"
red "不支持的系统!"
exit 1
fi
elif [ -n "$(type -P dnf)" ] || [ -n "$(type -P microdnf)" ] || [ -n "$(type -P yum)" ]; then
distro_like="rhel"
if [ -n "$(type -P dnf)" ]; then
pkg="dnf"
elif [ -n "$(type -P microdnf)" ]; then
pkg="microdnf"
else
pkg="yum"
fi
if [ -z "$(type -P rpm)" ]; then
red "rpm命令不存在!"
red "不支持的系统!"
exit 1
fi
if ! "$pkg" --help | grep -q "\\-\\-setopt"; then
red "$pkg 命令不支持 \\-\\-setopt 选项"
red "不支持的系统!"
exit 1
fi
if ! "$pkg" --help | grep -q "\\-\\-disablerepo"; then
red "$pkg 命令不支持 \\-\\-disablerepo 选项"
red "不支持的系统!"
exit 1
fi
if ! "$pkg" --help | grep -q "\\-\\-enablerepo"; then
red "$pkg 命令不支持 \\-\\-enablerepo 选项"
red "不支持的系统!"
exit 1
fi
if [ "$pkg" != "dnf" ]; then
if rpm -q dnf > /dev/null 2>&1; then
red "dnf 已安装但没有可执行文件!"
report_bug_exit
fi
tyblue "缺少包管理器dnf,尝试安装。。。"
install_dependencies dnf
check_and_get_system_info
return
fi
else
red "apt/apt-get/dnf/microdnf/yum命令均不存在!"
red "不支持的系统!"
exit 1
fi
trim_str()
{
if [[ "${temp_str}" =~ '"' ]]; then
if ! [[ "${temp_str}" =~ ^'"'.*'"'$ ]]; then
red "获取os-release信息失败!"
red "不支持的系统!"
exit 1
fi
temp_str="${temp_str#*\"}"
temp_str="${temp_str%\"*}"
fi
}
local temp_str
local id
temp_str="$(grep '^[ '$'\t]*ID[ '$'\t]*=' /etc/os-release | cut -d = -f 2-)"
trim_str
id="${temp_str}"
local name
temp_str="$(grep '^[ '$'\t]*NAME[ '$'\t]*=' /etc/os-release | cut -d = -f 2-)"
trim_str
name="${temp_str}"
if [ -z "$id" ] || [ -z "$name" ]; then
red "获取os-release信息失败!"
red "不支持的系统!"
exit 1
fi
while :
do
if grep -qiw ubuntu <<< "$id"; then
if grep -qiw ubuntu <<< "$name" && [ "$distro_like" == "debian" ]; then
distro="ubuntu"
break
fi
elif grep -qiw debian <<< "$id"; then
if grep -qiw debian <<< "$name" && [ "$distro_like" == "debian" ]; then
distro="debian"
break
fi
elif grep -qiw fedora <<< "$id"; then
if grep -qiw fedora <<< "$name" && [ "$distro_like" == "rhel" ]; then
distro="fedora"
break
fi
elif grep -qiw centos <<< "$id"; then
if grep -qiw centos <<< "$name" && [ "$distro_like" == "rhel" ]; then
if grep -qiw stream <<< "$name"; then
distro="centos-stream"
else
distro="centos"
fi
break
fi
elif grep -qiw oracle <<< "$name"; then
if grep -qiw 'ol\|oracle' <<< "$id" && [ "$distro_like" == "rhel" ]; then
distro="oracle"
break
fi
elif grep -qiw rhel <<< "$id"; then
if grep -qiw 'red hat\|redhat' <<< "$name" && [ "$distro_like" == "rhel" ]; then
distro="rhel"
break
fi
else
distro="unknow"
break
fi
red "os-release系统发行版信息id与name不符,或者发行版信息与软件包管理器不自洽!"
red "获取系统发行版信息失败!"
exit 1
done
temp_str="$(grep '^[ '$'\t'']*VERSION_ID[ '$'\t'']*=' /etc/os-release | cut -d = -f 2-)"
trim_str
system_version="${temp_str}"
case "$(arch)" in
'amd64' | 'x86_64')
arch='amd64'
;;
'armv5tel')
arch='armv5'
;;
'armv6l')
arch='armv6'
;;
'armv7' | 'armv7l')
arch='armv7'
;;
'armv8' | 'aarch64')
arch='arm64'
;;
*)
arch=''
;;
esac
if ! nproc="$(nproc)" || ! [[ "$nproc" =~ ^(((-|)[1-9][0-9]*)|0)$ ]] || [ "$nproc" -le 0 ]; then
red "获取处理器线程数失败"
exit 1
fi
if [ "$distro" == "oracle" ] && ! version_ge "$system_version" 7; then
red "系统版本过低!请使用 Oracle Linux 版本 >= 7 ,或其它发行版"
exit 1
elif [ "$distro" == "centos" ] && version_ge "$system_version" 8; then
red "Centos 8已经弃用,请使用Centos Stream 8!"
exit 1
fi
if [ -z "${BASH_SOURCE[0]}" ] || [[ "${BASH_SOURCE[0]}" =~ ^"/dev/fd/" ]]; then
red "请以 \"bash 文件名\" 的形式运行脚本!"
exit 1
fi
}
clear_config()
{
unset reality_private_key
unset reality_public_key
unset protocol_3
protocol_3=0
unset protocol_2
protocol_2=0
unset protocol_1
protocol_1=0
unset xid_3
unset xid_2
unset xid_1
unset path
unset serviceName
# 域名配置
unset domain_list
unset true_domain_list
unset domain_config_list
unset pretend_list
unset pretend_redirect_list
unset pretend_redirect_index_list
return 0
}
#获取配置信息
get_config_info()
{
# 改进:移除json中的注释?
local temp
[ $is_installed -eq 0 ] && clear_config && return
reality_private_key="$(grep '"privateKey"' "$xray_config" | cut -d : -f 2 | cut -d \" -f 2)"
[ -z "$reality_private_key" ] && clear_config && return
reality_public_key="$(grep '"reality_public_key"' "$xray_config" | cut -d : -f 2 | cut -d \" -f 2)"
[ -z "$reality_public_key" ] && clear_config && return
if grep -q '"network"[ '$'\t]*:[ '$'\t]*"ws"' "$xray_config"; then
if [[ "$(grep -oE '"protocol"[ '$'\t'']*:[ '$'\t'']*"(vmess|vless)"' "$xray_config" | tail -n 1)" =~ '"vmess"' ]]; then
protocol_3=2
else
protocol_3=1
fi
path="$(grep '"path"' "$xray_config" | tail -n 1 | cut -d : -f 2 | cut -d \" -f 2)"
[ -z "$path" ] && clear_config && return
xid_3="$(grep '"id"' "$xray_config" | tail -n 1 | cut -d : -f 2 | cut -d \" -f 2)"
[ -z "$xid_3" ] && clear_config && return
else
protocol_3=0
fi
if grep -q '"network"[ '$'\t'']*:[ '$'\t'']*"grpc"' "$xray_config"; then
if [ $protocol_3 -ne 0 ]; then
temp=2
else
temp=1
fi
if [[ "$(grep -oE '"protocol"[ '$'\t]*:[ '$'\t]*"(vmess|vless)"' "$xray_config" | tail -n $temp | head -n 1)" =~ \"vmess\" ]]; then
protocol_2=2
else
protocol_2=1
fi
serviceName="$(grep '"serviceName"' "$xray_config" | cut -d : -f 2 | cut -d \" -f 2)"
[ -z "$serviceName" ] && clear_config && return
xid_2="$(grep '"id"' "$xray_config" | tail -n $temp | head -n 1 | cut -d : -f 2 | cut -d \" -f 2)"
[ -z "$xid_2" ] && clear_config && return
else
protocol_2=0
fi
temp=1
[ $protocol_2 -ne 0 ] && ((temp++))
[ $protocol_3 -ne 0 ] && ((temp++))
if [ "$(grep -c '"clients"' "$xray_config")" -eq $temp ]; then
protocol_1=1
xid_1="$(grep '"id"' "$xray_config" | head -n 1 | cut -d : -f 2 | cut -d \" -f 2)"
[ -z "$xid_1" ] && clear_config && return
else
protocol_1=0
fi
unset domain_list
unset true_domain_list
unset domain_config_list
unset pretend_list
unset pretend_redirect_list
domain_list=($(grep "^#domain_list=" "$nginx_config" | cut -d = -f 2))
[ ${#domain_list[@]} -le 0 ] && clear_config && return
true_domain_list=($(grep "^#true_domain_list=" "$nginx_config" | cut -d = -f 2))
[ ${#true_domain_list[@]} -ne ${#domain_list[@]} ] && clear_config && return
domain_config_list=($(grep "^#domain_config_list=" "$nginx_config" | cut -d = -f 2))
[ ${#domain_config_list[@]} -ne ${#domain_list[@]} ] && clear_config && return
pretend_list=($(grep "^#pretend_list=" "$nginx_config" | cut -d = -f 2))
[ ${#pretend_list[@]} -ne ${#domain_list[@]} ] && clear_config && return
pretend_redirect_list=($(grep "^#pretend_redirect_list=" "$nginx_config" | cut -d = -f 2))
[ ${#pretend_redirect_list[@]} -ne ${#domain_list[@]} ] && clear_config && return
unset pretend_redirect_index_list
local _redirect
local i
for _redirect in "${pretend_redirect_list[@]}"
do
if [ "$_redirect" == "-" ]; then
pretend_redirect_index_list+=("")
continue
fi
for ((i = 0; i < ${#domain_list[@]}; ++i))
do
if [ "$_redirect" == "${true_domain_list[$i]}" ]; then
pretend_redirect_index_list+=("$i")
break
fi
done
clear_config
return
done
}
get_install_info()
{
[ -f /usr/local/bin/xray ] && [ -f "$xray_config" ] && systemctl cat xray > /dev/null 2>&1 && xray_is_installed=1 || xray_is_installed=0
[ -f "$nginx_config" ] && [ -f "$nginx_service" ] && [ -d "${nginx_prefix}/certs" ] && nginx_is_installed=1 || nginx_is_installed=0
[ -f "${php_prefix}/php-fpm.service.default" ] && [ -f "$php_service" ] && php_is_installed=1 || php_is_installed=0
[ $xray_is_installed -eq 1 ] && [ $nginx_is_installed -eq 1 ] && is_installed=1 || is_installed=0
get_config_info
}
#安装依赖
try_install_dependencies()
{
if [ "$#" -le 0 ] || { [ "$#" -eq 1 ] && [ -z "$1" ]; }; then
red "没有输入要安装的软件包!"
report_bug_exit
fi
if [ "$distro_like" == "debian" ]; then
if apt -y --no-install-recommends -o Dpkg::Options::="--force-confnew" install "$@"; then
return 0
fi
apt update
if apt -y --no-install-recommends -o Dpkg::Options::="--force-confnew" install "$@"; then
return 0
fi
apt update
apt -y -f --no-install-recommends -o Dpkg::Options::="--force-confnew" install
if apt -y --no-install-recommends -o Dpkg::Options::="--force-confnew" install "$@"; then
return 0
fi
else
# yum 安装多个软件包时,若其中某些软件包不存在,不会报错
if [ "$pkg" == "yum" ] && [ "$#" -gt 1 ]; then
red "异常行为:yum install 多个包"
report_bug_exit
fi
gen_enablerepo_str()
{
if "$pkg" --help | grep -q "\\-\\-enablerepo="; then
enablerepo_str=("--enablerepo=$1")
else
enablerepo_str=("--enablerepo" "$1")
fi
}
gen_disablerepo_str()
{
if "$pkg" --help | grep -q "\\-\\-disablerepo="; then
disablerepo_str=("--disablerepo=$1")
else
disablerepo_str=("--disablerepo" "$1")
fi
}
local no_install_recommends
local enablerepo_str
local disablerepo_str
if "$pkg" --help | grep -q "\\-\\-setopt="; then
no_install_recommends=("--setopt=install_weak_deps=0")
else
no_install_recommends=("--setopt" "install_weak_deps=0")
fi
if "$pkg" -y "${no_install_recommends[@]}" install "$@"; then
return 0
fi
local epel_repo
if [ "$distro" == centos-stream ]; then
epel_repo="epel,epel-next"
elif [ "$distro" == oracle ]; then
if version_ge "$system_version" 9; then
epel_repo="ol9_developer_EPEL"
elif version_ge "$system_version" 8; then
epel_repo="ol8_developer_EPEL"
elif version_ge "$system_version" 7; then
epel_repo="ol7_developer_EPEL"
fi
else
epel_repo="epel"
fi
gen_enablerepo_str "$epel_repo"
if "$pkg" -y "${no_install_recommends[@]}" "${enablerepo_str[@]}" install "$@"; then
return 0
fi
gen_enablerepo_str "$epel_repo,remi*"
if "$pkg" -y "${no_install_recommends[@]}" "${enablerepo_str[@]}" install "$@"; then
return 0
fi
gen_enablerepo_str "$epel_repo,powertools"
if "$pkg" -y "${no_install_recommends[@]}" "${enablerepo_str[@]}" install "$@"; then
return 0
fi
gen_enablerepo_str "$epel_repo,PowerTools"
if "$pkg" -y "${no_install_recommends[@]}" "${enablerepo_str[@]}" install "$@"; then
return 0
fi
gen_enablerepo_str "*"
gen_disablerepo_str "*-debug,*-debuginfo,*-source"
if "$pkg" -y "${no_install_recommends[@]}" "${enablerepo_str[@]}" "${disablerepo_str[@]}" install "$@"; then
return 0
fi
if "$pkg" -y "${no_install_recommends[@]}" "${enablerepo_str[@]}" install "$@"; then
return 0
fi
fi
return 1
}
install_dependencies()
{
if try_install_dependencies "$@"; then
return 0
fi
yellow "依赖安装失败!!"
report_bug
return 1
}
# 检查并安装单个依赖:首先检查该依赖是否已经安装(dpkg/rpm),如果该依赖已经安装,则不再安装(apt/dnf install)
# $1 : debian基系统
# $2 : redhat基系统
check_install_dependency()
{
local output
local package_name
local ret=0
if [ "$distro_like" == "debian" ]; then
if english_run dpkg -s "$1" 2>/dev/null | grep -qi 'status[ '$'\t]*:[ '$'\t]*install[ '$'\t]*ok[ '$'\t]*installed[ '$'\t]*$'; then
if ! output="$(english_run apt-mark manual "$1")"; then
ret=1
elif ! grep -qi 'set[ '$'\t]*to[ '$'\t]*manually[ '$'\t]*installed' <<< "$output"; then
ret=1
fi
package_name="$1"
else
install_dependencies "$1"
fi
else
if rpm -q "$2" > /dev/null 2>&1; then
if [ "$pkg" != "dnf" ]; then
red "异常行为:调用check_install_dependency包管理器不是dnf!"
report_bug_exit
fi
dnf mark install "$2"
ret=$?
package_name="$2"
else
install_dependencies "$2"
fi
fi
if [ $ret -ne 0 ]; then
red "标记依赖 $package_name 手动安装失败!"
report_bug
fi
}
# 卸载软件包,对于debian基系统(使用apt),将会先检测软件包是否存在,请传入软件包使用正则表达式
remove_dependencies()
{
pkg_exist()
{
local package
local installed_packages
installed_packages="$(english_run dpkg -l | grep '^[ '$'\t]*ii[ '$'\t]' | awk '{print $2}' | cut -d : -f 1)"
for package in "$@"
do
if grep -q "$package" <<< "$installed_packages"; then
exist_pkgs+=("$package")
fi
done
}
local ret
if [ "$distro_like" == debian ]; then
# 防止apt在卸载时自动下载替代软件包
local exist_pkgs=()
pkg_exist "$@"
mv /etc/apt/sources.list /etc/apt/sources.list.bak
mv /etc/apt/sources.list.d /etc/apt/sources.list.d.bak
apt -y --allow-change-held-packages purge "${exist_pkgs[@]}"
ret=$?
mv /etc/apt/sources.list.bak /etc/apt/sources.list
mv /etc/apt/sources.list.d.bak /etc/apt/sources.list.d
if [ $ret -ne 0 ]; then
if ! apt -y -f --no-install-recommends -o Dpkg::Options::="--force-confnew" install; then
apt update
apt -y -f --no-install-recommends -o Dpkg::Options::="--force-confnew" install
fi
fi
else
# dnf卸载不存在的包时一般返回0
if [ "$pkg" != "dnf" ]; then
red "异常行为:调用remove_dependencies包管理器不是dnf!"
report_bug_exit
fi
dnf -y remove "$@"
ret=$?
fi
if [ $ret -ne 0 ]; then
red "卸载软件包 $* 失败!"
report_bug
fi
}
#升级系统组件
doupdate()
{
updateSystem()
{
check_install_dependency ubuntu-release-upgrader-core ""
echo -e "\\n\\n\\n"
tyblue "------------------请选择升级系统版本--------------------"
tyblue " 1. beta版(测试版) 当前版本号:23.10"
tyblue " 2. release版(稳定版) 当前版本号:23.04"
tyblue " 3. LTS版(长期支持版) 当前版本号:22.04"
tyblue " 0. 不升级系统"
tyblue "-------------------------注意事项-------------------------"
yellow " 1.升级过程中遇到问话/对话框,如果不清楚,请选择yes/y/第一个选项"
yellow " 2.升级系统可能需要15分钟或更久"
yellow " 3.有的时候不能一次性更新到所选择的版本,可能要更新多次"
yellow " 4.升级系统后以下配置可能会恢复系统默认配置:"
yellow " ssh端口 ssh超时时间 bbr加速(恢复到关闭状态)"
tyblue "----------------------------------------------------------"
green " 您现在的系统版本是:$system_version"
tyblue "----------------------------------------------------------"
echo
choice=""
while [[ ! "$choice" =~ ^(0|[1-9][0-9]*)$ ]] || ((choice>3))
do
read -rp "您的选择是:" choice
done
if [ "$choice" -ne 0 ]; then
if ! [[ "$(grep -i '^[ '$'\t]*port[ '$'\t]' /etc/ssh/sshd_config | awk '{print $2}')" =~ ^("22"|)$ ]]; then
red "检测到ssh端口号被修改"
red "升级系统后ssh端口号可能恢复默认值(22)"
yellow "按回车键继续。。。"
read -rs
fi
if [ $in_install_update_xray_reality_web -eq 1 ]; then
echo
tyblue "提示:即将开始升级系统"
yellow " 升级完系统后服务器将重启,重启后,请再次运行脚本完成 Xray-TLS+Web 剩余部分的安装/升级"
yellow " 再次运行脚本时,重复之前选过的选项即可"
echo
sleep 2s
yellow "按回车键以继续。。。"
read -rs
echo
fi
fi
local i
for ((i=0;i<2;i++))
do
sed -i '/^[ \t]*Prompt[ \t]*=/d' /etc/update-manager/release-upgrades
echo 'Prompt=normal' >> /etc/update-manager/release-upgrades
case "$choice" in
1)
do-release-upgrade -d -m server
do-release-upgrade -d -m server
sed -i 's/Prompt=normal/Prompt=lts/' /etc/update-manager/release-upgrades
do-release-upgrade -d -m server
do-release-upgrade -d -m server
sed -i 's/Prompt=lts/Prompt=normal/' /etc/update-manager/release-upgrades
do-release-upgrade -p -m server
do-release-upgrade -p -m server
sed -i 's/Prompt=normal/Prompt=lts/' /etc/update-manager/release-upgrades
do-release-upgrade -p -m server
do-release-upgrade -p -m server
;;
2)
do-release-upgrade -m server
do-release-upgrade -m server
;;
3)
sed -i 's/Prompt=normal/Prompt=lts/' /etc/update-manager/release-upgrades
do-release-upgrade -m server
do-release-upgrade -m server
;;
0)
;;
esac
apt -y --purge --allow-change-held-packages autoremove
apt update
apt -y --auto-remove --purge --no-install-recommends -o Dpkg::Options::="--force-confnew" --allow-change-held-packages full-upgrade
apt -y --purge --allow-change-held-packages autoremove
apt clean
apt autoclean
done
}
while :
do
echo -e "\\n\\n\\n"
tyblue "-----------------------是否更新系统组件?-----------------------"
green " 1. 更新已安装软件,并升级系统 (仅Ubuntu可用)"
green " 2. 仅更新已安装软件"
red " 3. 不更新"
if [ "$distro" == "ubuntu" ] && (($(free -b | sed -n 2p | awk '{print $2}') < 419430400)); then
red "当前VPS内存不足400M,升级系统可能导致无法开机,请谨慎选择"
fi
echo
choice=""
while [ "$choice" != "1" ] && [ "$choice" != "2" ] && [ "$choice" != "3" ]
do
read -rp "您的选择是:" choice
done
if [ "$distro" == "ubuntu" ] || [ $choice -ne 1 ]; then
break
fi
echo
yellow " 更新系统仅支持Ubuntu!"
sleep 3s
done
if [ "$choice" -eq 1 ]; then
updateSystem
elif [ "$choice" -eq 2 ]; then
tyblue "-----------------------即将开始更新-----------------------"
yellow " 更新过程中遇到问话/对话框,如果不清楚,请选择yes/y/第一个选项"
yellow " 按回车键继续。。。"
read -rs
echo
if [ "$distro_like" == "debian" ]; then
apt -y --purge --allow-change-held-packages autoremove
apt update
apt -y --auto-remove --purge --no-install-recommends -o Dpkg::Options::="--force-confnew" --allow-change-held-packages full-upgrade
apt -y --purge --allow-change-held-packages autoremove
apt clean
apt autoclean
else
dnf -y autoremove
local no_install_recommends
if dnf --help | grep -q "\\-\\-setopt="; then
no_install_recommends=("--setopt=install_weak_deps=0")
else
no_install_recommends=("--setopt" "install_weak_deps=0")
fi
dnf "${no_install_recommends[@]}" -y upgrade
dnf -y autoremove
dnf clean all
fi
fi
}
#安装bbr
install_bbr()
{
#输出:latest_kernel_version 和 your_kernel_version
get_kernel_info()
{
green "正在获取最新版本内核版本号。。。。(20内秒未获取成功自动跳过)"
your_kernel_version="$(uname -r | cut -d - -f 1)"
while [ ${your_kernel_version##*.} -eq 0 ]
do
your_kernel_version=${your_kernel_version%.*}
done
if ! timeout 20 curl -Lo "temp_kernel_version" "https://kernel.ubuntu.com/~kernel-ppa/mainline/"; then
latest_kernel_version="error"
return 1
fi
local kernel_list=()
local kernel_list_temp
kernel_list_temp=($(awk -F'\"v' '/v[0-9]/{print $2}' "temp_kernel_version" | cut -d '"' -f1 | cut -d '/' -f1 | sort -rV))
if [ ${#kernel_list_temp[@]} -le 1 ]; then
latest_kernel_version="error"
return 1
fi
local i2=0
local i3
local kernel_rc=""
local kernel_list_temp2
while ((i2<${#kernel_list_temp[@]}))
do
if [[ "${kernel_list_temp[$i2]}" =~ -rc(0|[1-9][0-9]*)$ ]] && [ "$kernel_rc" == "" ]; then
kernel_list_temp2=("${kernel_list_temp[$i2]}")
kernel_rc="${kernel_list_temp[$i2]%-*}"
((i2++))
elif [[ "${kernel_list_temp[$i2]}" =~ -rc(0|[1-9][0-9]*)$ ]] && [ "${kernel_list_temp[$i2]%-*}" == "$kernel_rc" ]; then
kernel_list_temp2+=("${kernel_list_temp[$i2]}")
((i2++))
elif [[ "${kernel_list_temp[$i2]}" =~ -rc(0|[1-9][0-9]*)$ ]] && [ "${kernel_list_temp[$i2]%-*}" != "$kernel_rc" ]; then
for((i3=0;i3<${#kernel_list_temp2[@]};i3++))
do
kernel_list+=("${kernel_list_temp2[$i3]}")
done
kernel_rc=""
elif [ -z "$kernel_rc" ] || version_ge "${kernel_list_temp[$i2]}" "$kernel_rc"; then
kernel_list+=("${kernel_list_temp[$i2]}")
((i2++))
else
for((i3=0;i3<${#kernel_list_temp2[@]};i3++))
do
kernel_list+=("${kernel_list_temp2[$i3]}")
done
kernel_rc=""
fi
done
if [ -n "$kernel_rc" ]; then
for((i3=0;i3<${#kernel_list_temp2[@]};i3++))
do
kernel_list+=("${kernel_list_temp2[$i3]}")
done
fi
latest_kernel_version="${kernel_list[0]}"
if [ "$distro_like" == "debian" ]; then
local rc_version
rc_version="$(uname -r | cut -d - -f 2)"
if [[ $rc_version =~ rc ]]; then
rc_version="${rc_version##*'rc'}"
your_kernel_version="${your_kernel_version}-rc${rc_version}"
fi
uname -r | grep -q xanmod && your_kernel_version="${your_kernel_version}-xanmod"
else
latest_kernel_version="${latest_kernel_version%%-*}"
fi
}
#卸载多余内核
remove_other_kernel()
{
local exit_code=1
if [ "$distro_like" == "debian" ]; then
english_run dpkg --list > "temp_installed_list"
local kernel_list_image
kernel_list_image=($(awk '{print $2}' "temp_installed_list" | grep '^linux-image'))
local kernel_list_modules
kernel_list_modules=($(awk '{print $2}' "temp_installed_list" | grep '^linux-modules'))
local kernel_now
kernel_now="$(uname -r)"
local ok_install=0
for ((i=${#kernel_list_image[@]}-1;i>=0;i--))
do
if [[ "${kernel_list_image[$i]}" == *"$kernel_now"* ]]; then
unset 'kernel_list_image[$i]'
((ok_install++))
fi
done
if [ $ok_install -lt 1 ]; then
red "未发现正在使用的内核,可能已经被卸载,请先重新启动"
yellow "按回车键继续。。。"
read -rs
echo
return 1
fi
for ((i=${#kernel_list_modules[@]}-1;i>=0;i--))
do
if [[ "${kernel_list_modules[$i]}" == *"$kernel_now"* ]]; then
unset 'kernel_list_modules[$i]'
fi
done
if [ ${#kernel_list_modules[@]} -eq 0 ] && [ ${#kernel_list_image[@]} -eq 0 ]; then
yellow "没有内核可卸载"