• 导航

VPS配置一键脚本

记事本 2024-04-06 23 次浏览

背景

自己有一台服务器,每次切换机房时,机器会被重置(提供商不提供备份机制),导致又得按照之前的配置手动来一遍,非常的耗时,也不方便。

解决方案

受网上一键脚本启发,制作了一个适合自己服务器的一键脚本。

可学到的知识点

如何在 shell 中显示和操作可选择菜单。
如何安装系统服务。
什么是 ACME。
什么是 Frps
如何配置 Nginx

一键脚本

已脱敏处理。
      
  #!/bin/bash

RED="\033[31m" # Error message
GREEN="\033[32m" # Success message
YELLOW="\033[33m" # Warning message
BLUE="\033[36m" # Info message
PLAIN='\033[0m'

CMD_INSTALL="yum install -y "

console() {
echo -e "${1}${@:2}${PLAIN}"
}

resetTimezone() {
console $GREEN "重置为中国时区"
timezone=`timedatectl | cut -d: -f2 | sed -n 4p`
console $GREEN "之前时区:$timezone"
timedatectl set-timezone Asia/Shanghai
timezone=`timedatectl | cut -d: -f2 | sed -n 4p`
console $GREEN "当前时区:$timezone"
}

updateSystem() {
console $GREEN "更新系统"
yum update
console $GREEN "安装 make zlib zlib-devel gcc-c++ libtool openssl openssl-devel libxslt-devel git tar vim unzip"
$CMD_INSTALL make zlib zlib-devel gcc-c++ libtool openssl openssl-devel libxslt-devel git tar vim unzip
}

startFirewall() {
# https://www.linode.com/docs/security/firewalls/introduction-to-firewalld-on-centos/
console $GREEN "开启防火墙,打开 80/443 端口"
systemctl start firewalld
systemctl enable firewalld
firewall-cmd --zone=public --add-service=http --permanent
firewall-cmd --zone=public --add-service=https --permanent
# firewall-cmd --zone=public --add-port=9055/tcp --permanent
# firewall-cmd --zone=public --remove-port=18646/tcp --permanent
# firewall-cmd --list-ports
# firewall-cmd --state
firewall-cmd --reload
}

cloneJSGardenSite() {
console $GREEN "配置 JS 花园站点"
mkdir /opt/site
git clone https://github.com/xbf321/js-garden-page.git /opt/site/js-garden
}

installACME() {
# https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E
console $GREEN "安装 ACME"
cd ~
curl -sL https://get.acme.sh | sh -s email=xbf321@gmail.com
~/.acme.sh/acme.sh --upgrade --auto-upgrade
}

installNginx() {
console $GREEN "安装 Nginx ..."
$CMD_INSTALL epel-release
$CMD_INSTALL nginx
if [[ "$?" != "0" ]]; then
console $RED " Nginx安装失败,请手动安装"
exit 1
fi
$CMD_INSTALL nginx-mod-stream
# 证书都放到这里
mkdir /etc/nginx/ssl/
systemctl enable nginx
systemctl start nginx
}

installTrojanGo() {
console $GREEN "安装 Trojan-Go ..."
ZIP_FILE="trojan-go"
wget -O /tmp/${ZIP_FILE}.zip https://github.com/p4gefau1t/trojan-go/releases/download/v0.10.6/trojan-go-linux-amd64.zip
if [[ ! -f /tmp/${ZIP_FILE}.zip ]]; then
console $RED "trojan-go安装文件下载失败,请检查网络或重试"
exit 1
fi
mkdir -p /etc/trojan-go
rm -rf /tmp/${ZIP_FILE}
unzip /tmp/${ZIP_FILE}.zip -d /tmp/${ZIP_FILE}
cp /tmp/${ZIP_FILE}/trojan-go /usr/bin
cp /tmp/${ZIP_FILE}/geoip.dat /etc/trojan-go/
cp /tmp/${ZIP_FILE}/geosite.dat /etc/trojan-go/
cp /tmp/${ZIP_FILE}/example/trojan-go.service /etc/systemd/system/
sed -i '/User=nobody/d' /etc/systemd/system/trojan-go.service
systemctl daemon-reload
systemctl enable trojan-go
rm -rf /tmp/${ZIP_FILE}
console $YELLOW "trojan-go安装成功!"
}

