Linux 常用脚本教程
在 VPS 或云服务器上搭建网站,脚本化操作不仅能提高效率,还能保证一致性和可重复性。本文将全面介绍 Linux 环境下各阶段所需的 Bash 脚本、Ansible 自动化、CI/CD 脚本等,从服务器初始化、安全加固、软件安装、网站部署到运维监控,覆盖网站全生命周期管理。
目录
- 服务器初始化脚本
- 安全加固脚本
- 环境安装脚本
- LAMP/LEMP 环境
- Node.js/PM2 环境
- 网站自动化部署脚本
- Git 部署脚本
- Ansible 自动化
- SSL 证书自动续期脚本
- 备份与恢复脚本
- 数据库备份
- 文件同步
- 日志管理与日志切割脚本
- 监控与告警脚本
- 定时任务(Crontab)示例
- 常见脚本优化建议
- Docker容器部署脚本
- Kubernetes部署脚本
- 性能优化脚本
- 高级监控脚本
- 自动化测试脚本
- 灾难恢复脚本
- 多服务器管理脚本
- 证书管理脚本
- 零停机部署脚本
- 自动化安全扫描脚本
- 常用网络调试命令
1. 服务器初始化脚本
首次购买 VPS 后,第一步是基础配置:更新系统、设置时区、创建新用户并配置 SSH 公钥登录、关闭 root 直连等。
#!/usr/bin/env bash
# server_init.sh # 1. 设置时区
timedatectl set-timezone Asia/Shanghai # 2. 更新系统
apt update && apt -y upgrade # Debian/Ubuntu
# yum update -y # RHEL/CentOS # 3. 安装基本工具
apt install -y vim wget curl git ufw # 4. 创建新用户
read -p "请输入新用户名: " USERNAME
groupadd sudo
useradd -m -s /bin/bash -G sudo $USERNAME # 5. 配置 SSH 公钥登录
mkdir -p /home/$USERNAME/.ssh
read -p "请输入公钥内容: " PUBKEY
echo $PUBKEY > /home/$USERNAME/.ssh/authorized_keys
chmod 700 /home/$USERNAME/.ssh
ochmod 600 /home/$USERNAME/.ssh/authorized_keys
chown -R $USERNAME:$USERNAME /home/$USERNAME/.ssh # 6. 禁用 root 密码登录
sed -i 's/^PermitRootLogin .*/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd echo "初始化完成,用户 $USERNAME 已创建并配置 SSH 登录。" 此脚本完成了基础环境准备,接下来可在同一脚本中添加防火墙规则。
2. 安全加固脚本
安全加固主要包含防火墙(UFW/iptables)、Fail2ban、SSH 限制等。
#!/usr/bin/env bash
# security_hardening.sh # 1. 配置 UFW
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp # SSH
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw enable # 2. 安装并配置 Fail2ban
apt install -y fail2ban
cat > /etc/fail2ban/jail.local <<EOF
[sshd]
enabled = true
port = 22
filter = sshd
action = iptables[name=SSH, port=22, protocol=tcp]
logpath = /var/log/auth.log
maxretry = 5
EOF
systemctl restart fail2ban # 3. 修改 SSH 默认端口
NEW_PORT=2222
sed -i "s/#Port 22/Port $NEW_PORT/" /etc/ssh/sshd_config
ufw allow $NEW_PORT/tcp
describe UFW rules
echo "请手动验证 SSH 端口已修改并配置防火墙规则。" 通过脚本方式,安全设置可一键完成。
3. 环境安装脚本
3.1 LAMP/LEMP 环境
LAMP (Linux + Apache + MySQL/MariaDB + PHP):
#!/usr/bin/env bash
# install_lamp.sh # 更新源
apt update # 安装 Apache, MariaDB, PHP
apt install -y apache2 mariadb-server php php-mysql libapache2-mod-php # 启动并开机自启
systemctl enable --now apache2 mariadb # 初始化数据库安全
mysql_secure_installation <<EOF
Y
root_password
root_password
Y
Y
Y
Y
EOF # 测试 PHP
cat > /var/www/html/info.php <<EOF
<?php phpinfo(); ?>
EOF echo "LAMP 环境安装完成,访问 http://服务器IP/info.php 查看 PHP 信息。" LEMP (Nginx + MariaDB + PHP-FPM):
#!/usr/bin/env bash
# install_lemp.sh apt update
apt install -y nginx mariadb-server php-fpm php-mysql # 启动并开机自启
systemctl enable --now nginx mariadb php7.*-fpm # 配置 Nginx
cat > /etc/nginx/sites-available/default <<EOF
server { listen 80; server_name example.com; root /var/www/html; index index.php index.html; location / { try_files $uri $uri/ =404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php7.*-fpm.sock; }
}
EOF nginx -t && systemctl reload nginx echo "LEMP 环境安装完成,请将网站文件放入 /var/www/html。" 3.2 Node.js & PM2 环境
#!/usr/bin/env bash
# install_node_pm2.sh apt update
# 安装 Node.js 16.x
curl -fsSL https://deb.nodesource.com/setup_16.x | bash -
apt install -y nodejs # 安装并配置 PM2
npm install -g pm2
pm2 startup systemd -u $USER --hp /home/$USER # 示例启动应用
cd /path/to/your/app
pm2 start app.js --name my-app
pm2 save echo "Node.js & PM2 环境配置完成,使用 'pm2 status' 查看进程。" 4. 网站自动化部署脚本
4.1 Git 部署脚本
简单的拉取并重启示例:
#!/usr/bin/env bash
# deploy.sh APP_DIR=/var/www/html/your-app
BRANCH=main cd $APP_DIR
# 拉取最新代码
git fetch origin
git reset --hard origin/$BRANCH # 依赖安装 & 构建
npm install && npm run build # 或者 composer install, pip install -r requirements.txt # 重启服务
pm2 restart my-app # Node.js 服务
systemctl restart php-fpm # PHP-FPM
systemctl reload nginx # Nginx echo "部署完成:分支 $BRANCH 的最新代码已上线。" 4.2 Ansible 自动化剧本
Ansible 剧本将多台服务器统一管理,可定义安装、配置、部署流程。
# site.yml
- hosts: webservers become: yes vars: app_repo: '[email protected]:your/repo.git' app_path: '/var/www/html/your-app' tasks: - name: 更新 apt 缓存 apt: update_cache: yes - name: 安装必要软件 apt: name: - nginx - git - php-fpm state: present - name: 拉取应用代码 git: repo: '{{ app_repo }}' dest: '{{ app_path }}' version: 'main' - name: 安装依赖 shell: 'cd {{ app_path }} && npm install' - name: 配置 Nginx template: src: templates/nginx.conf.j2 dest: /etc/nginx/sites-available/default - name: 重启服务 service: name: nginx state: restarted - name: 启动应用 shell: 'pm2 restart all' 使用 ansible-playbook -i inventory site.yml 一键完成多节点部署。
5. SSL证书自动续期脚本
使用 Certbot 获取并续期 Let's Encrypt 证书。
#!/usr/bin/env bash
# ssl_renew.sh # 停用 nginx
systemctl stop nginx # 获取/续期证书
certbot certonly --standalone -d example.com -m [email protected] --agree-tos --non-interactive # 生成合并证书(可选)
cat /etc/letsencrypt/live/example.com/fullchain.pem /etc/letsencrypt/live/example.com/privkey.pem > /etc/nginx/ssl/example.com.pem # 启动 nginx
systemctl start nginx echo "证书续期完成:$(date '+%F %T')" 并在 crontab 中添加:
0 3 */60 * * /path/to/ssl_renew.sh >> /var/log/ssl_renew.log 2>&1 6. 备份与恢复脚本
6.1 数据库备份
#!/usr/bin/env bash
# db_backup.sh DB_USER=root
DB_PASS=your_password
DB_NAME=your_db
BACKUP_DIR=/backup/mysql/$(date +"%F") mkdir -p $BACKUP_DIR
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_DIR/${DB_NAME}_$(date +"%H%M").sql.gz # 删除 7 天前备份
dfind $BACKUP_DIR -type f -mtime +7 -exec rm {} \; # 可选:同步到远程服务器
# rsync -az $BACKUP_DIR user@backup-server:/remote/backup/mysql/ echo "数据库备份完成:$BACKUP_DIR" 6.2 文件同步备份
#!/usr/bin/env bash
# file_backup.sh SOURCE_DIR=/var/www/html
DEST_USER=backup
DEST_HOST=backup.example.com
DEST_DIR=/remote/backup/www rsync -avz --delete $SOURCE_DIR $DEST_USER@$DEST_HOST:$DEST_DIR echo "文件同步备份完成:$SOURCE_DIR -> $DEST_HOST:$DEST_DIR" 7. 日志管理与日志切割脚本
使用 logrotate 管理日志,保持磁盘空间。
# /etc/logrotate.d/nginx
/var/log/nginx/*.log { daily rotate 14 missingok compress delaycompress notifempty create 0640 www-data adm sharedscripts postrotate systemctl reload nginx > /dev/null endscript
} 对于自定义日志,可在 /etc/logrotate.d/ 中类似添加。
8. 监控与告警脚本
8.1 简易磁盘使用监控
#!/usr/bin/env bash
# disk_alert.sh THRESHOLD=80
df -H | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }' | while read output; do usep=$(echo $output | awk '{ print $1}' | sed 's/%//') partition=$(echo $output | awk '{ print $2 }') if [ $usep -ge $THRESHOLD ]; then echo "Warning: Partition $partition usage is at $usep%!" | mail -s "Disk Alert" [email protected] fi
done 8.2 服务状态检查
#!/usr/bin/env bash
# service_check.sh SERVICES=(nginx mariadb php7.*-fpm pm2)
for SERVICE in "${SERVICES[@]}"; do if ! systemctl is-active --quiet $SERVICE; then echo "服务 $SERVICE 已停止!" | mail -s "Service Alert: $SERVICE" [email protected] fi
done 将以上脚本放入 cron 定时执行,即可实现基础告警。
9. 定时任务(Crontab)示例
# 每日凌晨 2 点:系统更新
0 2 * * * /usr/bin/apt update && /usr/bin/apt -y upgrade # 每小时执行磁盘监控
0 * * * * /path/to/disk_alert.sh # 每日 3:30 证书续期
30 3 * * * /path/to/ssl_renew.sh # 每日备份数据库
0 1 * * * /path/to/db_backup.sh 10. 常见脚本优化建议
- 错误处理:在关键命令后加
|| exit 1或set -e,确保脚本失败时及时中断。 - 日志输出:统一输出到日志文件,使用
exec >>/var/log/脚本名.log 2>&1。 - 参数化:将可变参数(路径、端口、用户等)提取为变量或通过命令行传入。
- 注释与文档:每个脚本应包含用途说明、参数说明及运行示例。
- 权限控制:谨慎使用
sudo,脚本文件权限建议700,避免泄露敏感信息。
11. Docker容器部署脚本
#!/usr/bin/env bash
# deploy_docker.sh IMAGE_NAME=your-app
CONTAINER_NAME=your-app-container
HOST_PORT=80
CONTAINER_PORT=80
VOLUME_MOUNT="/host/path:/container/path" # 停止并删除旧容器
docker rm -f $CONTAINER_NAME 2>/dev/null || true # 清理旧镜像
docker rmi $(docker images -q -f dangling=true) 2>/dev/null || true # 构建新镜像
docker build -t $IMAGE_NAME . # 运行容器
docker run -d \ --name $CONTAINER_NAME \ --restart=unless-stopped \ -p $HOST_PORT:$CONTAINER_PORT \ -v $VOLUME_MOUNT \ --env-file .env \ $IMAGE_NAME # 健康检查
echo "容器状态:"
docker ps -f name=$CONTAINER_NAME
echo -e "\n日志输出:"
docker logs --tail 50 $CONTAINER_NAME echo "Docker 容器部署完成,访问 http://服务器IP:$HOST_PORT" 12. Kubernetes部署脚本
#!/usr/bin/env bash
# deploy_k8s.sh NAMESPACE=production
DEPLOYMENT=web-app # 应用配置更新
kubectl apply -f k8s/deployment.yaml --namespace=$NAMESPACE # 滚动更新
kubectl rollout restart deployment/$DEPLOYMENT --namespace=$NAMESPACE # 监控更新状态
kubectl rollout status deployment/$DEPLOYMENT --namespace=$NAMESPACE --timeout=300s # 获取服务信息
echo "服务状态:"
kubectl get svc -n $NAMESPACE
echo -e "\nPod状态:"
kubectl get pods -n $NAMESPACE -l app=$DEPLOYMENT echo "Kubernetes 部署完成!" 13. 性能优化脚本
13.1 内核参数优化
#!/usr/bin/env bash
# tune_kernel.sh # 备份当前配置
cp /etc/sysctl.conf /etc/sysctl.conf.bak_$(date +%F) # 添加优化参数
cat <<EOF | tee -a /etc/sysctl.conf
# 网络性能优化
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 4096
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.tcp_syncookies = 1 # 内存优化
vm.swappiness = 10
vm.overcommit_memory = 1
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5 # 文件系统优化
fs.file-max = 2097152
EOF # 应用配置
sysctl -p
echo "内核参数优化完成!" 13.2 Nginx 性能调优
#!/usr/bin/env bash
# tune_nginx.sh # 备份原始配置
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak_$(date +%F) # 应用优化参数
sed -i '/worker_processes/c\worker_processes auto;' /etc/nginx/nginx.conf
sed -i '/events {/a\ worker_connections 4096;' /etc/nginx/nginx.conf
sed -i '/events {/a\ use epoll;' /etc/nginx/nginx.conf
sed -i '/events {/a\ multi_accept on;' /etc/nginx/nginx.conf # 添加TCP优化
cat <<EOF | tee -a /etc/nginx/nginx.conf
# TCP优化
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 10000;
sendfile on;
client_max_body_size 100m;
client_body_buffer_size 128k;
client_header_buffer_size 4k;
large_client_header_buffers 4 16k;
EOF # 测试并重载配置
nginx -t && systemctl reload nginx
echo "Nginx性能优化完成!" 14. 高级监控脚本
14.1 容器资源监控
#!/usr/bin/env bash
# container_monitor.sh # 监控Docker容器资源使用
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}" > /tmp/docker_stats.txt # 检查异常容器
ALERT_CONTAINERS=$(awk '$2 > "80.00%" || $3 > "1GiB" {print $1}' /tmp/docker_stats.txt) if [ -n "$ALERT_CONTAINERS" ]; then echo "高资源使用容器:" echo "$ALERT_CONTAINERS" | while read container; do echo "容器: $container" docker top $container echo "----------------------" done | mail -s "容器资源告警" [email protected]
fi 14.2 网络连接监控
#!/usr/bin/env bash
# network_monitor.sh # 监控异常连接
ABNORMAL_CONNS=$(ss -antp state established | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -10) # 检测SYN洪水攻击
SYN_FLOOD=$(netstat -n -p tcp | grep SYN_RECV | wc -l) if [ $SYN_FLOOD -gt 100 ]; then echo "检测到SYN洪水攻击! SYN_RECV连接数: $SYN_FLOOD" | mail -s "网络攻击告警" [email protected]
fi # 每日报告
echo "Top 10连接:"
echo "$ABNORMAL_CONNS"
echo -e "\n当前连接状态:"
ss -s | head -10 15. 自动化测试脚本
#!/usr/bin/env bash
# run_tests.sh APP_URL="http://localhost:8000"
TEST_DIR="/path/to/tests" # 运行单元测试
pytest $TEST_DIR/unit_tests # 运行API测试
echo "运行API测试..."
newman run $TEST_DIR/api_tests.postman_collection.json --env-var "baseUrl=$APP_URL" # 运行负载测试
echo "运行负载测试..."
k6 run $TEST_DIR/load_test.js # 运行安全扫描
echo "运行安全扫描..."
zap-cli quick-scan -s all $APP_URL echo "测试套件执行完成!" 16. 灾难恢复脚本
#!/usr/bin/env bash
# disaster_recovery.sh # 1. 恢复数据库
mysql -u root -p < /backups/db/latest_full.sql # 2. 恢复网站文件
rsync -avz /backups/files/latest/ /var/www/html/ # 3. 恢复配置
cp /backups/configs/nginx.conf /etc/nginx/nginx.conf
cp /backups/configs/my.cnf /etc/mysql/my.cnf # 4. 重启服务
systemctl restart mysql nginx php-fpm # 5. 验证恢复
curl -I http://localhost > /dev/null && echo "服务已恢复" || echo "恢复失败,请检查" 17. 多服务器管理脚本
#!/usr/bin/env bash
# multi_server_ops.sh SERVERS=("web1.example.com" "web2.example.com" "db.example.com")
ADMIN_USER="opsadmin" for server in "${SERVERS[@]}"; do echo "===== 操作服务器: $server =====" # 执行安全更新 ssh $ADMIN_USER@$server "sudo apt update && sudo apt upgrade -y" # 检查磁盘空间 ssh $ADMIN_USER@$server "df -h /" # 重启服务 ssh $ADMIN_USER@$server "sudo systemctl restart nginx mysql" # 获取服务状态 ssh $ADMIN_USER@$server "sudo systemctl status nginx mysql | head -10" echo "=============================="
done echo "所有服务器操作完成!" 18. 证书管理脚本
#!/usr/bin/env bash
# cert_manager.sh DOMAIN="example.com"
EMAIL="[email protected]" # 创建新证书
certbot certonly --nginx -d $DOMAIN -d www.$DOMAIN \ --non-interactive --agree-tos -m $EMAIL # 创建PFX格式证书(用于Windows服务)
openssl pkcs12 -export -out /etc/letsencrypt/live/$DOMAIN/cert.pfx \ -inkey /etc/letsencrypt/live/$DOMAIN/privkey.pem \ -in /etc/letsencrypt/live/$DOMAIN/cert.pem \ -passout pass: # 更新HAProxy证书
cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem \ /etc/letsencrypt/live/$DOMAIN/privkey.pem \ > /etc/haproxy/certs/$DOMAIN.pem # 重启服务
systemctl reload nginx haproxy echo "证书管理操作完成!" 19. 零停机部署脚本
#!/usr/bin/env bash
# zero_downtime_deploy.sh # 蓝绿部署策略
BLUE_PORT=8080
GREEN_PORT=8081
CURRENT_COLOR=$(curl -s http://localhost/color) if [ "$CURRENT_COLOR" == "blue" ]; then TARGET_COLOR="green" TARGET_PORT=$GREEN_PORT OLD_PORT=$BLUE_PORT
else TARGET_COLOR="blue" TARGET_PORT=$BLUE_PORT OLD_PORT=$GREEN_PORT
fi # 部署新版本
docker run -d --name app-$TARGET_COLOR -p $TARGET_PORT:8000 your-app:new-version # 等待新实例就绪
while ! nc -z localhost $TARGET_PORT; do sleep 1
done # 切换流量
sed -i "s/backend app-backend.*/backend app-backend\n server app-server localhost:$TARGET_PORT check/" /etc/haproxy/haproxy.cfg
systemctl reload haproxy # 停止旧实例
docker stop app-$([ "$TARGET_COLOR" == "green" ] && echo "blue" || echo "green") | xargs docker rm echo "零停机部署完成!当前运行版本: $TARGET_COLOR" 20. 自动化安全扫描脚本
#!/usr/bin/env bash
# security_scan.sh # 使用多种工具进行安全扫描
SCAN_DIR="/var/www/html"
REPORT_DIR="/reports/security" mkdir -p $REPORT_DIR # Lynis 系统审计
lynis audit system --cronjob > $REPORT_DIR/lynis_$(date +%F).log # ClamAV 病毒扫描
freshclam
clamscan -r -i $SCAN_DIR > $REPORT_DIR/clamav_$(date +%F).log # Rkhunter 后门检测
rkhunter --check --sk > $REPORT_DIR/rkhunter_$(date +%F).log # Web漏洞扫描
nikto -h localhost -output $REPORT_DIR/nikto_$(date +%F).html # 发送报告
tar -czf $REPORT_DIR/security_reports_$(date +%F).tar.gz $REPORT_DIR/*.log $REPORT_DIR/*.html
echo "安全扫描报告" | mail -a $REPORT_DIR/security_reports_$(date +%F).tar.gz -s "安全扫描报告" [email protected] echo "安全扫描完成!报告已发送" 21. 常用网络调试命令
ss -tulwn:列出所有 Listening 套接字ss -s:摘要网络状态netstat -anp:查看网络连接与进程(需安装 net-tools)tcpdump -i eth0 port 80 -w http.pcap:抓包保存 HTTP 流量traceroute example.com:跟踪路由mtr -rw example.com:实时路由追踪iperf3 -s/iperf3 -c server_ip:网络带宽测试
