本文基于 CentOS 7.9.2009 操作系统最小化安装进行说明

初始设置

字符集

如果使用英文安装系统之后,如果系统中有中文会显示乱码,这个时候需要修改系统默认的字符集:

1
2
echo 'LANG="zh_CN.UTF-8"' > /etc/sysconfig/i18n
source /etc/sysconfig/i18n

将系统的编码修改为 zh_CN.UTF-8,后面一句命令是让修改立即生效

欢迎信息

1
2
echo "Welcome to Server" > /etc/issue 
echo "Welcome to Server" > /etc/redhat-release

主机名

1
2
3
4
5
6
#修改主机名
echo 'xxx' > /etc/hostname
#查看当前主机名
cat /etc/hostname
#修改 hosts
vi /etc/hosts

设置网络

静态分配

网卡配置文件存放在:/etc/sysconfig/network-scripts/ 目录

1
2
3
4
5
6
7
8
9
10
vi /etc/sysconfig/network-scripts/ifcfg-eth0

BOOTPROTO="static"
IPADDR="192.168.1.103"
NETMASK="255.255.255.0"
GATEWAY="192.168.1.1"
DNS1="223.5.5.5"
DNS2="8.8.8.8"
……
ONBOOT="yes"

添加第二块网卡(按需)
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
#获取 UUID
nmcli con
#获取 MAC
ip addr
cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth1
vi /etc/sysconfig/network-scripts/ifcfg-eth1
#替换增加如下字段
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="static"
IPADDR="192.168.1.103"
NETMASK="255.255.255.0"
GATEWAY="192.168.1.1"
DNS1="223.5.5.5"
DNS2="8.8.8.8"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="eth0"
UUID="6e099b8a-6fea-4c25-80f0-f7ec48e18efa"
DEVICE="eth0"
ONBOOT="yes"
IPV6_PRIVACY="no"

设置 DNS

1
2
echo "nameserver 114.114.114.114" > /etc/resolv.conf
systemctl restart network

关闭 Selinux

1
2
3
4
5
6
7
8
#查看状态,enforcing 表示开启,disabled 则是关闭
getenforce && setenforce 0
#临时操作开启关闭
setenforce 0/1
#永久关闭,需要重启
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
#重启
reboot

关闭防火墙

直接关闭防火墙,如果开启需要设置相应的策略


1
2
3
4
#关闭并删除开机启动
systemctl status firewalld
systemctl stop firewalld
systemctl disable firewalld

关闭 Swap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
## 删除 Swap 区所有内容
swapoff -a
swapoff /swap
rm /swap
## 重启
reboot
## Swap 行全部是 0 表示删除成功
free -h
## 重新开启 Swap
fallocate -l 1G /swap
dd if=/dev/zero of=/swap bs=1024 count=1048576
chmod 600 /swap && ls -l /swap
mkswap /swap
swapon /swap

时间同步

1
2
3
4
5
6
7
8
9
10
11
12
chkconfig --list | grep ntp
#安装同步软件
yum install -y ntpdate
#手动同步
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #设置 Shanghai 时区
timedatectl status
ntpdate ntp.aliyun.com; hwclock–w #同步时间并写入 blos 硬件时间
#利用 crontab 自动同步
#每天 0 点执行
echo '0 0 * * * /usr/sbin/ntpdate ntp.aliyun.com; hwclock -w ' >> /var/spool/cron/root
systemctl restart crond
crontab -l

性能优化

资源限制

  • 系统级:当前系统可打开的最大数量,通过 fs.file-max 参数可修改
  • 用户级:指定用户可打开的最大数量,修改 /etc/security/limits.conf
  • 进程级:单个进程可打开的最大数量,通过 fs.nr_open 参数可修改
    1
    2
    3
    4
    5
    vi /etc/sysctl.conf
    #多留点 buffer
    fs.file-max=1100000
    #要比 hard nofile 大一点
    fs.nr_open=1100000
    修改 /etc/security/limits.conf 文件,格式:限制对象 限制级别 限制参数 限制大小
  • 限制对象:用户、用户组(前面添加@区分),可以使用通配符(*、%)
  • 限制级别:hard & soft 分别表示报错和告警的级别
  • 限制参数:nofile & nproc 表示最大文件数和最大进程数