installFrps() {
console $GREEN "安装 Frp 服务端 ..."
ZIP_FILE="frp"
mkdir -p /tmp/frp
mkdir -p /etc/frp
wget -O /tmp/${ZIP_FILE}.tar.gz https://github.com/fatedier/frp/releases/download/v0.39.0/frp_0.39.0_linux_amd64.tar.gz
if [[ ! -f /tmp/${ZIP_FILE}.tar.gz ]]; then
console $RED "frp安装文件下载失败,请检查网络或重试"
exit 1
fi
tar -xzvf /tmp/${ZIP_FILE}.tar.gz --strip-components 1 -C /tmp/frp
cp /tmp/frp/frps /usr/bin
cp /tmp/frp/frps.ini /etc/frp/
cp /tmp/frp/systemd/frps.service /etc/systemd/system/
sed -i '/User=nobody/d' /etc/systemd/system/frps.service
systemctl daemon-reload
systemctl enable frps
rm -rf /tmp/${ZIP_FILE}
console $YELLOW "frps 安装成功!"
}

configFrps() {
console $GREEN "配置 Frp 服务端 ..."
cat > /etc/frp/frps.ini <<-"EOF"
[common]
bind_addr = 0.0.0.0
bind_port = 9000
bind_udp_port = 9001
kcp_bind_port = 9000

# auth token
token = token

# dashboard
dashboard_addr = 0.0.0.0
dashboard_port = 9500
dashboard_user = root
dashboard_pwd = pwd

log_file = /var/log/frps.log
log_level = info
log_max_days = 3

# only allow frpc to bind ports you list, if you set nothing, there won't be any limit
allow_ports = 9000-9999

# pool_count in each proxy will change to max_pool_count if they exceed the maximum value
max_pool_count = 5

# max ports can be used for each client, default value is 0 means no limit
# if tcp stream multiplexing is used, default is true
tcp_mux = true
EOF
systemctl restart frps
}

buildXingBaifangSSL() {
console $GREEN "生成 xingbaifang.com 域名证书"
export GD_Key="key"
export GD_Secret="secret"
~/.acme.sh/acme.sh --issue --dns dns_gd -d xingbaifang.com -d www.xingbaifang.com
~/.acme.sh/acme.sh --issue --dns dns_gd -d tro-go.xingbaifang.com
console $GREEN "安装 xingbaifang.com 域名证书到 Nginx SSL 目录下"
~/.acme.sh/acme.sh --installcert -d xingbaifang.com -d www.xingbaifang.com \
--key-file /etc/nginx/ssl/xingbaifang.com.key \
--fullchain-file /etc/nginx/ssl/xingbaifang.com.fullchain.cer
~/.acme.sh/acme.sh --installcert -d tro-go.xingbaifang.com \
--key-file /etc/nginx/ssl/tro-go.xingbaifang.com.key \
--fullchain-file /etc/nginx/ssl/tro-go.xingbaifang.com.fullchain.cer
}

buildXingshuoSSL() {
console $GREEN "生成 xingshuo.me 域名证书"
export GD_Key="key"
export GD_Secret="script"
~/.acme.sh/acme.sh --issue --dns dns_gd -d xingshuo.me -d www.xingshuo.me
~/.acme.sh/acme.sh --issue --dns dns_gd -d tro-go.xingshuo.me
console $GREEN "安装 xingshuo.me 域名证书到 Nginx SSL 目录下"
~/.acme.sh/acme.sh --installcert -d xingshuo.me -d www.xingshuo.me \
--key-file /etc/nginx/ssl/xingshuo.me.key \
--fullchain-file /etc/nginx/ssl/xingshuo.me.fullchain.cer
~/.acme.sh/acme.sh --installcert -d tro-go.xingshuo.me \
--key-file /etc/nginx/ssl/tro-go.xingshuo.me.key \
--fullchain-file /etc/nginx/ssl/tro-go.xingshuo.me.fullchain.cer
}

