[TOC] # 高级系统命令 ## lsattr & chattr 在Linux中有一些不常用的命令,但是重要时刻它又能派上用场,譬如加固你的系统安全,今天笔者就来介绍这这两个命令: * lsattr 查看文件的特殊属性 * chattr 增加或删除文件的特殊属性 **命令的使用** 首先你会发现有的文件,就连root也无法编辑,以下案例root用户向test文件追加一个字符串,会报没有权限的错误。 ``` [djangowang@localhost ~]# echo "Tencent Cloud" >> test -bash: test: Permission denied ``` 这种情况多半可能是文件加了特殊文件位,我们可以通过lsattr命令来确认。 ``` [djangowang@localhost ~]# lsattr test ----i----------- test ``` 我们可以通过chattr命令,去掉这个文件特殊文件位。 ``` [djangowang@localhost ~]# chattr -i test && lsattr test ---------------- test ``` 这时我们就可以再次向文件追加内容了。 关于lsattr命令的参数: * \+ :在原有参数设定基础上,追加参数 * \- :在原有参数设定基础上,移除参数 * \= :更新为指定参数设定 * a:即append,设定该参数后,只能向文件中添加数据,而不能删除,多用于服务器日志文件安全,只有root才能设定这个属性 * i:设定文件不能被删除、改名、设定链接关系,同时不能写入或新增内容 **应用场景** 1.对系统的重点文件进行加固安全,如 /etc/resolv.conf 文件 ,加固方式如下: ``` [djangowang@localhost ~]# chattr +i /etc/resolv.conf ``` 这时我们就不能改此文件,从而加强了系统安全。 2.让某个文件只能往里面追加数据,但不能删除,适用于各种日志文件。 ``` [djangowang@localhost ~]# chattr +a /var/log/messages ``` ## 查看单独IP的网络流量 在运维服务器的过程中,我们经常会遇到这样场景,某个IP访问服务器流量过大,导致服务器响应过慢,这时我们就需要快速定位具体是哪个独立IP在访问我们的服务器,如何快速定位就需要借助工具,这里推荐iptraf-ng这个工具。iptraf是一个基于ncurses开发的网监控工具,它可以实时地监视网卡流量,可以生成各种网络统计数据,包括TCP信息、UDP统计、ICMP和OSPF信息、以太网负载信息、节点统计和IP校验信息等,在CentOS7.8中需要手动安装它,方式如下。 ``` [djangowang@localhost ~]# yum install iptraf-ng ``` 安装后直接在终端输入iptraf-ng命令可以出现工具界面。 ![](https://img.kancloud.cn/47/c5/47c5445cae0af0233c09b5e6d3520e0d_1697x225.png) ## Rsync Rsync可以用于数据备份、增量备份和代码发布等运维中的主要场景。 ## 软连接 & 硬连接 ## 查看硬件信息 作为系统管理员当你拿到一台服务器后总会想知道它的一些硬件信息,如果服务器是在云服务商买的可以直接在服务商的控制台查看,但是如果给你100台服务器或者更多,这些服务器运行在不同的云服务商,如何更快的查看它们的硬件配置,这时我们就可以使用自动化运维工具,将远程服务器系统可识别的硬件信息录入到本地的cmdb中,以方便我们查看。本节就来介绍,如何通过系统文件查看一些比较重要的硬件信息。 * dmidecode查看硬件信息 * 查看CPU型号 * 查看CPU核心数 * 查看网卡信息 * 查看系统位数 * 查看系统的Linux发行版本 通过dmidecode命令查看硬件信息。 ``` [djangowang@localhost ~]# dmidecode | more ``` 查看CPU的型号。 ``` [djangowang@localhost ~]# grep name /proc/cpuinfo model name : AMD EPYC 7K62 48-Core Processor ``` 查看CPU的核数或使用lscpu命令。 ``` [djangowang@localhost ~]# cat /proc/cpuinfo | grep processor processor : 0 processor : 1 ``` 查看网卡信息。 ``` [djangowang@localhost ~]# lspci | grep Ethernet 00:05.0 Ethernet controller: Red Hat, Inc. Virtio network device ``` 查看系统位数,它会返回64或32,表示其系统位数。 ``` [djangowang@localhost ~]# getconf LONG_BIT 64 ``` 查看操作系统的发行版本。 ``` [djangowang@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.8.2003 (Core) ``` ## 软连接 & 硬连接 软链接与硬链接是Linux系统中非常常用的功能类似于Windows创建快捷方式,但在Linux有着更强的应用场景。 **软链接** 软链接可以链接文件或目录,它的格式为( ln -s oldfile slink)。软链接的特点: * 软链接类似Windows系统的快捷方式 * 软链接里面存放的是源文件的路径,指向源文件 * 删除源文件,软链接依然存在,但无法访问源文件内容 * 软链接失效时一般是白字红底闪烁 * 创建软链接命令 ln -s 源文件 软链接文件 * 软链接和源文件是不同的文件,文件类型也不同,Inode号也不同 * 软链接的文件类型是“l”,可以用rm删除 以下分别创建目录链接和文件链接。文件链接。 ``` [djangowang@localhost ~]# ln -s ./passwd_link /etc/passwd ``` 2. 目录链接。 ``` [djangowang@localhost ~]# ln -s ./etc_link /etc/ ``` 3. 检查这些链接。 ``` [djangowang@localhost ~]# ls -al etc_link passwd_link lrwxrwxrwx 1 root root 11 1月 20 10:39 passwd_link -> /etc/passwd lrwxrwxrwx 1 root root 5 1月 20 10:39 etc_link -> /etc/ ``` **硬链接** 硬链接可以关联两个文件的Inode,它的格式为( ln oldfile slink)。硬链接的特点: * 具有相同inode节点号的多个文件互为硬链接文件 * 删除硬链接文件或者删除源文件任意之一,文件实体并未被删除 * 只有删除了源文件和所有对应的硬链接文件,文件实体才会被删除 * 硬链接文件是文件的另一个入口 * 可以通过给文件设置硬链接文件来防止重要文件被误删 * 可以通过ls -i看到Index * 硬链接文件是普通文件,可以用rm删除 如何创建硬链接。 ``` [djangowang@localhost ~]# ls -al etc_link passwd_link ``` # 日志服务 # SSH ## 远程登录Linux 运维服务器远程登录分为两种: * 从Windows登录Linux * 从Linux登录Linux * 从Mac登录Linux **从Windows登录Linux** 推荐Xshell、putty.exe或Securecrt。但需要注意建议这里工具到官网网站或正规渠道下载,早期互联网这种工具在第三方网站下载有存在病毒木马的情况。 **从Linux登录Linux** 这里推荐大家使用SSH命令。譬如从A服务器登录到B服务器,两端均为Linux,同时B启动了SSH服务(端口为22)我们可以执行以下命令在A服务器。 ``` [djangowang@localhost ~]# ssh -l root 192.168.0.11(B服务器的IP) ``` 或者 ``` [djangowang@localhost ~]# ssh root@192.168.0.11(B服务器的IP) ``` **从Mac登录Linux** 推荐iTerm2 ( https://iterm2.com/ ) 或系统自带的终端,直接通过SSH登录就可以。 ## 服务端配置SSH sshd_config文件是SSH守护进程的配置文件。我们来看有关sshd_config配置文件比较重要的参数: * Port 22 # 守护进程的端口 * ListenAddress 0.0.0.0 # 监听的IP地址 * PermitRootLogin yes # 是否允许root账户SSH登录,生产环境中建议改成no,使用普通账户SSH登录 * UseDNS no # 是否使用DNS反向解析 ## 第三方SSH gotty https://github.com/xtermjs/xterm.js/ ## SSH的端口转发 端口转发也是业务运维中比较常用的场景。关于SSH端口转发的参数: * -N: 不执行远程指令 * -v: 打印更详细信息 * -L: listen-port:host:port 指派本地的 port 到达端机器地址上的 port * -R: listen-port:host:port 指派远程上的 port 到本地地址上的 port * -f: 后台执行ssh指令 **将本地端口的流量转发到远程端口** 譬如远程服务器启动了一个Redis服务,监听的是127.0.0.1:6379,要想在本地访问远程的Redis可以这样做 。 ``` ssh -N -v -L localhost:6379:localhost:6379 user@remote_ip ``` **将远程端口流量转发到本地端口** 比如本地启动了一个web服务,监听了127.0.0.1:80。想要在访问remote\_ip:80时就能访问到本地的80端口,可以在本地机器运行 ``` ssh -N -v -R localhost:80:localhost:80 user@remote_ip ``` # 向Linux服务器传输数据 我们在管理服务器的过程中难免向服务器传输一些数据,而传输数据的种类有很多根据场景这里推荐一些使用的工具。 ## Windows传输Linux服务器 如Samba、FTP、SFTP 、对象存储、winscp和rz命令等。 如果是小文件,这里推荐使用"rz"命令,我们需要登录Linux服务器后执行"rz -be"从服务器端将本地数据上传到服务器上,但使用rz命令的前题是服务器需要安装(yum install -y lrzsz)软件包。如果大文件推荐FTP、Samba或对象存储等工具。 使用rz命令上传文件。 关于rz命令的参数: * -b --binary:以二进制方式传输 * -e --escape:对所有控制字符转义 通过rz命令上传文件。 ``` [djangowang@localhost ~]# rz -be ``` 还有一个比较使用的命令就是sz,它和sz命令正好相反用于从服务器下载文件到本机。使用方式,譬如从服务器下载test.txt文件到本机,如下: ``` [djangowang@localhost ~]# sz -be test.xtx ``` ## Linux传输Linux服务器 如FTP、对象存储、scp、rsync和rz命令等。如果是小文件,仍然推荐使用(rz)命令或(scp)命令,(scp)命令有别与(rz)命令,他是本地推送数据到远程的Linux服务器而且走的是ssh加密通道更加的安全,关于scp命令的参数: * \-C: 允许压缩。(将-C标志传递给ssh,从而打开压缩功能) * \-p:保留原文件的修改时间,访问时间和访问权限 * \-q: 不显示传输进度条 * \-r: 递归复制整个目录 * \-c cipher: 以cipher将数据传输进行加密,这个选项将直接传递给ssh * \-F ssh\_config: 指定一个替代的ssh配置文件,此参数直接传递给ssh * \-i identity\_file: 从指定文件中读取传输时使用的密钥文件,此参数直接传递给ssh * \-l limit: 限定用户所能使用的带宽,以Kbit/s为单位 * \-o ssh\_option: 如果习惯于使用ssh\_config(5)中的参数传递方式 * \-P port:注意是大写的P, port是指定数据传输用到的端口号 我们来看一个案例,在本地Linux,推动test.txt文件到远程的Linux服务器。 ``` [djangowang@localhost ~]# scp ./test.txt root@192.168.1.7:/tmp ``` 因为scp是一个命令,所以我们在批量管理多台服务器时可以配合Shell来推送数据文件。 *注:我们在A服务器传输test.txt文件到B服务器,这时我们登录B服务器在A传输那一刻会马上看到B创建了一个test.txt文件,这里需要了解与rsync工具不一样,rsync工具会在B端服务器创建一个临时文件,当整个传输结束后再将临时文件更改为传输前的名字,而 scp直接创建文件。* # 批量登录服务器 通常我们使用expect来批量管理服务器,expect是一个自动化交互套件。我们可以通过( yum install -y expect)安装它。 关于expect的常用命令如下: ``` spawn 交互程序开始后面跟命令或者指定程序 expect 获取匹配信息匹配成功则执行expect后面的程序动作 send exp_send 用于发送指定的字符串信息 exp_continue 在expect中多次匹配就需要用到 send_user 用来打印输出 相当于shell中的echo exit 退出expect脚本 eof expect执行结束 退出 set 定义变量 puts 输出变量 set timeout 设置超时时间 ``` ## 通过账号密码登录服务器 通过(vim)编辑login.expect文件,内容如下。执行./login.expect ,其中(pass)替换为服务器密码然后执行./login.expect来执行查看最终效果。 ``` #!/usr/bin/expect set timeout 5 spawn ssh djangowang@192.168.1.77 expect "password" send "pass\r" #登录成功后在服务端执行的命令 send "touch test.txt\r" expect eof ``` ## 通过秘钥登录服务器 通过Vim命令编辑login.expect文件,内容如下。执行./login.expect 来最终执行并查看结果。 ``` #!/usr/bin/expect set timeout 3 set host [lindex $argv 0] set command [lindex $argv 1] spawn ssh -i djangowang.pem root@$host $command expect "*connecting" send "yes\r" interact ``` # 批量测试服务器是否存活 当我们管理很多服务器的时候,就需要检测这些服务器是否存活,检测方式有很多中譬如ping服务器、telnet服务器或使用一些程序语言通过socket网络连接检测服务器端口连通性。这里笔者推荐一个更为简单的工具来批量检测服务器的联动性,那就是(nc)命令。 在使用前请使用(yum install nc)确保服务器安装了这个工具。 ``` #!/bin/bash port=80 while read line do if nc -z -w1 $line $port ;then echo $line $port "ok" else echo $line $port "fail" fi done < iplist ``` 其中iplist文件为IP地址的列表文件,这个脚本是判断iplist中的IP端口的连通性。关于nc命令的参数: * \-z 表示zero,表示扫描时不发送任何数据 * \-w1 超时秒数,后面跟数字 如果你检测的服务器不是很多,我们也可以将它写为1行,如下: ``` [djangowang@localhost ~]# if nc -z -w1 ip 80 ;then echo "ok"; else echo "fail"; fi ``` 其中IP可以替换为自己的IP地址。 # 系统调优 ## 如何解决time_wait状态 * 如何查看time_wait状态 * 如何解决time_wait状态 **如何查看time_wait状态** ``` [djangowang@localhost ~]# netstat -ant|awk '/^tcp/ {++S[$NF]} END {for(a in S) print (a,S[a])}' LAST_ACK 14 SYN_RECV 348 ESTABLISHED 70 FIN_WAIT1 229 FIN_WAIT2 30 CLOSING 33 TIME_WAIT 18122 ``` **如何解决time_wait状态** ``` net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 net.ipv4.tcp_fin_timeout 修改系默认的 TIMEOUT 时间 ``` ## 深入解决Buffer/Cache 我们在上一章介绍过free这个命令,在命令的回显中有一个重要的指标Buff/Cache。其中Buffer(buff) 是用来缓存尚未“写入”磁盘的内容,Cache(Page Cache) 是用来缓存从磁盘“读取”出来的东西。 ``` [djangowang@localhost ~]# free -m total used free shared buff/cache available Mem: 992 385 63 0 544 459 Swap: 0 0 0 ``` Linux内核会在内存将要耗尽的时候,自动触发内存回收的工作,以便释放出内存给急需内存的进程使用。但在整个触发回收的过程中也是有成本的,成本来自Cache中存在着一部分Write操作的数据,所以必须保证Cache中的数据跟对应文件中的数据一致,才能对Cache进行释放。于是伴随着Cache清除的行为的,一般都是系统IO飙高。这是因为内核要将Cache中缓存的Write数据进行回写。 我们可以通过以下方式人工,触发缓存清除的操作,Linux 提供了三种清空方式: ``` echo 1 > /proc/sys/vm/drop_caches # 仅清除页面缓存 echo 2 > /proc/sys/vm/drop_caches # 清除目录项和inode echo 3 > /proc/sys/vm/drop_caches # Pagecache、Dentries和Inodes ``` 在回收的过程中,我们可以通过以下两个测试案例来深入了解Buffer/Cache。关于测试案例我们用到了dd命令和vmstat命令: * Linux dd命令,可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。 * vmstat命令功能强大,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。 ### 测试Cache案例 1.为避免测试时,现有系统缓存的数据影响,我们先清理Pagecache、Dentries和Inodes,清理方式如下。 ``` [djangowang@localhost ~]# echo 3 > /proc/sys/vm/drop_caches ``` 2. 我们分别登陆两个终端登陆到一台服务器,其中终端1,执行vmstat命令。 ``` [djangowang@localhost ~]# vmstat 1 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 3412304 5196 247376 0 0 136 0 965 481 0 35 65 1 0 1 0 0 3258172 5196 400952 0 0 0 0 2089 953 1 51 49 0 0 1 0 0 3105904 5212 552940 0 0 12 122976 1914 950 0 51 48 2 0 1 0 0 2981224 5228 678220 0 0 16 122880 1460 877 1 41 48 10 0 3 0 0 2847500 5232 811796 0 0 8 122884 1279 527 0 44 48 8 0 0 4 0 2795112 5240 864020 0 0 20 168 584 740 0 19 34 48 0 1 5 0 2698032 5256 959228 0 0 116 166864 1541 1782 1 32 23 43 0 1 4 0 2623828 5424 1033208 0 0 376 105992 1061 859 0 25 6 70 0 ... ``` 同时在终端2中执行以下命令,随机读取一个1G文件。可以发现vmstat命令的回显Cache会不断的上涨。但buff并没有认可变化。 ``` [djangowang@localhost ~]# dd if=/dev/urandom of=/tmp/file bs=1M count=1024 ``` ### 测试Buff案例 1.再次执行以下命令,来清理Pagecache、Dentries和Inodes。 ``` [djangowang@localhost ~]# echo 3 > /proc/sys/vm/drop_caches ``` 2.我们分别登陆两个终端登陆到一台服务器,其中终端1,执行vmstat命令。 ``` [djangowang@localhost ~]# vmstat 1 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 1 0 0 3516848 6020 143556 0 0 0 13 1 17 0 0 99 0 0 0 0 0 3515620 6020 143592 0 0 0 0 410 712 0 1 99 0 0 0 0 0 3515660 6028 143592 0 0 8 16 349 628 0 0 100 0 0 0 0 0 3515644 6064 143588 0 0 36 0 419 722 0 1 99 1 0 0 1 0 3345116 175092 143680 0 0 169104 0 784 879 0 3 61 36 0 0 1 0 3218748 302092 143604 0 0 126992 72 746 933 1 3 49 48 0 1 2 0 3086932 433180 143700 0 0 131088 0 852 1032 1 2 48 50 0 0 2 0 3042452 478256 143652 0 0 45076 284 1027 1454 0 2 44 55 0 0 1 0 2974220 547900 143836 0 0 69644 0 1095 1531 0 1 49 49 0 0 1 0 2834804 687164 144124 0 0 139264 0 621 742 0 2 50 48 0 ... ``` 同时在终端2中执行以下命令,向磁盘写入1G的文件数据。 ``` [djangowang@localhost ~]# dd if=/dev/vda1 of=/dev/null bs=1M count=1024 ``` 这次往磁盘快速写数据与上次读取数据正好相反。buff快速上涨,而Cache没有变化。 # SELINUX # 本章小结 # 习题