还有其他参数,一般很少用到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#        - core - limits the core file size (KB)
# - data - max data size (KB)
# - fsize - maximum filesize (KB)
# - memlock - max locked-in-memory address space (KB)
# - nofile - max number of open file descriptors
# - rss - max resident set size (KB)
# - stack - max stack size (KB)
# - cpu - max CPU time (MIN)
# - nproc - max number of processes
# - as - address space limit (KB)
# - maxlogins - max number of logins for this user
# - maxsyslogins - max number of logins on the system
# - priority - the priority to run user process with
# - locks - max number of file locks the user can hold
# - sigpending - max number of pending signals
# - msgqueue - max memory used by POSIX message queues (bytes)
# - nice - max nice priority allowed to raise to values: [-20, 19]
# - rtprio - max realtime priority

查看当前数值
1
2
#查看当前句柄数,切换到不同用户进行测试
ulimit -a


查看进程句柄数
1
ps -ef | grep nginx


然后使用进程号查看
1
cat /proc/进程号/limits


使用以下命令或者直接修改(如果多用户环境,不建议使用 * 设置)

  • soft nproc:单个用户可用的最大进程数量(告警)
  • hard nproc:单个用户可用的最大进程数量(报错)
  • soft nofile :可打开的文件描述符的最大数(告警)
  • hard nofile:可打开的文件描述符的最大数(报错)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    cat >> /etc/security/limits.conf <<EOF
    root soft nofile 65536
    root hard nofile 65536
    root soft nproc 65536
    root hard nproc 65536
    app soft nofile 65536
    app hard nofile 65536
    app soft nproc 65536
    app hard nproc 65536
    EOF
    PS.针对被限制无法修改的句柄数
  • 修改 /etc/ssh/sshd_config,将 UseLogin 参数值改为 yes
    1
    2
    3
    vi /etc/ssh/sshd_config
    UseLogin yes
    UsePrivilegeSeparation no
  • 修改 /etc/pam.d/login,增加条目
    1
    2
    vi /etc/pam.d/login
    session required pam_limits.so
  • 再去修改 limits.conf 之后重启 sshd 服务

    内核参数

    修改 /etc/sysctl.conf 添加如下配置,修改完成后输入 sysctl -p 生效
    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
    cat >> /etc/sysctl.conf << EOF
    #控制系统调试内核的功能,不同的值对应不同的功能:
    #0 禁用 sysrq 组合键
    #1 启用 sysrq 组合键
    #2 启用控制台日志级别控制
    #4 启用键盘控制(SAK、unraw)
    #8 启用进程的调试信息输出等
    #16 启用同步命令
    #32 启用重新挂载为只读
    #64 启用进程信号(终止、杀死、溢出杀死)
    #128 允许重启、关机
    #256 控制实时任务的优先级控制(nicing)
    kernel.sysrq = 0

    #尽量使用内存,减少使用磁盘交换分区,内存速度明显高于磁盘一个数量级
    vm.swappiness = 0
    vm.max_map_count=262144

    #避免放大攻击
    net.ipv4.icmp_echo_ignore_broadcasts = 1

    #开启恶意 ICMP 错误消息保护
    net.ipv4.icmp_ignore_bogus_error_responses = 1

    #开启 SYN 洪水攻击保护
    net.ipv4.tcp_syncookies = 1

    #开启并记录欺骗,源路由和重定向包
    net.ipv4.conf.all.log_martians = 1
    net.ipv4.conf.default.log_martians = 1

    #处理无源路由的包
    net.ipv4.conf.all.accept_source_route = 0
    net.ipv4.conf.default.accept_source_route = 0

    #开启反向路径过滤
    net.ipv4.conf.all.rp_filter = 1
    net.ipv4.conf.default.rp_filter = 1

    #启用转发
    net.ipv4.ip_forward = 1
    net.ipv4.conf.all.send_redirects = 0
    net.ipv4.conf.default.send_redirects = 0

    #确保无人能修改路由表
    net.ipv4.conf.all.accept_redirects = 0
    net.ipv4.conf.default.accept_redirects = 0
    net.ipv4.conf.all.secure_redirects = 0
    net.ipv4.conf.default.secure_redirects = 0

    #开启 execshild
    kernel.exec-shield = 1
    kernel.randomize_va_space = 1

    #IPv6 设置
    net.ipv6.conf.default.router_solicitations = 0
    net.ipv6.conf.default.accept_ra_rtr_pref = 0
    net.ipv6.conf.default.accept_ra_pinfo = 0
    net.ipv6.conf.default.accept_ra_defrtr = 0
    net.ipv6.conf.default.autoconf = 0
    net.ipv6.conf.default.dad_transmits = 0
    net.ipv6.conf.default.max_addresses = 1

    #优化 LB 使用的端口

    #增加系统文件描述符限制
    fs.file-max = 65535

    #允许更多的 PIDs (减少滚动翻转问题)
    kernel.pid_max = 65536

    #增加系统 IP 端口限制
    net.ipv4.ip_local_port_range = 5000 65535

    #FIN-WAIT-2 状态超时时间
    net.ipv4.tcp_fin_timeout = 30

    #保持 TIME_WAIT 状态的最大数量
    net.ipv4.tcp_max_tw_buckets = 32768

    #开启 TCP 连接中 TIME_WAIT 套接字的快速回收
    net.ipv4.tcp_timestamps = 1
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tw_recycle = 1
    #Linux 4.1 内核删除
    net.ipv4.tcp_tw_recycle = 1

    net.ipv4.tcp_max_orphans = 262144
    net.ipv4.tcp_max_syn_backlog = 262144

    #Keepalive 生效时,发送 TCP 消息的频度
    net.ipv4.tcp_keepalive_time = 1200

    #TCP Socket
    net.ipv4.tcp_mem = 64608 86144 129216
    net.ipv4.tcp_rmem = 4096 87380 16777216
    net.ipv4.tcp_wmem = 4096 65536 16777216
    net.core.rmem_default = 262144
    net.core.wmem_default = 262144
    net.core.rmem_max = 16777216
    net.core.wmem_max = 16777216
    net.core.netdev_max_backlog = 262144
    net.ipv4.tcp_window_scaling = 1
    EOF
    随机端口:Linux 下如果没有使用 Listen、Connect 指定端口,就从 Port Range 中随机取一个可用的
    1
    2
    cat /proc/sys/net/ipv4/ip_local_port_range
    2000 65535
    系统内核优化
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    net.ipv4.tcp_fin_timeout = 2
    net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_syncookies = 1
    net.ipv4.tcp_keepalive_time = 600
    net.ipv4.ip_local_port_range = 400065000
    net.ipv4.tcp_max_syn_backlog = 16384
    net.ipv4.tcp_max_tw_buckets = 36000
    net.ipv4.route.gc_timeout = 100
    net.ipv4.tcp_syn_retries = 1
    net.ipv4.tcp_synack_retries = 1
    net.ipv4.ip_conntrack_max = 25000000
    net.ipv4.netfilter.ip_conntrack_max=25000000
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_established=180
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait=120
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait=60
    net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait=120

    内存阈值

    修改 /etc/rc.local 文件
    1
    2
    3
    4
    5
    6
    7
    #无内存过量使用处理策略,使用这个设置会增大内存超载的可能性,但也可以增强大量使用内存任务的性能
    echo 1 > /proc/sys/vm/overcommit_memory
    #设置最大连接队列
    echo 8192 > /proc/sys/net/core/somaxconn
    #禁用大页内存
    echo never > /sys/kernel/mm/transparent_hugepage/enabled
    reboot

    安全设置

    修改密码长度

    1
    2
    vi /etc/login.defs
    PASS_MIN_LEN 18

    创建普通账号

    并设置密码,这样所有的操作都使用该普通账号进行,后面还要禁止 root 帐号的操作。
    1
    2
    3
    4
    5
    6
    useradd -d /app app 
    passwd app
    cp /etc/skel/.bash_logout /app/
    cp /etc/skel/.bash_profile /app/
    cp /etc/skel/.bashrc /app/
    chown app:app /app && chmod 755 /app

    禁用多余帐号

    Linux 默认提供了很多账号,越容易受到攻击,所以禁止默认的被操作系统本身启动的且不必要的账号;使用 vi /etc/passwd 查看系统账号,使用 vi /etc/group 查看系统的用户组
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    userdel adm
    userdel lp
    userdel sync
    userdel shutdown
    userdel halt
    userdel news
    userdel uucp
    userdel operator
    userdel games
    userdel gopher
    userdel ftp
    groupdel adm
    groupdel lp
    groupdel news
    groupdel uucp
    groupdel games
    groupdel dip
    groupdel pppusers
    以上代码一条一条输入运行即可

    禁止非授权用户获得权限

    1
    2
    3
    4
    chattr +i /etc/passwd
    chattr +i /etc/shadow
    chattr +i /etc/group
    chattr +i /etc/gshadow
    这样操作之后也无法创建账号和修改密码,后面可以使用 chattr -i 命令恢复之后再进行操作

    禁用 Ctrl+Alt+Delete 重启

    修改 /etc/inittab 文件,将下面一行注释掉
    1
    ca::ctrlaltdel:/sbin/shutdown -t3 -r now
    或者
    1
    2
    vi /etc/init/control-alt-delete.conf 
    #exec /sbin/shutdown -r now "Control-Alt-Deletepressed" #注释掉

    修改 /etc/profile 配置

    1
    2
    3
    4
    5
    6
    7
    # 设置自动退出终端,防止非法关闭ssh客户端造成登录进程过多,可以设置大一些,单位为秒
    echo "TMOUT=3600" >> /etc/profile
    # 历史命令记录数量设置为 300 条
    sed -i "s/HISTSIZE=1000/HISTSIZE=300/" /etc/profile
    # 历史命令记录添加日期和时间,方便审计
    echo "export HISTTIMEFORMAT='%F %T '" >> /etc/profile
    source /etc/profile
    进阶:增加登录 IP、用户名
    1
    export HISTTIMEFORMAT="%F %T `who \-u am i 2>/dev/null | awk '{print $NF}' | sed \-e 's/[()]//g'` `whoami` "

    /etc/rc.d/init.d/ 目录权限

    /etc/rc.d/init.d/ 目录下所有文件仅 root 账号可以读、写和执行其中的所有脚本文件:
    1
    chmod -R 700 /etc/rc.d/init.d/*

    修改 SSH 配置

    接下来先备份原来的配置文件
1
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

然后修改 vi /etc/ssh/sshd_config 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# SSH 的端口,默认为 22
Port 5028
# 将#protocol 2,1改为
protocol 2

# 不允许 root 用户直接登录
PermitRootLogin no
# 不允许空密码登录
PermitEmptyPasswords no
# SSH 探活:5 检查一次,共 3 次
ClientAliveInterval 300
ClientAliveCountMax 3
# 不允许使用网址登录
UseDns no

然后使用 service sshd restart 重启 SSH 服务

防止攻击

阻止 ping

/proc/sys/net/ipv4/icmp_echo_ignore_all 文件的内容修改为 1,不过这样的话如果服务器重启之后就会恢复为 0 了

可以将下面的内容加入到 /etc/rc.d/rc.local 文件中:

1
echo 1 /proc/sys/net/ipv4/icmp_echo_ignore_all

防止 IP 欺骗攻击

编辑 /etc/host.conf 文件,在下面增加如下几行:

1
2
3
4
vi /etc/host.conf
order bind,hosts
multi off
nospoof on

防止 DoS 攻击

对系统所有的用户设置资源限制可以防止 DoS 类型攻击,如最大进程数和内存使用数量,对 /etc/security/limits.conf 文件添加如下内容:

1
2
3
4
5
6
# 禁止调试文件
* hard core 0
# 限制内存使用为5MB
* hard rss 5000
# 限制进程数为20
* hard nproc 20

接下来必须编辑 /etc/pam.d/login 文件确认下面一行是否存在,如果不存在的话添加上:
1
session required /lib/security/pam_limits.so

对于 DDos 攻击可以使用 DDoS deflate 脚本

工具依赖

1
2
3
4
#编译依赖
yum install gcc gcc-c++ openssl openssl-devel pcre pcre-devel zlib zlib-devel patch make
#调试
yum install vim zip unzip tar net-tools telnet curl wget fontconfig lrzsz

History

vi /etc/profile
HISTSIZE=1000
HISTTIMEFORMAT
/etc/bashrc

HISTSIZE:控制缓冲区历史记录的最大个数
HISTFILESIZE:控制历史记录文件中的最大个数
HISTIGNORE:设置哪些命令不记录到历史记录
HISTTIMEFORMAT:设置历史命令显示的时间格式
HISTCONTROL:扩展的控制选项
如果在生产环境,这些环境变量需要持久化到配置文件 ~/.bash_profile
export HISTSIZE=1000
export HISTFILESIZE=200000
export HISTIGNORE=”ls:history”
export HISTTIMEFORMAT=”%F %T “
export HISTCONTROL=ignoreboth

  • ignorespace: 忽略空格开头的命令
  • ignoredups: 忽略连续重复命令
  • ignoreboth: 表示上述两个参数都设置
  • 设置追加而不是覆盖
    shopt -s histappend