Linux 系统管理和维护
系统服务管理
systemd 服务管理
# 查看服务状态
systemctl status nginx
systemctl is-active nginx
systemctl is-enabled nginx
# 启动和停止服务
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx # 重新加载配置
# 开机自启动
sudo systemctl enable nginx # 设置开机启动
sudo systemctl disable nginx # 取消开机启动
sudo systemctl enable --now nginx # 启用并立即启动
# 查看所有服务
systemctl list-units --type=service
systemctl list-unit-files --type=service
# 查看失败的服务
systemctl --failed
# 查看服务日志
journalctl -u nginx
journalctl -u nginx -f # 实时查看
journalctl -u nginx --since today # 今天的日志
journalctl -u nginx --since "2024-01-01"
journalctl -u nginx -n 50 # 最后50行
创建自定义服务
# 创建服务文件
sudo vim /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/start.sh
ExecStop=/opt/myapp/stop.sh
Restart=on-failure
RestartSec=5s
# 环境变量
Environment="NODE_ENV=production"
Environment="PORT=3000"
# 日志
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
[Install]
WantedBy=multi-user.target
# 重新加载配置
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start myapp
sudo systemctl enable myapp
# 查看状态
sudo systemctl status myapp
日志管理
系统日志
# journalctl - systemd 日志
journalctl # 查看所有日志
journalctl -f # 实时查看
journalctl -n 100 # 最后100行
journalctl --since "1 hour ago" # 最近1小时
journalctl --since yesterday # 昨天至今
journalctl -p err # 只看错误级别
journalctl -k # 内核消息
# 清理日志
sudo journalctl --vacuum-time=7d # 保留7天
sudo journalctl --vacuum-size=500M # 限制大小
传统日志文件
# 常见日志位置
/var/log/syslog # 系统日志(Debian/Ubuntu)
/var/log/messages # 系统日志(CentOS/RHEL)
/var/log/auth.log # 认证日志
/var/log/kern.log # 内核日志
/var/log/apache2/ # Apache日志
/var/log/nginx/ # Nginx日志
# 查看日志
tail -f /var/log/syslog
tail -n 100 /var/log/auth.log
grep "error" /var/log/syslog
# 日志轮转配置
sudo vim /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 appuser appuser
sharedscripts
postrotate
systemctl reload myapp > /dev/null 2>&1 || true
endscript
}
计划任务
crontab 定时任务
# 编辑当前用户的crontab
crontab -e
# 查看crontab
crontab -l
# 删除crontab
crontab -r
# 编辑其他用户的crontab
sudo crontab -u username -e
crontab 语法:
# ┌───────────── 分钟 (0 - 59)
# │ ┌───────────── 小时 (0 - 23)
# │ │ ┌───────────── 日 (1 - 31)
# │ │ │ ┌───────────── 月 (1 - 12)
# │ │ │ │ ┌───────────── 星期 (0 - 7) (周日=0或7)
# │ │ │ │ │
# * * * * * command
# 示例
0 2 * * * /path/to/backup.sh # 每天凌晨2点
*/5 * * * * /path/to/monitor.sh # 每5分钟
0 0 * * 0 /path/to/weekly.sh # 每周日凌晨
0 */2 * * * /path/to/check.sh # 每2小时
30 3 1 * * /path/to/monthly.sh # 每月1号3:30
0 9-18 * * 1-5 /path/to/work-hours.sh # 工作日9-18点每小时
常用cron任务
# 清理临时文件
0 3 * * * find /tmp -type f -mtime +7 -delete
# 备份数据库
0 2 * * * /usr/local/bin/backup-mysql.sh >> /var/log/backup.log 2>&1
# 检查磁盘空间
0 */6 * * * df -h | mail -s "Disk Space Report" admin@example.com
# 重启应用
0 4 * * 0 systemctl restart myapp
# 清理日志
0 0 * * * find /var/log/myapp -name "*.log" -mtime +30 -delete
用户和权限管理
用户管理
# 创建用户
sudo useradd -m -s /bin/bash username # 创建用户和主目录
sudo useradd -m -G sudo username # 添加到sudo组
sudo passwd username # 设置密码
# 修改用户
sudo usermod -aG docker username # 添加到附加组
sudo usermod -s /bin/zsh username # 修改shell
sudo usermod -L username # 锁定用户
sudo usermod -U username # 解锁用户
# 删除用户
sudo userdel username # 删除用户
sudo userdel -r username # 删除用户和主目录
# 用户信息
id username # 查看用户ID和组
finger username # 查看用户详细信息
last username # 查看登录历史
sudo 权限
# 添加sudo权限
sudo usermod -aG sudo username # Debian/Ubuntu
sudo usermod -aG wheel username # CentOS/RHEL
# 编辑sudoers文件
sudo visudo
# 允许用户无密码使用sudo
username ALL=(ALL) NOPASSWD: ALL
# 只允许特定命令
username ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
# 允许组使用sudo
%admin ALL=(ALL) ALL
文件权限
# 特殊权限
chmod u+s file # SUID
chmod g+s directory # SGID
chmod +t directory # Sticky Bit
# ACL 访问控制列表
setfacl -m u:username:rwx file # 设置用户权限
setfacl -m g:groupname:rx directory # 设置组权限
getfacl file # 查看ACL
setfacl -x u:username file # 删除ACL
setfacl -b file # 清除所有ACL
磁盘管理
磁盘使用
# 查看磁盘使用
df -h # 文件系统使用情况
df -i # inode使用情况
du -sh /path # 目录大小
du -h --max-depth=1 /path # 一级子目录大小
# 查找大文件
find / -type f -size +100M -exec ls -lh {} \;
du -a /var | sort -n -r | head -n 10
# 分析磁盘使用
ncdu / # 交互式磁盘分析工具
磁盘分区
# 查看分区
lsblk
fdisk -l
parted -l
# 创建分区(GPT)
sudo parted /dev/sdb
(parted) mklabel gpt
(parted) mkpart primary 0% 100%
(parted) quit
# 格式化分区
sudo mkfs.ext4 /dev/sdb1
sudo mkfs.xfs /dev/sdb1
# 挂载
sudo mkdir /mnt/data
sudo mount /dev/sdb1 /mnt/data
# 永久挂载
sudo vim /etc/fstab
/dev/sdb1 /mnt/data ext4 defaults 0 2
# 卸载
sudo umount /mnt/data
逻辑卷管理 (LVM)
# 创建物理卷
sudo pvcreate /dev/sdb1
# 创建卷组
sudo vgcreate vg_data /dev/sdb1
# 创建逻辑卷
sudo lvcreate -L 10G -n lv_data vg_data
# 格式化和挂载
sudo mkfs.ext4 /dev/vg_data/lv_data
sudo mount /dev/vg_data/lv_data /mnt/data
# 扩展逻辑卷
sudo lvextend -L +5G /dev/vg_data/lv_data
sudo resize2fs /dev/vg_data/lv_data
网络配置
网络接口配置
- Ubuntu (Netplan)
- NetworkManager
- 传统方式 (CentOS 7)
# /etc/netplan/01-netcfg.yaml
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: no
addresses:
- 192.168.1.100/24
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
# 应用配置
sudo netplan apply
# 查看连接
nmcli connection show
# 修改连接
nmcli connection modify eth0 ipv4.addresses 192.168.1.100/24
nmcli connection modify eth0 ipv4.gateway 192.168.1.1
nmcli connection modify eth0 ipv4.dns "8.8.8.8 8.8.4.4"
nmcli connection modify eth0 ipv4.method manual
# 重启连接
nmcli connection down eth0
nmcli connection up eth0
# /etc/sysconfig/network-scripts/ifcfg-eth0
TYPE=Ethernet
BOOTPROTO=static
NAME=eth0
DEVICE=eth0
ONBOOT=yes
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
DNS2=8.8.4.4
# 重启网络
sudo systemctl restart network
防火墙配置
- UFW (Ubuntu)
- Firewalld (CentOS)
# 启用防火墙
sudo ufw enable
# 查看状态
sudo ufw status
sudo ufw status verbose
# 允许端口
sudo ufw allow 22
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3000:3010/tcp # 端口范围
# 允许来源IP
sudo ufw allow from 192.168.1.0/24
# 拒绝端口
sudo ufw deny 23
# 删除规则
sudo ufw delete allow 80
# 重置防火墙
sudo ufw reset
# 查看状态
sudo firewall-cmd --state
# 查看所有规则
sudo firewall-cmd --list-all
# 允许服务
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
# 允许端口
sudo firewall-cmd --permanent --add-port=3000/tcp
sudo firewall-cmd --reload
# 允许源IP
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" accept'
sudo firewall-cmd --reload
# 删除规则
sudo firewall-cmd --permanent --remove-port=3000/tcp
sudo firewall-cmd --reload
性能调优
系统参数优化
# 编辑系统参数
sudo vim /etc/sysctl.conf
# 网络优化
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_max_syn_backlog = 8192
net.core.somaxconn = 1024
net.core.netdev_max_backlog = 5000
# 文件描述符限制
fs.file-max = 65536
# 内存优化
vm.swappiness = 10
vm.dirty_ratio = 60
vm.dirty_background_ratio = 2
# 应用配置
sudo sysctl -p
用户限制
# 编辑limits配置
sudo vim /etc/security/limits.conf
# 文件描述符限制
* soft nofile 65536
* hard nofile 65536
# 进程数限制
* soft nproc 4096
* hard nproc 4096
# 查看当前限制
ulimit -a
ulimit -n # 文件描述符
ulimit -u # 进程数
备份和恢复
文件备份
# rsync 备份
rsync -avz --delete /source/ /backup/
rsync -avz /source/ user@remote:/backup/
# tar 备份
tar -czf backup-$(date +%Y%m%d).tar.gz /data/
tar -czf - /data/ | split -b 1G - backup.tar.gz.
# 增量备份
rsync -avz --link-dest=/backup/prev /source/ /backup/current/
自动备份脚本
#!/bin/bash
# /usr/local/bin/backup.sh
BACKUP_DIR="/backup"
SOURCE_DIR="/var/www"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="backup_$DATE.tar.gz"
RETENTION_DAYS=7
# 创建备份
tar -czf "$BACKUP_DIR/$BACKUP_FILE" "$SOURCE_DIR"
# 检查备份结果
if [ $? -eq 0 ]; then
echo "$(date): Backup successful - $BACKUP_FILE" >> /var/log/backup.log
# 删除旧备份
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +$RETENTION_DAYS -delete
else
echo "$(date): Backup failed!" >> /var/log/backup.log
exit 1
fi
数据库备份
# MySQL 备份脚本
#!/bin/bash
DB_USER="root"
DB_PASS="password"
DB_NAME="mydb"
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d)
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME | gzip > "$BACKUP_DIR/${DB_NAME}_$DATE.sql.gz"
# PostgreSQL 备份
pg_dump -U postgres mydb | gzip > /backup/postgres/mydb_$DATE.sql.gz
系统安全
SSH 安全配置
# 编辑SSH配置
sudo vim /etc/ssh/sshd_config
# 推荐配置
Port 2222 # 更改默认端口
PermitRootLogin no # 禁止root登录
PasswordAuthentication no # 禁用密码登录
PubkeyAuthentication yes # 启用密钥认证
AllowUsers user1 user2 # 只允许特定用户
MaxAuthTries 3 # 最大认证尝试次数
ClientAliveInterval 300 # 保持连接
ClientAliveCountMax 2
# 重启SSH服务
sudo systemctl restart sshd
密钥认证
# 生成SSH密钥对
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
ssh-keygen -t ed25519 -C "your_email@example.com"
# 复制公钥到服务器
ssh-copy-id user@host
ssh-copy-id -i ~/.ssh/id_rsa.pub user@host -p 2222
# 手动添加公钥
cat ~/.ssh/id_rsa.pub | ssh user@host 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'
# 设置权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
fail2ban 防暴力破解
# 安装
sudo apt install fail2ban
# 配置
sudo vim /etc/fail2ban/jail.local
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
[sshd]
enabled = true
port = 2222
logpath = /var/log/auth.log
[nginx-http-auth]
enabled = true
# 启动服务
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# 查看状态
sudo fail2ban-client status
sudo fail2ban-client status sshd
# 解封IP
sudo fail2ban-client set sshd unbanip 192.168.1.100
系统监控告警
简单监控脚本
#!/bin/bash
# /usr/local/bin/monitor.sh
# 检查磁盘使用
DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
if [ $DISK_USAGE -gt 80 ]; then
echo "Disk usage is above 80%: ${DISK_USAGE}%" | mail -s "Disk Alert" admin@example.com
fi
# 检查内存使用
MEM_USAGE=$(free | grep Mem | awk '{print ($3/$2) * 100}' | cut -d. -f1)
if [ $MEM_USAGE -gt 90 ]; then
echo "Memory usage is above 90%: ${MEM_USAGE}%" | mail -s "Memory Alert" admin@example.com
fi
# 检查服务状态
if ! systemctl is-active --quiet nginx; then
echo "Nginx is not running!" | mail -s "Service Alert" admin@example.com
systemctl start nginx
fi
最佳实践
系统管理最佳实践
常用维护命令总结
# 系统信息
uname -a && cat /etc/os-release && uptime
# 资源使用
free -h && df -h && top -bn1 | head -20
# 网络状态
ip addr && ss -tulpn && ping -c 3 8.8.8.8
# 服务状态
systemctl list-units --type=service --state=running
# 日志检查
journalctl -p err --since today
tail -f /var/log/syslog
# 安全检查
last -20 && who && w
# 磁盘清理
sudo apt autoremove && sudo apt clean
find /tmp -type f -mtime +7 -delete