configXingBaifangTrojan() {
console $GREEN "配置 tro-go.xingbaifang.com"
cat > /etc/trojan-go/config.json <<-"EOF"
{
"run_type": "server",
"local_addr": "0.0.0.0",
"local_port": 11443,
"remote_addr": "127.0.0.1",
"remote_port": 80,
"password": [
"pwd",
],
"ssl": {
"cert": "/etc/nginx/ssl/tro-go.xingbaifang.com.fullchain.cer",
"key": "/etc/nginx/ssl/tro-go.xingbaifang.com.key"
},
"mux": {
"enabled": true,
"concurrency": 8,
"idle_timeout": 60
},
"router": {
"enabled": true,
"block": [
"geoip:private"
],
"geoip": "/etc/trojan-go/geoip.dat",
"geosite": "/etc/trojan-go/geosite.dat"
}
}
EOF
console $GREEN "启动Trojan-Go服务"
systemctl restart trojan-go
}

configXingshuoTrojan() {
console $GREEN "配置 tro-go.xingshuo.me"
cat > /etc/trojan-go/config.json <<-"EOF"
{
"run_type": "server",
"local_addr": "0.0.0.0",
"local_port": 11443,
"remote_addr": "127.0.0.1",
"remote_port": 80,
"password": [
"pwd",
],
"ssl": {
"cert": "/etc/nginx/ssl/tro-go.xingshuo.me.fullchain.cer",
"key": "/etc/nginx/ssl/tro-go.xingshuo.me.key"
},
"mux": {
"enabled": true,
"concurrency": 8,
"idle_timeout": 60
},
"router": {
"enabled": true,
"block": [
"geoip:private"
],
"geoip": "/etc/trojan-go/geoip.dat",
"geosite": "/etc/trojan-go/geosite.dat"
}
}
EOF
console $GREEN "启动Trojan-Go服务"
systemctl restart trojan-go
}

