Linux 自定义配置
针对新安装或新购买的 CentOS、RedHat 等 Linux 系统,可参考如下步骤完成系统加固或前期规范操作。
交付前期
1. 替换为阿里云的yum源
- 以下以 CentOS 7.9 为例,其他版本请参考本站《linux更改yum源》
cat /etc/resolv.conf | grep nameserver | grep "223.5.5.5" || echo "nameserver 223.5.5.5" >> /etc/resolv.conf
mv /etc/yum.repos.d/CentOS-Base.repo /tmp/CentOS-Base.repo.$(date +%Y%m%d%H%M%S)
curl -sL http://mirrors.aliyun.com/repo/Centos-7.repo -o /etc/yum.repos.d/CentOS-Base.repo
yum makecache > /dev/null
2. 安装基础软件
yum install -y -q wget ntpdate lrzsz telnet zip unzip net-tools make
3. 关闭selinux
- 关闭 SELinux
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
setenforce 0
- 查看selinux的状态,返回Disabled或Enforcing
getenforce
sestatus -v | grep SELinux
- 启用 SELinux
sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
sed -i 's/^SELINUXTYPE=.*/SELINUXTYPE=targeted/' /etc/selinux/config
/usr/sbin/sestatus | grep SELinux
4. 修改ssh端口
- 为了降低被攻击的概率,建议禁ping并更改ssh的默认22端口,示例更改为 23245
注:若 Oracle Linux 8.9 未配置 SELinux,启动sshd服务则可能会报错 error: Bind to port 23245 on 0.0.0.0 failed: Permission denied.
#.针对 centos 7 更改ssh默认22端口为23245
sed -i "s/#Port/Port/" /etc/ssh/sshd_config
sed -i '/^Port/c Port 23245' /etc/ssh/sshd_config
grep "^Port" /etc/ssh/sshd_config
systemctl restart sshd.service
5. 更改机器名
- 示例将机器改为 centos7
hostnamectl set-hostname centos7
6. 设置DNS及时区及时间同步
- 设置DNS及时区,并同步时间
#.设置DNS
cat /etc/resolv.conf | grep "^nameserver" || echo "nameserver 223.5.5.5" > /etc/resolv.conf
#.设置时区为上海
timedatectl set-timezone "Asia/Shanghai"
timedatectl status | grep Time
#.配置ntp时间同步
yum install -y -q ntpdate
/usr/sbin/ntpdate -u ntp.aliyun.com
- 设置时间为24小时制,比如 01:02 PM 改为 13:02
echo "LANG=en_US.UTF-8" > /etc/default/locale
echo "LC_TIME=en_DK.UTF-8" >> /etc/default/locale
source /etc/default/locale
date
7. 配置iptables
- 从模板文件获取并启用iptables,限制敏感端口访问,并加入开机启动
#.获取iptables模板
touch /bin/iptables.sh
curl http://iso.sqlfans.cn/linux/iptables.sh > /bin/iptables.sh
chmod +x /bin/iptables.sh
#.添加到开机启动
cat /etc/rc.local | grep iptables || echo "bash /bin/iptables.sh" >> /etc/rc.local
chmod +x /etc/rc.local
8. 关闭系统swap
- 开启并使用 swap 可能会引入性能抖动问题,对于低延迟、稳定性要求高的数据库服务,建议永久关闭操作系统层 swap,可使用以下方法:
sed -i '/^vm.swappiness/d' /etc/sysctl.conf
echo "vm.swappiness = 0" >> /etc/sysctl.conf
/sbin/sysctl -p /etc/sysctl.conf > /dev/null 2>&1
# swapoff -a && swapon -a
swapoff -a
- 如果主机内存偏小,关闭系统 swap 可能会更容易触发 OOM 问题,可参考以如下方法将 swap 优先级调低,但不做永久关闭:
sed -i '/^vm.swappiness/d' /etc/sysctl.conf
echo "vm.swappiness = 0" >> /etc/sysctl.conf
/sbin/sysctl -p /etc/sysctl.conf > /dev/null 2>&1
9. 优化ulimit
- 优化ulimit
ulimit -n 655350
cat /etc/security/limits.conf | grep nofile | grep 655350 || echo "* - nofile 655350" >> /etc/security/limits.conf
cat /etc/security/limits.conf | grep nproc | grep 655350 || echo "* - nproc 655350" >> /etc/security/limits.conf
cat /etc/security/limits.conf | grep core | grep unlimited || echo "* - core unlimited" >> /etc/security/limits.conf
cat /etc/security/limits.conf | grep stack | grep unlimited || echo "* - stack unlimited" >> /etc/security/limits.conf
cat /etc/security/limits.conf | grep "^*"
- 需退出当前会话,并重新连接
ulimit -a | egrep "(size|files)"
10. 关闭透明大页
- 针对数据库服务器,建议关闭透明大页(即 Transparent Huge Pages,缩写为 THP)
- 数据库的内存访问模式往往是稀疏的而非连续的,当高阶内存碎片化比较严重时,分配 THP 页面会出现较高的延迟
#.临时关闭透明大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
#.写入开机启动
sed -i '/transparent_hugepage/d' /etc/rc.d/rc.local
echo 'echo never > /sys/kernel/mm/transparent_hugepage/defrag' >> /etc/rc.d/rc.local
echo 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' >> /etc/rc.d/rc.local
#.通过grub永久关闭
cp /etc/default/grub /etc/default/grub.$(date +%Y%m%d%H%M%S)
cat /etc/default/grub | grep transparent_hugepage || sed -i 's/rhgb quiet/rhgb quiet transparent_hugepage=never/g' /etc/default/grub
grub2-mkconfig -o /etc/grub2.cfg
#.同时关闭透明大页和NUMA
cp /etc/default/grub /etc/default/grub.$(date +%Y%m%d%H%M%S)
cat /etc/default/grub | grep transparent_hugepage || sed -i 's/rhgb quiet/rhgb quiet transparent_hugepage=never numa=off/g' /etc/default/grub
grub2-mkconfig -o /etc/grub2.cfg
11. 关闭NUMA
#.CentOS/Redhat
cp /etc/default/grub /etc/default/grub.$(date +%Y%m%d%H%M%S)
cat /etc/default/grub | grep numa || sed -i 's/rhgb quiet/rhgb quiet numa=off/g' /etc/default/grub
grub2-mkconfig -o /etc/grub2.cfg
#.Kylin|麒麟
if [ -e "/boot/grub2/grub.cfg" ]; then
grub2-mkconfig -o /boot/grub2/grub.cfg
elif [ -e "/boot/efi/EFI/kylin/grub.cfg" ]; then
grub2-mkconfig -o /boot/efi/EFI/kylin/grub.cfg
fi
12. 优化内核参数
- linux 内核参数,请务必慎重修改 ...
#.为了避免修改失败,先依次删除相关参数的配置
sed -i '/^fs.aio-max-nr/d' /etc/sysctl.conf
sed -i '/^fs.file-max/d' /etc/sysctl.conf
sed -i '/^vm.max_map_count/d' /etc/sysctl.conf
sed -i '/^fs.nr_open/d' /etc/sysctl.conf
sed -i '/^kernel.shmall/d' /etc/sysctl.conf
sed -i '/^kernel.shmmax/d' /etc/sysctl.conf
sed -i '/^kernel.shmmni/d' /etc/sysctl.conf
sed -i '/^kernel.sem/d' /etc/sysctl.conf
sed -i '/^net.ipv4.ip_local_port_range/d' /etc/sysctl.conf
sed -i '/^net.core.rmem_default/d' /etc/sysctl.conf
sed -i '/^net.core.rmem_max/d' /etc/sysctl.conf
sed -i '/^net.core.wmem_default/d' /etc/sysctl.conf
sed -i '/^net.core.wmem_max/d' /etc/sysctl.conf
#.再重新配置相关参数
echo "fs.aio-max-nr= 1048576" >> /etc/sysctl.conf
echo "fs.file-max= 6815744" >> /etc/sysctl.conf
echo "vm.max_map_count=655360" >> /etc/sysctl.conf
echo "fs.nr_open = 20480000" >> /etc/sysctl.conf
echo "kernel.shmall = 2097152" >> /etc/sysctl.conf
echo "kernel.shmmax = 4294967295" >> /etc/sysctl.conf
echo "kernel.shmmni = 4096" >> /etc/sysctl.conf
echo "kernel.sem = 250 32000 100 128" >> /etc/sysctl.conf
echo "net.ipv4.ip_local_port_range = 9000 65500" >> /etc/sysctl.conf
echo "net.core.rmem_default = 262144" >> /etc/sysctl.conf
echo "net.core.rmem_max = 4194304" >> /etc/sysctl.conf
echo "net.core.wmem_default = 262144" >> /etc/sysctl.conf
echo "net.core.wmem_max = 1048576" >> /etc/sysctl.conf
#.执行sysctl生效
/sbin/sysctl -p /etc/sysctl.conf > /dev/null 2>&1
脚本开发
1. 适配 OS 版本
RedHat系列:Red Hat、CentOS、Oracle Linux、Fedora、Rocky Linux、AlmaLinux、Alibaba Cloud Linux
Debian系列:Debian、Ubuntu
SUSE系列:SUSE Linux、openSUSE
国产系列:Kylin麒麟、UOS统信、EulerOS欧拉(openEuler开源欧拉)
- 关于获取 OS Version 的几种方式介绍:
| OS Version | /etc/redhat-release | /etc/issue | lsb_release -a | /etc/os-release | 推荐 |
|---|---|---|---|---|---|
| Red Hat Linux | ✔ | ✖ | ✖ | ✔ | /etc/redhat-release |
| CentOS Linux 7/8/9 | ✔ | ✖ | ✖ | ✔ | /etc/redhat-release |
| CentOS Linux 5/6 | ✔ | ✔ | ✖ | ✖ | /etc/redhat-release |
| Oracle Linux | ✔(返回Red Hat) | ✖ | ✖ | ✔ | /etc/os-release |
| Debian | ✖ | ✔ | ✔ | ✔ | /etc/os-release |
| Ubuntu Server | ✖ | ✔ | ✔ | ✔ | /etc/os-release |
| openSUSE Leap 15.5 | ✖ | ✖ | ✖ | ✔ | /etc/os-release |
| Kylin Server | ✖ | ✖ | ✖ | ✔ | /etc/kylin-release |
| UOS Server | ✖ | ✔ | ✔ | ✔ | /etc/issue |
| openEuler | ✖ | ✖ | ✖ | ✔ | /etc/openEuler-release |
- [推荐] 通过 /etc/os-release 获取版本信息
注:CentOS 6.x 不存在 /etc/os-release
#.通过cat获取版本信息
cat /etc/os-release | grep PRETTY_NAME | cut -d= -f2 | tr -d '"'
#.通过source获取版本信息, 以下是各种OS的返回信息
[root@localhost ~]# source /etc/os-release && echo $PRETTY_NAME
Red Hat Enterprise Linux 8.6 (Ootpa)
CentOS Linux 7 (Core) #.查看 /etc/redhat-release 返回 CentOS Linux release 7.9.2009 (Core)
Oracle Linux Server 8.9
Debian GNU/Linux 13 (trixie)
Ubuntu 24.04.3 LTS
openSUSE Leap 15.5
Kylin Linux Advanced Server V10 (Halberd)
UOS Server 20
openEuler 24.03 (LTS-SP3)
- [推荐] 通过判断OS 类型并创建账号,示例:用户
appadmin密码WZ6HeMax3GR0_5hp
grep -q appadmin /etc/group || groupadd appadmin
grep -q appadmin /etc/passwd || useradd -g appadmin -s /bin/bash -m appadmin
source /etc/os-release
echo "$PRETTY_NAME" | grep -q Ubuntu && echo "appadmin:WZ6HeMax3GR0_5hp" | chpasswd
echo "$PRETTY_NAME" | grep -qE "(CentOS|Oracle|Kylin|UOS|openEuler)" && echo 'WZ6HeMax3GR0_5hp' | passwd appadmin --stdin
- [推荐] 通过判断 OS 类型并调整软件安装方式
#.CentOS|Oracle|Kylin|UOS|openEuler均使用yum安装软件, 唯独Ubuntu使用apt安装软件
source /etc/os-release
is_ubuntu=`echo $PRETTY_NAME | grep Ubuntu | wc -l`
is_linux=`echo $PRETTY_NAME | egrep "(CentOS|Oracle|Kylin|UOS|openEuler)" | wc -l`
if [ $is_ubuntu -eq 1 ]; then apt install -y sshpass; fi
if [ $is_linux -eq 1 ]; then yum install -y sshpass; fi
- [推荐] 通过判断是否存在 apt 或 yum 命令并调整软件安装方式
if ! command -v sshpass &> /dev/null; then
echo -e "[警告] 检测到 sshpass 未安装, 正在尝试自动安装..."
printf "\n"
if command -v apt &> /dev/null; then
sudo apt update -y &> /dev/null
sudo apt install -y sshpass &> /dev/null
elif command -v yum &> /dev/null; then
sudo yum install -y sshpass &> /dev/null
else
echo -e "[错误] 自动安装依赖失败, 请手动安装: sshpass"
exit 1
fi
fi