Linux系统基础性能调优策略总结
原创
一、系统基础配置与调优
1、系统安装和分区经验
(1)、磁盘与raid
如果是自建服务器(非云服务器),那么在安装系统前,磁盘是必须要做raid的,raid可以保护系统数据安全,同时也能最大限度的提高磁盘的读、写性能。
那么什么是raid呢,简单普及下基础:
RAID ( Redundant Array of Independent Disks )即独立磁盘冗余阵列,它是一种把多块独立的硬盘(物理硬盘)按不同的方式组合起来形成一个硬盘组(逻辑硬盘),从而提供比单个硬盘更高的存储性能和提供数据备份技术。
RAID 的基本思想是将多个容量较小、相对廉价的磁盘进行有机组合,从而以较低的成本获得与昂贵大容量磁盘相当的容量、性能、可靠性。
RAID 中主要有三个关键概念和技术:镜像( Mirroring )、数据条带( Data Stripping )和数据校验( Data parity )
根据运用或组合运用这三种技术的策略和架构,可以把 RAID分为不同的等级,以满足不同数据应用的需求。业界公认的标准是 RAID0 ~ RAID5。
实际应用领域中使用最多的 RAID 等级是 RAID0 、 RAID1 、RAID5 、RAID10。
RAID 每一个等级代表一种实现方法和技术,等级之间并无高低之分。在实际应用中,应当根据用户的数据应用特点,综合考虑可用性、性能和成本来选择合适的 RAID 等级,以及具体的实现方式。
那么线上服务器环境RAID如何选型呢,这里给一个参考给大家:
因此,根据实际应用需要,我们在部署线上服务器的时候,最好配置两组raid,一组是系统盘raid,对系统盘(安装操作系统的磁盘)推荐配置为raid1,另一组是数据盘raid,对数据盘(存放应用程序、各种数据)推荐采用raid1、raid5或者raid10。
看视频版本,请戳我
(2)、linux系统版本选择
线上服务器安装操作系统推荐红帽系列发行版本,具体的版本推荐almalinux或者rocky linux版本,这也是目前最常用的两个版本,要说为什么这么推荐,原因很简单,一些老的产品和系统基本都是运行在rhel系列版本上,而未来的系统升级趋势肯定是rhel系列,所以选择这两个版本肯定没错。
(3)、Linux分区与swap使用经验
在安装操作系统的时候,对磁盘分区的配置也非常重要,正确的磁盘分区设置可以最大限度的保证系统稳定运行,减少后期很多运维工作。那么如何将分区设置为最优呢,这里有个原则:系统分区和数据分区分离。
首先,在系统分区的创建上,建议划分系统必须的一些分区,例如/、/boot、/var、/usr这四个最好独立分区。同时这四个分区最好在一个物理raid1上,也就是在一组raid上单独安装操作系统。
接着,还需要创建数据分区,数据分区主要用来存放程序数据、数据库数据、web数据等等,这部分数据非常重要,不容丢失,数据分区可以创建多个,也可以创建一个,比如创建两个数据分区,一个存储web数据,一个存储db数据,同时,这些数据分区最好也要在一个物理raid(raid1、raid5等)上。
关于磁盘分区,默认安装的话,会使用LVM(逻辑卷管理)进行分区管理,作为线上生产环境,我其实是强烈不推荐使用LVM的,因为LVM的动态扩容功能,对现在大硬盘时代来说,基本没什么用处了,一般可以一次性规划好硬盘的最大使用空间,相反,使用LVM带来的负面影响更大,首先,它影响磁盘读写性能,其次,它不便于后期的运维,因为LVM的磁盘分区一旦故障,数据基本无法恢复,基于这些原因,不推荐使用LVM进行磁盘管理。
最后,再说说swap,现在内存价格越来越便宜了,上百G内存的服务器也很常见了,那么安装操作系统的时候,swap还需要设置吗,答案是需要,原因有二:
第一,交换分区主要是在内存不够用的时候,将部分内存上的数据交换到swap空间上,以便让系统不会因内存不够用而导致oom或者更致命的情况出现。如果你的物理内存不够大,通过设置swap可以在内存不够用的时候不至于触发oom-killer导致某些关键进程被杀掉,比如数据库业务。
第二,有些业务系统,比如redis、elasticsearch等主要使用物理内存的系统,我们不希望让它使用swap,因为大量使用swap会导致性能急剧下降,而如果不设置swap的话,如果使用内存量激增,那么可能会出现oom-killer的情况,导致应用宕机;而如果设置了swap,此时可以通过设置/proc/sys/vm/swappiness这个swap参数,调整使用swap的几率,此值越小,使用swap的机率就越低,这样既可以解决oom-killer的情况,也可以避免出现swap过度使用的情况。
那么问题来了,swap设置多少合适呢,一个原则是:物理内存在16GB以下的,swap设置为物理内存的2倍即可,而物理内存大于16GB的话,一般推荐swap设置8GB左右即可。
(4)、系统软件包安装建议
linux系统安装盘中默认自带了很多开源软件包,这些软件包对线上服务器来说大部分是不需要的,所以,作为服务器只需要安装一个基础内核加一些辅助的软件以及网络工具即可,所以安装软件包的策略是:仅安装需要的,按需安装、不用不装。
在almalinux8.x、9.x版本下,选择“server with GUI”、“开发工具”即可。
2、ssh登录系统策略
linux服务器的远程维护管理都是通过ssh服务完成的,默认使用22端口监听,这些默认的配置已经成为黑 客扫描的常用方式,所以对ssh服务的配置需要做一些安全加固和优化。
ssh服务的配置文件为/etc/ssh/sshd_config,常用的优化选项有如下几个:
Port 22221
SSH默认端口配置,修改默认22端口为1万以上端口号,避免被扫描和攻 击。
UseDNS no
不使用DNS反查,可提高ssh连接速度
GSSAPIAuthentication no
关闭GSSAPI验证,可提高ssh连接速度
PermitRootLogin no
禁止root账号ssh登陆
3、selinux策略设置
selinux是个鸡肋,在线上服务器上部署应用的时候,推荐关闭selinux,关闭方法如下:
Selinux的状态有如下几个:
enforcing 开启状态
permissive 提醒的状态
disabled 关闭状态
要查看当前selinux的状态,可执行如下命令:
[root@ACA8D5EF ~]# /usr/sbin/sestatus -v
SELinux status: enforcing
要关闭selinux,有两种方式,一种是命令行临时关闭,命令如下:
[root@ACA8D5EF ~]#setenforce 0
另一种是永久关闭,修改/etc/selinux/config,将
SELINUX=disabled
修改为
SELINUX=disabled
然后重启系统生效。
4、定时自动更新服务器时间
线上服务器对时间的要求是非常严格的,为了避免服务器时间因为在长时间运行中所导致的时间偏差,进行时间同步(synchronize)的工作是非常必要的。Linux系统下,一般使用ntp服务来同步不同机器的时间。NTP是网络时间协议(Network Time Protocol)的简称,干嘛用的呢?就是通过网络协议使计算机之间的时间同步。
对服务器进行时间同步的方式有两种,一种是自己搭建NTP服务器,然后跟互联网上的时间服务器做校对,另一种是通过在服务器上设置定时任务,定期去一个或多个时间服务器进行时间同步。
如果你同步的服务器较多(超过100台),建议在自己的网络中搭建一台NTP服务器,然后让你网络中的其它服务器都与这个NTP服务器进行同步,而这个ntp 服务器再去互联网上跟其他NTP server进行同步,通过多级同步,即可完成时间的一致性校验。
如果服务器较少的话,可以直接在服务器上设置crontab定时任务即可,例如,可以在自己服务器上设置如下计划任务:
10 * * * * /usr/sbin/ntpdate ntp1.aliyun.com >> /var/log/ntp.log 2>&1; /sbin/hwclock -w
这个计划任务是每个小时跟阿里云时间服务器同步一次,同时将同步过程写入到ntp.log文件中,最后将系统时钟同步到硬件时钟。
网上可用的时间服务器有很多,推荐使用阿里云的,或者centos自带的例如0.centos.pool.ntp.org都可以使用。
5、更新yum源及必要软件安装
在操作系统安装完成后,系统默认的软件版本(gcc、glibc、glib、openssl等)都比较低,可能存在bug或者漏洞,因此,升级软件的版本,非常重要,要快速升级软件版本,可通过yum工具实现,在升级软件之前,给系统添加几个扩展yum源。
epel源:https://fedoraproject.org/wiki/EPEL
repoforge源:http://repoforge.org/use/
安装上面两个yum源过程如下:
[root@ACA8D5EF ~]#yum install epel-release
[root@ACA8D5EF ~]# rpm -ivh http://repository.it4i.cz/mirrors/repoforge/redhat/el7/en/x86_64/rpmforge/RPMS/rpmforge-release-0.5.3-1.el7.rf.x86_64.rpm
最后,执行系统更新:
[root@ACA8D5EF ~]#yum update
6、重要文件加锁
系统运维人员有时候可能会遇到通过root用户都不能修改或者删除某个文件的情况,产生这种情况的大部分原因可能是这个文件被锁定了。在Linux下锁定文件的命令是chattr,通过这个命令可以修改ext2、ext3、ext4文件系统下文件属性,但是这个命令必须有超级用户root来执行。和这个命令对应的命令是lsattr,这个命令用来查询文件属性。
对一些重要的目录和文件可以加上“i”属性,常见的文件和目录有:
chattr +i /etc/sudoers
chattr +i /etc/shadow
chattr +i /etc/passwd
chattr +i /etc/grub.conf
其中,“+i”选项即immutable,用来设定文件不能被修改、删除、重命名、设定链接等,同时不能写入或新增内容。这个参数对于文件系统的安全设置有很大帮助
对一些重要的日志文件可以加上“a”属性,常见的有:
chattr +a /var/log/messages
chattr +a /var/log/wtmp
其中,“+a”选项即append,设定该参数后,只能向文件中添加数据,而不能删除。常用于服务器日志文件安全,只有root用户才能设置这个属性。
7、系统资源参数优化
通过命令“ ulimit -a”可以看到所有系统资源参数,这里面需要重点设置的是“open files”和“max user processes”,其它可以酌情设置。
要永久设置资源参数,主要是通过下面两个文件来实现:
/etc/security/limits.conf
/etc/security/limits.d/20-nproc.conf
将下面内容添加到/etc/security/limits.conf中,然后退出shell,重新登录即可生效。
* soft nproc 20480
* hard nproc 20480
* soft nofile 655360
* hard nofile 655360
* soft memlock unlimited
* hard memlock unlimited
需要注意的是,不同版本下,limits配置文件可能略有不同。
二、系统安全与防护策略
2.1、设定tcp_wrappers防火墙
Tcp_Wrappers是一个用来分析TCP/IP封包的软件,类似的IP封包软件还有iptables。Linux默认都安装了Tcp_Wrappers。作为一个安全的系统,Linux本身有两层安全防火墙,通过IP过滤机制的iptables实现第一层防护。
iptables防火墙通过直观地监视系统的运行状况,阻挡网络中的一些恶意扫描和攻 击,保护整个系统正常运行,免遭攻 击和破坏。如果通过了第一层防护,那么下一层防护就是tcp_wrappers了。通过Tcp_Wrappers可以实现对系统中提供的某些服务的开放与关闭、允许和禁止,从而更有效地保证系统安全运行。
要安装Tcp_Wrappers,可执行如下命令:
[root@localhost ~]# yum install tcp_wrappers
tcp_wrappers防火墙的实现是通过/etc/hosts.allow和/etc/hosts.deny两个文件来完成的,首先看一下设定的格式:
service:host(s) [:action]
? service:代表服务名,例如sshd、vsftpd、sendmail等。
? host(s):主机名或者IP地址,可以有多个,例如192.168.12.0、www.ixdba.net。
? action:动作,符合条件后所采取的动作。
配置文件中常用的关键字有:
? ALL:所有服务或者所有IP。
? ALL EXCEPT:所有的服务或者所有IP除去指定的。
例如:
ALL:ALL EXCEPT 192.168.12.189
表示除了192.168.12.189这台机器,任何机器执行所有服务时或被允许或被拒绝。
了解了设定语法后,下面就可以对服务进行访问限定。
例如,互联网上一台Linux服务器,实现的目标是:仅仅允许222.61.58.88、61.186.232.58以及域名www.ixdba.net 通过SSH服务远程登录到系统,下面介绍具体的设置过程。
首先设定允许登录的计算机,即配置/etc/hosts.allow文件,设置很简单,只要修改/etc/hosts.allow(如果没有此文件,请自行建立)这个文件,即只需将下面规则加入/etc/hosts.allow即可。
sshd: 222.61.58.88
sshd: 61.186.232.58
sshd: www.ixdba.net
接着设置不允许登录的机器,也就是配置/etc/hosts.deny文件。
一般情况下,Linux会首先判断/etc/hosts.allow这个文件,如果远程登录的计算机满足文件/etc/hosts.allow设定,就不会去使用/etc/hosts.deny文件了;相反,如果不满足hosts.allow文件设定的规则,就会去使用hosts.deny文件了,如果满足hosts.deny的规则,此主机就被限制为不可访问Linux服务器,如果也不满足hosts.deny的设定,此主机默认是可以访问linux服务器的。因此,当设定好/etc/hosts.allow文件访问规则之后,只需设置/etc/hosts.deny为“所有计算机都不能登录状态”:
sshd:ALL
这样,一个简单的tcp_wrappers防火墙就设置完毕了。
2.2、合理使用Shell历史命令记录功能
在Linux下可通过history命令查看用户所有的历史操作记录,同时shell命令操作记录默认保存在用户目录下的.bash_history文件中,通过这个文件可以查询shell命令的执行历史,有助于运维人员进行系统审计和问题排查,同时,在服务器遭受攻 击后,也可以通过这个命令或文件查询被攻 击者登录服务器所执行的历史命令操作,但是有时候黑 客攻 击服务器后为了毁灭痕迹,可能会删除.bash_history文件,这就需要合理的保护或备份.bash_history文件。下面介绍下history日志文件的安全配置方法。
为了确保服务器的安全,保留shell命令的执行历史是非常有用的一条技巧。shell虽然有历史功能,但是这个功能并非针对审计目的而设计,因此很容易被黑 客篡改或是丢失。下面再介绍一种方法,可以实现详细记录登录过系统的用户、IP地址、shell命令以及详细操作时间等,并将这些信息以文件的形式保存在一个安全的地方,以供系统审计和故障排查。
将下面这段代码添加到/etc/profile文件中,即可实现上述功能。
#history
USER_IP=`who -u am i 2>/dev/null| awk '{print $NF}'|sed -e 's/[()]//g'`
HISTDIR=/usr/share/.history
if [ -z $USER_IP ]
then
USER_IP=`hostname`
fi
if [ ! -d $HISTDIR ]
then
mkdir -p $HISTDIR
chmod 777 $HISTDIR
fi
if [ ! -d $HISTDIR/${LOGNAME} ]
then
mkdir -p $HISTDIR/${LOGNAME}
chmod 300 $HISTDIR/${LOGNAME}
fi
export HISTSIZE=4000
DT=`date +%Y%m%d_%H%M%S`
export HISTFILE="$HISTDIR/${LOGNAME}/${USER_IP}.history.$DT"
export HISTTIMEFORMAT="[%Y.%m.%d %H:%M:%S]"
chmod 600 $HISTDIR/${LOGNAME}/*.history* 2>/dev/null
这段代码将每个用户的shell命令执行历史以文件的形式保存在/usr/share/.history目录中,每个用户一个文件夹,并且文件夹下的每个文件以IP地址加shell命令操作时间的格式命名。下面是root用户执行shell命令的历史记录文件,基本效果如下:
[root@localhost root]# pwd
/usr/share/.history/root
[root@localhost root]# ll
total 24
-rw------- 1 root root 134 Nov 2 17:21 172.16.213.132.history.20181102_172121
-rw------- 1 root root 793 Nov 2 17:44 172.16.213.132.history.20181102_174256
保存历史命令的文件夹目录要尽量隐蔽,避免被攻 击者发现后删除。
2.3、Linux软件防火墙iptables
1、 iptables的概念
iptables是linux系统内嵌的一个防火墙软件(封包过滤式防火墙),它集成在系统内核中,因此执行效率非常的高,iptables通过设置一些封包过滤规则,来定义什么数据可以接收,什么数据需要剔除,因此,用户通过iptables可以对进出计算机的数据包进行IP过滤,以达到保护主机的目的。
iptables是有最基本的多个表格(tables)组成的,而且每个表格的用途都不一样,在每个表格中,又定义了多个链(chain),通过这些链可以设置相应的规则和策略.
2、 filter表
iptables有3种常用的表选项,包括管理本机数据进出的filter、管理防火墙内部主机nat 和改变不同包及包头内容的mangle。
filter表一般用于的信息包过滤,内置了INPUT、OUTPUT和FORWARD链。
INPUT链:主要是对外部数据包进入linux系统进行信息过滤。
OUTPUT链:主要是对内部linux系统所要发送的数据包进行信息过滤。
FORWARD链:将外面过来的数据包传递到内部计算机中。
3、 NAT表
NAT表主要用处是网络地址转换,即Network Address Translation,缩写为NAT,它包含PREROUTING、POSTROUTING和OUTPUT链。
PREROUTING链:是在数据包刚刚到达防火墙时,根据需要改变它的目的地址。例如DNAT操作,就是通过一个合法的公网IP地址,通过对防火墙的访问,重定向到防火墙内的其它计算机(DMZ区域),也就是说通过防火墙改变了访问的目的地址,以使数据包能重定向到指定的主机
POSTROUTING链:在包就要离开防火墙之前改变其源地址,例如SNAT操作,屏蔽了本地局域网主机的信息,本地主机通过防火墙连接到internet,这样在internet上看到的本地主机的来源地址都是同一个IP,屏蔽了来源主机地址信息
OUTPUT链:改变了本地产生包的目的地址
4、防火墙规则的查看与清除
列出当前系统filter table的几条链规则:
[root@localhost ~]# iptables -L -n
列出nat表的链信息:
[root@localhost ~]# iptables -t nat -L -n
清除规则
清除本机防火墙的所有规则设定:
[root@localhost ~]# iptables -F
[root@localhost ~]# iptables -X
[root@localhost ~]# iptables –Z
上面三条指令可以清除防火墙的所有规则,但是不能清除预设的默认规则(policy)
5、线上服务器iptables推荐配置
下面是一个常规的线上linux服务器iptables配置规则:
iptables -P INPUT ACCEPT
iptables -F
iptables -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A INPUT -s 1.1.1.0/24 -p tcp -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 2.2.2.2 -p tcp -m tcp --dport 22 -j ACCEPT
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,ACK FIN -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags PSH,ACK PSH -j DROP
iptables -A INPUT -p tcp -m tcp --tcp-flags ACK,URG URG -j DROP
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -P FORWARD DROP
这个配置规则很简单,主要是为了限制进来的请求,所以仅仅配置了INPUT链,刚开始是先打开INPUT链,然后清除所有规则,接着,对全网开启服务器上80、443端口(因为是网站服务器,所以必须对全网开启80和443),然后,针对两个客户端IP开启远程连接22端口的权限,这个主要是用于远程对服务器的维护。接着,对网络接口eth1(内网网卡)、lo(回环地址)开启全部允许进入访问。
接着下面是对tcp连接状态的设置,当连接状态满足“RELATED,ESTABLISHED“时,开启连接请求,当有非法连接状态时(通过tcp-flags标记),直接DROP请求。
最后,将INPUT链、FORWARD链全部关闭,仅开放OUTPUT链。