configXingBaifangNginx() {
console $GREEN "配置 xingbaifang.com Nginx"
cat > /etc/nginx/nginx.conf<<-"EOF"
load_module /usr/lib64/nginx/modules/ngx_stream_module.so;
user root;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/log/nginx/nginx.pid;
events {
worker_connections 1024;
}
stream {
map $ssl_preread_server_name $backend_name {
tro-go.xingbaifang.com 127.0.0.1:11443;
xingbaifang.com 127.0.0.1:10443;
}
server {
listen 443 reuseport;
listen [::]:443 reuseport;
proxy_pass $backend_name;
ssl_preread on;
}
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;

sendfile on;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
# ssl common config
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE';
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Securit max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
server {
listen 80;
server_name localhost;
root /opt/site/js-garden;
location / {
index index.html;
}
}
include /etc/nginx/conf.d/*.conf;
}
EOF
cat > /etc/nginx/conf.d/xingbaifang.com.conf<<-"EOF"
server {
listen 80;
server_name xingbaifang.com www.xingbaifang.com;
return 301 https://$host$request_uri;
}
server {
listen 10443 ssl http2;
server_name xingbaifang.com www.xingbaifang.com;
ssl_certificate /etc/nginx/ssl/xingbaifang.com.fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/xingbaifang.com.key;
location / {
proxy_pass http://xingshuo.me:9055;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /test {
default_type text/html;
return 200 "hello world! ";
}
client_max_body_size 1024m;
}
EOF
console $GREEN "重启 Nginx"
nginx -s reload
}

configXingshuoNginx() {
console $GREEN "配置 xingshuo.me Nginx"
cat > /etc/nginx/nginx.conf<<-"EOF"
load_module /usr/lib64/nginx/modules/ngx_stream_module.so;
user root;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/log/nginx/nginx.pid;
events {
worker_connections 1024;
}
stream {
map $ssl_preread_server_name $backend_name {
tro-go.xingshuo.me 127.0.0.1:14443;
x.xingshuo.me 127.0.0.1:13443;
frp.xingshuo.me 127.0.0.1:12443;
trojan.xingshuo.me 127.0.0.1:11443;
xingshuo.me 127.0.0.1:10443;
}
server {
listen 443 reuseport;
listen [::]:443 reuseport;
proxy_pass $backend_name;
ssl_preread on;
}
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
server_tokens off;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
# ssl common config
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE';
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Securit max-age=15768000;
ssl_stapling on;
ssl_stapling_verify on;
server {
listen 80;
server_name localhost;
root /opt/site/js-garden;
location / {
index index.html;
}
}
include /etc/nginx/conf.d/*.conf;
}
EOF
cat > /etc/nginx/conf.d/xingshuo.me.conf<<-"EOF"
server {
listen 80;
server_name xingshuo.me www.xingshuo.me;
return 301 https://$host$request_uri;
}
server {
listen 10443 ssl http2;
server_name xingshuo.me www.xingshuo.me;
root /opt/site/js-garden;
ssl_certificate /etc/nginx/ssl/xingshuo.me.fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/xingshuo.me.key;
location / {
index index.html;
}
location /test {
default_type text/html;
return 200 "hello world! ";
}
# v2ray
location /2dhcp {
limit_req zone=mylimit burst=4 nodelay;
proxy_redirect off;
proxy_pass http://127.0.0.1:9527;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Show realip in v2ray access.log
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
client_max_body_size 50m;
}
EOF
cat > /etc/nginx/conf.d/frp.xingshuo.me.conf<<-"EOF"
server {
listen 80;
server_name frp.xingshuo.me;
return 301 https://$host$request_uri;
}
server {
listen 12443 ssl http2;
server_name frp.xingshuo.me;
ssl_certificate /etc/nginx/ssl/frp.xingshuo.me.fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/frp.xingshuo.me.key;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://127.0.0.1:9500;
}
client_max_body_size 50m;
}
EOF
cat > /etc/nginx/conf.d/wildcard.frp.xingshuo.me.conf<<-"EOF"
upstream adguard {
server 127.0.0.1:9043;
}
server {
listen 80;
server_name *.frp.xingshuo.me;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_buffering off;
if ( $host ~* (.*)\.frp\.xingshuo\.me ) {
set $prefix $1;
}
proxy_pass http://$prefix;
}
client_max_body_size 50m;
}
EOF
console $GREEN "重启 Nginx"
nginx -s reload
}

installBasePackage() {
resetTimezone
updateSystem
startFirewall
cloneJSGardenSite
installNginx
installACME
installTrojanGo
installFrps
}

menu() {
clear
echo "#############################################################"
echo -e " ${GREEN}1.${PLAIN} 安装基础服务(更新系统/Nginx/ACME/Trojan-Go/JSGardenSite/Frps)"
echo -e " ${GREEN}2.${PLAIN} 配置 frps"
echo -e " ${GREEN}3.${PLAIN} 安装 xingbaifang.com 证书且配置 Nginx 和 Trojan-Go"
echo -e " ${GREEN}4.${PLAIN} 安装 xingshuo.me 证书且配置 Nginx 和 Trojan-Go"
echo -e " ${GREEN}0.${PLAIN} 退出"
echo "#############################################################"
echo

read -p " 请选择操作[0-4]:" answer
case $answer in
0)
exit 0
;;
1)
installBasePackage
;;
2)
configFrps
;;
3)
buildXingBaifangSSL
configXingBaifangTrojan
configXingBaifangNginx
;;
4)
buildXingshuoSSL
configXingshuoTrojan
configXingshuoNginx
;;
*)
echo -e "$RED 请选择正确的操作!${PLAIN}"
exit 1
;;
esac
}

action=$1
[[ -z $1 ]] && action=menu
case "$action" in
menu)
${action}
;;
*)
echo " 参数错误"
echo " 用法: `basename $0` [menu]"
;;
esac