<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/rss.xsl" type="text/xsl"?>
<rss version="2.0">
  <channel>
    <title>IT瘾linux推荐</title>
    <link>https://itindex.net/categories/linux</link>
    <description>IT社区推荐资讯 - ITIndex.net</description>
    <language>zh</language>
    <copyright>https://itindex.net/</copyright>
    <generator>https://itindex.net/</generator>
    <docs>http://backend.userland.com/rss</docs>
    <image>
      <url>https://itindex.net/images/logo.gif</url>
      <title>IT社区推荐资讯 - ITIndex.net</title>
      <link>https://itindex.net/categories/linux</link>
    </image>
    <item>
      <title>接近九成 Windows 游戏能在 Linux 上运行</title>
      <link>https://itindex.net/detail/63077-windows-%E6%B8%B8%E6%88%8F-linux</link>
      <description>根据 ProtonDB 的数据，近九成 Windows 游戏现在能在 Linux 上运行。这一进步受益于 WINE 和 Proton 翻译层开发者的努力，以及对 Steam Deck 等 Linux 掌机的兴趣。ProtonDB 将游戏分为五类：白金级游戏无需任何调整即可完美运行；金级游戏需要进行小的调整；银级游戏可玩但并不完美；Borked 级游戏完全无法运行；
铜级游戏介于银级和 Borked 级之间。数据显示，白金级新游戏数量正在增长，而 Borked 级游戏数量则在减少。很多热门游戏不支持 Linux 主要是因为反作弊软件与 Linux 的不兼容性导致的。
 &lt;p&gt;&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/63077-windows-%E6%B8%B8%E6%88%8F-linux</guid>
      <pubDate>Wed, 29 Oct 2025 15:49:15 CST</pubDate>
    </item>
    <item>
      <title>保护核心资产: LINUX内核防护</title>
      <link>https://itindex.net/detail/62805-%E6%A0%B8%E5%BF%83-%E8%B5%84%E4%BA%A7-linux</link>
      <description>Shawn the R0ck 写道：操作系统内核常遭受的漏洞利用典型表现为内存污染、进程凭证窃取等。这些漏洞利用往往在操作系统内核内部甚至更深的地方发生，使得它们极为难以侦测和追踪。更加令人担忧的是，内核漏洞利用因其深入系统的最底层并具有最高级别的操作权限，所以其破坏力异常巨大。HardenedVault为Linux操作系统设计了Vault Exploits Defense (VED)作为其基础安全方案。内核级别的防护长期以来一直是网络空中挑战最为严峻的技术难题之一。然而，HardenedVault 利用创新的方式，实现了运行时的全面防护，Vault Exploits Defense (VED) 能有效地检测并阻止已知（Nday）和未知（0day）的 Linux 内核漏洞利用，而这些漏洞利用往往具备极大的破坏力，并且十分难以侦测。另一方面，消除一两个漏洞利用方法比硬编码的防御一堆0day漏洞利用更有价值。无论是已知或者未知(n-day/0-day)的漏洞都可以利用新的漏洞利用方法重新构造漏洞利用，这种数字军火的更替会使防御体系难以应对。因此，未公开的漏洞利用方法的危险程度远高于一堆0day漏洞。VED 经过数年的进化，其特性达到了在预防利用和利用阶段之间的效果，不仅对于绕过 Tetragon 或者 Pipe primitive 这类漏洞利用方法具备免疫能力，甚至一些常见的漏洞利用方法也会在早期被 VED 检测和阻止。对运行时和rootkits防护有兴趣的币圈，链圈，电商圈，X圈的朋友们可以尝试AWS的安全加固镜像（集成了基础长期维护版本的VED）。
 &lt;p&gt;&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62805-%E6%A0%B8%E5%BF%83-%E8%B5%84%E4%BA%A7-linux</guid>
      <pubDate>Thu, 13 Jul 2023 20:48:51 CST</pubDate>
    </item>
    <item>
      <title>Linux系统中负载较高问题排查思路与解决方法 - 朝明 - 博客园</title>
      <link>https://itindex.net/detail/62798-linux-%E7%B3%BB%E7%BB%9F-%E8%B4%9F%E8%BD%BD</link>
      <description>&lt;div&gt;    &lt;blockquote&gt;      &lt;p&gt;Load 就是对计算机干活多少的度量，Load Average 就是一段时间（1分钟、5分钟、15分钟）内平均Load。&lt;/p&gt;&lt;/blockquote&gt;    &lt;h3&gt;一、Load分析：&lt;/h3&gt;    &lt;h5&gt;情况1：CPU高、Load高&lt;/h5&gt;    &lt;ol&gt;      &lt;li&gt;通过top命令查找占用CPU最高的进程PID；&lt;/li&gt;      &lt;li&gt;通过top -Hp PID查找占用CPU最高的线程TID;&lt;/li&gt;      &lt;li&gt;对于java程序，使用jstack打印线程堆栈信息（可联系业务进行排查定位）；&lt;/li&gt;      &lt;li&gt;通过        &lt;code&gt;printf %x tid&lt;/code&gt;打印出最消耗CPU线程的十六进制；&lt;/li&gt;      &lt;li&gt;在堆栈信息中查看该线程的堆栈信息；&lt;/li&gt;&lt;/ol&gt;    &lt;h5&gt;情况2：CPU低、Load高&lt;/h5&gt;    &lt;ol&gt;      &lt;li&gt;通过top命令查看CPU等待IO时间，即        &lt;code&gt;%wa&lt;/code&gt;；&lt;/li&gt;      &lt;li&gt;通过        &lt;code&gt;iostat -d -x -m 1 10&lt;/code&gt;查看磁盘IO情况；(安装命令        &lt;code&gt;yum install -y sysstat&lt;/code&gt;)&lt;/li&gt;      &lt;li&gt;通过        &lt;code&gt;sar -n DEV 1 10&lt;/code&gt;查看网络IO情况；&lt;/li&gt;      &lt;li&gt;通过如下命令查找占用IO的程序；&lt;/li&gt;&lt;/ol&gt;    &lt;pre&gt;      &lt;code&gt;ps -e -L h o state,cmd  | awk &amp;apos;{if($1==&amp;quot;R&amp;quot;||$1==&amp;quot;D&amp;quot;){print $0}}&amp;apos; | sort | uniq -c | sort -k 1nr&lt;/code&gt;&lt;/pre&gt;    &lt;h3&gt;二、CPU高、Load高情况分析&lt;/h3&gt;    &lt;ul&gt;      &lt;li&gt;使用        &lt;code&gt;vmstat&lt;/code&gt;查看系统纬度的 CPU 负载；&lt;/li&gt;      &lt;li&gt;使用        &lt;code&gt;top&lt;/code&gt;查看进程纬度的 CPU 负载；&lt;/li&gt;&lt;/ul&gt;    &lt;h4&gt;2.1、使用 vmstat 查看系统纬度的 CPU 负载&lt;/h4&gt;    &lt;p&gt;可以通过 vmstat 从系统维度查看 CPU 资源的使用情况&lt;/p&gt;    &lt;p&gt;格式：      &lt;code&gt;vmstat -n 1&lt;/code&gt;      &lt;code&gt;-n 1&lt;/code&gt;表示结果一秒刷新一次&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;[root@k8s-10 ~]# vmstat -n 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  1      0 2798000   2076 6375040    0    0    10    76   10   49  6  2 91  1  0
 0  0      0 2798232   2076 6375128    0    0     0   207 7965 12525  7  2 90  2  0&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;返回结果中的主要数据列说明：&lt;/p&gt;    &lt;ul&gt;      &lt;li&gt;        &lt;p&gt;          &lt;strong&gt;r&lt;/strong&gt;： 表示系统中 CPU 等待处理的线程。由于 CPU 每次只能处理一个线程，所以，该数值越大，通常表示系统运行越慢。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;          &lt;strong&gt;b&lt;/strong&gt;： 表示阻塞的进程,这个不多说，进程阻塞，大家懂的。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;          &lt;strong&gt;us&lt;/strong&gt;： 用户CPU时间，我曾经在一个做加密解密很频繁的服务器上，可以看到us接近100,r运行队列达到80(机器在做压力测试，性能表现不佳)。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;          &lt;strong&gt;sy&lt;/strong&gt;： 系统CPU时间，如果太高，表示系统调用时间长，例如是IO操作频繁。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;          &lt;strong&gt;wa&lt;/strong&gt;：IO 等待消耗的 CPU 时间百分比。该值较高时，说明 IO 等待比较严重，这可能磁盘大量作随机访问造成的，也可能是磁盘性能出现了瓶颈。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;          &lt;strong&gt;id&lt;/strong&gt;：处于空闲状态的 CPU 时间百分比。如果该值持续为 0，同时 sy 是 us 的两倍，则通常说明系统则面临着 CPU 资源的短缺。&lt;/p&gt;        &lt;p&gt;          &lt;strong&gt;常见问题及解决方法：&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;如果r经常大于4，且id经常少于40，表示cpu的负荷很重。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;如果pi，po长期不等于0，表示内存不足。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;如果disk经常不等于0，且在b中的队列大于3，表示io性能不好。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;h4&gt;2.1、使用 top 查看进程纬度的 CPU 负载&lt;/h4&gt;    &lt;p&gt;可以通过 top 从进程纬度来查看其 CPU、内存等资源的使用情况。&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;[root@k8s-10 ~]# top -c
top - 19:53:49 up 2 days,  7:57,  3 users,  load average: 0.76, 0.79, 0.58
Tasks: 282 total,   2 running, 280 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.4 us,  1.4 sy,  0.0 ni, 95.0 id,  1.2 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 12304204 total,  2800864 free,  3119064 used,  6384276 buff/cache
KiB Swap:        0 total,        0 free,        0 used.  8164632 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
29884 root      20   0 5346580 929332  14556 S   0.0  7.6   6:19.19 /opt/jdk1.8.0_144/bin/java -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apach+
  875 root      20   0  729524 563424  38612 S   3.1  4.6  93:22.70 kube-apiserver --authorization-mode=Node,RBAC --service-node-port-range=80-60000 --advertise-address=10.68.7.162 --allow-privileged=true -+
 3870 nfsnobo+  20   0  910376 317248  22812 S   1.6  2.6  42:29.59 /bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --storage.tsdb.retention=1d --web.enable-life+&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;默认界面上第三行会显示当前 CPU 资源的总体使用情况，下方会显示各个进程的资源占用情况。&lt;/p&gt;    &lt;p&gt;可以直接在界面输入大小字母 P，来使监控结果按 CPU 使用率倒序排列，进而定位系统中占用 CPU 较高的进程。最后，根据系统日志和程序自身相关日志，对相应进程做进一步排查分析，以判断其占用过高 CPU 的原因。&lt;/p&gt;    &lt;h4&gt;2.2、strace命令分析&lt;/h4&gt;    &lt;p&gt;      &lt;a href="https://oa.kedacom.com/confluence/pages/viewpage.action?pageId=77136289" rel="noopener" target="_blank"&gt;https://oa.kedacom.com/confluence/pages/viewpage.action?pageId=77136289&lt;/a&gt;&lt;/p&gt;    &lt;h3&gt;三、CPU低、Load高情况分析&lt;/h3&gt;    &lt;p&gt;      &lt;strong&gt;问题描述&lt;/strong&gt;：      &lt;br /&gt;Linux 系统没有业务程序运行，通过 top 观察，类似如下图所示，CPU 很空闲，但是 load average 却非常高：&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;处理办法&lt;/strong&gt;：&lt;/p&gt;    &lt;ul&gt;      &lt;li&gt;load average 是对 CPU 负载的评估，其值越高，说明其任务队列越长，处于等待执行的任务越多。&lt;/li&gt;      &lt;li&gt;出现此种情况时，可能是由于僵死进程导致的。可以通过指令        &lt;code&gt;ps -axjf&lt;/code&gt;查看是否存在 D 状态进程。&lt;/li&gt;      &lt;li&gt;D 状态是指不可中断的睡眠状态。该状态的进程无法被 kill，也无法自行退出。只能通过恢复其依赖的资源或者重启系统来解决。&lt;/li&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;等待I/O的进程通过处于uninterruptible sleep或D状态；通过给出这些信息我们就可以简单的查找出处在wait状态的进程
ps -eo state,pid,cmd | grep &amp;quot;^D&amp;quot;; echo &amp;quot;----&amp;quot;

- 查找占用IO的程序
ps -e -L h o state,cmd  | awk &amp;apos;{if($1==&amp;quot;R&amp;quot;||$1==&amp;quot;D&amp;quot;){print $0}}&amp;apos; | sort | uniq -c | sort -k 1nr&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62798-linux-%E7%B3%BB%E7%BB%9F-%E8%B4%9F%E8%BD%BD</guid>
      <pubDate>Sat, 08 Jul 2023 12:01:28 CST</pubDate>
    </item>
    <item>
      <title>Linux 下如何查找木马并处理 - ericyuan - 博客园</title>
      <link>https://itindex.net/detail/62734-linux-%E6%9C%A8%E9%A9%AC-ericyuan</link>
      <description>&lt;div&gt;    &lt;p&gt;1、cat /etc/passwd 未发现陌生用户和可疑root权限用户。&lt;/p&gt;    &lt;p&gt;2、netstat -anp 查看所有进程及pid号，未发现异常连接。&lt;/p&gt;    &lt;p&gt;3、last 查看最近登录用户，未发现异常&lt;/p&gt;    &lt;p&gt;4、cat /etc/profile 查看系统环境变量，未发现异常&lt;/p&gt;    &lt;p&gt;5、ls -al /etc/rc.d/rc3.d ，查看当前级别下开机启动程序，未见异常（有一些脸生，只好利用搜索引擎了）&lt;/p&gt;    &lt;p&gt;6、crontab -l 检查计划任务，root用户和web运行用户各检查一遍，未见任何异常&lt;/p&gt;    &lt;p&gt;7、cat /root/.bashrc 和 cat /home/用户/.bashrc 查看各用户变量，未发现异常&lt;/p&gt;    &lt;p&gt;8、查看系统日志。主要是/var/log/messages(进程日志)、/var/log/wtmp(系统登录成功日志 who /var/log/wtmp)、/var/log//bmtp(系统登录失败日志)、/var/log/pureftpd.log(pureftpd的连接日志)，未发现异常（考虑到了可能的日志擦除，重点看了日志的连续性，未发现明显的空白时间段）&lt;/p&gt;    &lt;p&gt;9、history 查看命令历史。cat /home/用户/.bash_history 查看各用户命令记录，未发现异常&lt;/p&gt;    &lt;p&gt;10、系统的查完了，就开始查web的。初步查看各站点修改时间，继而查看各站点的access.log和error.log（具体路径不发了 ），未发现报告时间前后有异常访问。虽有大量攻击尝试，未发现成功。&lt;/p&gt;    &lt;p&gt;11、日志分析完毕，查找可能存在的webshell。方法有两个，其一在服务器上手动查找；其二，将web程序下载到本地使用webshellscanner或者web杀毒等软件进行查杀。考虑到站点较多，数据量大，按第一种方法来。 在linux上查找webshell基本两个思路：修改时间和特征码查找。 特征码例子：find 目录 -name &amp;quot;*.php&amp;quot;（asp、aspx或jsp） |xargs grep &amp;quot;POST[（特征码部分自己添加）&amp;quot; |more 修改时间：查看最新3天内修改的文件，find 目录 -mtime 0 -o -mtime 1 -o -mtime 2 当然也可以将两者结合在一起，find 目录 -mtime 0 -o -mtime 1 -o -mtime 2 -name &amp;quot;*.php&amp;quot; 的确查找到了一些停用的站点下有webshell&lt;/p&gt;    &lt;p&gt;--------&lt;/p&gt;    &lt;p&gt;查找全站关键字：“pack”、“eval”&lt;/p&gt;&lt;/div&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62734-linux-%E6%9C%A8%E9%A9%AC-ericyuan</guid>
      <pubDate>Thu, 13 Apr 2023 22:41:24 CST</pubDate>
    </item>
    <item>
      <title>linux下模拟一个木马程序运行过程</title>
      <link>https://itindex.net/detail/62733-linux-%E6%A8%A1%E6%8B%9F-%E6%9C%A8%E9%A9%AC%E7%A8%8B%E5%BA%8F</link>
      <description>&lt;p&gt;预备知识：&lt;/p&gt; &lt;p&gt;将一个程序放入到后台，悄悄的执行&lt;/p&gt; &lt;p&gt;./xxx.sh &amp;amp;&lt;/p&gt; &lt;p&gt;进程：&lt;/p&gt; &lt;p&gt;用户进程：由用户来管理&lt;/p&gt; &lt;p&gt;系统进程：由系统内核自行管理&lt;/p&gt; &lt;p&gt;系统中的每个进程，都有一个位置的ID，这就是pid，而且每次启动进程以后，PID都不相同&lt;/p&gt; &lt;p&gt;进程相关的命令&lt;/p&gt; &lt;p&gt;jobs&lt;/p&gt; &lt;p&gt;作用：查看当前运行在后台的进程有哪些&lt;/p&gt; &lt;p&gt;信息&lt;/p&gt; &lt;p&gt;第一列：进程编号&lt;/p&gt; &lt;p&gt;第二列：进程状态&lt;/p&gt; &lt;p&gt;第三列：进程是如何发起的&lt;/p&gt; &lt;p&gt;fg   进程编号    把进程从后台调到前台执行&lt;/p&gt; &lt;p&gt;kill %进程编号  杀死进程&lt;/p&gt; &lt;p&gt;ps aux   打印系统所有进程&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="fe5411f1440651980d04c56b598dc550.png" src="https://img-blog.csdnimg.cn/img_convert/fe5411f1440651980d04c56b598dc550.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;num=`ps aux | grep myser |wc -l`   #执行grep myser本身就会创建一个进程，如果有myser这个进程则num为2,如果没有myser这个进程,则num为1,&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="584fd45fc169198f07a317dae6c4d9df.png" src="https://img-blog.csdnimg.cn/img_convert/584fd45fc169198f07a317dae6c4d9df.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;kill作用杀死进程&lt;/p&gt; &lt;p&gt;格式：kill 信号级别 进程PID&lt;/p&gt; &lt;p&gt;信号级别&lt;/p&gt; &lt;p&gt;-9：斩立决。立刻杀死进程&lt;/p&gt; &lt;p&gt;-15：死缓。等待现有的客户端处理完毕之后，立刻杀死进程&lt;/p&gt; &lt;p&gt;【等待期间新的用户请求无法被接入】&lt;/p&gt; &lt;p&gt;木马最终效果&lt;/p&gt; &lt;p&gt;让程序自动运行，而且是开机自动运行起来&lt;/p&gt; &lt;p&gt;程序还可以自我保护&lt;/p&gt; &lt;p&gt;防止程序文件被删除&lt;/p&gt; &lt;p&gt;实现步骤&lt;/p&gt; &lt;p&gt;1. 开发一个伪木马myser,位置：可以随便放，这里为了方便放在/下，实际使用时是放在非常隐蔽的目录下&lt;/p&gt; &lt;p&gt;#!/bin/bash&lt;/p&gt; &lt;p&gt;while true&lt;/p&gt; &lt;p&gt;do&lt;/p&gt; &lt;p&gt;touch /home/`date +%T`.txt    #在/home/下每隔一秒就创建一个文件，文件名为 创建时间.txt&lt;/p&gt; &lt;p&gt;sleep 1&lt;/p&gt; &lt;p&gt;done&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="81debb3e4abc766840cb5e33b156003b.png" src="https://img-blog.csdnimg.cn/img_convert/81debb3e4abc766840cb5e33b156003b.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;创建完后赋权限        chmod +x myser&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="09c2ce8eb27fc1ab91a1fb9f96ac5aad.png" src="https://img-blog.csdnimg.cn/img_convert/09c2ce8eb27fc1ab91a1fb9f96ac5aad.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;试运行      ./myser      ctrl+c停止  cd到/home/目录下查看&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="a402eeebbe8ba57ef4d94b9f1f7c6b1b.png" src="https://img-blog.csdnimg.cn/img_convert/a402eeebbe8ba57ef4d94b9f1f7c6b1b.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;2. 将这个木马设置为开机自动启动&lt;/p&gt; &lt;p&gt;在/etc/rc.local中写入&lt;/p&gt; &lt;p&gt;/bin/bash /myser &amp;amp;&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="987310767c33aef94ab532aeaacb1e5f.png" src="https://img-blog.csdnimg.cn/img_convert/987310767c33aef94ab532aeaacb1e5f.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;3. 开发一个检查木马进程是否正在运行的程序,check.sh ,位置：可以随便放，这里为了方便放在/下，实际使用时是放在非常隐蔽的目录下&lt;/p&gt; &lt;p&gt;#!/bin/bash&lt;/p&gt; &lt;p&gt;num=`ps aux | grep myser |wc -l`   #执行grep myser本身就会创建一个进程，如果有myser这个进程则num为2,如果没有myser这个进程,则num为1(),&lt;/p&gt; &lt;p&gt;if [ $num -eq 1 ];then     #num为1则表示木马进程已被杀死，需重新启动木马&lt;/p&gt; &lt;p&gt;/bin/bash /myser &amp;amp;   # &amp;amp;表示后台启动，不再屏幕上出现信息&lt;/p&gt; &lt;p&gt;fi&lt;/p&gt; &lt;p&gt;创建完后赋权限        chmod +x check.sh&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="d7a0960e9c364a0d4c07927320fdcb7d.png" src="https://img-blog.csdnimg.cn/img_convert/d7a0960e9c364a0d4c07927320fdcb7d.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;4.将check.sh写进或放进计划任务中&lt;/p&gt; &lt;p&gt;思路1:&lt;/p&gt; &lt;p&gt;写进计划任务中  但这样很容易用crontab -l 查看发现&lt;/p&gt; &lt;p&gt;crontab -e     #创建计划任务&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="b49174f5fb8d6d961533ebbc89f97c69.png" src="https://img-blog.csdnimg.cn/img_convert/b49174f5fb8d6d961533ebbc89f97c69.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;每分钟执行一次&lt;/p&gt; &lt;p&gt;*  *  *  *  *    # 分 时 日 月 周&lt;/p&gt; &lt;p&gt;crontab -l    #查看当前创建了哪些计划任务&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="64362536e293687b75d8b2cad97aa5a3.png" src="https://img-blog.csdnimg.cn/img_convert/64362536e293687b75d8b2cad97aa5a3.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;思路2:&lt;/p&gt; &lt;p&gt;将check.sh放在/etc/cron.d/cron.hourly&lt;/p&gt; &lt;p&gt;这个目录下的程序会每隔1h自动执行一次&lt;/p&gt; &lt;p&gt;思路3：&lt;/p&gt; &lt;p&gt;执行check.sh的计划任务写在/etc/crontab   #这个目录下的crontab中的任务计划不会出现在crontab -l中&lt;/p&gt; &lt;p&gt;*/5 * * * * /bin/bash /etc/check.sh&lt;/p&gt; &lt;p&gt;思路4:&lt;/p&gt; &lt;p&gt;在/etc/init.d下随便找个程序，将执行check的命令写进去&lt;/p&gt; &lt;p&gt;5.重启验证效果---------------reboot关机&lt;/p&gt; &lt;p&gt;开机后在/home/下发现一堆文件&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="8ea87b4b18887a2a77d74d505ef4357a.png" src="https://img-blog.csdnimg.cn/img_convert/8ea87b4b18887a2a77d74d505ef4357a.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;脚本正在运行&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="cb21bcbd2fa9772686a38c1c27af62c5.png" src="https://img-blog.csdnimg.cn/img_convert/cb21bcbd2fa9772686a38c1c27af62c5.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;杀死进程&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="02e51f118872aa171e3b0ce494310217.png" src="https://img-blog.csdnimg.cn/img_convert/02e51f118872aa171e3b0ce494310217.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;过一分钟后再次查看，发现进程已重启，注意看PID是不一样的，表示进程是重新启动过的&lt;/p&gt; &lt;p align="center"&gt;  &lt;img alt="8a596292252b07154edc71fbe3703afe.png" src="https://img-blog.csdnimg.cn/img_convert/8a596292252b07154edc71fbe3703afe.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;p&gt;自此完成&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62733-linux-%E6%A8%A1%E6%8B%9F-%E6%9C%A8%E9%A9%AC%E7%A8%8B%E5%BA%8F</guid>
      <pubDate>Thu, 13 Apr 2023 22:40:45 CST</pubDate>
    </item>
    <item>
      <title>Linux 系统安全检查</title>
      <link>https://itindex.net/detail/62728-linux-%E7%B3%BB%E7%BB%9F-%E5%AE%89%E5%85%A8%E6%A3%80%E6%9F%A5</link>
      <description>&lt;div&gt;    &lt;p&gt;对linux系统进行安全检查的方法      &lt;br /&gt;1、充分利用Linux和Unix系统中内置的检查命令来检测系统。例如，下面的几个命令在      &lt;br /&gt;Linux和Unix系统中就很有用处： &lt;/p&gt;    &lt;p&gt;-who，查看谁登陆到系统中； &lt;/p&gt;    &lt;p&gt;-w，查看谁登陆到系统中，且在做什么操作； &lt;/p&gt;    &lt;p&gt;-last，显示系统曾经被登陆的用户和TTYS； &lt;/p&gt;    &lt;p&gt;-history，显示系统过去被运行的命令； &lt;/p&gt;    &lt;p&gt;-netstat，可以查看现在的网络状态； &lt;/p&gt;    &lt;p&gt;-top，动态实时察看系统的进程； &lt;/p&gt;    &lt;p&gt;-finger，查看所有的登陆用户。 &lt;/p&gt;    &lt;p&gt;2、定期检查系统中的日志、文件、时间和进程信息。如： &lt;/p&gt;    &lt;p&gt;-检查/var/log/messages日志文件查看外部用户的登陆状况； &lt;/p&gt;    &lt;p&gt;-检查用户目录下/home/username下的登陆历史文件(如：.history 文件)； &lt;/p&gt;    &lt;p&gt;-检查用户目录下/home/username的.rhosts、.forward远程登陆文件； &lt;/p&gt;    &lt;p&gt;-用“find / -ctime -2 -ctime +1 -ls”命令来查看不到两天以内修改的一些文件； &lt;/p&gt;    &lt;p&gt;-用“ls -lac”命令去查看文件真正的修改时间； &lt;/p&gt;    &lt;p&gt;-用“cmp file1 file2”命令来比较文件大小的变化； &lt;/p&gt;    &lt;p&gt;3，CPU 查看方式      &lt;br /&gt;//查看系统cpu使用情况      &lt;br /&gt;top&lt;/p&gt;    &lt;p&gt;//查看所有cpu核信息      &lt;br /&gt;mpstat -P ALL 1&lt;/p&gt;    &lt;p&gt;//查看cpu使用情况以及平均负载      &lt;br /&gt;vmstat 1&lt;/p&gt;    &lt;p&gt;//进程cpu的统计信息      &lt;br /&gt;pidstat -u 1 -p pid&lt;/p&gt;    &lt;p&gt;//跟踪进程内部函数级cpu使用情况      &lt;br /&gt;perf top -p pid -e cpu-clock&lt;/p&gt;    &lt;p&gt;4，MEM 查看方式&lt;/p&gt;    &lt;p&gt;//查看系统内存使用情况      &lt;br /&gt;free -m&lt;/p&gt;    &lt;p&gt;//虚拟内存统计信息      &lt;br /&gt;vmstat 1&lt;/p&gt;    &lt;p&gt;//查看系统内存情况      &lt;br /&gt;top&lt;/p&gt;    &lt;p&gt;//1s采集周期，获取内存的统计信息      &lt;br /&gt;pidstat -p pid -r 1&lt;/p&gt;    &lt;p&gt;//查看进程的内存映像信息      &lt;br /&gt;pmap -d pid&lt;/p&gt;    &lt;p&gt;//检测程序内存问题      &lt;br /&gt;valgrind --tool=memcheck --leak-check=full --log-file=./log.txt  ./程序名&lt;/p&gt;    &lt;p&gt;5，磁盘方式      &lt;br /&gt;//查看系统io信息      &lt;br /&gt;iotop&lt;/p&gt;    &lt;p&gt;//统计io详细信息      &lt;br /&gt;iostat -d -x -k 1 10&lt;/p&gt;    &lt;p&gt;//查看进程级io的信息      &lt;br /&gt;pidstat -d 1 -p  pid&lt;/p&gt;    &lt;p&gt;//查看系统IO的请求，比如可以在发现系统IO异常时，可以使用该命令进行调查，就能指定到底是什么原因导致的IO异常      &lt;br /&gt;perf record -e block:block_rq_issue -ag      &lt;br /&gt;^C      &lt;br /&gt;perf report&lt;/p&gt;    &lt;p&gt;6，网络方式      &lt;br /&gt;//显示网络统计信息      &lt;br /&gt;netstat -s&lt;/p&gt;    &lt;p&gt;//显示当前UDP连接状况      &lt;br /&gt;netstat -nu&lt;/p&gt;    &lt;p&gt;//显示UDP端口号的使用情况      &lt;br /&gt;netstat -apu&lt;/p&gt;    &lt;p&gt;//统计机器中网络连接各个状态个数      &lt;br /&gt;netstat -a | awk \\&amp;apos;/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}\\&amp;apos;&lt;/p&gt;    &lt;p&gt;7，系统负载方式      &lt;br /&gt;//查看负载情况      &lt;br /&gt;uptime&lt;/p&gt;    &lt;p&gt;top&lt;/p&gt;    &lt;p&gt;vmstat&lt;/p&gt;    &lt;p&gt;//统计系统调用耗时情况      &lt;br /&gt;strace -c -p pid&lt;/p&gt;    &lt;p&gt;//跟踪指定的系统操作例如epoll_wait      &lt;br /&gt;strace -T -e epoll_wait -p pid&lt;/p&gt;    &lt;p&gt;//查看内核日志信息      &lt;br /&gt;dmesg&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;//显示TCP连接      &lt;br /&gt;ss -t -a&lt;/p&gt;    &lt;p&gt;//显示sockets摘要信息      &lt;br /&gt;ss -s&lt;/p&gt;    &lt;p&gt;//显示所有udp sockets      &lt;br /&gt;ss -u -a&lt;/p&gt;    &lt;p&gt;//tcp,etcp状态      &lt;br /&gt;sar -n TCP,ETCP 1&lt;/p&gt;    &lt;p&gt;//查看网络IO      &lt;br /&gt;sar -n DEV 1&lt;/p&gt;    &lt;p&gt;//抓包以包为单位进行输出      &lt;br /&gt;tcpdump -i eth1 host 192.168.1.1 and port 80 &lt;/p&gt;    &lt;p&gt;//抓包以流为单位显示数据内容      &lt;br /&gt;tcpflow -cp host 192.168.1.1&lt;/p&gt;    &lt;p&gt;8，分析系统      &lt;br /&gt;TOP      &lt;br /&gt;perf top -p pid&lt;/p&gt;    &lt;p&gt;检查脚本.sh&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;#!/bin/bash
echo &amp;quot;Version:1.3&amp;quot;
echo &amp;quot;Author:飞鸟&amp;quot;
echo &amp;quot;Mail:liuquyong112@gmail.com&amp;quot;

cat &amp;lt;&amp;lt;EOF
*********************************************
Linux主机安全检查:
	1.首先采集原始信息保存到/tmp/liuxcheck_${ipadd}_${date}/check_file/文件夹下
	2.将系统日志、应用日志打包并保存到/tmp/linuxcheck_${ipadd}_${date}/log/目录下
	3.在检查过程中若发现存在问题则直接输出到/tmp/linuxcheck_${ipadd}_${date}/danger_file.txt文件中
	4.有些未检查可能存在问题的需要人工分析原始文件
	5.脚本编写环境Centos7,在实际使用过程中若发现问题可以邮件联系:liuquyong112@gmail.com
	6.使用过程中若在windows下修改再同步到Linux下，请使用dos2unix工具进行格式转换,不然可能会报错
	7.在使用过程中必须使用root账号,不然可能导致某些项无法分析

如何使用:
	1.本脚本可以单独运行,单独运行中只需要将本脚本上传到相应的服务器中,然后sh linuxcheck.sh即可
	2.另外本脚本可以作为多台服务器全面检查的安全检查模板,本脚本不需要手工运行,只需要将相应服务器的IP、账号、密码写到hosts.txt文件中，然后sh login.sh即可

功能设计:
	1.V1.0主要功能用来采集信息
	2.V1.1主要功能将原始数据进行分析,并找出存在可疑或危险项
	3.V1.2增加基线检查的功能
	4.V1.3对收集过来的信息,如网络连接的IP、定时任务的URL、自启动文件、关键文件的MD5通过第三方的威胁情报接口进行查询并返回相应的结果
	5.V1.4可以进行相关危险项或可疑项的自动处理


检查内容
	0.IP及版本
		0.1 IP地址
		0.2 版本信息
			0.2.1 系统内核版本
			0.2.2 系统发行版本
		0.3 ARP
			0.3.1 ARP表
			0.3.2 ARP攻击
	1.端口情况
		1.1 开放端口
			1.1.1 TCP开放端口
			1.1.2 UDP开放端口
		1.2 TCP高危端口
		1.3 UDP高危端口
		1.4 端口转发
	2.网络连接
	3.网卡模式
	4.自启动项
		4.1 用户自定义启动项
		4.2 系统自启动项
	5.定时任务
		5.1 系统定时任务
			5.1.1 时间看系统定时任务
			5.1.2 分析可疑系统定时任务
		5.2 用户定时任务
			5.2.1 时间看用户定时任务
			5.2.2 分析可疑用户定时任务
	6.路由与路由转发
	7.进程分析
		7.1 系统进程
		7.2 守护进程
	8.关键文件检查
		8.1 DNS文件
		8.2 hosts文件
		8.3 公钥文件
		8.4 私钥文件
	9.运行服务
	10.登录情况
	11.用户与用户组
		11.1 超级用户
		11.2 克隆用户
		11.3 可登录用户
		11.4 非系统用户
		11.5 shadow文件
		11.6 空口令用户
		11.7 空口令且可登录
		11.8 口令未加密
		11.9 用户组分析
			11.9.1 用户组情况
			11.9.2 特权用户
			11.9.3 相同UID用户组
			11.9.4 相同用户组名
		11.10 文件权限
			11.10.1 etc文件权限
			11.10.2 shadow文件权限
			11.10.3 passwd文件权限
			11.10.4 group文件权限
			11.10.5 securetty文件权限
			11.10.6 services文件权限
			11.10.7 grub.conf文件权限
			11.10.8 xinetd.conf文件权限
			11.10.9 lilo.conf文件权限
			11.10.10 limits.conf文件权限
	12.历史命令
		12.1 系统历史命令
			12.1.1 系统操作历史命令
			12.1.2 是否下载过脚本文件
			12.1.3 是否增加过账号
			12.1.4 是否删除过账号
			12.1.5 历史可疑命令
			12.1.6 本地下载文件
		12.2 数据库历史命令
	13.策略与配置
		13.1 防火墙策略
		13.2 远程访问策略
			13.2.1 远程允许策略
			13.2.2 远程拒绝策略
		13.3 账号与密码策略
			13.3.1 密码有效期策略
			13.3.2 密码复杂度策略
			13.3.3 密码已过期用户
			13.3.4 账号超时锁定策略
			13.3.5 grub密码策略检查
			13.3.6 lilo密码策略检查
		13.4 selinux策略
		13.5 sshd配置
			13.5.1 sshd配置
			13.5.2 空口令登录
			13.5.3 root远程登录
			13.5.4 ssh协议版本
		13.6 NIS配置
		13.7 Nginx配置
			13.7.1 原始配置
			13.7.2 可疑配置
		13.8 SNMP配置检查
	14.可疑文件
		14.1 脚本文件
		14.2 恶意文件
		14.3 最近变动的文件
		14.4 文件属性
			14.4.1 passwd文件属性
			14.4.2 shadow文件属性
			14.4.3 gshadow文件属性
			14.4.4 group文件属性
	15.系统文件完整性
	16.系统日志分析
		16.1 日志配置与打包
			16.1.1 查看日志配置
			16.1.2日志是否存在
			16.1.3 日志审核是否开启
			16.1.4 自动打包日志
		16.2 secure日志分析
			16.2.1 成功登录
			16.2.2 登录失败
			16.2.3 图形登录情况
			16.2.4 新建用户与用户组
		16.3 message日志分析
			16.3.1 传输文件
			16.3.2 历史使用DNS
		16.4 cron日志分析
			16.4.1 定时下载
			16.4.2 定时执行脚本
		16.5 yum日志分析
			16.5.1 下载软件情况
			16.5.2 卸载软件情况
			16.5.3 可疑软件
		16.6 dmesg日志分析
			16.6.1 内核自检分析
		16.7 btmp日志分析
			16.7.1 错误登录分析
		16.8 lastlog日志分析
			16.8.1 所有用户最后一次登录分析
		16.9 wtmp 日志分析
			16.9.1 所有用户登录分析
	17.内核检查
		17.1 内核信息
		17.2 异常内核
	18.安装软件
		18.1 安装软件
		18.2 可疑软件
	19.环境变量
	20.性能分析
		20.1 磁盘使用
			20.1.1 磁盘使用情况
			20.1.2 磁盘使用过大
		20.2 CPU
			20.2.1 CPU情况
			20.2.2 占用CPU前五进程
			20.2.3 占用CPU较多资源进程
		20.3 内存
			20.3.1 内存情况
			20.3.2 占用内存前五进程
			20.3.3 占用内存占多进程
		20.4 网络连接
			20.4.1 并发连接
		20.5 其他
			20.5.1 运行时间及负载情况


*********************************************
EOF

dos2unix linuxcheck.sh
date=$(date +%Y%m%d)

ipadd=$(ifconfig -a | grep -w inet | grep -v 127.0.0.1 | awk &amp;apos;NR==1{print $2}&amp;apos;)

check_file=&amp;quot;/tmp/linuxcheck_${ipadd}_${date}/check_file/&amp;quot;
danger_file=&amp;quot;/tmp/linuxcheck_${ipadd}_${date}/danger_file.txt&amp;quot;
log_file=&amp;quot;/tmp/linuxcheck_${ipadd}_${date}/log/&amp;quot;
rm -rf $check_file
rm -rf $danger_file
rm -rf log_file
mkdir /tmp/linuxcheck_${ipadd}_${date}/
echo &amp;quot;检查发现危险项,请注意:&amp;quot; &amp;gt; ${danger_file}
mkdir $check_file
echo &amp;quot;&amp;quot; &amp;gt;&amp;gt; $danger_file
mkdir $log_file
cd $check_file

if [ $(whoami) != &amp;quot;root&amp;quot; ];then
	echo &amp;quot;安全检查必须使用root账号,否则某些项无法检查&amp;quot;
	exit 1
fi


saveresult=&amp;quot;tee -a checkresult.txt&amp;quot;
echo &amp;quot;[0.1]正在检查IP地址.....&amp;quot; &amp;amp;&amp;amp; &amp;quot;$saveresult&amp;quot;

echo -------------0.IP及版本-------------------
echo -------------0.1IP地址-------------------
echo &amp;quot;[0.1]正在检查IP地址.....&amp;quot; | $saveresult
ip=$(ifconfig -a | grep -w inet | awk &amp;apos;{print $2}&amp;apos;)
if [ -n &amp;quot;$ip&amp;quot; ];then
	(echo &amp;quot;[*]本机IP地址信息:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$ip&amp;quot;)  | $saveresult
else
	echo &amp;quot;[!!!]本机未配置IP地址&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------0.2版本信息------------------
echo &amp;quot;[0.2.1]正在检查系统内核版本.....&amp;quot; | $saveresult
corever=$(uname -a)
if [ -n &amp;quot;$corever&amp;quot; ];then
	(echo &amp;quot;[*]系统内核版本信息:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$corever&amp;quot;) | $saveresult
else
	echo &amp;quot;[!!!]未发现内核版本信息&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo &amp;quot;[0.2.2]正在检查系统发行版本.....&amp;quot; | $saveresult
systemver=$(cat /etc/redhat-release)
if [ -n &amp;quot;$systemver&amp;quot; ];then
	(echo &amp;quot;[*]系统发行版本:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$systemver&amp;quot;) | $saveresult
else
	echo &amp;quot;[!!!]未发现发行版本信息&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------0.3 ARP------------------
echo -------------0.3.1 ARP表项-------------
echo &amp;quot;[0.3.1]正在查看ARP表项.....&amp;quot; | $saveresult
arp=$(arp -a -n)
if [ -n &amp;quot;$arp&amp;quot; ];then
	(echo &amp;quot;[*]ARP表项如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$arp&amp;quot;) | $saveresult
else
	echo &amp;quot;[未发现arp表]&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------0.3.2 ARP攻击-------------
echo &amp;quot;[0.3.2]正在检测是否存在ARP攻击.....&amp;quot; | $saveresult
arpattack=$(arp -a -n | awk &amp;apos;{++S[$4]} END {for(a in S) {if($2&amp;gt;1) print $2,a,S[a]}}&amp;apos;)
if [ -n &amp;quot;$arpattack&amp;quot; ];then
	(echo &amp;quot;[!!!]发现存在ARP攻击:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$arpattack&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现ARP攻击&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------1.查看端口情况-----------------
echo -------------1.1 查看开放端口--------------
echo -------------1.1.1 查看TCP开放端口--------------
#TCP或UDP端口绑定在0.0.0.0、127.0.0.1、192.168.1.1这种IP上只表示这些端口开放
#只有绑定在0.0.0.0上局域网才可以访问
echo &amp;quot;[1.1.1]正在检查TCP开放端口.....&amp;quot; | $saveresult
listenport=$(netstat -anltp | grep LISTEN | awk  &amp;apos;{print $4,$7}&amp;apos; | sed &amp;apos;s/:/ /g&amp;apos; | awk &amp;apos;{print $2,$3}&amp;apos; | sed &amp;apos;s/\// /g&amp;apos; | awk &amp;apos;{printf &amp;quot;%-20s%-10s\n&amp;quot;,$1,$NF}&amp;apos; | sort -n | uniq)
if [ -n &amp;quot;$listenport&amp;quot; ];then
	(echo &amp;quot;[*]该服务器开放TCP端口以及对应的服务:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$listenport&amp;quot;) | $saveresult
else
	echo &amp;quot;[!!!]系统未开放TCP端口&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

accessport=$(netstat -anltp | grep LISTEN | awk  &amp;apos;{print $4,$7}&amp;apos; | egrep &amp;quot;(0.0.0.0|:::)&amp;quot; | sed &amp;apos;s/:/ /g&amp;apos; | awk &amp;apos;{print $(NF-1),$NF}&amp;apos; | sed &amp;apos;s/\// /g&amp;apos; | awk &amp;apos;{printf &amp;quot;%-20s%-10s\n&amp;quot;,$1,$NF}&amp;apos; | sort -n | uniq)
if [ -n &amp;quot;$accessport&amp;quot; ];then
	(echo &amp;quot;[!!!]以下TCP端口面向局域网或互联网开放,请注意！&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$accessport&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]端口未面向局域网或互联网开放&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------1.1.2 查看UDP开放端口--------------
echo &amp;quot;[1.1.2]正在检查UDP开放端口.....&amp;quot; | $saveresult
udpopen=$(netstat -anlup | awk  &amp;apos;{print $4,$NF}&amp;apos; | grep : | sed &amp;apos;s/:/ /g&amp;apos; | awk &amp;apos;{print $2,$3}&amp;apos; | sed &amp;apos;s/\// /g&amp;apos; | awk &amp;apos;{printf &amp;quot;%-20s%-10s\n&amp;quot;,$1,$NF}&amp;apos; | sort -n | uniq)
if [ -n &amp;quot;$udpopen&amp;quot; ];then
	(echo &amp;quot;[*]该服务器开放UDP端口以及对应的服务:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$udpopen&amp;quot;) | $saveresult
else
	echo &amp;quot;[!!!]系统未开放UDP端口&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

udpports=$(netstat -anlup | awk &amp;apos;{print $4}&amp;apos; | egrep &amp;quot;(0.0.0.0|:::)&amp;quot; | awk -F: &amp;apos;{print $NF}&amp;apos; | sort -n | uniq)
if [ -n &amp;quot;$udpports&amp;quot; ];then
	echo &amp;quot;[*]以下UDP端口面向局域网或互联网开放:&amp;quot; | $saveresult
	for port in $udpports
	do
		nc -uz 127.0.0.1 $port
		if [ $? -eq 0 ];then
			echo $port  | $saveresult
		fi
	done
else 
	echo &amp;quot;[*]未发现在UDP端口面向局域网或互联网开放.&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------1.2 TCP高危端口--------------
echo &amp;quot;[1.2]正在检查TCP高危端口.....&amp;quot; | $saveresult
tcpport=`netstat -anlpt | awk &amp;apos;{print $4}&amp;apos; | awk -F: &amp;apos;{print $NF}&amp;apos; | sort | uniq | grep &amp;apos;[0-9].*&amp;apos;`
count=0
if [ -n &amp;quot;$tcpport&amp;quot; ];then
	for port in $tcpport
	do
		for i in `cat /tmp/dangerstcpports.dat`
		do
			tcpport=`echo $i | awk -F &amp;quot;[:]&amp;quot; &amp;apos;{print $1}&amp;apos;`
			desc=`echo $i | awk -F &amp;quot;[:]&amp;quot; &amp;apos;{print $2}&amp;apos;`
			process=`echo $i | awk -F &amp;quot;[:]&amp;quot; &amp;apos;{print $3}&amp;apos;`
			if [ $tcpport == $port ];then
				echo &amp;quot;$tcpport,$desc,$process&amp;quot; | tee -a $danger_file | $saveresult
				count=count+1
			fi
		done
	done
fi
if [ $count = 0 ];then
	echo &amp;quot;[*]未发现TCP危险端口&amp;quot; | $saveresult
else
	echo &amp;quot;[!!!]请人工对TCP危险端口进行关联分析与确认&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------1.3 UDP高危端口--------------
echo &amp;quot;[1.3]正在检查UDP高危端口.....&amp;quot;
udpport=`netstat -anlpu | awk &amp;apos;{print $4}&amp;apos; | awk -F: &amp;apos;{print $NF}&amp;apos; | sort | uniq | grep &amp;apos;[0-9].*&amp;apos;`
count=0
if [ -n &amp;quot;$udpport&amp;quot; ];then
	for port in $udpport
	do
		for i in `cat /tmp/dangersudpports.dat`
		do
			udpport=`echo $i | awk -F &amp;quot;[:]&amp;quot; &amp;apos;{print $1}&amp;apos;`
			desc=`echo $i | awk -F &amp;quot;[:]&amp;quot; &amp;apos;{print $2}&amp;apos;`
			process=`echo $i | awk -F &amp;quot;[:]&amp;quot; &amp;apos;{print $3}&amp;apos;`
			if [ $udpport == $port ];then
				echo &amp;quot;$udpport,$desc,$process&amp;quot; | tee -a $danger_file | $saveresult
				count=count+1
			fi
		done
	done
fi
if [ $count = 0 ];then
	echo &amp;quot;[*]未发现UDP危险端口&amp;quot; | $saveresult
else
	echo &amp;quot;[!!!]请人工对UDP危险端口进行关联分析与确认&amp;quot;
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------2.网络连接---------------------
echo &amp;quot;[2.1]正在检查网络连接情况.....&amp;quot; | $saveresult
netstat=$(netstat -anlp | grep ESTABLISHED)
netstatnum=$(netstat -n | awk &amp;apos;/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}&amp;apos;)
if [ -n &amp;quot;$netstat&amp;quot; ];then
	(echo &amp;quot;[*]网络连接情况:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$netstat&amp;quot;) | $saveresult
	if [ -n &amp;quot;$netstatnum&amp;quot; ];then
		(echo &amp;quot;[*]各个状态的数量如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$netstatnum&amp;quot;) | $saveresult
	fi
else
	echo &amp;quot;[*]未发现网络连接&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------3.网卡模式---------------------
echo &amp;quot;[3.1]正在检查网卡模式.....&amp;quot; | $saveresult
ifconfigmode=$(ifconfig -a | grep flags | awk -F &amp;apos;[: = &amp;lt; &amp;gt;]&amp;apos; &amp;apos;{print &amp;quot;网卡:&amp;quot;,$1,&amp;quot;模式:&amp;quot;,$5}&amp;apos;)
if [ -n &amp;quot;$ifconfigmode&amp;quot; ];then
	(echo &amp;quot;网卡工作模式如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$ifconfigmode&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未找到网卡模式相关信息,请人工分析&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo &amp;quot;[3.2]正在分析是否有网卡处于混杂模式.....&amp;quot; | $saveresult
Promisc=`ifconfig | grep PROMISC | gawk -F: &amp;apos;{ print $1}&amp;apos;`
if [ -n &amp;quot;$Promisc&amp;quot; ];then
	(echo &amp;quot;[!!!]网卡处于混杂模式:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$Promisc&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现网卡处于混杂模式&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo &amp;quot;[3.3]正在分析是否有网卡处于监听模式.....&amp;quot; | $saveresult
Monitor=`ifconfig | grep -E &amp;quot;Mode:Monitor&amp;quot; | gawk -F: &amp;apos;{ print $1}&amp;apos;`
if [ -n &amp;quot;$Monitor&amp;quot; ];then
	(echo &amp;quot;[!!!]网卡处于监听模式:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$Monitor&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现网卡处于监听模式&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------4.启动项-----------------------
echo -------------4.1 用户自定义启动项-----------------------
echo &amp;quot;[4.1]正在检查用户自定义启动项.....&amp;quot; | $saveresult
chkconfig=$(chkconfig --list | grep -E &amp;quot;:on|启用&amp;quot; | awk &amp;apos;{print $1}&amp;apos;)
if [ -n &amp;quot;$chkconfig&amp;quot; ];then
	(echo &amp;quot;[*]用户自定义启动项:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$chkconfig&amp;quot;) | $saveresult
else
	echo &amp;quot;[!!!]未发现用户自定义启动项&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------4.2 系统自启动项-----------------------
echo &amp;quot;[4.2]正在检查系统自启动项.....&amp;quot; | $saveresult
systemchkconfig=$(systemctl list-unit-files | grep enabled | awk &amp;apos;{print $1}&amp;apos;)
if [ -n &amp;quot;$systemchkconfig&amp;quot; ];then
	(echo &amp;quot;[*]系统自启动项如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$systemchkconfig&amp;quot;)  | $saveresult
else
	echo &amp;quot;[*]未发现系统自启动项&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------4.3 危险启动项-----------------------
echo &amp;quot;[4.3]正在检查危险启动项.....&amp;quot; | $saveresult
dangerstarup=$(chkconfig --list | grep -E &amp;quot;:on|启用&amp;quot; | awk &amp;apos;{print $1}&amp;apos; | grep -E &amp;quot;\.(sh|per|py)$&amp;quot;)
if [ -n &amp;quot;$dangerstarup&amp;quot; ];then
	(echo &amp;quot;[!!!]发现危险启动项:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$dangerstarup&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现危险启动项&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------5.查看定时任务-------------------
echo ------------5.1系统定时任务分析-------------------
echo ------------5.1.1查看系统定时任务-------------------
echo &amp;quot;[5.1.1]正在分析系统定时任务.....&amp;quot; | $saveresult
syscrontab=$(more /etc/crontab | grep -v &amp;quot;# run-parts&amp;quot; | grep run-parts)
if [ -n &amp;quot;$syscrontab&amp;quot; ];then
	(echo &amp;quot;[!!!]发现存在系统定时任务:&amp;quot; &amp;amp;&amp;amp; more /etc/crontab ) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现系统定时任务&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

# if [ $? -eq 0 ]表示上面命令执行成功;执行成功输出的是0；失败非0
#ifconfig  echo $? 返回0，表示执行成功
# if [ $? != 0 ]表示上面命令执行失败

echo ------------5.1.2分析系统可疑定时任务-------------------
echo &amp;quot;[5.1.2]正在分析系统可疑任务.....&amp;quot; | $saveresult
dangersyscron=$(egrep &amp;quot;((chmod|useradd|groupadd|chattr)|((wget|curl)*\.(sh|pl|py)$))&amp;quot;  /etc/cron*/* /var/spool/cron/*)
if [ $? -eq 0 ];then
	(echo &amp;quot;[!!!]发现下面的定时任务可疑,请注意！！！&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$dangersyscron&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现可疑系统定时任务&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------5.2分析用户定时任务-------------------
echo ------------5.2.1查看用户定时任务-------------------
echo &amp;quot;[5.2.1]正在查看用户定时任务.....&amp;quot; | $saveresult
crontab=$(crontab -l)
if [ $? -eq 0 ];then
	(echo &amp;quot;[!!!]发现用户定时任务如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$crontab&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现用户定时任务&amp;quot;  | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------5.2.2查看可疑用户定时任务-------------------
echo &amp;quot;[5.2.2]正在分析可疑用户定时任务.....&amp;quot; | $saveresult
danger_crontab=$(crontab -l | egrep &amp;quot;((chmod|useradd|groupadd|chattr)|((wget|curl).*\.(sh|pl|py)))&amp;quot;)
if [ $? -eq 0 ];then
	(echo &amp;quot;[!!!]发现可疑定时任务,请注意！！！&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$danger_crontab&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现可疑定时任务&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo -------------6.路由与路由转发----------------
echo &amp;quot;[6.1]正在检查路由表.....&amp;quot; | $saveresult
route=$(route -n)
if [ -n &amp;quot;$route&amp;quot; ];then
	(echo &amp;quot;[*]路由表如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$route&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现路由器表&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo &amp;quot;[6.2]正在分析是否开启转发功能.....&amp;quot; | $saveresult
#数值分析
#1:开启路由转发
#0:未开启路由转发
ip_forward=`more /proc/sys/net/ipv4/ip_forward | gawk -F: &amp;apos;{if ($1==1) print &amp;quot;1&amp;quot;}&amp;apos;`
if [ -n &amp;quot;$ip_forward&amp;quot; ];then
	echo &amp;quot;[!!!]该服务器开启路由转发,请注意！&amp;quot; | tee -a $danger_file  | $saveresult
else
	echo &amp;quot;[*]该服务器未开启路由转发&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------7.进程分析--------------------
echo ------------7.1系统进程--------------------
echo &amp;quot;[7.1]正在检查进程.....&amp;quot; | $saveresult
ps=$(ps -aux)
if [ -n &amp;quot;$ps&amp;quot; ];then
	(echo &amp;quot;[*]系统进程如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$ps&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现系统进程&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo &amp;quot;[7.2]正在检查守护进程.....&amp;quot; | $saveresult
if [ -e /etc/xinetd.d/rsync ];then
	(echo &amp;quot;[*]系统守护进程:&amp;quot; &amp;amp;&amp;amp; more /etc/xinetd.d/rsync | grep -v &amp;quot;^#&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现守护进程&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------8.关键文件检查-----------------
echo ------------8.1DNS文件检查-----------------
echo &amp;quot;[8.1]正在检查DNS文件.....&amp;quot; | $saveresult
resolv=$(more /etc/resolv.conf | grep ^nameserver | awk &amp;apos;{print $NF}&amp;apos;) 
if [ -n &amp;quot;$resolv&amp;quot; ];then
	(echo &amp;quot;[*]该服务器使用以下DNS服务器:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$resolv&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现DNS服务器&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------8.2hosts文件检查-----------------
echo &amp;quot;[8.2]正在检查hosts文件.....&amp;quot; | $saveresult
hosts=$(more /etc/hosts)
if [ -n &amp;quot;$hosts&amp;quot; ];then
	(echo &amp;quot;[*]hosts文件如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$hosts&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现hosts文件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------8.3公钥文件检查-----------------
echo &amp;quot;[8.3]正在检查公钥文件.....&amp;quot; | $saveresult
if [  -e /root/.ssh/*.pub ];then
	echo &amp;quot;[!!!]发现公钥文件,请注意！&amp;quot;  | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现公钥文件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------8.4私钥文件检查-----------------
echo &amp;quot;[8.4]正在检查私钥文件.....&amp;quot; | $saveresult
if [ -e /root/.ssh/id_rsa ];then
	echo &amp;quot;[!!!]发现私钥文件,请注意！&amp;quot; | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现私钥文件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult


echo ------------9.运行服务----------------------
echo &amp;quot;[9.1]正在检查运行服务.....&amp;quot; | $saveresult
services=$(systemctl | grep -E &amp;quot;\.service.*running&amp;quot; | awk -F. &amp;apos;{print $1}&amp;apos;)
if [ -n &amp;quot;$services&amp;quot; ];then
	(echo &amp;quot;[*]以下服务正在运行：&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$services&amp;quot;) | $saveresult
else
	echo &amp;quot;[!!!]未发现正在运行的服务！&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------10.查看登录用户------------------
echo &amp;quot;[10.1]正在检查正在登录的用户.....&amp;quot; | $saveresult
(echo &amp;quot;[*]系统登录用户:&amp;quot; &amp;amp;&amp;amp; who ) | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.查看用户信息------------------
echo &amp;quot;[11]正在查看用户信息.....&amp;quot; | $saveresult
echo &amp;quot;[*]用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录Shell&amp;quot; | $saveresult
more /etc/passwd  | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.1超级用户---------------------
#UID=0的为超级用户,系统默认root的UID为0
echo &amp;quot;[11.1]正在检查是否存在超级用户.....&amp;quot; | $saveresult
Superuser=`more /etc/passwd | egrep -v &amp;apos;^root|^#|^(\+:\*)?:0:0:::&amp;apos; | awk -F: &amp;apos;{if($3==0) print $1}&amp;apos;`
if [ -n &amp;quot;$Superuser&amp;quot; ];then
	echo &amp;quot;[!!!]除root外发现超级用户:&amp;quot; | tee -a $danger_file | $saveresult
	for user in $Superuser
	do
		echo $user | $saveresult
		if [ &amp;quot;${user}&amp;quot; = &amp;quot;toor&amp;quot; ];then
			echo &amp;quot;[!!!]BSD系统默认安装toor用户,其他系统默认未安装toor用户,若非BSD系统建议删除该账号&amp;quot; | $saveresult
		fi
	done
else
	echo &amp;quot;[*]未发现超级用户&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.2克隆用户---------------------
#相同的UID为克隆用户
echo &amp;quot;[11.2]正在检查是否存在克隆用户.....&amp;quot; | $saveresult
uid=`awk -F: &amp;apos;{a[$3]++}END{for(i in a)if(a[i]&amp;gt;1)print i}&amp;apos; /etc/passwd`
if [ -n &amp;quot;$uid&amp;quot; ];then
	echo &amp;quot;[!!!]发现下面用户的UID相同:&amp;quot; | tee -a $danger_file | $saveresult
	(more /etc/passwd | grep $uid | awk -F: &amp;apos;{print $1}&amp;apos;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现相同UID的用户&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.3可登录用户-------------------
echo &amp;quot;[11.3]正在检查可登录的用户......&amp;quot; | $saveresult
loginuser=`cat /etc/passwd  | grep -E &amp;quot;/bin/bash$&amp;quot; | awk -F: &amp;apos;{print $1}&amp;apos;`
if [ -n &amp;quot;$loginuser&amp;quot; ];then
	echo &amp;quot;[!!!]以下用户可以登录：&amp;quot; | tee -a $danger_file | $saveresult
	for user in $loginuser
	do
		echo $user | tee -a $danger_file | $saveresult
	done
else
	echo &amp;quot;[*]未发现可以登录的用户&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.4非系统用户-----------------
echo &amp;quot;[11.4]正在检查非系统本身自带用户&amp;quot; | $saveresult
if [ -f /etc/login.defs ];then
	uid=$(grep &amp;quot;^UID_MIN&amp;quot; /etc/login.defs | awk &amp;apos;{print $2}&amp;apos;)
	(echo &amp;quot;系统最小UID为&amp;quot;$uid) | $saveresult
	nosystemuser=`gawk -F: &amp;apos;{if ($3&amp;gt;=&amp;apos;$uid&amp;apos; &amp;amp;&amp;amp; $3!=65534) {print $1}}&amp;apos; /etc/passwd`
	if [ -n &amp;quot;$nosystemuser&amp;quot; ];then
		(echo &amp;quot;以下用户为非系统本身自带用户:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$nosystemuser&amp;quot;) | tee -a $danger_file | $saveresult
	else
		echo &amp;quot;[*]未发现除系统本身外的其他用户&amp;quot; | $saveresult
	fi
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.5shadow文件-----------------
echo &amp;quot;[11.5]正在检查shadow文件.....&amp;quot; | $saveresult
(echo &amp;quot;[*]shadow文件&amp;quot; &amp;amp;&amp;amp; more /etc/shadow ) | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.6空口令用户-----------------
echo &amp;quot;[11.6]正在检查空口令用户.....&amp;quot; | $saveresult
nopasswd=`gawk -F: &amp;apos;($2==&amp;quot;&amp;quot;) {print $1}&amp;apos; /etc/shadow`
if [ -n &amp;quot;$nopasswd&amp;quot; ];then
	(echo &amp;quot;[!!!]以下用户口令为空：&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$nopasswd&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现空口令用户&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.7空口令且可登录-----------------
echo &amp;quot;[11.7]正在检查空口令且可登录的用户.....&amp;quot; | $saveresult
#允许空口令用户登录方法
#1.passwd -d username
#2.echo &amp;quot;PermitEmptyPasswords yes&amp;quot; &amp;gt;&amp;gt;/etc/ssh/sshd_config
#3.service sshd restart
aa=$(cat /etc/passwd  | grep -E &amp;quot;/bin/bash$&amp;quot; | awk -F: &amp;apos;{print $1}&amp;apos;)
bb=$(gawk -F: &amp;apos;($2==&amp;quot;&amp;quot;) {print $1}&amp;apos; /etc/shadow)
cc=$(cat /etc/ssh/sshd_config | grep -w &amp;quot;^PermitEmptyPasswords yes&amp;quot;)
flag=&amp;quot;&amp;quot;
for a in $aa
do
    for b in $bb
    do
        if [ &amp;quot;$a&amp;quot; = &amp;quot;$b&amp;quot; ] &amp;amp;&amp;amp; [ -n &amp;quot;$cc&amp;quot; ];then
            echo &amp;quot;[!!!]发现空口令且可登录用户:&amp;quot;$a | $saveresult
            flag=1
        fi
    done
done
if [ -n &amp;quot;$flag&amp;quot; ];then
	echo &amp;quot;请人工分析配置和账号&amp;quot; | $saveresult
else
	echo &amp;quot;[*]未发现空口令且可登录用户&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.8口令未加密----------------
echo &amp;quot;[11.8]正在检查口令加密用户.....&amp;quot; | $saveresult
noenypasswd=$(awk -F: &amp;apos;{if($2!=&amp;quot;x&amp;quot;) {print $1}}&amp;apos; /etc/passwd)
if [ -n &amp;quot;$noenypasswd&amp;quot; ];then
	(echo &amp;quot;[!!!]以下用户口令未加密:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$noenypasswd&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现口令未加密的用户&amp;quot;  | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.9用户组分析-----------------------
echo ------------11.9.1 用户组信息------------ ----
echo &amp;quot;[11.9.1]正在检查用户组信息.....&amp;quot; | $saveresult
echo &amp;quot;[*]用户组信息如下:&amp;quot;
(more /etc/group | grep -v &amp;quot;^#&amp;quot;) | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.9.2 特权用户--------------------
echo &amp;quot;[11.9.2]正在检查特权用户.....&amp;quot; | $saveresult
roots=$(more /etc/group | grep -v &amp;apos;^#&amp;apos; | gawk -F: &amp;apos;{if ($1!=&amp;quot;root&amp;quot;&amp;amp;&amp;amp;$3==0) print $1}&amp;apos;)
if [ -n &amp;quot;$roots&amp;quot; ];then
	echo &amp;quot;[!!!]除root用户外root组还有以下用户:&amp;quot; | tee -a $danger_file | $saveresult
	for user in $roots
	do
		echo $user | tee -a $danger_file | $saveresult
	done
else 
	echo &amp;quot;[*]除root用户外root组未发现其他用户&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.9.3 相同GID用户组--------------------
echo &amp;quot;[11.9.3]正在检查相应GID用户组.....&amp;quot; | $saveresult
groupuid=$(more /etc/group | grep -v &amp;quot;^$&amp;quot; | awk -F: &amp;apos;{print $3}&amp;apos; | uniq -d)
if [ -n &amp;quot;$groupuid&amp;quot; ];then
	(echo &amp;quot;[!!!]发现相同GID用户组:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$groupuid&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现相同GID的用户组&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.9.4 相同用户组名--------------------
echo &amp;quot;[11.9.4]正在检查相同用户组名.....&amp;quot; | $saveresult
groupname=$(more /etc/group | grep -v &amp;quot;^$&amp;quot; | awk -F: &amp;apos;{print $1}&amp;apos; | uniq -d)
if [ -n &amp;quot;$groupname&amp;quot; ];then
	(echo &amp;quot;[!!!]发现相同用户组名:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$groupname&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现相同用户组名&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.10 文件权限--------------------
echo ------------11.10.1 etc文件权限--------------------
echo &amp;quot;[11.10.1]正在检查etc文件权限.....&amp;quot; | $saveresult
etc=$(ls -l / | grep etc | awk &amp;apos;{print $1}&amp;apos;)
if [ &amp;quot;${etc:1:9}&amp;quot; = &amp;quot;rwxr-x---&amp;quot; ]; then
    echo &amp;quot;[*]/etc/权限为750,权限正常&amp;quot; | $saveresult
else
    echo &amp;quot;[!!!]/etc/文件权限为:&amp;quot;&amp;quot;${etc:1:9}&amp;quot;,&amp;quot;权限不符合规划,权限应改为750&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.10.2 shadow文件权限--------------------
echo &amp;quot;[11.10.2]正在检查shadow文件权限.....&amp;quot; | $saveresult
shadow=$(ls -l /etc/shadow | awk &amp;apos;{print $1}&amp;apos;)
if [ &amp;quot;${shadow:1:9}&amp;quot; = &amp;quot;rw-------&amp;quot; ]; then
    echo &amp;quot;[*]/etc/shadow文件权限为600,权限符合规范&amp;quot; | $saveresult
else
    echo &amp;quot;[!!!]/etc/shadow文件权限为:&amp;quot;&amp;quot;${shadow:1:9}&amp;quot;&amp;quot;,不符合规范,权限应改为600&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.10.3 passwd文件权限--------------------
echo &amp;quot;[11.10.3]正在检查passwd文件权限.....&amp;quot; | $saveresult
passwd=$(ls -l /etc/passwd | awk &amp;apos;{print $1}&amp;apos;)
if [ &amp;quot;${passwd:1:9}&amp;quot; = &amp;quot;rw-r--r--&amp;quot; ]; then
    echo &amp;quot;[*]/etc/passwd文件权限为644,符合规范&amp;quot; | $saveresult
else
    echo &amp;quot;[!!!]/etc/passwd文件权限为:&amp;quot;&amp;quot;${passwd:1:9}&amp;quot;&amp;quot;,权限不符合规范,建议改为644&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.10.4 group文件权限--------------------
echo &amp;quot;[11.10.4]正在检查group文件权限.....&amp;quot; | $saveresult
group=$(ls -l /etc/group | awk &amp;apos;{print $1}&amp;apos;)
if [ &amp;quot;${group:1:9}&amp;quot; = &amp;quot;rw-r--r--&amp;quot; ]; then
    echo &amp;quot;[*]/etc/group文件权限为644,符合规范&amp;quot; | $saveresult
else
    echo &amp;quot;[!!!]/etc/goup文件权限为&amp;quot;&amp;quot;${group:1:9}&amp;quot;,&amp;quot;不符合规范,权限应改为644&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.10.5 securetty文件权限--------------------
echo &amp;quot;[11.10.5]正在检查securetty文件权限.....&amp;quot; | $saveresult
securetty=$(ls -l /etc/securetty | awk &amp;apos;{print $1}&amp;apos;)
if [ &amp;quot;${securetty:1:9}&amp;quot; = &amp;quot;-rw-------&amp;quot; ]; then
    echo &amp;quot;[*]/etc/securetty文件权限为600,符合规范&amp;quot; | $saveresult
else
    echo &amp;quot;[!!!]/etc/securetty文件权限为&amp;quot;&amp;quot;${securetty:1:9}&amp;quot;,&amp;quot;不符合规范,权限应改为600&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.10.6 services文件权限--------------------
echo &amp;quot;[11.10.6]正在检查services文件权限.....&amp;quot; | $saveresult
services=$(ls -l /etc/services | awk &amp;apos;{print $1}&amp;apos;)
if [ &amp;quot;${services:1:9}&amp;quot; = &amp;quot;-rw-r--r--&amp;quot; ]; then
    echo &amp;quot;[*]/etc/services文件权限为644,符合规范&amp;quot; | $saveresult
else
    echo &amp;quot;[!!!]/etc/services文件权限为&amp;quot;&amp;quot;$services:1:9}&amp;quot;,&amp;quot;不符合规范,权限应改为644&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.10.7 grub.conf文件权限--------------------
echo &amp;quot;[11.10.7]正在检查grub.conf文件权限.....&amp;quot; | $saveresult
grubconf=$(ls -l /etc/grub.conf | awk &amp;apos;{print $1}&amp;apos;)
if [ &amp;quot;${grubconf:1:9}&amp;quot; = &amp;quot;-rw-------&amp;quot; ]; then
    echo &amp;quot;[*]/etc/grub.conf文件权限为600,符合规范&amp;quot; | $saveresult
else
    echo &amp;quot;[!!!]/etc/grub.conf文件权限为&amp;quot;&amp;quot;${grubconf:1:9}&amp;quot;,&amp;quot;不符合规范,权限应改为600&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.10.8 xinetd.conf文件权限--------------------
echo &amp;quot;[11.10.8]正在检查xinetd.conf文件权限.....&amp;quot; | $saveresult
xinetdconf=$(ls -l /etc/xinetd.conf | awk &amp;apos;{print $1}&amp;apos;)
if [ &amp;quot;${xinetdconf:1:9}&amp;quot; = &amp;quot;-rw-------&amp;quot; ]; then
    echo &amp;quot;[*]/etc/xinetd.conf文件权限为600,符合规范&amp;quot; | $saveresult
else
    echo &amp;quot;[!!!]/etc/xinetd.conf文件权限为&amp;quot;&amp;quot;${xinetdconf:1:9}&amp;quot;,&amp;quot;不符合规范,权限应改为600&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.10.9 lilo.conf文件权限--------------------
echo &amp;quot;[11.10.9]正在检查lilo.conf文件权限.....&amp;quot; | $saveresult
if [ -f /etc/lilo.conf ];then
liloconf=$(ls -l /etc/lilo.conf | awk &amp;apos;{print $1}&amp;apos;)
	if [ &amp;quot;${liloconf:1:9}&amp;quot; = &amp;quot;-rw-------&amp;quot; ];then
		echo &amp;quot;/etc/lilo.conf文件权限为600,符合要求&amp;quot; | $saveresult
	else
		echo &amp;quot;/etc/lilo.conf文件权限不为600,不符合要求,建议设置权限为600&amp;quot; | $saveresult
	fi
else
	echo &amp;quot;/etc/lilo.conf文件夹不存在,不检查,符合要求&amp;quot;
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------11.10.10 limits.conf文件权限--------------------
echo &amp;quot;[11.10.10]正在检查limits.conf文件权限.....&amp;quot; | $saveresult
cat /etc/security/limits.conf | grep -v ^# | grep core
if [ $? -eq 0 ];then
	soft=`cat /etc/security/limits.conf | grep -v ^# | grep core | awk -F &amp;apos; &amp;apos; &amp;apos;{print $2}&amp;apos;`
	for i in $soft
	do
		if [ $i = &amp;quot;soft&amp;quot; ];then
			echo &amp;quot;* soft core 0 已经设置,符合要求&amp;quot; | $saveresult
		fi
		if [ $i = &amp;quot;hard&amp;quot; ];then
			echo &amp;quot;* hard core 0 已经设置,符合要求&amp;quot; | $saveresult
		fi
	done
else 
	echo &amp;quot;没有设置core,建议在/etc/security/limits.conf中添加* soft core 0和* hard core 0&amp;quot;  | $saveresult
fi

echo ------------11.11其他--------------------
###############################################
#Access:访问时间,每次访问文件时都会更新这个时间,如使用more、cat
#Modify:修改时间,文件内容改变会导致该时间更新
#Change:改变时间,文件属性变化会导致该时间更新,当文件修改时也会导致该时间更新;但是改变文件的属性,如读写权限时只会导致该时间更新，不会导致修改时间更新
###############################################
echo &amp;quot;[11.11]正在检查useradd时间属性.....&amp;quot; | $saveresult
echo &amp;quot;[*]useradd时间属性:&amp;quot; | $saveresult
stat /usr/sbin/useradd | egrep &amp;quot;Access|Modify|Change&amp;quot; | grep -v &amp;apos;(&amp;apos; | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo &amp;quot;[11.11]正在检查userdel时间属性.....&amp;quot; | $saveresult
echo &amp;quot;[*]userdel时间属性:&amp;quot; | $saveresult
stat /usr/sbin/userdel | egrep &amp;quot;Access|Modify|Change&amp;quot; | grep -v &amp;apos;(&amp;apos; | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------12历史命令--------------------------
echo ------------12.1系统操作历史命令---------------
echo ------------12.1.1系统操作历史命令---------------
echo &amp;quot;[12.1.1]正在检查操作系统历史命令.....&amp;quot; | $saveresult
history=$(more /root/.bash_history)
if [ -n &amp;quot;$history&amp;quot; ];then
	(echo &amp;quot;[*]操作系统历史命令如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$history&amp;quot;) | $saveresult
else
	echo &amp;quot;[!!!]未发现历史命令,请检查是否记录及已被清除&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------12.1.2是否下载过脚本文件---------------
echo &amp;quot;[12.1.2]正在检查是否下载过脚本文件.....&amp;quot; | $saveresult
scripts=$(more /root/.bash_history | grep -E &amp;quot;((wget|curl).*\.(sh|pl|py)$)&amp;quot; | grep -v grep)
if [ -n &amp;quot;$scripts&amp;quot; ];then
	(echo &amp;quot;[!!!]该服务器下载过脚本以下脚本：&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$scripts&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]该服务器未下载过脚本文件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------12.1.3是否增加过账号---------------
echo &amp;quot;[12.1.3]正在检查是否增加过账号.....&amp;quot; | $saveresult
addusers=$(history | egrep &amp;quot;(useradd|groupadd)&amp;quot; | grep -v grep)
if [ -n &amp;quot;$addusers&amp;quot; ];then
	(echo &amp;quot;[!!!]该服务器增加过以下账号:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$addusers&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]该服务器未增加过账号&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------12.1.4是否删除过账号--------------
echo &amp;quot;[12.1.4]正在检查是否删除过账号.....&amp;quot; | $saveresult
delusers=$(history | egrep &amp;quot;(userdel|groupdel)&amp;quot; | grep -v grep)
if [ -n &amp;quot;$delusers&amp;quot; ];then
	(echo &amp;quot;[!!!]该服务器删除过以下账号:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$delusers&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]该服务器未删除过账号&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------12.1.5可疑历史命令--------------
echo &amp;quot;[12.1.5]正在检查历史可疑命令.....&amp;quot; | $saveresult
danger_histroy=$(history | grep -E &amp;quot;(whois|sqlmap|nmap|beef|nikto|john|ettercap|backdoor|proxy|msfconsole|msf)&amp;quot; | grep -v grep)
if [ -n &amp;quot;$danger_histroy&amp;quot; ];then
	(echo &amp;quot;[!!!]发现可疑历史命令&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$danger_histroy&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现可疑历史命令&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------12.1.6本地下载文件--------------
echo &amp;quot;[12.1.6]正在检查历史日志中本地下载文件记录.....&amp;quot; | $saveresult
uploadfiles=$(history | grep sz | grep -v grep | awk &amp;apos;{print $3}&amp;apos;)
if [ -n &amp;quot;$uploadfiles&amp;quot; ];then
	(echo &amp;quot;[!!!]通过历史日志发现本地主机下载过以下文件:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$uploadfiles&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]通过历史日志未发现本地主机下载过文件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult


echo ------------12.2数据库操作历史命令---------------
echo &amp;quot;[12.2]正在检查数据库操作历史命令.....&amp;quot; | $saveresult
mysql_history=$(more /root/.mysql_history)
if [ -n &amp;quot;$mysql_history&amp;quot; ];then
	(echo &amp;quot;[*]数据库操作历史命令如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$mysql_history&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现数据库历史命令&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.策略情况---------------------
echo ------------13.1防火墙策略-------------------
echo &amp;quot;[13.1]正在检查防火墙策略.....&amp;quot; | $saveresult
firewalledstatus=$(systemctl status firewalld | grep &amp;quot;active (running)&amp;quot;)
firewalledpolicy=$(iptables -L | grep &amp;quot;\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}&amp;quot;)
if [ -n &amp;quot;$firewalledstatus&amp;quot; ];then
	echo &amp;quot;[*]该服务器防火墙已打开&amp;quot;
	if [ -n &amp;quot;$firewalledpolicy&amp;quot; ];then
		(echo &amp;quot;[*]防火墙策略如下&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$firewalledpolicy&amp;quot;) | $saveresult
	else
		echo &amp;quot;[!!!]防火墙策略未配置,建议配置防火墙策略!&amp;quot; | tee -a $danger_file | $saveresult
	fi
else
	echo &amp;quot;[！！！]防火墙未开启,建议开启防火墙&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.2远程访问策略-----------------
echo ------------13.2.1远程允许策略-----------------
echo &amp;quot;[13.2.1]正在检查远程允许策略.....&amp;quot; | $saveresult
hostsallow=$(more /etc/hosts.allow | grep -v &amp;apos;#&amp;apos;)
if [ -n &amp;quot;$hostsallow&amp;quot; ];then
	(echo &amp;quot;[!!!]允许以下IP远程访问:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$hostsallow&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]hosts.allow文件未发现允许远程访问地址&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.2.2远程拒绝策略-----------------
echo &amp;quot;[13.2.2]正在检查远程拒绝策略.....&amp;quot; | $saveresult
hostsdeny=$(more /etc/hosts.deny | grep -v &amp;apos;#&amp;apos;)
if [ -n &amp;quot;$hostsdeny&amp;quot; ];then
	(echo &amp;quot;[!!!]拒绝以下IP远程访问:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$hostsdeny&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]hosts.deny文件未发现拒绝远程访问地址&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.3密码策略------------------------
echo ------------13.3.1密码有效期策略------------------------
echo &amp;quot;[13.3.1]正在检查密码有效期策略.....&amp;quot; | $saveresult
(echo &amp;quot;[*]密码有效期策略如下:&amp;quot; &amp;amp;&amp;amp; more /etc/login.defs | grep -v &amp;quot;#&amp;quot; | grep PASS ) | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo &amp;quot;[*]正在进行具体项的基线检查......&amp;quot; | $saveresult
passmax=$(cat /etc/login.defs | grep PASS_MAX_DAYS | grep -v ^# | awk &amp;apos;{print $2}&amp;apos;)
if [ $passmax -le 90 -a $passmax -gt 0 ];then
	echo &amp;quot;[*]口令生存周期为${passmax}天,符合要求&amp;quot; | $saveresult
else
	echo &amp;quot;[!!!]口令生存周期为${passmax}天,不符合要求,建议设置为0-90天&amp;quot; | $saveresult
fi

passmin=$(cat /etc/login.defs | grep PASS_MIN_DAYS | grep -v ^# | awk &amp;apos;{print $2}&amp;apos;)
if [ $passmin -ge 6 ];then
	echo &amp;quot;[*]口令更改最小时间间隔为${passmin}天,符合要求&amp;quot; | $saveresult
else
	echo &amp;quot;[!!!]口令更改最小时间间隔为${passmin}天,不符合要求,建议设置不小于6天&amp;quot; | $saveresult
fi

passlen=$(cat /etc/login.defs | grep PASS_MIN_LEN | grep -v ^# | awk &amp;apos;{print $2}&amp;apos;)
if [ $passlen -ge 8 ];then
	echo &amp;quot;[*]口令最小长度为${passlen},符合要求&amp;quot; | $saveresult
else
	echo &amp;quot;[!!!]口令最小长度为${passlen},不符合要求,建议设置最小长度大于等于8&amp;quot; | $saveresult
fi

passage=$(cat /etc/login.defs | grep PASS_WARN_AGE | grep -v ^# | awk &amp;apos;{print $2}&amp;apos;)
if [ $passage -ge 30 -a $passage -lt $passmax ];then
	echo &amp;quot;[*]口令过期警告时间天数为${passage},符合要求&amp;quot; | $saveresult
else
	echo &amp;quot;[!!!]口令过期警告时间天数为${passage},不符合要求,建议设置大于等于30并小于口令生存周期&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.3.2密码复杂度策略------------------------
echo &amp;quot;[13.3.1]正在检查密码复杂度策略.....&amp;quot; | $saveresult
(echo &amp;quot;[*]密码复杂度策略如下:&amp;quot; &amp;amp;&amp;amp; more /etc/pam.d/system-auth | grep -v &amp;quot;#&amp;quot;) | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.3.3 密码已过期用户---------------------------
echo &amp;quot;[13.3.3]正在检查密码已过期用户.....&amp;quot; | $saveresult
NOW=$(date &amp;quot;+%s&amp;quot;)
day=$((${NOW}/86400))
passwdexpired=$(grep -v &amp;quot;:[\!\*x]([\*\!])?:&amp;quot; /etc/shadow | awk -v today=${day} -F: &amp;apos;{ if (($5!=&amp;quot;&amp;quot;) &amp;amp;&amp;amp; (today&amp;gt;$3+$5)) { print $1 }}&amp;apos;)
if [ -n &amp;quot;$passwdexpired&amp;quot; ];then
	(echo &amp;quot;[*]以下用户的密码已过期:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$passwdexpired&amp;quot;)  | $saveresult
else
	echo &amp;quot;[*]未发现密码已过期用户&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.3.4 账号超时锁定策略---------------------------
echo &amp;quot;[13.3.4]正在检查账号超时锁定策略.....&amp;quot; | $saveresult
account_timeout=`cat /etc/profile | grep TMOUT | awk -F[=] &amp;apos;{print $2}&amp;apos;` 
if [ &amp;quot;$account_timeout&amp;quot; != &amp;quot;&amp;quot;  ];then
	TMOUT=`cat /etc/profile | grep TMOUT | awk -F[=] &amp;apos;{print $2}&amp;apos;`
	if [ $TMOUT -le 600 -a $TMOUT -ge 10 ];then
		echo &amp;quot;[*]账号超时时间为${TMOUT}秒,符合要求&amp;quot; | $saveresult
	else
		echo &amp;quot;[!!!]账号超时时间为${TMOUT}秒,不符合要求,建议设置小于600秒&amp;quot; | $saveresult
fi
else
	echo &amp;quot;[!!!]账号超时未锁定,不符合要求,建议设置小于600秒&amp;quot; | $saveresult 
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.3.5 grub密码策略检查---------------------------
echo &amp;quot;[13.3.5]正在检查grub密码策略.....&amp;quot; | $saveresult
grubpass=$(cat /etc/grub.conf | grep password)
if [ $? -eq 0 ];then
	echo &amp;quot;[*]已设置grub密码,符合要求&amp;quot; | $saveresult 
else
	echo &amp;quot;[!!!]未设置grub密码,不符合要求,建议设置grub密码&amp;quot; | $saveresult 
fi
printf &amp;quot;\n&amp;quot; | $saveresult


echo ------------13.3.6 lilo密码策略检查---------------------------
echo &amp;quot;[13.3.6]正在检查lilo密码策略.....&amp;quot; | $saveresult
if [ -f  /etc/lilo.conf ];then
	lilopass=$(cat /etc/lilo.conf | grep password 2&amp;gt; /dev/null)
	if [ $? -eq 0 ];then
		echo &amp;quot;[*]已设置lilo密码,符合要求&amp;quot; | $saveresult
	else
		echo &amp;quot;[!!!]未设置lilo密码,不符合要求,建议设置lilo密码&amp;quot; | $saveresult
	fi
else
	echo &amp;quot;[*]未发现/etc/lilo.conf文件&amp;quot; | $saveresult
fi


echo ------------13.4selinux策略----------------------
echo &amp;quot;[13.4]正在检查selinux策略.....&amp;quot; | $saveresult
(echo &amp;quot;selinux策略如下:&amp;quot; &amp;amp;&amp;amp; egrep -v &amp;apos;#|^$&amp;apos; /etc/sysconfig/selinux ) | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.5sshd配置文件--------------------
echo ------------13.5.1sshd配置----------------------
echo &amp;quot;[13.5.1]正在检查sshd配置.....&amp;quot; | $saveresult
sshdconfig=$(more /etc/ssh/sshd_config | egrep -v &amp;quot;#|^$&amp;quot;)
if [ -n &amp;quot;$sshdconfig&amp;quot; ];then
	(echo &amp;quot;[*]sshd配置文件如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$sshdconfig&amp;quot;) | $saveresult
else
	echo &amp;quot;[！]未发现sshd配置文件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.5.2空口令登录检查--------------------
echo &amp;quot;[13.5.2]正在检查是否允许空口令登录.....&amp;quot; | $saveresult
emptypasswd=$(cat /etc/ssh/sshd_config | grep -w &amp;quot;^PermitEmptyPasswords yes&amp;quot;)
nopasswd=`gawk -F: &amp;apos;($2==&amp;quot;&amp;quot;) {print $1}&amp;apos; /etc/shadow`
if [ -n &amp;quot;$emptypasswd&amp;quot; ];then
	echo &amp;quot;[!!!]允许空口令登录,请注意！！！&amp;quot;
	if [ -n &amp;quot;$nopasswd&amp;quot; ];then
		(echo &amp;quot;[!!!]以下用户空口令:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$nopasswd&amp;quot;) | tee -a $danger_file | $saveresult
	else
		echo &amp;quot;[*]但未发现空口令用户&amp;quot; | $saveresult
	fi
else
	echo &amp;quot;[*]不允许空口令用户登录&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.5.3 root远程登录--------------------
echo &amp;quot;[13.5.3]正在检查是否允许root远程登录.....&amp;quot; | $saveresult
cat /etc/ssh/sshd_config | grep -v ^# |grep &amp;quot;PermitRootLogin no&amp;quot;
if [ $? -eq 0 ];then
	echo &amp;quot;[*]root不允许登陆,符合要求&amp;quot; | $saveresult
else
	echo &amp;quot;[!!!]允许root远程登陆,不符合要求,建议/etc/ssh/sshd_config添加PermitRootLogin no&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.5.4 ssh协议版本--------------------
echo &amp;quot;[13.5.4]正在检查ssh协议版本.....&amp;quot; | $saveresult
protocolver=$(more /etc/ssh/sshd_config | grep -v ^$ | grep Protocol | awk &amp;apos;{print $2}&amp;apos;)
if [ &amp;quot;$protocolver&amp;quot; -eq &amp;quot;2&amp;quot; ];then
	echo &amp;quot;[*]openssh使用ssh2协议,符合要求&amp;quot; 
else
	echo &amp;quot;[!!!]openssh未ssh2协议,不符合要求&amp;quot;
fi

echo ------------13.6 NIS 配置文件--------------------
echo &amp;quot;[13.6]正在检查nis配置.....&amp;quot; | $saveresult
nisconfig=$(more /etc/nsswitch.conf | egrep -v &amp;apos;#|^$&amp;apos;)
if [ -n &amp;quot;$nisconfig&amp;quot; ];then
	(echo &amp;quot;[*]NIS服务配置如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$nisconfig&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现NIS服务配置&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.7 Nginx配置----------------------
echo ------------13.7.1 Nginx配置---------------------
echo &amp;quot;[13.7.1]正在检查Nginx配置文件......&amp;quot; | $saveresult
nginx=$(whereis nginx | awk -F: &amp;apos;{print $2}&amp;apos;)
if [ -n &amp;quot;$nginx&amp;quot; ];then
	(echo &amp;quot;[*]Nginx配置文件如下:&amp;quot; &amp;amp;&amp;amp; more $nginx/conf/nginx.conf) | $saveresult
else
	echo &amp;quot;[*]未发现Nginx服务&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.7.2 Nginx端口转发分析-------------
echo &amp;quot;[13.7.2]正在检查Nginx端口转发配置......&amp;quot; | $saveresult
nginx=$(whereis nginx | awk -F: &amp;apos;{print $2}&amp;apos;)
nginxportconf=$(more $nginx/conf/nginx.conf | egrep &amp;quot;listen|server |server_name |upstream|proxy_pass|location&amp;quot;| grep -v \#)
if [ -n &amp;quot;$nginxportconf&amp;quot; ];then
	(echo &amp;quot;[*]可能存在端口转发的情况,请人工分析:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$nginxportconf&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现端口转发配置&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------13.8 SNMP配置检查-------------
echo &amp;quot;[13.8]正在检查SNMP配置......&amp;quot; | $saveresult
if [ -f /etc/snmp/snmpd.conf ];then
	public=$(cat /etc/snmp/snmpd.conf | grep public | grep -v ^# | awk &amp;apos;{print $4}&amp;apos;)
	private=$(cat /etc/snmp/snmpd.conf | grep private | grep -v ^# | awk &amp;apos;{print $4}&amp;apos;)
	if [ &amp;quot;$public&amp;quot; -eq &amp;quot;public&amp;quot; ];then
		echo &amp;quot;发现snmp服务存在默认团体名public,不符合要求&amp;quot; | $saveresult
	fi
	if [ &amp;quot;$private&amp;quot; -eq &amp;quot;private&amp;quot; ];then
		echo &amp;quot;发现snmp服务存在默认团体名private,不符合要求&amp;quot; | $saveresult
	fi
else
	echo &amp;quot;snmp服务配置文件不存在,可能没有运行snmp服务&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------14. 可疑文件-------------------------
echo ------------14.1 脚本文件------------------------
#下面脚本不查找/usr目录和/etc目录,检查时可以根据需求来调整
echo &amp;quot;[14.1]正在检查脚本文件.....&amp;quot; | $saveresult
scripts=$(find / *.* | egrep &amp;quot;\.(py|sh|per|pl)$&amp;quot; | egrep -v &amp;quot;/usr|/etc|/var&amp;quot;)
if [ -n &amp;quot;scripts&amp;quot; ];then
	(echo &amp;quot;[!!!]发现以下脚本文件,请注意！！！&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$scripts&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现脚本文件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------14.2 恶意文件---------------------
#webshell这一块因为技术难度相对较高,并且已有专业的工具，目前这一块建议使用专门的安全检查工具来实现
#系统层的恶意文件建议使用rootkit专杀工具来查杀,如rkhunter,下载地址:http://rkhunter.sourceforge.net

echo ------------14.3 最近24小时内变动的文件---------------------
#查看最近24小时内有改变的文件
(find / -mtime 0 | grep -E &amp;quot;\.(py|sh|per|pl|php|asp|jsp)$&amp;quot;) | tee -a $danger_file | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult


echo ------------14.4 文件属性---------------------
echo ------------14.4.1 passwd文件属性---------------------
echo &amp;quot;[14.4.1]正在检查passwd文件属性......&amp;quot; | $saveresult
flag=0
for ((x=1;x&amp;lt;=15;x++))
do
	apend=`lsattr /etc/passwd | cut -c $x`
	if [ $apend = &amp;quot;i&amp;quot; ];then
		echo &amp;quot;/etc/passwd文件存在i安全属性,符合要求&amp;quot; | $saveresult
		flag=1
	fi
	if [ $apend = &amp;quot;a&amp;quot; ];then
		echo &amp;quot;/etc/passwd文件存在a安全属性&amp;quot; | $saveresult
		flag=1
	fi
done

if [ $flag = 0 ];then
	echo &amp;quot;/etc/passwd文件不存在相关安全属性,建议使用chattr +i或chattr +a防止/etc/passwd被删除或修改&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------14.4.2 shadow文件属性---------------------
echo &amp;quot;[14.4.2]正在检查shadow文件属性......&amp;quot; | $saveresult
flag=0
for ((x=1;x&amp;lt;=15;x++))
do
	apend=`lsattr /etc/shadow | cut -c $x`
	if [ $apend = &amp;quot;i&amp;quot; ];then
		echo &amp;quot;/etc/shadow文件存在i安全属性,符合要求&amp;quot; | $saveresult
		flag=1
	fi
	if [ $apend = &amp;quot;a&amp;quot; ];then
		echo &amp;quot;/etc/shadow文件存在a安全属性&amp;quot; | $saveresult
		flag=1
	fi
done
if [ $flag = 0 ];then
	echo &amp;quot;/etc/shadow文件不存在相关安全属性,建议使用chattr +i或chattr +a防止/etc/shadow被删除或修改&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------14.4.3 gshadow文件属性---------------------
echo &amp;quot;[14.4.3]正在检查gshadow文件属性......&amp;quot; | $saveresult
flag=0
for ((x=1;x&amp;lt;=15;x++))
do
	apend=`lsattr /etc/gshadow | cut -c $x`
	if [ $apend = &amp;quot;i&amp;quot; ];then
		echo &amp;quot;/etc/gshadow文件存在i安全属性,符合要求&amp;quot; | $saveresult
		flag=1
	fi
	if [ $apend = &amp;quot;a&amp;quot; ];then
		echo &amp;quot;/etc/gshadow文件存在a安全属性&amp;quot; | $saveresult
		flag=1
	fi
done
if [ $flag = 0 ];then
	echo &amp;quot;/etc/gshadow文件不存在相关安全属性,建议使用chattr +i或chattr +a防止/etc/gshadow被删除或修改&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult


echo ------------14.4.4 group文件属性---------------------
echo &amp;quot;[14.4.4]正在检查group文件属性......&amp;quot; | $saveresult
flag=0
for ((x=1;x&amp;lt;=15;x++))
do
	apend=`lsattr /etc/group | cut -c $x`
	if [ $apend = &amp;quot;i&amp;quot; ];then
		echo &amp;quot;/etc/group文件存在i安全属性,符合要求&amp;quot; | $saveresult
		flag=1
	fi
	if [ $apend = &amp;quot;a&amp;quot; ];then
		echo &amp;quot;/etc/group文件存在a安全属性&amp;quot; | $saveresult
		flag=1
	fi
done
if [ $flag = 0 ];then
	echo &amp;quot;/etc/group文件不存在相关安全属性,建议使用chattr +i或chattr +a防止/etc/group被删除或修改&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult


echo ------------15 文件完整性----------------------
echo ------------15.1 系统文件完整性----------------------
#通过取出系统关键文件的MD5值,一方面可以直接将这些关键文件的MD5值通过威胁情报平台进行查询
#另一方面,使用该软件进行多次检查时会将相应的MD5值进行对比,若和上次不一样,则会进行提示

echo &amp;quot;[15.1]正在采集系统关键文件MD5.....&amp;quot;
file=&amp;quot;/tmp/linuxcheck_${ipadd}_${date}/sysfile_md5.txt&amp;quot;
if [ -e &amp;quot;$file&amp;quot; ]; then 
	md5sum -c &amp;quot;$file&amp;quot; 2&amp;gt;&amp;amp;1; 
else
	md5sum /usr/bin/awk &amp;gt;&amp;gt; $file
	md5sum /usr/bin/basename &amp;gt;&amp;gt; $file
	md5sum /usr/bin/bash &amp;gt;&amp;gt; $file
	md5sum /usr/bin/cat &amp;gt;&amp;gt; $file
	md5sum /usr/bin/chattr &amp;gt;&amp;gt; $file
	md5sum /usr/bin/chmod &amp;gt;&amp;gt; $file
	md5sum /usr/bin/chown &amp;gt;&amp;gt; $file
	md5sum /usr/bin/cp &amp;gt;&amp;gt; $file
	md5sum /usr/bin/csh &amp;gt;&amp;gt; $file
	md5sum /usr/bin/curl &amp;gt;&amp;gt; $file
	md5sum /usr/bin/cut &amp;gt;&amp;gt; $file
	md5sum /usr/bin/date &amp;gt;&amp;gt; $file
	md5sum /usr/bin/df &amp;gt;&amp;gt; $file
	md5sum /usr/bin/diff &amp;gt;&amp;gt; $file
	md5sum /usr/bin/dirname &amp;gt;&amp;gt; $file
	md5sum /usr/bin/dmesg &amp;gt;&amp;gt; $file
	md5sum /usr/bin/du &amp;gt;&amp;gt; $file
	md5sum /usr/bin/echo &amp;gt;&amp;gt; $file
	md5sum /usr/bin/ed &amp;gt;&amp;gt; $file
	md5sum /usr/bin/egrep &amp;gt;&amp;gt; $file
	md5sum /usr/bin/env &amp;gt;&amp;gt; $file
	md5sum /usr/bin/fgrep &amp;gt;&amp;gt; $file
	md5sum /usr/bin/file &amp;gt;&amp;gt; $file
	md5sum /usr/bin/find &amp;gt;&amp;gt; $file
	md5sum /usr/bin/gawk &amp;gt;&amp;gt; $file
	md5sum /usr/bin/GET &amp;gt;&amp;gt; $file
	md5sum /usr/bin/grep &amp;gt;&amp;gt; $file
	md5sum /usr/bin/groups &amp;gt;&amp;gt; $file
	md5sum /usr/bin/head &amp;gt;&amp;gt; $file
	md5sum /usr/bin/id &amp;gt;&amp;gt; $file
	md5sum /usr/bin/ipcs &amp;gt;&amp;gt; $file
	md5sum /usr/bin/kill &amp;gt;&amp;gt; $file
	md5sum /usr/bin/killall &amp;gt;&amp;gt; $file
	md5sum /usr/bin/kmod &amp;gt;&amp;gt; $file
	md5sum /usr/bin/last &amp;gt;&amp;gt; $file
	md5sum /usr/bin/lastlog &amp;gt;&amp;gt; $file
	md5sum /usr/bin/ldd &amp;gt;&amp;gt; $file
	md5sum /usr/bin/less &amp;gt;&amp;gt; $file
	md5sum /usr/bin/locate &amp;gt;&amp;gt; $file
	md5sum /usr/bin/logger &amp;gt;&amp;gt; $file
	md5sum /usr/bin/login &amp;gt;&amp;gt; $file
	md5sum /usr/bin/ls &amp;gt;&amp;gt; $file
	md5sum /usr/bin/lsattr &amp;gt;&amp;gt; $file
	md5sum /usr/bin/lynx &amp;gt;&amp;gt; $file
	md5sum /usr/bin/mail &amp;gt;&amp;gt; $file
	md5sum /usr/bin/mailx &amp;gt;&amp;gt; $file
	md5sum /usr/bin/md5sum &amp;gt;&amp;gt; $file
	md5sum /usr/bin/mktemp &amp;gt;&amp;gt; $file
	md5sum /usr/bin/more &amp;gt;&amp;gt; $file
	md5sum /usr/bin/mount &amp;gt;&amp;gt; $file
	md5sum /usr/bin/mv &amp;gt;&amp;gt; $file
	md5sum /usr/bin/netstat &amp;gt;&amp;gt; $file
	md5sum /usr/bin/newgrp &amp;gt;&amp;gt; $file
	md5sum /usr/bin/numfmt &amp;gt;&amp;gt; $file
	md5sum /usr/bin/passwd &amp;gt;&amp;gt; $file
	md5sum /usr/bin/perl &amp;gt;&amp;gt; $file
	md5sum /usr/bin/pgrep &amp;gt;&amp;gt; $file
	md5sum /usr/bin/ping &amp;gt;&amp;gt; $file
	md5sum /usr/bin/pkill &amp;gt;&amp;gt; $file
	md5sum /usr/bin/ps &amp;gt;&amp;gt; $file
	md5sum /usr/bin/pstree &amp;gt;&amp;gt; $file
	md5sum /usr/bin/pwd &amp;gt;&amp;gt; $file
	md5sum /usr/bin/readlink &amp;gt;&amp;gt; $file
	md5sum /usr/bin/rpm &amp;gt;&amp;gt; $file
	md5sum /usr/bin/runcon &amp;gt;&amp;gt; $file
	md5sum /usr/bin/sed &amp;gt;&amp;gt; $file
	md5sum /usr/bin/sh &amp;gt;&amp;gt; $file
	md5sum /usr/bin/sha1sum &amp;gt;&amp;gt; $file
	md5sum /usr/bin/sha224sum &amp;gt;&amp;gt; $file
	md5sum /usr/bin/sha256sum &amp;gt;&amp;gt; $file
	md5sum /usr/bin/sha384sum &amp;gt;&amp;gt; $file
	md5sum /usr/bin/sha512sum &amp;gt;&amp;gt; $file
	md5sum /usr/bin/size &amp;gt;&amp;gt; $file
	md5sum /usr/bin/sort &amp;gt;&amp;gt; $file
	md5sum /usr/bin/ssh &amp;gt;&amp;gt; $file
	md5sum /usr/bin/stat &amp;gt;&amp;gt; $file
	md5sum /usr/bin/strace &amp;gt;&amp;gt; $file
	md5sum /usr/bin/strings &amp;gt;&amp;gt; $file
	md5sum /usr/bin/su &amp;gt;&amp;gt; $file
	md5sum /usr/bin/sudo &amp;gt;&amp;gt; $file
	md5sum /usr/bin/systemctl &amp;gt;&amp;gt; $file
	md5sum /usr/bin/tail &amp;gt;&amp;gt; $file
	md5sum /usr/bin/tcsh &amp;gt;&amp;gt; $file
	md5sum /usr/bin/telnet &amp;gt;&amp;gt; $file
	md5sum /usr/bin/test &amp;gt;&amp;gt; $file
	md5sum /usr/bin/top &amp;gt;&amp;gt; $file
	md5sum /usr/bin/touch &amp;gt;&amp;gt; $file
	md5sum /usr/bin/tr &amp;gt;&amp;gt; $file
	md5sum /usr/bin/uname &amp;gt;&amp;gt; $file
	md5sum /usr/bin/uniq &amp;gt;&amp;gt; $file
	md5sum /usr/bin/users &amp;gt;&amp;gt; $file
	md5sum /usr/bin/vmstat &amp;gt;&amp;gt; $file
	md5sum /usr/bin/w &amp;gt;&amp;gt; $file
	md5sum /usr/bin/watch &amp;gt;&amp;gt; $file
	md5sum /usr/bin/wc &amp;gt;&amp;gt; $file
	md5sum /usr/bin/wget &amp;gt;&amp;gt; $file
	md5sum /usr/bin/whatis &amp;gt;&amp;gt; $file
	md5sum /usr/bin/whereis &amp;gt;&amp;gt; $file
	md5sum /usr/bin/which &amp;gt;&amp;gt; $file
	md5sum /usr/bin/who &amp;gt;&amp;gt; $file
	md5sum /usr/bin/whoami &amp;gt;&amp;gt; $file
	md5sum /usr/lib/systemd/s &amp;gt;&amp;gt; $file
	md5sum /usr/local/bin/rkh &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/adduser &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/chkconfi &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/chroot &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/depmod &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/fsck &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/fuser &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/groupadd &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/groupdel &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/groupmod &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/grpck &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/ifconfig &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/ifdown &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/ifup &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/init &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/insmod &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/ip &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/lsmod &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/lsof &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/modinfo &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/modprobe &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/nologin &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/pwck &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/rmmod &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/route &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/rsyslogd &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/runlevel &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/sestatus &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/sshd &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/sulogin &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/sysctl &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/tcpd &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/useradd &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/userdel &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/usermod &amp;gt;&amp;gt; $file
	md5sum /usr/sbin/vipw &amp;gt;&amp;gt; $file
fi
printf &amp;quot;\n&amp;quot; | $saveresult


echo ------------16 日志分析------------------------------
echo ------------16.1 查看日志配置与打包-------------------
echo ------------16.1.1 查看日志配置----------------------
echo &amp;quot;[16.1.1]正在查看日志配置.....&amp;quot; | $saveresult
logconf=$(more /etc/rsyslog.conf | egrep -v &amp;quot;#|^$&amp;quot;)
if [ -n &amp;quot;$logconf&amp;quot; ];then
	(echo &amp;quot;[*]日志配置如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$logconf&amp;quot;) | $saveresult
else
	echo &amp;quot;[!!!]未发现日志配置文件&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.1.2日志是否存在---------------
echo &amp;quot;[16.1.2]正在分析日志文件是否存在.....&amp;quot; | $saveresult
logs=$(ls -l /var/log/)
if [ -n &amp;quot;$logs&amp;quot; ];then
	echo &amp;quot;[*]日志文件存在&amp;quot; | $saveresult
else
	echo &amp;quot;[!!!]日志文件不存在,请分析是否被清除！&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.1.3 日志审核是否开启---------------
echo &amp;quot;[16.1.3]正在分析日志审核是否开启.....&amp;quot; | $saveresult
service auditd status | grep running
if [ $? -eq 0 ];then
	echo &amp;quot;[*]系统日志审核功能已开启,符合要求&amp;quot; | $saveresult
else
	echo &amp;quot;[!!!]系统日志审核功能已关闭,不符合要求,建议开启日志审核。可使用以下命令开启:service auditd start&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.1.4 打包日志---------------
echo &amp;quot;[16.1.4]正在打包日志......&amp;quot; | $saveresult
zip -r ${log_file}system_log.zip /var/log/
if [ $? -eq 0 ];then
	echo &amp;quot;[*]日志打包成功&amp;quot; | $saveresult
else
	echo &amp;quot;[!!!]日志打包失败,请工人导出日志&amp;quot; | tee -a $danger_file | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.2secure日志分析---------------
echo ------------16.2.1成功登录--------------------
echo &amp;quot;[16.2.1]正在检查日志中成功登录的情况.....&amp;quot; | $saveresult
loginsuccess=$(more /var/log/secure* | grep &amp;quot;Accepted password&amp;quot; | awk &amp;apos;{print $1,$2,$3,$9,$11}&amp;apos;)
if [ -n &amp;quot;$loginsuccess&amp;quot; ];then
	(echo &amp;quot;[*]日志中分析到以下用户成功登录:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$loginsuccess&amp;quot;)  | $saveresult
	(echo &amp;quot;[*]登录成功的IP及次数如下：&amp;quot; &amp;amp;&amp;amp; grep &amp;quot;Accepted &amp;quot; /var/log/secure* | awk &amp;apos;{print $11}&amp;apos; | sort -nr | uniq -c )  | $saveresult
	(echo &amp;quot;[*]登录成功的用户及次数如下:&amp;quot; &amp;amp;&amp;amp; grep &amp;quot;Accepted&amp;quot; /var/log/secure* | awk &amp;apos;{print $9}&amp;apos; | sort -nr | uniq -c )  | $saveresult
else
	echo &amp;quot;[*]日志中未发现成功登录的情况&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.2.2登录失败--------------------
echo &amp;quot;[16.2.2]存在检查日志中登录失败的情况.....&amp;quot; | $saveresult
loginfailed=$(more /var/log/secure* | grep &amp;quot;Failed password&amp;quot; | awk &amp;apos;{print $1,$2,$3,$9,$11}&amp;apos;)
if [ -n &amp;quot;$loginfailed&amp;quot; ];then
	(echo &amp;quot;[!!!]日志中发现以下登录失败的情况:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$loginfailed&amp;quot;) |  tee -a $danger_file  | $saveresult
	(echo &amp;quot;[!!!]登录失败的IP及次数如下:&amp;quot; &amp;amp;&amp;amp; grep &amp;quot;Failed password&amp;quot; /var/log/secure* | awk &amp;apos;{print $11}&amp;apos; | sort -nr | uniq -c)  | $saveresult
	(echo &amp;quot;[!!!]登录失败的用户及次数如下:&amp;quot; &amp;amp;&amp;amp; grep &amp;quot;Failed password&amp;quot; /var/log/secure* | awk &amp;apos;{print $9}&amp;apos; | sort -nr | uniq -c)  | $saveresult
else
	echo &amp;quot;[*]日志中未发现登录失败的情况&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.2.3本机登录情况-----------------
echo &amp;quot;[16.2.4]正在检查图本机登录情况.....&amp;quot; | $saveresult
systemlogin=$(more /var/log/secure* | grep -E &amp;quot;sshd:session.*session opened&amp;quot; | awk &amp;apos;{print $1,$2,$3,$11}&amp;apos;)
if [ -n &amp;quot;$systemlogin&amp;quot; ];then
	(echo &amp;quot;[*]本机登录情况:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$systemlogin&amp;quot;) | $saveresult
	(echo &amp;quot;[*]本机登录账号及次数如下:&amp;quot; &amp;amp;&amp;amp; more /var/log/secure* | grep -E &amp;quot;sshd:session.*session opened&amp;quot; | awk &amp;apos;{print $11}&amp;apos; | sort -nr | uniq -c) | $saveresult
else
	echo &amp;quot;[!!!]未发现在本机登录退出情况,请注意！！！&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.2.4新增用户-------------------
echo &amp;quot;[16.2.4]正在检查新增用户.....&amp;quot; | $saveresult
newusers=$(more /var/log/secure* | grep &amp;quot;new user&amp;quot;  | awk -F &amp;apos;[=,]&amp;apos; &amp;apos;{print $1,$2}&amp;apos; | awk &amp;apos;{print $1,$2,$3,$9}&amp;apos;)
if [ -n &amp;quot;$newusers&amp;quot; ];then
	(echo &amp;quot;[!!!]日志中发现新增用户:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$newusers&amp;quot;) | tee -a $danger_file | $saveresult
	(echo &amp;quot;[*]新增用户账号及次数如下:&amp;quot; &amp;amp;&amp;amp; more /var/log/secure* | grep &amp;quot;new user&amp;quot; | awk &amp;apos;{print $8}&amp;apos; | awk -F &amp;apos;[=,]&amp;apos; &amp;apos;{print $2}&amp;apos; | sort | uniq -c) | $saveresult
else
	echo &amp;quot;[*]日志中未发现新增加用户&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.2.5新增用户组-----------------
echo &amp;quot;[16.2.5]正在检查新增用户组.....&amp;quot; | $saveresult
newgoup=$(more /var/log/secure* | grep &amp;quot;new group&amp;quot;  | awk -F &amp;apos;[=,]&amp;apos; &amp;apos;{print $1,$2}&amp;apos; | awk &amp;apos;{print $1,$2,$3,$9}&amp;apos;)
if [ -n &amp;quot;$newgoup&amp;quot; ];then
	(echo &amp;quot;[!!!]日志中发现新增用户组:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$newgoup&amp;quot;) | tee -a $danger_file | $saveresult
	(echo &amp;quot;[*]新增用户组及次数如下:&amp;quot; &amp;amp;&amp;amp; more /var/log/secure* | grep &amp;quot;new group&amp;quot; | awk &amp;apos;{print $8}&amp;apos; | awk -F &amp;apos;[=,]&amp;apos; &amp;apos;{print $2}&amp;apos; | sort | uniq -c) | $saveresult
else
	echo &amp;quot;[*]日志中未发现新增加用户组&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.3message日志分析---------------
echo ------------16.3.1传输文件--------------------
#下面命令仅显示传输的文件名,并会将相同文件名的去重
#more /var/log/message* | grep &amp;quot;ZMODEM:.*BPS&amp;quot; | awk -F &amp;apos;[]/]&amp;apos; &amp;apos;{print $0}&amp;apos; | sort | uniq
echo &amp;quot;[16.3.1]正在检查传输文件.....&amp;quot; | $saveresult
zmodem=$(more /var/log/message* | grep &amp;quot;ZMODEM:.*BPS&amp;quot;)
if [ -n &amp;quot;$zmodem&amp;quot; ];then
	(echo &amp;quot;[!!!]传输文件情况:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$zmodem&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]日志中未发现传输文件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.3.2历史使用DNS服务器------------
echo &amp;quot;[16.3.2]正在检查日志中使用DNS服务器的情况.....&amp;quot; | $saveresult
dns_history=$(more /var/log/messages* | grep &amp;quot;using nameserver&amp;quot; | awk &amp;apos;{print $NF}&amp;apos; | awk -F# &amp;apos;{print $1}&amp;apos; | sort | uniq)
if [ -n &amp;quot;$dns_history&amp;quot; ];then
	(echo &amp;quot;[!!!]该服务器曾经使用以下DNS:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$dns_history&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现使用DNS服务器&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.4cron日志分析---------------
echo ------------16.4.1定时下载-----------------
echo &amp;quot;[16.4.1]正在分析定时下载.....&amp;quot; | $saveresult
cron_download=$(more /var/log/cron* | grep &amp;quot;wget|curl&amp;quot;)
if [ -n &amp;quot;$cron_download&amp;quot; ];then
	(echo &amp;quot;[!!!]定时下载情况:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$cron_download&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现定时下载情况&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.4.2定时执行脚本-----------------
echo &amp;quot;[16.4.2]正在分析定时执行脚本.....&amp;quot; | $saveresult
cron_shell=$(more /var/log/cron* | grep -E &amp;quot;\.py$|\.sh$|\.pl$&amp;quot;) 
if [ -n &amp;quot;$cron_shell&amp;quot; ];then
	(echo &amp;quot;[!!!]发现定时执行脚本:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$cron_download&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现定时下载脚本&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.5yum日志分析----------------------
echo ------------16.5.1下载软件情况-------------------
echo &amp;quot;[16.5.1]正在分析使用yum下载软件情况.....&amp;quot; | $saveresult
yum_install=$(more /var/log/yum* | grep Installed | awk &amp;apos;{print $NF}&amp;apos; | sort | uniq)
if [ -n &amp;quot;$yum_install&amp;quot; ];then
	(echo &amp;quot;[*]曾使用yum下载以下软件:&amp;quot;  &amp;amp;&amp;amp; echo &amp;quot;$yum_install&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未使用yum下载过软件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.5.2下载脚本文件-------------------
echo &amp;quot;[16.5.2]正在分析使用yum下载脚本文件.....&amp;quot; | $saveresult
yum_installscripts=$(more /var/log/yum* | grep Installed | grep -E &amp;quot;(\.sh$\.py$|\.pl$)&amp;quot; | awk &amp;apos;{print $NF}&amp;apos; | sort | uniq)
if [ -n &amp;quot;$yum_installscripts&amp;quot; ];then
	(echo &amp;quot;[*]曾使用yum下载以下脚本文件:&amp;quot;  &amp;amp;&amp;amp; echo &amp;quot;$yum_installscripts&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未使用yum下载过脚本文件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.5.3卸载软件情况-------------------
echo &amp;quot;[16.5.3]正在检查使用yum卸载软件情况.....&amp;quot; | $saveresult
yum_erased=$(more /var/log/yum* | grep Erased)
if [ -n &amp;quot;$yum_erased&amp;quot; ];then
	(echo &amp;quot;[*]使用yum曾卸载以下软件:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$yum_erased&amp;quot;)  | $saveresult
else
	echo &amp;quot;[*]未使用yum卸载过软件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.5.4可疑工具-----------------
echo &amp;quot;[16.5.4]正在检查使用yum安装的可疑工具.....&amp;quot; | $saveresult
hacker_tools=$(more /var/log/yum* | awk -F: &amp;apos;{print $NF}&amp;apos; | awk -F &amp;apos;[-]&amp;apos; &amp;apos;{print $1}&amp;apos; | sort | uniq | grep -E &amp;quot;(^nc|sqlmap|nmap|beef|nikto|john|ettercap|backdoor|proxy|msfconsole|msf)&amp;quot;)
if [ -n &amp;quot;$hacker_tools&amp;quot; ];then
	(echo &amp;quot;[!!!]发现使用yum下载过以下可疑软件:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$hacker_tools&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现使用yum下载过可疑软件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.6 dmesg日志分析----------------------
echo ------------16.6.1 内核自检日志---------------------
echo &amp;quot;[16.6.1]正在查看内核自检日志.....&amp;quot; | $saveresult
dmesg=$(dmesg)
if [ $? -eq 0 ];then
	(echo &amp;quot;[*]日志自检日志如下：&amp;quot; &amp;amp;&amp;amp; &amp;quot;$dmesg&amp;quot; ) | $saveresult
else
	echo &amp;quot;[*]未发现内核自检日志&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.7 btmp日志分析----------------------
echo ------------16.7.1 错误登录日志分析-----------------
echo &amp;quot;[16.7.1]正在分析错误登录日志.....&amp;quot; | $saveresult
lastb=$(lastb)
if [ -n &amp;quot;$lastb&amp;quot; ];then
	(echo &amp;quot;[*]错误登录日志如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$lastb&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现错误登录日志&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.8 lastlog日志分析----------------------
echo ------------16.8.1 所有用户最后一次登录日志分析-----------------
echo &amp;quot;[16.8.1]正在分析所有用户最后一次登录日志.....&amp;quot; | $saveresult
lastlog=$(lastlog)
if [ -n &amp;quot;$lastlog&amp;quot; ];then
	(echo &amp;quot;[*]所有用户最后一次登录日志如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$lastlog&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现所有用户最后一次登录日志&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------16.9 wtmp日志分析---------------
echo ------------16.9.1所有登录用户分析-------
echo &amp;quot;[16.9.1]正在检查历史上登录到本机的用户:&amp;quot; | $saveresult
lasts=$(last | grep pts | grep -vw :0)
if [ -n &amp;quot;$lasts&amp;quot; ];then
	(echo &amp;quot;[*]历史上登录到本机的用户如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$lasts&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现历史上登录到本机的用户信息&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------17 内核检查-------------------
echo ------------17.1 内核情况-----------------
echo &amp;quot;[17.1]正在检查内核信息......&amp;quot; | $saveresult
lsmod=$(lsmod)
if [ -n &amp;quot;$lsmod&amp;quot; ];then
	(echo &amp;quot;[*]内核信息如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$lsmod&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现内核信息&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------17.2 可疑内核检查-----------------
echo &amp;quot;[17.2]正在检查可疑内核.....&amp;quot; | $saveresult
danger_lsmod=$(lsmod | grep -Ev &amp;quot;ablk_helper|ac97_bus|acpi_power_meter|aesni_intel|ahci|ata_generic|ata_piix|auth_rpcgss|binfmt_misc|bluetooth|bnep|bnx2|bridge|cdrom|cirrus|coretemp|crc_t10dif|crc32_pclmul|crc32c_intel|crct10dif_common|crct10dif_generic|crct10dif_pclmul|cryptd|dca|dcdbas|dm_log|dm_mirror|dm_mod|dm_region_hash|drm|drm_kms_helper|drm_panel_orientation_quirks|e1000|ebtable_broute|ebtable_filter|ebtable_nat|ebtables|edac_core|ext4|fb_sys_fops|floppy|fuse|gf128mul|ghash_clmulni_intel|glue_helper|grace|i2c_algo_bit|i2c_core|i2c_piix4|i7core_edac|intel_powerclamp|ioatdma|ip_set|ip_tables|ip6_tables|ip6t_REJECT|ip6t_rpfilter|ip6table_filter|ip6table_mangle|ip6table_nat|ip6table_raw|ip6table_security|ipmi_devintf|ipmi_msghandler|ipmi_si|ipmi_ssif|ipt_MASQUERADE|ipt_REJECT|iptable_filter|iptable_mangle|iptable_nat|iptable_raw|iptable_security|iTCO_vendor_support|iTCO_wdt|jbd2|joydev|kvm|kvm_intel|libahci|libata|libcrc32c|llc|lockd|lpc_ich|lrw|mbcache|megaraid_sas|mfd_core|mgag200|Module|mptbase|mptscsih|mptspi|nf_conntrack|nf_conntrack_ipv4|nf_conntrack_ipv6|nf_defrag_ipv4|nf_defrag_ipv6|nf_nat|nf_nat_ipv4|nf_nat_ipv6|nf_nat_masquerade_ipv4|nfnetlink|nfnetlink_log|nfnetlink_queue|nfs_acl|nfsd|parport|parport_pc|pata_acpi|pcspkr|ppdev|rfkill|sch_fq_codel|scsi_transport_spi|sd_mod|serio_raw|sg|shpchp|snd|snd_ac97_codec|snd_ens1371|snd_page_alloc|snd_pcm|snd_rawmidi|snd_seq|snd_seq_device|snd_seq_midi|snd_seq_midi_event|snd_timer|soundcore|sr_mod|stp|sunrpc|syscopyarea|sysfillrect|sysimgblt|tcp_lp|ttm|tun|uvcvideo|videobuf2_core|videobuf2_memops|videobuf2_vmalloc|videodev|virtio|virtio_balloon|virtio_console|virtio_net|virtio_pci|virtio_ring|virtio_scsi|vmhgfs|vmw_balloon|vmw_vmci|vmw_vsock_vmci_transport|vmware_balloon|vmwgfx|vsock|xfs|xt_CHECKSUM|xt_conntrack|xt_state&amp;quot;)
if [ -n &amp;quot;$danger_lsmod&amp;quot; ];then
	(echo &amp;quot;[!!!]发现可疑内核模块:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$danger_lsmod&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现可疑内核模块&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------18 安装软件-------------------
echo ------------18.1 安装软件及版本-----------------
echo &amp;quot;[18.1]正在检查安装软件及版本情况.....&amp;quot; | $saveresult
software=$(rpm -qa | awk -F- &amp;apos;{print $1,$2}&amp;apos; | sort -nr -k2 | uniq)
if [ -n &amp;quot;$software&amp;quot; ];then
	(echo &amp;quot;[*]系统安装与版本如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$software&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]系统未安装软件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------18.2可疑软件-----------------
echo &amp;quot;[18.2]正在检查安装的可疑软件.....&amp;quot; | $saveresult
danger_soft=$(rpm -qa  | awk -F- &amp;apos;{print $1}&amp;apos; | sort | uniq | grep -E &amp;quot;^(ncat|sqlmap|nmap|beef|nikto|john|ettercap|backdoor|proxy|msfconsole|msf)$&amp;quot;)
if [ -n &amp;quot;$danger_soft&amp;quot; ];then
	(echo &amp;quot;[!!!]以下安装的软件可疑,需要人工分析:&amp;quot;  &amp;amp;&amp;amp; echo &amp;quot;$danger_soft&amp;quot;) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现安装可疑软件&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------19环境变量-----------------
echo &amp;quot;[18]正在检查环境变量.....&amp;quot; | $saveresult
env=$(env)
if [ -n &amp;quot;$env&amp;quot; ];then
	(echo &amp;quot;[*]环境变量:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$env&amp;quot;) | $saveresult
else
	echo &amp;quot;[*]未发现环境变量&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------20性能分析-----------------
echo ------------20.1磁盘分析-----------------
echo ------------20.1.1磁盘使用-----------------
echo &amp;quot;[20.1.1]正在检查磁盘使用.....&amp;quot; | $saveresult
echo &amp;quot;[*]磁盘使用情况如下:&amp;quot; &amp;amp;&amp;amp; df -h  | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------20.1.2检查磁盘使用过大-----------------
echo &amp;quot;[20.1.2]正在检查磁盘使用是否过大.....&amp;quot; | $saveresult
#使用超过70%告警
df=$(df -h | awk &amp;apos;NR!=1{print $1,$5}&amp;apos; | awk -F% &amp;apos;{print $1}&amp;apos; | awk &amp;apos;{if ($2&amp;gt;70) print $1,$2}&amp;apos;)
if [ -n &amp;quot;$df&amp;quot; ];then
	(echo &amp;quot;[!!!]硬盘空间使用过高，请注意！！！&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$df&amp;quot; ) | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]硬盘空间足够&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------20.2CPU分析-----------------
echo ------------20.2.1CPU情况-----------------
echo &amp;quot;[20.2.1]正在检查CPU相关信息.....&amp;quot; | $saveresult
(echo &amp;quot;CPU硬件信息如下:&amp;quot; &amp;amp;&amp;amp; more /proc/cpuinfo ) | $saveresult
(echo &amp;quot;CPU使用情况如下:&amp;quot; &amp;amp;&amp;amp; ps -aux | sort -nr -k 3 | awk  &amp;apos;{print $1,$2,$3,$NF}&amp;apos;) | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------20.2.2占用CPU前5进程-----------------
echo &amp;quot;[20.2.2]正在检查占用CPU前5资源的进程.....&amp;quot; | $saveresult
(echo &amp;quot;占用CPU资源前5进程：&amp;quot; &amp;amp;&amp;amp; ps -aux | sort -nr -k 3 | head -5)  | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------20.2.3占用CPU较大进程-----------------
echo &amp;quot;[20.2.3]正在检查占用CPU较大的进程.....&amp;quot; | $saveresult
pscpu=$(ps -aux | sort -nr -k 3 | head -5 | awk &amp;apos;{if($3&amp;gt;=20) print $0}&amp;apos;)
if [ -n &amp;quot;$pscpu&amp;quot; ];then
	echo &amp;quot;[!!!]以下进程占用的CPU超过20%:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;UID         PID   PPID  C STIME TTY          TIME CMD&amp;quot; 
	echo &amp;quot;$pscpu&amp;quot; | tee -a 20.2.3_pscpu.txt | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现进程占用资源超过20%&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------20.3 内存分析-----------------
echo ------------20.3.1 内存情况-----------------
echo &amp;quot;[20.3.1]正在检查内存相关信息.....&amp;quot; | $saveresult
(echo &amp;quot;[*]内存信息如下:&amp;quot; &amp;amp;&amp;amp; more /proc/meminfo) | $saveresult
(echo &amp;quot;[*]内存使用情况如下:&amp;quot; &amp;amp;&amp;amp; free -m) | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------20.3.2占用内存前5进程-----------------
echo &amp;quot;[20.2.2]正在检查占用内存前5资源的进程.....&amp;quot; | $saveresult
(echo &amp;quot;[*]占用内存资源前5进程：&amp;quot; &amp;amp;&amp;amp; ps -aux | sort -nr -k 4 | head -5) | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------20.3.3占用内存较多进程-----------------
echo &amp;quot;[20.3.3]正在检查占用内存较多的进程.....&amp;quot; | $saveresult
psmem=$(ps -aux | sort -nr -k 4 | head -5 | awk &amp;apos;{if($4&amp;gt;=2) print $0}&amp;apos;)
if [ -n &amp;quot;$psmem&amp;quot; ];then
	echo &amp;quot;[!!!]以下进程占用的内存超过20%:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;UID         PID   PPID  C STIME TTY          TIME CMD&amp;quot;
	echo &amp;quot;$psmem&amp;quot; | tee -a $danger_file | $saveresult
else
	echo &amp;quot;[*]未发现进程占用内存资源超过20%&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------20.4网络连接-----------------
echo &amp;quot;[20.4]正在检查网络连接情况......&amp;quot; | $saveresult
netstat=$(netstat -anlp | grep ESTABLISHED)
netstatnum=$(netstat -n | awk &amp;apos;/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}&amp;apos;)
if [ -n &amp;quot;$netstat&amp;quot; ];then
	(echo &amp;quot;[*]网络连接情况:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$netstat&amp;quot;) | $saveresult
	if [ -n &amp;quot;$netstatnum&amp;quot; ];then
		(echo &amp;quot;[*]各个状态的数量如下:&amp;quot; &amp;amp;&amp;amp; echo &amp;quot;$netstatnum&amp;quot;)  | $saveresult
	fi
else
	echo &amp;quot;[*]未发现网络连接&amp;quot; | $saveresult
fi
printf &amp;quot;\n&amp;quot; | $saveresult

echo ------------20.5 其他----------------------
echo ------------20.5.1 运行时间及负载-----------------
echo &amp;quot;[20.5.1]正在检查系统运行时间及负载情况......&amp;quot; | $saveresult
(echo &amp;quot;[*]系统运行时间如下:&amp;quot; &amp;amp;&amp;amp; uptime) | $saveresult
printf &amp;quot;\n&amp;quot; | $saveresult

echo &amp;quot;[*]正在将检查文件压缩到/tmp/目录下......&amp;quot;
zip -r /tmp/linuxcheck_${ipadd}_${date}.zip /tmp/linuxcheck_${ipadd}_${date}/*

echo &amp;quot;检查结束！！！&amp;quot;
echo &amp;quot;Version:1.2&amp;quot;
echo &amp;quot;Date:2022-11-28&amp;quot;&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;&lt;/p&gt;&lt;/div&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62728-linux-%E7%B3%BB%E7%BB%9F-%E5%AE%89%E5%85%A8%E6%A3%80%E6%9F%A5</guid>
      <pubDate>Sun, 09 Apr 2023 10:53:37 CST</pubDate>
    </item>
    <item>
      <title>Linux的root密码恢复</title>
      <link>https://itindex.net/detail/62534-linux-root-%E5%AF%86%E7%A0%81</link>
      <description>&lt;hr&gt;&lt;/hr&gt;
 &lt;h2&gt;theme: condensed-night-purple&lt;/h2&gt;
 &lt;p&gt;  &lt;em&gt;   &lt;strong&gt;本文正在参加    &lt;a href="https://juejin.cn/post/7162096952883019783" title="https://juejin.cn/post/7162096952883019783"&gt;「金石计划 . 瓜分6万现金大奖」&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
 &lt;h1&gt;恢复root密码&lt;/h1&gt;
 &lt;h2&gt;centos恢复密码&lt;/h2&gt;
 &lt;p&gt;1.首先，启动系统，进入开机界面，先让光标停在上面这个内核(Core)上,在界面中按“e”进入编辑界面&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="image-20221209131954450" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/06d6f7508d84406c930e24948c893d9e~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ol start="2"&gt;
  &lt;li&gt;
   &lt;p&gt;进入编辑界面，使用键盘上的上下键把光标往下移动，找到以““Linux16”开头内容所在的行数”，在行的UTF-8最后面输入：init=/bin/sh。&lt;/p&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;p&gt;输入完成后，直接按快捷键：Ctrl+x 进入单用户模式。&lt;/p&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;p&gt;接着，在光标闪烁的位置中输入：&lt;/p&gt;
   &lt;pre&gt;    &lt;code&gt;mount -o remount,rw /
&lt;/code&gt;&lt;/pre&gt;
   &lt;p&gt;以读写方式在/上重新挂载文件系统&lt;/p&gt;
   &lt;p&gt;回车&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

 &lt;ol start="5"&gt;
  &lt;li&gt;
   &lt;p&gt;在新的一行最后面输入：passwd， 完成后按键盘的回车键（Enter）。&lt;/p&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;p&gt;输入密码，然后再次确认密码即可密码修改成功后，会显示passwd.....的样式&lt;/p&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;p&gt;最后一行中输入：&lt;/p&gt;
   &lt;pre&gt;    &lt;code&gt;touch  /.autorelabel
&lt;/code&gt;&lt;/pre&gt;
   &lt;p&gt;回车&lt;/p&gt;
&lt;/li&gt;
  &lt;li&gt;
   &lt;p&gt;输入：&lt;/p&gt;
   &lt;pre&gt;    &lt;code&gt;exec /sbin/init
&lt;/code&gt;&lt;/pre&gt;
   &lt;p&gt;回车&lt;/p&gt;
   &lt;p&gt;漫长等待，且切记不要随意点击！！！&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
 &lt;h2&gt;redhat恢复密码&lt;/h2&gt;
 &lt;p&gt;我们将重置root密码，我们想达到的结果是能够重置丢失的超级用户密码，而不需要对机器进行另一种形式的超级用户访问。&lt;/p&gt;
 &lt;blockquote&gt;
  &lt;p&gt;假设我们没有对servera上的root帐户的无密码ssh访问权限，并且servera上的学生帐户没有完全的sudo访问权限。&lt;/p&gt;
&lt;/blockquote&gt;
 &lt;ol&gt;
  &lt;li&gt;打开servera的控制台，并重新启动它。进入grub菜单，强制系统在执行初始ram disk时暂停启动。&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;1.1 从控制台重新启动服务器。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="image-20221209110927315" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/dcddfbc51d0c4927a35da449e95c35d2~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;1.2. 出现grub菜单倒计时时，按任意键暂停倒计时。&lt;/p&gt;
 &lt;p&gt;1.3. 突出显示默认条目，并按e键编辑它。&lt;/p&gt;
 &lt;p&gt;1.4 向下滚动到以linux16开头的行，按End跳转到行尾，删除最后一个  &lt;strong&gt;console=&lt;/strong&gt;，并追加rd.break。&lt;/p&gt;
 &lt;p&gt;1.5 按Ctrl+X以这些修改后的设置启动&lt;/p&gt;
 &lt;ol start="2"&gt;
  &lt;li&gt;将系统上的root密码改为redhat，注意不要干扰任何SELinux上下文。&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;2.1 以读写方式在/sysroot上重新挂载文件系统&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="image-20221209111309912" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7771b0de2dfd4fc0acf612eaee775331~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;2.2 将root切换到/sysroot目录&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="image-20221209111352986" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0f04a30d0d3544fd8ce2ff24056cfcfc~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;2.3. 将root密码设置为redhat。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="image-20221209111448461" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9f6b4abf4c52445393ebcd9f4eefe671~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;2.4 加载默认的SELinux策略。如果失败，请确保系统将在下次重新启动时执行完整的重新标记。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="image-20221209112218751" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/58e82d9863794f61b091270f4e5de9aa~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;2.5 递归恢复/etc上的SELinux上下文。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="image-20221209112318860" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f1355c8e06d1429d82ccba7a6f2a5f68~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;blockquote&gt;
  &lt;p&gt;   &lt;strong&gt;在更改root密码之前加载SELinux策略会导致在尝试更新root密码时被拒绝。设置密码然后再加载策略并修复上下文，证实有效。如果您忘记更新上下文，那么在重新启动后，将导致没有本地用户可以登录，因为/etc/shadow上将有一个无效的安全上下文。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
 &lt;ol start="3"&gt;
  &lt;li&gt;重新启动servera系统，并验证您可以使用该密码以root用户身份登录redhat。&lt;/li&gt;
&lt;/ol&gt;
 &lt;p&gt;按Ctrl+D两次，以来重新启动servera系统。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="image-20221209130845162" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d4af0fbcb9ae450abf171e170408e433~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;如果你必须上一步中新建文件   &lt;strong&gt;/.autorelabel&lt;/strong&gt;那么你的系统现在将重新启动两次;否则，只需发生一次重启。&lt;/p&gt;
 &lt;ol start="4"&gt;
  &lt;li&gt;尝试以root用户身份使用密码redhat登录控制台。&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62534-linux-root-%E5%AF%86%E7%A0%81</guid>
      <pubDate>Fri, 09 Dec 2022 15:09:36 CST</pubDate>
    </item>
    <item>
      <title>Linux网络丢包排查 - 墨天轮</title>
      <link>https://itindex.net/detail/62475-linux-%E7%BD%91%E7%BB%9C-%E4%B8%A2%E5%8C%85</link>
      <description>&lt;div&gt;    &lt;p&gt;      &lt;strong&gt;&lt;/strong&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;一、简介&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;工作中遇到的服务器，最常用的操作系统就是linux系统，linux 系统使用网络适配器和外部进行数据交换。当在高速链路或异常环境下进行网络通信时，就有可能出现网络数据丢包现象，接下来我主要要说的是：网路丢包的故障定位思路和解决方法。&lt;/p&gt;    &lt;p&gt;      &lt;img src="https://oss-emcsprod-public.modb.pro/wechatSpider/modb_20211019_c4d1098e-30e0-11ec-8b07-fa163eb4f6be.png"&gt;&lt;/img&gt;&lt;/p&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;二、相关原理介绍&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;1&lt;/strong&gt;      &lt;strong&gt;、网络消息的收发（报文收发过程）&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;在说丢包故障定位之前，我先来了介绍“网络报文收发过程”。本文以接收报文为例，发送报文与之类似，只是报文的传输方向相反。&lt;/p&gt;    &lt;p&gt;1、网络packet首先通过网线被网卡获取，网卡检查packet的crc正常后，去掉packet头得到frame，如果frame中MAC的目的地址为本机地址，则接受该报文，否则丢弃（在混杂模式下也会接收该报文）&lt;/p&gt;    &lt;p&gt;2、网卡将frame拷贝到网卡内部缓冲区中，一般是网卡的ring buffer中，拷贝完成后触发软中断通知内核处理&lt;/p&gt;    &lt;p&gt;3、内核从ring buffer中拷贝网络数据，并传递给网络协议栈进行解析&lt;/p&gt;    &lt;p&gt;4、协议栈解析完成后将数据放入ocket套接字的buffer中，最终传递给上层应用&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;2&lt;/strong&gt;      &lt;strong&gt;、相关名词解释&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;-&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;enp125s0f0:flags=4163  mtu 1500&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;inet90.90.160.163  netmask 255.255.252.0  broadcast 90.90.163.255&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;inet6fe80::903a:4e71:69cd:eb09  prefixlen 64  scopeid 0x20&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;ether08:4f:0a:04:85:ac  txqueuelen 1000  (Ethernet)&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;RXpackets 28356  bytes 4397271 (4.1 MiB)&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;RXerrors 0  dropped 15869  overruns 0  frame 0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;TXpackets 3003  bytes 450378 (439.8 KiB)&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;TXerrors 0  dropped 0 overruns 0  carrier 0  collisions 0&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;table&gt;      &lt;tr&gt;&lt;/tr&gt;&lt;/table&gt;    &lt;p&gt;RX errors：表示总的收包的错误数量&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;RX dropped：表示数据包已进入Ring buffer，但是由于系统原因(如内存不足)导致在拷贝到内存中的过程中被丢弃&lt;/p&gt;    &lt;p&gt;RX overruns：表示数据还未进入网卡缓存(Ring buffer)时就被丢弃了，一般是由于Ring buffer中的数据未被及时取出导致溢出，新来的数据只能被丢弃。例如CPU负载大，导致处理网卡数据的速度小于网卡接收数据的速度，Ring buffer溢出。&lt;/p&gt;    &lt;p&gt;RX frame：表示misaligend的frames数量&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;三、丢包故障定位与解决&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;1&lt;/strong&gt;      &lt;strong&gt;、网卡丢包&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;首先检查丢包是否是因为crc校验错误导致的：&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;[root@localhost ~]# ethtool -S enp1s0f0 | grep crc&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;rx_crc_errors_phy:0&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;p&gt;如果crc字段为非0，则表示网络报文在传输时出现了差错，此时可以更换线缆或网卡再做验证。&lt;/p&gt;    &lt;p&gt;如果丢包发生在网卡上，则可以通过ethtool -S eth0 | egrep-i drop|error确认&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;table&gt;      &lt;tr&gt;        &lt;td&gt;          &lt;br /&gt;&lt;/td&gt;        &lt;td&gt;          &lt;br /&gt;&lt;/td&gt;        &lt;td&gt;          &lt;br /&gt;&lt;/td&gt;        &lt;td&gt;          &lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;[root@localhost ~]# ethtool -S enp125s0f0 | egrep -ierror|drop&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;rxq#0_rx_dropped: 0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;rxq#0_errors: 0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;rx_oq_drop_pkt_cnt:0&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;p&gt;netstat -i也可以提供网卡的收发报文和丢包情况，正常情况下error、drop和overrun字段应该为0&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;p&gt;如果RX_OVR一直在增加，说明Ringbuffer有溢出，除了Ring Buffer太小以外，有可能是CPU处于高负荷下，来不及从Ring buffer中获取数据，此时可以检查CPU高负荷的原因，对网卡进行中断亲和设置等操作。通过查看/proc/net/dev也可以查看是否有Ring buffer满而导致的丢包&lt;/p&gt;    &lt;p&gt;[root@localhost~]# netstat -i&lt;/p&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;KernelInterface table&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;IfaceMTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp125s0f01500    29113      0  16149 0          3258      0      0      0 BMRU&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp125s0f11500        0      0      0 0             0      0      0      0 BMU&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp125s0f21500        0      0      0 0             0      0      0      0 BMU&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp125s0f31500        0      0      0 0             0      0      0      0 BMRU&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp1s0f01500        0      0      0 0             0      0      0      0 BMU&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;        &lt;br /&gt;&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;        &lt;br /&gt;&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp1s0f11500        0      0      0 0             0      0      0      0 BMU&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;lo65536     1820      0      0 0          1820      0      0      0 LRU&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;p&gt;如果硬件或者驱动没有问题，一般网卡丢包是由于Ring buffer太小导致，可以使用ethtool -G修改Ring buffer大小。&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;[root@localhost~]# cat proc/net/dev&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Inter-|Receive                                                |  Transmit&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;face|bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp125s0f1:0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;        &lt;br /&gt;&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;        &lt;br /&gt;&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp125s0f3:0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp125s0f2:0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp1s0f1:0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp1s0f0:0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;lo:169176    1948    0    0    0     0          0         0   169176    1948    0    0    0     0       0          0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;enp125s0f0:4880071   32037    0 18238    0     0          0     40408   486664    3302    0    0    0     0       0          0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;        &lt;br /&gt;&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;p&gt;       &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;2&lt;/strong&gt;      &lt;strong&gt;、内核丢包&lt;/strong&gt;其中的fifo字段统计的是Ringbuffer满而丢弃的包      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;内核从网卡收到数据以后，交给协议栈处理之前会有缓冲队列backlog，每个CPU都有一个backlog队列，当从网卡中获取数据到backlog中的速率大于从backlog中将数据交给协议栈的速率时就会发生溢出。可以查看/proc/net/softnet_stat文件确认是否有backlog溢出：&lt;/p&gt;    &lt;p&gt;-&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;[root@localhost~]# cat proc/net/softnet_stat&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0000000300000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0000000000000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0000000000000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0000000000000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0000000000000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0000000000000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0000000000000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;ul&gt;      &lt;li&gt;        &lt;p&gt;每一行代表一个CPU core接收数据的情况&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;第1列表示收到的包总数&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;第2列是丢弃的包计数，此处的丢包指的是从网卡Ring buffer中输出到内核缓存队列时，由于队列满了而丢弃的数据包&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;第3列表示软中断一次取走netdev_budget个数据包，或取数据包时间超过2ms的次数&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;第4列~第8列固定为0，没有意义&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;第9列表示发送数据包时，对应的队列被锁住的次数&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;p&gt;如果是因为backlog队列溢出导致的丢包，可以修改backlog队列的大小，通过systctl修改netdev      &lt;em&gt;max&lt;/em&gt;backlog参数，默认大小为1000&lt;/p&gt;    &lt;p&gt;-&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;table&gt;      &lt;tr&gt;        &lt;td&gt;          &lt;p&gt; sysctl -w net.core.netdev_max_backlog=2000                &lt;br /&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;    &lt;p&gt;在将数据交给内核协议栈后，协议栈进行分析处理。在协议栈中也有可能丢包，通过netstat-s可以查看是否有协议栈丢包，-u参数指定udp协议，-t参数指定tcp协议，也可以加-c参数持续输出，看各个数据的变化，本文以UDP协议为例进行讲解&lt;/p&gt;    &lt;p&gt;-&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;[root@localhost~]# netstat -s -u&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;IcmpMsg:&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;InType3:1006&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;OutType3:1006&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Udp:&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0packetsreceived&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;1006packetsto unknown port received.&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0packetreceive errors&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;1081packetssent&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0receivebuffer errors&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;0sendbuffer errors&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;UdpLite:&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;IpExt:&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;InMcastPkts:3245&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;OutMcastPkts:11&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;InBcastPkts:6213&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;InOctets:2859135&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;OutOctets:633832&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;InMcastOctets:495247&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;OutMcastOctets:2658&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;InBcastOctets:2038580&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;InNoECTPkts:13895&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;[root@localhost~]#&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;ul&gt;      &lt;li&gt;        &lt;p&gt;packet receive errors表示接收有丢包&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;packets to unknown port received表示系统接收到的UDP报文的目标端口没有应用在监听，一般影响不严重&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;receive/send buffer errors表示收发队列太小导致的丢包数量&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;p&gt;对于收发队列太小导致的丢包，可以通过调整收发队列参数来解决，系统默认的receive/sendbuffer大小如下：&lt;/p&gt;    &lt;p&gt;-&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;[root@localhost ~]# sysctlnet.core.rmem_default&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;net.core.rmem_default =229376&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;[root@localhost ~]# sysctlnet.core.wmem_default&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;net.core.wmem_default =229376&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;可以使用以下命令修改buffer大小&lt;/p&gt;    &lt;p&gt;-&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;sysctl-w net.core.rmem_max=26214400# 设置为 25M&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;sysctl -w net.core.wmem_max=26214400# 设置为 25M&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;通过查看/proc/net/snmp文件也可以查看各个协议的收发包情况：&lt;/p&gt;    &lt;p&gt;-&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;Ip: Forwarding DefaultTTL InReceives InHdrErrorsInAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequestsOutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKsFragFails FragCreates&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Ip: 2 64 14757 0 28 0 0 0 4844 5745 512 0 0 0 0 0 0 00&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Icmp: InMsgs InErrors InCsumErrors InDestUnreachsInTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoRepsInTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrorsOutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchosOutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Icmp: 1038 0 0 1038 0 0 0 0 0 0 0 0 0 0 1038 0 1038 00 0 0 0 0 0 0 0 0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;IcmpMsg: InType3 OutType3&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;IcmpMsg: 1038 1038&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpensPassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegsInErrs OutRsts InCsumErrors&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Tcp: 1 200 120000 -1 0 2 0 0 2 2768 3592 0 0 0 0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Udp: InDatagrams NoPorts InErrors OutDatagramsRcvbufErrors SndbufErrors InCsumErrors IgnoredMulti&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Udp: 0 1038 0 1113 0 0 0 0&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;UdpLite: InDatagrams NoPorts InErrors OutDatagramsRcvbufErrors SndbufErrors InCsumErrors IgnoredMulti&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;UdpLite: 0 0 0 0 0 0 0 0/&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;3&lt;/strong&gt;      &lt;strong&gt;、应用丢包&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;内核协议栈把接收到的报文放到socket套接字的buffer中，应用程序从buffer中不断读取报文。所以这里有两个和应用程序有关的因素会影响丢包：socket buffer的大小和应用程序报文读取速度。&lt;/p&gt;    &lt;p&gt;socket buffer大小可在应用程序初始化socket时设置，不过增大buffer的值会增加内存的使用，请根据实际情况配置；对于应用程序报文处理速度，应采用异步方式处理&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;四、其他定位方法&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;1&lt;/strong&gt;      &lt;strong&gt;、dropwatch&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;dropwatch可以输出数据包是在哪个内核函数中丢失的：&lt;/p&gt;    &lt;p&gt;-&lt;/p&gt;    &lt;p&gt;Bash代码&lt;/p&gt;    &lt;p&gt;&lt;/p&gt;    &lt;ul&gt;&lt;/ul&gt;    &lt;pre&gt;      &lt;code&gt;[root@localhost~]# dropwatch -l kas&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Initalizingkallsyms db&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;dropwatch&amp;gt;start&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Enablingmonitoring...&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;Kernelmonitoring activated.&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;IssueCtrl-C to stop monitoring&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;1drops at skb_queue_purge+20 (0xffff000008708d3c)&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;2drops at __netif_receive_skb_core+504(0xffff00000871bd7c)&lt;/code&gt;      &lt;br /&gt;      &lt;code&gt;1drops at __netif_receive_skb_core+504(0xffff00000871bd7c)&lt;/code&gt;      &lt;br /&gt;&lt;/pre&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;&lt;/div&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62475-linux-%E7%BD%91%E7%BB%9C-%E4%B8%A2%E5%8C%85</guid>
      <pubDate>Thu, 27 Oct 2022 14:56:59 CST</pubDate>
    </item>
    <item>
      <title>Linux丢包故障的解决与思路 - Albert的博客 | Albert's Blog</title>
      <link>https://itindex.net/detail/62474-linux-%E4%B8%A2%E5%8C%85-albert</link>
      <description>&lt;div&gt;    &lt;h1&gt;Linux丢包故障的解决与思路&lt;/h1&gt;    &lt;h2&gt;前言&lt;/h2&gt;    &lt;p&gt;​		本文为大部分内容是转载:      &lt;a href="https://www.sdnlab.com/17530.html?sukey=3997c0719f151520fe14b6d2b703c7ea3889a1f21e7fc199d455cf8cdf7053345d52740536b2c1038eedca9ed28382f6"&gt;原文地址&lt;/a&gt;，和之前一样，在原文的基础上进行了一些格式的调整，包括一些错别字的修正，以及进行了一些博文链接的插入，以便于读者或者我自己更好的理解。&lt;/p&gt;    &lt;p&gt;​		我们使用      &lt;code&gt;Linux&lt;/code&gt;作为服务器操作系统时，为了达到高并发处理能力，充分利用机器性能，经常会进行一些内核参数的调整优化，但不合理的调整常常也会引起意想不到的其他问题，本文就一次      &lt;code&gt;Linux&lt;/code&gt;服务器丢包故障的处理过程，结合      &lt;code&gt;Linux&lt;/code&gt;内核参数说明和      &lt;code&gt;TCP/IP&lt;/code&gt;协议栈相关的理论，介绍一些常见的丢包故障定位方法和解决思路。&lt;/p&gt;    &lt;p&gt;​	    在开始之前，我们先用一张图解释 linux 系统接收网络报文的过程。&lt;/p&gt;    &lt;blockquote&gt;      &lt;ol&gt;        &lt;li&gt;首先网络报文通过物理网线发送到网卡&lt;/li&gt;        &lt;li&gt;网络驱动程序会把网络中的报文读出来放到 ring buffer 中，这个过程使用 DMA（Direct Memory Access），这个过程不需要 CPU 参与&lt;/li&gt;        &lt;li&gt;内核从 ring buffer 中读取报文进行处理，执行 IP 和 TCP/UDP 层的逻辑，最后把报文放到应用程序的 socket buffer 中&lt;/li&gt;        &lt;li&gt;应用程序从 socket buffer 中读取报文进行处理&lt;/li&gt;&lt;/ol&gt;&lt;/blockquote&gt;    &lt;p&gt;      &lt;img alt="image1" src="https://gitee.com/cclinuxer/blog_image/raw/master/image/1.jpg"&gt;&lt;/img&gt;&lt;/p&gt;    &lt;p&gt;​		在接收 UDP 报文的过程中，图中任何一个过程都可能会主动或者被动地把报文丢弃，因此丢包可能发生在网卡和驱动，也可能发生在系统和应用。之所以没有分析发送数据流程，一是因为发送流程和接收类似，只是方向相反；另外发送流程报文丢失的概率比接收小，只有在应用程序发送的报文速率大于内核和网卡处理速率时才会发生。本篇文章假定机器只有一个名字为 eth0 的 interface，如果有多个 interface 或者 interface 的名字不是 eth0，请按照实际情况进行分析。&lt;/p&gt;    &lt;p&gt;      &lt;code&gt;NOTE：文中出现的 RX（receive） 表示接收报文，TX（transmit） 表示发送报文。&lt;/code&gt;&lt;/p&gt;    &lt;h2&gt;一、问题现象&lt;/h2&gt;    &lt;p&gt;​			本次故障的反馈现象是：从办公网访问公网服务器不稳定，服务器某些端口访问经常超时，但      &lt;code&gt;Ping&lt;/code&gt;测试显示客户端与服务器的链路始终是稳定低延迟的。通过在服务器端抓包，发现还有几个特点：&lt;/p&gt;    &lt;blockquote&gt;      &lt;ul&gt;        &lt;li&gt;从办公网访问服务器有多个客户端，是同一个出口IP，有少部分是始终能够稳定连接的，另一部分间歇访问超时或延迟很高&lt;/li&gt;        &lt;li&gt;同一时刻的访问，无论哪个客户端的数据包先到达，服务端会及时处理部分客户端的SYN请求，对另一部分客户端的SYN包“视而不见”，如tcpdump数据所示，源端口为56909的SYN请求没有得到响应，同一时间源端口为50212的另一客户端SYN请求马上得到响应。&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ sudo tcpdump -i eth0 port 22 and &amp;quot;tcp[tcpflags] &amp;amp; (tcp-syn) != 0&amp;quot;
18:56:37.404603 IP CLIENT.56909 &amp;gt; SERVER.22: Flags [S], seq 1190606850, win 29200, options [mss 1448,sackOK,TS val 198321481 ecr 0,nop,wscale 7], length 0
18:56:38.404582 IP CLIENT.56909 &amp;gt; SERVER.22: Flags [S], seq 1190606850, win 29200, options [mss 1448,sackOK,TS val 198321731 ecr 0,nop,wscale 7], length 0
18:56:40.407289 IP CLIENT.56909 &amp;gt; SERVER.22: Flags [S], seq 1190606850, win 29200, options [mss 1448,sackOK,TS val 198322232 ecr 0,nop,wscale 7], length 0
18:56:44.416108 IP CLIENT.56909 &amp;gt; SERVER.22: Flags [S], seq 1190606850, win 29200, options [mss 1448,sackOK,TS val 198323234 ecr 0,nop,wscale 7], length 0
18:56:45.100033 IP CLIENT.50212 &amp;gt; SERVER.22: Flags [S], seq 4207350463, win 65535, options [mss 1366,nop,wscale 5,nop,nop,TS val 821068631 ecr 0,sackOK,eol], length 0
18:56:45.100110 IP SERVER.22 &amp;gt; CLIENT.50212: Flags [S.], seq 1281140899, ack 4207350464, win 27960, options [mss 1410,sackOK,TS val 1709997543 ecr 821068631,nop,wscale 7], length 0
18:56:52.439086 IP CLIENT.56909 &amp;gt; SERVER.22: Flags [S], seq 1190606850, win 29200, options [mss 1448,sackOK,TS val 198325240 ecr 0,nop,wscale 7], length 0
18:57:08.472825 IP CLIENT.56909 &amp;gt; SERVER.22: Flags [S], seq 1190606850, win 29200, options [mss 1448,sackOK,TS val 198329248 ecr 0,nop,wscale 7], length 0
18:57:40.535621 IP CLIENT.56909 &amp;gt; SERVER.22: Flags [S], seq 1190606850, win 29200, options [mss 1448,sackOK,TS val 198337264 ecr 0,nop,wscale 7], length 0
18:57:40.535698 IP SERVER.22 &amp;gt; CLIENT.56909: Flags [S.], seq 3621462255, ack 1190606851, win 27960, options [mss 1410,sackOK,TS val 1710011402ecr 198337264,nop,wscale 7], length 0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;​			如果能排除网卡或者驱动丢包可能的话，      &lt;code&gt;linux&lt;/code&gt;系统丢包的原因相对就很多，常见的有：      &lt;code&gt;UDP&lt;/code&gt;报文错误、防火墙、      &lt;code&gt;UDP buffer size&lt;/code&gt;不足、系统负载过高等，这里对这些丢包原因进行分析。&lt;/p&gt;    &lt;h2&gt;二、名词解释&lt;/h2&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;# ifconfig em2
em2       Link encap:Ethernet  HWaddr AC::3D:A9::0D
          inet addr:211.211.211.211  Bcast:211.211.211.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:  Metric:
          RX packets: errors: dropped: overruns: frame:
          TX packets: errors: dropped: overruns: carrier:
          collisions: txqueuelen:
          RX bytes: ( (1.3 TiB)
          Memory:94b00000-94b20000&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;ul&gt;      &lt;li&gt;        &lt;p&gt;          &lt;code&gt;RX errors&lt;/code&gt;: 表示总的收包的错误数量，这包括 too-long-frames 错误，Ring Buffer 溢出错误，crc 校验错误，帧同步错误，fifo overruns 以及 missed pkg 等等。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;          &lt;code&gt;RX dropped&lt;/code&gt;: 表示数据包已经进入了 Ring Buffer，但是由于          &lt;strong&gt;内存不够&lt;/strong&gt;等系统原因，导致在拷贝到内存的过程中被丢弃。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;RX          &lt;code&gt;overruns&lt;/code&gt;: 表示了 fifo 的          &lt;code&gt;overruns&lt;/code&gt;，这是由于 Ring Buffer(aka Driver Queue) 传输的 IO 大于 kernel 能够处理的 IO 导致的，而 Ring Buffer 则是指在发起 IRQ 请求之前的那块 buffer。很明显，overruns 的增大意味着数据包没到 Ring Buffer 就被网卡物理层给丢弃了，而 CPU 无法即使的处理中断是造成 Ring Buffer 满的原因之一，上面那台有问题的机器就是因为          &lt;code&gt;interruprs&lt;/code&gt;分布的不均匀(都压在 core0)，没有做          &lt;code&gt;affinity&lt;/code&gt;而造成的丢包。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;          &lt;code&gt;RX frame&lt;/code&gt;: 表示          &lt;code&gt;misaligned&lt;/code&gt;的          &lt;code&gt;frames&lt;/code&gt;&lt;/p&gt;        &lt;p&gt;对于 TX 的来说，出现上述 counter 增大的原因主要包括 aborted transmission, errors due to carrirer, fifo error, heartbeat erros 以及 windown error，而 collisions 则表示由于 CSMA/CD 造成的传输中断。&lt;/p&gt;        &lt;p&gt;          &lt;code&gt;dropped&lt;/code&gt;与          &lt;code&gt;overruns&lt;/code&gt;的区别&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;code&gt;dropped&lt;/code&gt;：表示这个数据包已经进入到网卡的接收缓存    &lt;code&gt;fifo&lt;/code&gt;队列，并且开始被系统中断处理准备进行数据包拷贝（从网卡缓存    &lt;code&gt;fifo&lt;/code&gt;队列拷贝到系统内存），但由于此时的系统原因（比如内存不够等）导致这个数据包被丢掉，即这个数据包被    &lt;code&gt;Linux&lt;/code&gt;系统丢掉。    &lt;p&gt;​      &lt;code&gt;overruns&lt;/code&gt;：表示这个数据包还没有被进入到网卡的接收缓存fifo队列就被丢掉，因此此时网卡的fifo是满的。为什么fifo会是满的？因为系统繁忙，来不及响应网卡中断，导致网卡里的数据包没有及时的拷贝到系统内存，fifo是满的就导致后面的数据包进不来，即这个数据包被网卡硬件丢掉。所以，个人觉得遇到      &lt;code&gt;overruns&lt;/code&gt;非0，需要检测cpu负载与cpu中断情况&lt;/p&gt;    &lt;h2&gt;三、排查过程&lt;/h2&gt;    &lt;h3&gt;3.1、丢包的可能性&lt;/h3&gt;    &lt;p&gt;服务器能正常接收到数据包，问题可以限定在      &lt;strong&gt;两种可能&lt;/strong&gt;：&lt;/p&gt;    &lt;p&gt;部分客户端发出的数据包本身异常；&lt;/p&gt;    &lt;p&gt;服务器处理部分客户端的数据包时触发了某种机制丢弃了数据包。因为出问题的客户端能够正常访问公网上其他服务，后者的可能性更大。&lt;/p&gt;    &lt;p&gt;有哪些情况会导致Linux服务器丢弃数据包？&lt;/p&gt;    &lt;h3&gt;3.2 、确认有 UDP 丢包发生&lt;/h3&gt;    &lt;p&gt;要查看网卡是否有丢包，可以使用      &lt;code&gt;ethtool -S eth0&lt;/code&gt;查看，在输出中查找 bad 或者 drop 对应的字段是否有数据，在正常情况下，这些字段对应的数字应该都是 0。如果看到对应的数字在不断增长，就说明网卡有丢包。另外一个查看网卡丢包数据的命令是      &lt;code&gt;ifconfig&lt;/code&gt;，它的输出中会有 RX(receive 接收报文)和 TX（transmit 发送报文）的统计数据：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;~# ifconfig eth0
...
        RX packets 3553389376  bytes 2599862532475 (2.3 TiB)
        RX errors 0  dropped 1353  overruns 0  frame 0
        TX packets 3479495131  bytes 3205366800850 (2.9 TiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;此外，      &lt;code&gt;linux&lt;/code&gt;系统也提供了各个网络协议的丢包信息，可以使用      &lt;code&gt;netstat -s&lt;/code&gt;命令查看，加上 –udp 可以只看 UDP 相关的报文数据：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;[root@holodesk02 GOD]# netstat -s -u
IcmpMsg:
    InType0: 3
    InType3: 1719356
    InType8: 13
    InType11: 59
    OutType0: 13
    OutType3: 1737641
    OutType8: 10
    OutType11: 263
Udp:
    517488890 packets received
    2487375 packets to unknown port received.
    47533568 packet receive errors
    147264581 packets sent
    12851135 receive buffer errors
    0 send buffer errors
UdpLite:
IpExt:
    OutMcastPkts: 696
    InBcastPkts: 2373968
    InOctets: 4954097451540
    OutOctets: 5538322535160
    OutMcastOctets: 79632
    InBcastOctets: 934783053
    InNoECTPkts: 5584838675&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;对于上面的输出，关注下面的信息来查看 UDP 丢包的情况：&lt;/p&gt;    &lt;ul&gt;      &lt;li&gt;        &lt;code&gt;packet receive errors&lt;/code&gt;不为空，并且在一直增长说明系统有 UDP 丢包&lt;/li&gt;      &lt;li&gt;        &lt;code&gt;packets to unknown port received&lt;/code&gt;表示系统接收到的 UDP 报文所在的目标端口没有应用在监听，一般是服务没有启动导致的，并不会造成严重的问题&lt;/li&gt;      &lt;li&gt;        &lt;code&gt;receive buffer errors&lt;/code&gt;表示因为 UDP 的接收缓存太小导致丢包的数量&lt;/li&gt;&lt;/ul&gt;    &lt;p&gt;      &lt;strong&gt;NOTE： 并不是丢包数量不为零就有问题，对于 UDP 来说，如果有少量的丢包很可能是预期的行为，比如丢包率（丢包数量/接收报文数量）在万分之一甚至更低。&lt;/strong&gt;&lt;/p&gt;    &lt;h3&gt;3.2 、确认网卡或者驱动丢包&lt;/h3&gt;    &lt;p&gt;之前讲过，如果      &lt;code&gt;ethtool -S eth0&lt;/code&gt;中有      &lt;code&gt;rx_***_errors&lt;/code&gt;那么很可能是网卡有问题，导致系统丢包，需要联系服务器或者网卡供应商进行处理。&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;# ethtool -S eth0 | grep rx_ | grep errors
     rx_crc_errors: 0
     rx_missed_errors: 0
     rx_long_length_errors: 0
     rx_short_length_errors: 0
     rx_align_errors: 0
     rx_errors: 0
     rx_length_errors: 0
     rx_over_errors: 0
     rx_frame_errors: 0
     rx_fifo_errors: 0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;      &lt;code&gt;netstat -i&lt;/code&gt;也会提供每个网卡的接发报文以及丢包的情况，正常情况下输出中 error 或者 drop 应该为 0。&lt;/p&gt;    &lt;p&gt;如果硬件或者驱动没有问题，一般网卡丢包是因为设置的缓存区（ring buffer）太小，可以使用 ethtool 命令查看和设置网卡的 ring buffer。&lt;/p&gt;    &lt;p&gt;      &lt;code&gt;ethtool -g&lt;/code&gt;可以查看某个网卡的 ring buffer，比如下面的例子&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;# ethtool -g eth0
Ring parameters for eth0:
Pre-set maximums:
RX:		4096
RX Mini:	0
RX Jumbo:	0
TX:		4096
Current hardware settings:
RX:		256
RX Mini:	0
RX Jumbo:	0
TX:		256&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;Pre-set 表示网卡最大的      &lt;code&gt;ring buffer&lt;/code&gt;值，可以使用      &lt;code&gt;ethtool -G eth0 rx 8192&lt;/code&gt;设置它的值。&lt;/p&gt;    &lt;h3&gt;3.3 、UDP 报文错误丢包&lt;/h3&gt;    &lt;p&gt;​	如果在传输过程中UDP 报文被修改，会导致 checksum 错误，或者长度错误，linux 在接收到 UDP 报文时会对此进行校验，一旦发明错误会把报文丢弃。&lt;/p&gt;    &lt;p&gt;如果希望 UDP 报文 checksum 及时有错也要发送给应用程序，可以在通过 socket 参数禁用 UDP checksum 检查：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;int disable = 1;
setsockopt(sock_fd, SOL_SOCKET, SO_NO_CHECK, (void*)&amp;amp;disable, sizeof(disable)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;h3&gt;3.4 、UDP buffer size 不足丢包&lt;/h3&gt;    &lt;p&gt;​	linux 系统在接收报文之后，会把报文保存到缓存区中。因为缓存区的大小是有限的，如果出现 UDP 报文过大（超过缓存区大小或者 MTU 大小）、接收到报文的速率太快，都可能导致 linux 因为缓存满而直接丢包的情况。&lt;/p&gt;    &lt;p&gt;在系统层面，linux 设置了 receive buffer 可以配置的最大值，可以在下面的文件中查看，一般是 linux 在启动的时候会根据内存大小设置一个初始值。&lt;/p&gt;    &lt;blockquote&gt;      &lt;ul&gt;        &lt;li&gt;/proc/sys/net/core/rmem_max：允许设置的 receive buffer 最大值&lt;/li&gt;        &lt;li&gt;/proc/sys/net/core/rmem_default：默认使用的 receive buffer 值&lt;/li&gt;        &lt;li&gt;/proc/sys/net/core/wmem_max：允许设置的 send buffer 最大值&lt;/li&gt;        &lt;li&gt;/proc/sys/net/core/wmem_dafault：默认使用的 send buffer 最大值&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;    &lt;p&gt;但是这些初始值并不是为了应对大流量的 UDP 报文，如果应用程序接收和发送 UDP 报文非常多，需要将这个值调大。可以使用 sysctl 命令让它立即生效：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;sysctl -w net.core.rmem_max=26214400 # 设置为 25M，临时生效，下次启动消失&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;也可以修改      &lt;code&gt;/etc/sysctl.conf&lt;/code&gt;中对应的参数在下次启动时让参数保持生效。&lt;/p&gt;    &lt;p&gt;如果报文报文过大，可以在发送方对数据进行分割，保证每个报文的大小在 MTU 内。&lt;/p&gt;    &lt;p&gt;另外一个可以配置的参数是      &lt;code&gt;netdev_max_backlog&lt;/code&gt;，它表示 linux 内核从网卡驱动中读取报文后可以缓存的报文数量，默认是 1000，可以调大这个值，比如设置成 2000：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;sudo sysctl -w net.core.netdev_max_backlog=2000&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;h3&gt;3.5 、系统负载过高丢包&lt;/h3&gt;    &lt;p&gt;​	系统 CPU、memory、IO 负载过高都有可能导致网络丢包&lt;/p&gt;    &lt;blockquote&gt;      &lt;p&gt;​	比如 CPU 如果负载过高，系统没有时间进行报文的 checksum 计算、复制内存等操作，从而导致网卡或者 socket buffer 处丢包；&lt;/p&gt;      &lt;p&gt;​	memory 负载过高，会应用程序处理过慢，无法及时处理报文；&lt;/p&gt;      &lt;p&gt;​	IO 负载过高，CPU 都用来响应        &lt;code&gt;IO wait&lt;/code&gt;，没有时间处理缓存中的        &lt;code&gt;UDP&lt;/code&gt;报文。&lt;/p&gt;&lt;/blockquote&gt;    &lt;p&gt;      &lt;code&gt;linux&lt;/code&gt;系统本身就是相互关联的系统，任何一个组件出现问题都有可能影响到其他组件的正常运行。对于系统负载过高，要么是应用程序有问题，要么是系统不足。对于前者需要及时发现，debug 和修复；对于后者，也要及时发现并扩容。&lt;/p&gt;    &lt;h3&gt;3.6 、应用丢包&lt;/h3&gt;    &lt;p&gt;​	上面提到系统的      &lt;code&gt;UDP buffer size&lt;/code&gt;，调节的 sysctl 参数只是系统允许的最大值，每个应用程序在创建 socket 时需要设置自己      &lt;code&gt;socket buffer size&lt;/code&gt;的值。&lt;/p&gt;    &lt;p&gt;      &lt;code&gt;linux&lt;/code&gt;系统会把接受到的报文放到      &lt;code&gt;socket&lt;/code&gt;的      &lt;code&gt;buffer&lt;/code&gt;中，应用程序从 buffer 中不断地读取报文。所以这里有两个和应用有关的因素会影响是否会丢包：socket buffer size 大小以及应用程序读取报文的速度。&lt;/p&gt;    &lt;p&gt;​	对于第一个问题，可以在应用程序初始化      &lt;code&gt;socket&lt;/code&gt;的时候设置      &lt;code&gt;socket receive buffer&lt;/code&gt;的大小，比如下面的代码把 socket buffer 设置为 20MB：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;uint64_t receive_buf_size = 20*1024*1024;  //20 MB
setsockopt(socket_fd, SOL_SOCKET, SO_RCVBUF, &amp;amp;receive_buf_size, sizeof(receive_buf_size));&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;​	如果不是自己编写和维护的程序，修改应用代码是件不好甚至不太可能的事情。很多应用程序会提供配置参数来调节这个值，请参考对应的官方文档；如果没有可用的配置参数，只能给程序的开发者提 issue 了。很明显，增加应用的 receive buffer 会减少丢包的可能性，但同时会导致应用使用更多的内存，所以需要谨慎使用。另外一个因素是应用读取 buffer 中报文的速度，对于应用程序来说，      &lt;strong&gt;处理报文应该采取异步的方式&lt;/strong&gt;&lt;/p&gt;    &lt;h3&gt;3.7 、包丢在什么地方&lt;/h3&gt;    &lt;p&gt;想要详细了解 linux 系统在执行哪个函数时丢包的话，可以使用      &lt;code&gt;dropwatch&lt;/code&gt;工具，它监听系统丢包信息，并打印出丢包发生的函数地址：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;# dropwatch -l kas
Initalizing kallsyms db
dropwatch&amp;gt; start
Enabling monitoring...
Kernel monitoring activated.
Issue Ctrl-C to stop monitoring

1 drops at tcp_v4_do_rcv+cd (0xffffffff81799bad)
10 drops at tcp_v4_rcv+80 (0xffffffff8179a620)
1 drops at sk_stream_kill_queues+57 (0xffffffff81729ca7)
4 drops at unix_release_sock+20e (0xffffffff817dc94e)
1 drops at igmp_rcv+e1 (0xffffffff817b4c41)
1 drops at igmp_rcv+e1 (0xffffffff817b4c41)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;通过这些信息，找到对应的内核代码处，就能知道内核在哪个步骤中把报文丢弃，以及大致的丢包原因。如果      &lt;code&gt;dropwatch&lt;/code&gt;信息输出过多，或者不好用，可以阅读下我的另外两篇博文：      &lt;a href="https://cclinuxer.gitee.io/2020/08/Linux%E5%86%85%E6%A0%B8%E8%B0%83%E8%AF%95%E4%B9%8Biptables%E8%A7%82%E5%AF%9F%E6%95%B0%E6%8D%AE%E5%8C%85%E6%B5%81%E5%90%91/"&gt;iptables观察数据包流向&lt;/a&gt;、      &lt;a href="https://cclinuxer.gitee.io/2020/08/Linux%E5%86%85%E6%A0%B8%E8%B0%83%E8%AF%95%E4%B9%8Bnetfilter%E5%87%BD%E6%95%B0%E5%AE%9A%E4%BD%8D/"&gt;定位netfilter丢包&lt;/a&gt;。这两种方式可以解决绝大部分二三层的数据丢包问题。也可以在      &lt;code&gt;kfree_skb&lt;/code&gt;处编写小工具，实现过滤数据包打印栈回溯信息（ebpf可能是一种实现方式、我自己没有做过尝试，后续有时间会做一个）。&lt;/p&gt;    &lt;p&gt;此外，还可以使用 linux perf 工具监听 kfree_skb（把网络报文丢弃时会调用该函数） 事件的发生：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;sudo perf record -g -a -e skb:kfree_skb
sudo perf script&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;关于 perf 命令的使用和解读，网上有很多文章可以参考。&lt;/p&gt;    &lt;h3&gt;3.8 、关于UDP丢包的总结&lt;/h3&gt;    &lt;ul&gt;      &lt;li&gt;UDP 本身就是无连接不可靠的协议，适用于报文偶尔丢失也不影响程序状态的场景，比如视频、音频、游戏、监控等。对报文可靠性要求比较高的应用不要使用 UDP，推荐直接使用 TCP。当然，也可以在应用层做重试、去重保证可靠性&lt;/li&gt;      &lt;li&gt;如果发现服务器丢包，首先通过监控查看系统负载是否过高，先想办法把负载降低再看丢包问题是否消失&lt;/li&gt;      &lt;li&gt;如果系统负载过高，UDP 丢包是没有有效解决方案的。如果是应用异常导致 CPU、memory、IO 过高，请及时定位异常应用并修复；如果是资源不够，监控应该能及时发现并快速扩容&lt;/li&gt;      &lt;li&gt;对于系统大量接收或者发送 UDP 报文的，可以通过调节系统和程序的        &lt;code&gt;socket buffer size&lt;/code&gt;来降低丢包的概率&lt;/li&gt;      &lt;li&gt;应用程序在处理 UDP 报文时，要采用异步方式，在两次接收报文之间不要有太多的处理逻辑&lt;/li&gt;&lt;/ul&gt;    &lt;h3&gt;3.9、防火墙拦截&lt;/h3&gt;    &lt;p&gt;​	服务器端口无法连接，通常就是查看防火墙配置了，虽然这里已经确认同一个出口IP的客户端有的能够正常访问，但也不排除配置了DROP特定端口范围的可能性。如果系统防火墙丢包，表现的行为一般是所有的 UDP 报文都无法正常接收，当然不排除防火墙只 drop 一部分报文的可能性。如果遇到丢包比率非常大的情况，请先检查防火墙规则，保证防火墙没有主动      &lt;code&gt;drop UDP&lt;/code&gt;报文。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何确认&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;查看      &lt;code&gt;iptables filter&lt;/code&gt;表，确认是否有相应规则会导致此丢包行为：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ sudo iptables-save -t filter&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;这里容易排除防火墙拦截的可能性。      &lt;a href="https://cclinuxer.gitee.io/2020/08/Linux%E5%86%85%E6%A0%B8%E8%B0%83%E8%AF%95%E4%B9%8Biptables%E8%A7%82%E5%AF%9F%E6%95%B0%E6%8D%AE%E5%8C%85%E6%B5%81%E5%90%91/"&gt;iptables观察数据包流向&lt;/a&gt;、      &lt;a href="https://cclinuxer.gitee.io/2020/08/Linux%E5%86%85%E6%A0%B8%E8%B0%83%E8%AF%95%E4%B9%8Bnetfilter%E5%87%BD%E6%95%B0%E5%AE%9A%E4%BD%8D/"&gt;定位netfilter丢包&lt;/a&gt;。&lt;/p&gt;    &lt;h3&gt;3.10、连接跟踪表溢出&lt;/h3&gt;    &lt;p&gt;​		除了防火墙本身配置DROP规则外，与防火墙有关的还有连接跟踪表nf_conntrack，Linux为每个经过内核网络栈的数据包，生成一个新的连接记录项，当服务器处理的连接过多时，连接跟踪表被打满，服务器会丢弃新建连接的数据包。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何确认&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;通过dmesg可以确认是否有该情况发生：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ dmesg |grep nf_conntrack&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;如果输出值中有“nf_conntrack: table full, dropping packet”，说明服务器nf_conntrack表已经被打满。&lt;/p&gt;    &lt;p&gt;通过/proc文件系统查看nf_conntrack表实时状态：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;# 查看nf_conntrack表最大连接数
$ cat /proc/sys/net/netfilter/nf_conntrack_max
65536
# 查看nf_conntrack表当前连接数
$ cat /proc/sys/net/netfilter/nf_conntrack_count
7611&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;当前连接数远没有达到跟踪表最大值，排除这个因素。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何解决&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;如果确认服务器因连接跟踪表溢出而开始丢包，首先需要查看具体连接判断是否正遭受DOS攻击，如果是正常的业务流量造成，可以考虑调整nf_conntrack的参数：&lt;/p&gt;    &lt;p&gt;      &lt;code&gt;nf_conntrack_max&lt;/code&gt;决定连接跟踪表的大小，默认值是65535，可以根据系统内存大小计算一个合理值：      &lt;code&gt;CONNTRACK_MAX = RAMSIZE(in bytes)/16384/(ARCH/32)&lt;/code&gt;，如32G内存可以设置1048576；&lt;/p&gt;    &lt;p&gt;      &lt;code&gt;nf_conntrack_buckets&lt;/code&gt;决定存储      &lt;code&gt;conntrack&lt;/code&gt;条目的哈希表大小，默认值是      &lt;code&gt;nf_conntrack_max&lt;/code&gt;的1/4，延续这种计算方式：      &lt;code&gt;BUCKETS = CONNTRACK_MAX/4&lt;/code&gt;，如32G内存可以设置262144；&lt;/p&gt;    &lt;p&gt;      &lt;code&gt;nf_conntrack_tcp_timeout_established&lt;/code&gt;决定ESTABLISHED状态连接的超时时间，默认值是5天，可以缩短到1小时，即3600。&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ sysctl -w net.netfilter.nf_conntrack_max=1048576
$ sysctl -w net.netfilter.nf_conntrack_buckets=262144
$ sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;h3&gt;3.11、Ring Buffer溢出&lt;/h3&gt;    &lt;p&gt;排除了防火墙的因素，我们从底向上来看Linux接收数据包的处理过程，首先是网卡驱动层。如下图所示，物理介质上的数据帧到达后首先由NIC（网络适配器）读取，写入设备内部缓冲区Ring Buffer中，再由中断处理程序触发Softirq从中消费，Ring Buffer的大小因网卡设备而异。当网络数据包到达（生产）的速率快于内核处理（消费）的速率时，Ring Buffer很快会被填满，新来的数据包将被丢弃。&lt;/p&gt;    &lt;p&gt;      &lt;img alt="image2" src="https://gitee.com/cclinuxer/blog_image/raw/master/image/2.png"&gt;&lt;/img&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何确认&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;通过ethtool或/proc/net/dev可以查看因Ring Buffer满而丢弃的包统计，在统计项中以fifo标识：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ ethtool -S eth0|grep rx_fifo
rx_fifo_errors: 0
$ cat /proc/net/dev
Inter-|   Receive                                                |  Transmit

 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
  eth0: 17253386680731 42839525880    0    0    0     0          0 244182022 14879545018057 41657801805    0    0    0     0       0         0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;可以看到服务器的接收方向的fifo丢包数并没有增加，这里自然也排除这个原因。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何解决&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;如果发现服务器上某个网卡的fifo数持续增大，可以去确认CPU中断是否分配均匀，也可以尝试增加Ring Buffer的大小，通过ethtool可以查看网卡设备Ring Buffer最大值，修改Ring Buffer当前设置：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;# 查看eth0网卡Ring Buffer最大值和当前设置
$ ethtool -g eth0
Ring parameters for eth0:

Pre-set maximums:
RX:     4096   
RX Mini:    0
RX Jumbo:   0
TX:     4096   
Current hardware settings:
RX:     1024   
RX Mini:    0
RX Jumbo:   0
TX:     1024   
# 修改网卡eth0接收与发送硬件缓存区大小
$ ethtool -G eth0 rx 4096 tx 4096
Pre-set maximums:
RX:     4096   
RX Mini:    0
RX Jumbo:   0
TX:     4096   
Current hardware settings:
RX:     4096   
RX Mini:    0
RX Jumbo:   0
TX:     4096&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;h3&gt;3.12 netdev_max_backlog溢出&lt;/h3&gt;    &lt;p&gt;​      &lt;code&gt;netdev_max_backlog&lt;/code&gt;是内核从NIC收到包后，交由协议栈（如IP、TCP）处理之前的缓冲队列。每个CPU核都有一个      &lt;code&gt;backlog&lt;/code&gt;队列，与      &lt;code&gt;Ring Buffer&lt;/code&gt;同理，当接收包的速率大于内核协议栈处理的速率时，CPU的      &lt;code&gt;backlog&lt;/code&gt;队列不断增长，当达到设定的      &lt;code&gt;netdev_max_backlog&lt;/code&gt;值时，数据包将被丢弃。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何确认&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;通过查看/proc/net/softnet_stat可以确定是否发生了netdev backlog队列溢出：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ cat /proc/net/softnet_stat
01a7b464 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
01d4d71f 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
0349e798 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
017e0826 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;其中： 每一行代表每个CPU核的状态统计，从CPU0依次往下； 每一列代表一个CPU核的各项统计：第一列代表中断处理程序收到的包总数；第二列即代表由于netdev_max_backlog队列溢出而被丢弃的包总数。 从上面的输出可以看出，这台服务器统计中，并没有因为netdev_max_backlog导致的丢包。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何解决&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;netdev_max_backlog的默认值是1000，在高速链路上，可能会出现上述第二列统计不为0的情况，可以通过修改内核参数net.core.netdev_max_backlog来解决：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ sysctl -w net.core.netdev_max_backlog=2000&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;h3&gt;3.13、反向路由过滤&lt;/h3&gt;    &lt;p&gt;反向路由过滤机制是Linux通过反向路由查询，检查收到的数据包源IP是否可路由（Loose mode）、是否最佳路由（Strict mode），如果没有通过验证，则丢弃数据包，设计的目的是防范IP地址欺骗攻击。rp_filter提供了&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;三种模式供配置：&lt;/strong&gt;&lt;/p&gt;    &lt;ul&gt;      &lt;li&gt;0 - 不验证&lt;/li&gt;      &lt;li&gt;1 - RFC3704定义的严格模式：对每个收到的数据包，查询反向路由，如果数据包入口和反向路由出口不一致，则不通过&lt;/li&gt;      &lt;li&gt;2 - RFC3704定义的松散模式：对每个收到的数据包，查询反向路由，如果任何接口都不可达，则不通过&lt;/li&gt;&lt;/ul&gt;    &lt;p&gt;      &lt;strong&gt;如何确认&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;查看当前rp_filter策略配置：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ cat /proc/sys/net/ipv4/conf/eth0/rp_filter&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;如果这里设置为1，就需要查看主机的网络环境和路由策略是否可能会导致客户端的入包无法通过反向路由验证了。&lt;/p&gt;    &lt;p&gt;从原理来看这个机制工作在网络层，因此，如果客户端能够Ping通服务器，就能够排除这个因素了。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何解决&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;根据实际网络环境将rp_filter设置为0或2：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ sysctl -w net.ipv4.conf.all.rp_filter=2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;或&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ sysctl -w net.ipv4.conf.eth0.rp_filter=2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;h3&gt;3.14 半连接队列溢出&lt;/h3&gt;    &lt;p&gt;​		半连接队列指的是TCP传输中服务器收到SYN包但还未完成三次握手的连接队列，队列大小由内核参数tcp_max_syn_backlog定义。当服务器保持的半连接数量达到      &lt;code&gt;tcp_max_syn_backlog&lt;/code&gt;后，内核将会丢弃新来的SYN包。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何确认&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;通过dmesg可以确认是否有该情况发生：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ dmesg | grep &amp;quot;TCP: drop open request from&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;半连接队列的连接数量可以通过netstat统计SYN_RECV状态的连接得知&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ netstat -ant|grep SYN_RECV|wc -l
0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;大多数情况下这个值应该是0或很小，因为半连接状态从第一次握手完成时进入，第三次握手完成后退出，正常的网络环境中这个过程发生很快，如果这个值较大，服务器极有可能受到了SYN Flood攻击。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何解决&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;      &lt;code&gt;tcp_max_syn_backlog&lt;/code&gt;的默认值是256，通常推荐内存大于128MB的服务器可以将该值调高至1024，内存小于32MB的服务器调低到128，同样，该参数通过sysctl修改：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ sysctl -w net.ipv4.tcp_max_syn_backlog=1024&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;另外，上述行为受到内核参数      &lt;code&gt;tcp_syncookies&lt;/code&gt;的影响，若启用      &lt;code&gt;syncookie&lt;/code&gt;机制，当半连接队列溢出时，并不会直接丢弃SYN包，而是回复带有      &lt;code&gt;syncookie&lt;/code&gt;的SYC+ACK包，设计的目的是防范SYN Flood造成正常请求服务不可用。&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ sysctl -w net.ipv4.tcp_syncookies=1
net.ipv4.tcp_syncookies = 1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;h3&gt;3.15 PAWS&lt;/h3&gt;    &lt;p&gt;PAWS全名Protect Againest Wrapped Sequence numbers，目的是解决在高带宽下，TCP序列号在一次会话中可能被重复使用而带来的问题。&lt;/p&gt;    &lt;p&gt;      &lt;img alt="image2" src="https://jermine.vdo.pub/img/linux/3.png"&gt;&lt;/img&gt;&lt;/p&gt;    &lt;p&gt;如上图所示，客户端发送的序列号为A的数据包A1因某些原因在网络中“迷路”，在一定时间没有到达服务端，客户端超时重传序列号为A的数据包A2，接下来假设带宽足够，传输用尽序列号空间，重新使用A，此时服务端等待的是序列号为A的数据包A3，而恰巧此时前面“迷路”的A1到达服务端，如果服务端仅靠序列号A就判断数据包合法，就会将错误的数据传递到用户态程序，造成程序异常。&lt;/p&gt;    &lt;p&gt;PAWS要解决的就是上述问题，它依赖于timestamp机制，理论依据是：在一条正常的TCP流中，按序接收到的所有TCP数据包中的timestamp都应该是单调非递减的，这样就能判断那些timestamp小于当前TCP流已处理的最大timestamp值的报文是延迟到达的重复报文，可以予以丢弃。在上文的例子中，服务器已经处理数据包Z，而后到来的A1包的timestamp必然小于Z包的timestamp，因此服务端会丢弃迟到的A1包，等待正确的报文到来。&lt;/p&gt;    &lt;p&gt;PAWS机制的实现关键是内核保存了Per-Connection的最近接收时间戳，如果加以改进，就可以用来优化服务器TIME_WAIT状态的快速回收。&lt;/p&gt;    &lt;p&gt;TIME_WAIT状态是TCP四次挥手中主动关闭连接的一方需要进入的最后一个状态，并且通常需要在该状态保持2*MSL（报文最大生存时间），它存在的意义有两个：&lt;/p&gt;    &lt;p&gt;1.可靠地实现TCP全双工连接的关闭：关闭连接的四次挥手过程中，最终的ACK由主动关闭连接的一方（称为A）发出，如果这个ACK丢失，对端（称为B）将重发FIN，如果A不维持连接的TIME_WAIT状态，而是直接进入CLOSED，则无法重传ACK，B端的连接因此不能及时可靠释放。&lt;/p&gt;    &lt;p&gt;2.等待“迷路”的重复数据包在网络中因生存时间到期消失：通信双方A与B，A的数据包因“迷路”没有及时到达B，A会重发数据包，当A与B完成传输并断开连接后，如果A不维持TIME_WAIT状态2      &lt;em&gt;MSL时间，便有可能与B再次建立相同源端口和目的端口的“新连接”，而前一次连接中“迷路”的报文有可能在这时到达，并被B接收处理，造成异常，维持2&lt;/em&gt;MSL的目的就是等待前一次连接的数据包在网络中消失。&lt;/p&gt;    &lt;p&gt;TIME_WAIT状态的连接需要占用服务器内存资源维持，Linux内核提供了一个参数来控制TIME_WAIT状态的快速回收：tcp_tw_recycle，它的理论依据是：&lt;/p&gt;    &lt;p&gt;在PAWS的理论基础上，如果内核保存Per-Host的最近接收时间戳，接收数据包时进行时间戳比对，就能避免TIME_WAIT意图解决的第二个问题：前一个连接的数据包在新连接中被当做有效数据包处理的情况。这样就没有必要维持TIME_WAIT状态2*MSL的时间来等待数据包消失，仅需要等待足够的RTO（超时重传），解决ACK丢失需要重传的情况，来达到快速回收TIME_WAIT状态连接的目的。&lt;/p&gt;    &lt;p&gt;但上述理论在多个客户端使用NAT访问服务器时会产生新的问题：同一个NAT背后的多个客户端时间戳是很难保持一致的（timestamp机制使用的是系统启动相对时间），对于服务器来说，两台客户端主机各自建立的TCP连接表现为同一个对端IP的两个连接，按照Per-Host记录的最近接收时间戳会更新为两台客户端主机中时间戳较大的那个，而时间戳相对较小的客户端发出的所有数据包对服务器来说都是这台主机已过期的重复数据，因此会直接丢弃。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何确认&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;通过netstat可以得到因PAWS机制timestamp验证被丢弃的数据包统计：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ netstat -s |grep -e &amp;quot;passive connections rejected because of time stamp&amp;quot; -e &amp;quot;packets rejects in established connections because of timestamp”
387158 passive connections rejected because of time stamp
825313 packets rejects in established connections because of timestamp&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;通过sysctl查看是否启用了tcp_tw_recycle及tcp_timestamp:&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ sysctl net.ipv4.tcp_tw_recycle
net.ipv4.tcp_tw_recycle = 1
$ sysctl net.ipv4.tcp_timestamps
net.ipv4.tcp_timestamps = 1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;这次问题正是因为服务器同时开启了tcp_tw_recycle和timestamps，而客户端正是使用NAT来访问服务器，造成启动时间相对较短的客户端得不到服务器的正常响应。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;如何解决&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;如果服务器作为服务端提供服务，且明确客户端会通过NAT网络访问，或服务器之前有7层转发设备会替换客户端源IP时，是不应该开启tcp_tw_recycle的，而timestamps除了支持tcp_tw_recycle外还被其他机制依赖，推荐继续开启：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;$ sysctl -w net.ipv4.tcp_tw_recycle=0
$ sysctl -w net.ipv4.tcp_timestamps=1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;h3&gt;3.16 怎么知道为什么数据包被丢弃&lt;/h3&gt;    &lt;h4&gt;dropwatch&lt;/h4&gt;    &lt;p&gt;通过谷歌搜索，发现一个很酷的工具叫 dropwatch 。x相关知识可以参考      &lt;a href="https://blog.csdn.net/iampisfan/article/details/51099618"&gt;这篇博文&lt;/a&gt;。没有现成的 Ubuntu 安装软件包，但可以通过 github 下载：&lt;/p&gt;    &lt;p&gt;https://github.com/pavel-odintsov/drop_watch&lt;/p&gt;    &lt;p&gt;以下是我可以编译的说明：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;sudo apt-get install -y libnl-3-dev libnl-genl-3-dev binutils-dev libreadline6-dev
git clone https://github.com/pavel-odintsov/drop_watch.git
cd drop_watch/src
make&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;p&gt;这里是输出！ 它告诉我哪个内核函数丢失数据包，酷！&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;sudo ./dropwatch -l kas
Initalizing kallsyms db
dropwatch&amp;gt; start
Enabling monitoring...
Kernel monitoring activated.
Issue Ctrl-C to stop monitoring

1 drops at tcp_v4_do_rcv+cd (0xffffffff81799bad)
10 drops at tcp_v4_rcv+80 (0xffffffff8179a620)
1 drops at sk_stream_kill_queues+57 (0xffffffff81729ca7)
4 drops at unix_release_sock+20e (0xffffffff817dc94e)
1 drops at igmp_rcv+e1 (0xffffffff817b4c41)
1 drops at igmp_rcv+e1 (0xffffffff817b4c41)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;h4&gt;perf&lt;/h4&gt;    &lt;p&gt;用perf监控丢弃的数据包&lt;/p&gt;    &lt;p&gt;还有另一个很酷的方法，用来调试发生什么。&lt;/p&gt;    &lt;p&gt;可以使用 perf 监视 kfree_skb 事件，这将告诉你什么时候丢弃数据包（内核堆栈发生的地方）：&lt;/p&gt;    &lt;div&gt;      &lt;div&gt;        &lt;pre&gt;          &lt;code&gt;sudo perf record -g -a -e skb:kfree_skb
sudo perf script&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;    &lt;h2&gt;扩展阅读&lt;/h2&gt;    &lt;p&gt;还有这两个很酷的文章：&lt;/p&gt;    &lt;p&gt;监控和调优Linux网络堆栈：接收数据&lt;/p&gt;    &lt;p&gt;https://blog.packagecloud.io/eng/2016/06/22/monitoring-tuning-linux-networking-stack-receiving-data/&lt;/p&gt;    &lt;p&gt;监控和调优Linux网络堆栈：发送数据&lt;/p&gt;    &lt;p&gt;https://blog.packagecloud.io/eng/2017/02/06/monitoring-tuning-linux-networking-stack-sending-data/&lt;/p&gt;    &lt;h2&gt;结论&lt;/h2&gt;    &lt;p&gt;Linux提供了丰富的内核参数供使用者调整，调整得当可以大幅提高服务器的处理能力，但如果调整不当，就会引进莫名其妙的各种问题，比如这次开启tcp_tw_recycle导致丢包，实际也是为了减少TIME_WAIT连接数量而进行参数调优的结果。我们在做系统优化时，时刻要保持辩证和空杯的心态，不盲目吸收他人的果，而多去追求因，只有知其所以然，才能结合实际业务特点，得出最合理的优化配置。&lt;/p&gt;    &lt;p&gt;https://jermine.vdo.pub/linux/linux%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%B8%A2%E5%8C%85%E6%95%85%E9%9A%9C%E7%9A%84%E8%A7%A3%E5%86%B3/&lt;/p&gt;    &lt;p&gt;https://cizixs.com/2018/01/13/linux-udp-packet-drop-debug/&lt;/p&gt;    &lt;hr&gt;&lt;/hr&gt;    &lt;ul&gt;      &lt;li&gt;        &lt;a href="https://cclinuxer.github.io/2020/10/ebpf%E7%9F%A5%E8%AF%86%E5%A4%A7%E7%BA%B2/" title=""&gt;Previous          &lt;br /&gt;ebpf知识大纲&lt;/a&gt;&lt;/li&gt;      &lt;li&gt;        &lt;a href="https://cclinuxer.github.io/2020/11/Linux%E5%86%85%E5%AD%98%E5%9B%9E%E6%94%B6%E4%B9%8B(%E4%B8%80)-%E4%BA%A4%E6%8D%A2%E5%88%86%E5%8C%BA/" title=""&gt;Next          &lt;br /&gt;Linux内存回收之(一)---交换分区&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;div&gt;&lt;/div&gt;&lt;/div&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62474-linux-%E4%B8%A2%E5%8C%85-albert</guid>
      <pubDate>Thu, 27 Oct 2022 14:43:39 CST</pubDate>
    </item>
    <item>
      <title>Linux主机性能测试方法</title>
      <link>https://itindex.net/detail/62452-linux-%E4%B8%BB%E6%9C%BA-%E6%80%A7%E8%83%BD</link>
      <description>&lt;h2&gt;背景&lt;/h2&gt; &lt;p&gt;最近打算用躺家吃灰的树莓派4B搭一个NAS，用来快捷方便地访问和备份一些资源。由于备选的硬件（芯片、硬盘、网线、路由器等）和软件（内网穿透技术）的技术选型比较多，这时候就需要有一个能简单评估服务性能的方法。因此简单搜寻了一下常见方案，方便在技术选型时有个统一的对比标准，并且对一些常见指标能在数量级上有一些感性的理解。&lt;/p&gt; &lt;h2&gt;硬盘&lt;/h2&gt; &lt;p&gt;对于硬盘的读写速度测试，首先我们需要注意根据读写的实现细节不同，测试出的结果会有很大的差别。例如对于读来说，是否走缓存读、缓存的大小如何；对于写来说，是否只写缓存、是否同步等待刷盘、刷盘的时机如何，等等。&lt;/p&gt; &lt;p&gt;在实际测试的时候一定要明确自己使用的是哪种IO模式，否则就会得到一些似是而非的结论。&lt;/p&gt; &lt;h3&gt;设备查询&lt;/h3&gt; &lt;p&gt;在测试硬盘前，我们首先得知道我们有哪些硬盘、分别对应哪些分区。用   &lt;code&gt;lsblk&lt;/code&gt; （list block）命令可以查看当前机器下挂载的块设备：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    1 29.3G  0 disk
└─sda1        8:1    1 29.3G  0 part /media/pi/5615-BDE2
mmcblk0     179:0    0 59.5G  0 disk
├─mmcblk0p1 179:1    0  256M  0 part /boot
└─mmcblk0p2 179:2    0 59.2G  0 part /&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;可以看到，这里的 sda (SATA device a) 表示我外部插入的一个U盘；mmcblk0 (Multimedia card block 0) 表示树莓派自带的一张 SD 卡。这两个类型是 disk，也就是实体磁盘。&lt;/p&gt; &lt;p&gt;每个 disk 会被分成多个 partition，也就是这里的 sda1 和 mmcblk0p1、mmcblk0p2。每个 partition 又会 mount 到不同的文件夹下，用于在文件系统中进行访问。因此对于文件系统本身来说，我们只会关心到 partition 层面。&lt;/p&gt; &lt;p&gt;通过   &lt;code&gt;df&lt;/code&gt; 命令我们也能直接观察到所有分区的挂载情况：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        59G   11G   46G  19% /
devtmpfs        3.5G     0  3.5G   0% /dev
tmpfs           3.7G     0  3.7G   0% /dev/shm
tmpfs           3.7G   65M  3.6G   2% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           3.7G     0  3.7G   0% /sys/fs/cgroup
/dev/mmcblk0p1  253M   32M  221M  13% /boot
tmpfs           738M  4.0K  738M   1% /run/user/1000
/dev/sda1        30G   23M   30G   1% /media/pi/5615-BDE2&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;同时，disk 和 partition 的详细信息也可以通过   &lt;code&gt;fdisk&lt;/code&gt; 命令查看：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ sudo fdisk -l
Disk /dev/mmcblk0: 59.5 GiB, 63864569856 bytes, 124735488 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x140cee6b

Device         Boot  Start       End   Sectors  Size Id Type
/dev/mmcblk0p1        8192    532479    524288  256M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      532480 124735487 124203008 59.2G 83 Linux


Disk /dev/sda: 29.3 GiB, 31457280000 bytes, 61440000 sectors
Disk model: ProductCode
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xf3203eea

Device     Boot Start      End  Sectors  Size Id Type
/dev/sda1        2048 61439999 61437952 29.3G  7 HPFS/NTFS/exFAT&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;总之，在这里我们只需要搞清楚我们想测试的磁盘和分区分别是哪个即可。&lt;/p&gt; &lt;h3&gt;hdparm&lt;/h3&gt; &lt;p&gt;对于读性能测试，我们一般可以用   &lt;a href="https://sourceforge.net/projects/hdparm/"&gt;hdparm&lt;/a&gt; 工具（hard disk parameter? hardware device parameter?）。Debian下直接 apt 安装即可：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ sudo apt install hdparm -y&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;hdparm目前只支持磁盘读性能测试，提供了三种方式进行测试：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;直接读内存：    &lt;code&gt;sudo hdparm -T [device]&lt;/code&gt; 。&lt;/li&gt;  &lt;li&gt;带buffer读磁盘：    &lt;code&gt;sudo hdparm -t [device]&lt;/code&gt; 。&lt;/li&gt;  &lt;li&gt;不带buffer读磁盘:    &lt;code&gt;sudo hdparm -t --direct [device]&lt;/code&gt; 。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;以我的 mmcblk0 设备为例，跑出来结果分别如下（当然，每次测试建议跑多次取平均值，这里偷个懒）：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ sudo hdparm -T /dev/mmcblk0

/dev/mmcblk0:
 Timing cached reads:   1840 MB in  2.00 seconds = 921.43 MB/sec
 
$ sudo hdparm -t /dev/mmcblk0

/dev/mmcblk0:
 Timing buffered disk reads: 130 MB in  3.04 seconds =  42.74 MB/sec
 
$ sudo hdparm -t --direct /dev/mmcblk0

/dev/mmcblk0:
 Timing O_DIRECT disk reads: 124 MB in  3.01 seconds =  41.17 MB/sec
 &lt;/code&gt;&lt;/pre&gt; &lt;p&gt;显然，走内存读是飞快，不过对于测试磁盘性能来说没有任何意义；不带buffer看起来比带buffer要慢一点点，差别不太大；考虑到现实场景中大多数都是带buffer的读，因此我们在比较时用带buffer读的结果来进行参考即可。&lt;/p&gt; &lt;h3&gt;dd&lt;/h3&gt; &lt;p&gt;dd (data definition? data duplicator?) 是进行磁盘操作、文件生成之类的常用工具。在 gnu 的 coreutils 下，类 Unix 发行版几乎都自带。&lt;/p&gt; &lt;h4&gt;写性能&lt;/h4&gt; &lt;p&gt;一般我们会用 dd 来进行磁盘写性能测试，一般来说也有三种方式：&lt;/p&gt; &lt;ol&gt;  &lt;li&gt;直接写内存：    &lt;code&gt;dd bs=1M count=256 if=/dev/zero of=test&lt;/code&gt; 。&lt;/li&gt;  &lt;li&gt;使用内存做缓存写完后一次性刷盘：   &lt;code&gt;dd bs=1M count=256 if=/dev/zero of=test conv=fdatasync&lt;/code&gt;。&lt;/li&gt;  &lt;li&gt;使用内存做缓存，每写完一部分就刷一次盘：   &lt;code&gt;dd bs=1M count=256 if=/dev/zero of=test oflag=dsync&lt;/code&gt;。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;还是以我的 mmcblk0 设备为例（当前目录即挂载的 mmcblk0 设备），跑出来结果分别如下（当然，每次测试建议跑多次取平均值，这里还是偷个懒）：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ dd bs=1M count=256 if=/dev/zero of=test
256+0 records in
256+0 records out
268435456 bytes (268 MB, 256 MiB) copied, 1.39574 s, 192 MB/s

$ dd bs=1M count=256 if=/dev/zero of=test conv=fdatasync
256+0 records in
256+0 records out
268435456 bytes (268 MB, 256 MiB) copied, 31.739 s, 8.5 MB/s

$ dd bs=1M count=256 if=/dev/zero of=test oflag=dsync
256+0 records in
256+0 records out
268435456 bytes (268 MB, 256 MiB) copied, 39.694 s, 6.8 MB/s

$ rm test&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;可见写内存不sync的确还是快，不过还是没啥参考意义。考虑到实际情况下大部分程序都是采用 fdatasync 的模式来写，因此我们在比较时用这个数据即可。&lt;/p&gt; &lt;h4&gt;读性能&lt;/h4&gt; &lt;p&gt;当然，有人也会利用 dd 进行读性能测试，比如：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ sudo dd bs=1M count=256 if=/dev/mmcblk0 of=/dev/null
256+0 records in
256+0 records out
268435456 bytes (268 MB, 256 MiB) copied, 6.03649 s, 44.5 MB/s&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;看起来很美好，结果也和 hdparm 差不多。但是当你第二次再跑这个命令的时候，由于写缓存的存在，结果会快特别多：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ sudo dd bs=1M count=256 if=/dev/mmcblk0 of=/dev/null
256+0 records in
256+0 records out
268435456 bytes (268 MB, 256 MiB) copied, 0.267236 s, 1.0 GB/s&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;显然这样的测试是没有意义的。考虑到这种测试方法甚至很难做到幂等，这里还是不建议用 dd 来测试读性能。&lt;/p&gt; &lt;h3&gt;小结&lt;/h3&gt; &lt;p&gt;对于磁盘读性能测试，建议使用   &lt;code&gt;sudo hdparm -t [device]&lt;/code&gt;。&lt;/p&gt; &lt;p&gt;对于磁盘写性能测试，建议使用   &lt;code&gt;dd bs=1M count=256 if=/dev/zero of=test conv=fdatasync&lt;/code&gt;。&lt;/p&gt; &lt;h2&gt;网络&lt;/h2&gt; &lt;p&gt;网速测试一般分两种，一种是测试当前设备对普通公网设备的读写速度；另一种是点对点测试两个服务器之间的速度。&lt;/p&gt; &lt;h3&gt;speedtest&lt;/h3&gt; &lt;p&gt;speedtest 工具在各地都有测速服务器，通过命令行（speedtest-cli）或者网页（https://speedtest.cn，https://speedtest.net）都可以进行网速上下行的测试。这里以命令行为例：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ sudo apt install speedtest-cli -y

$ speedtest-cli
Retrieving speedtest.net configuration...
Testing from China Mobile (183.192.82.69)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Chinamobile-5G (Shanghai) [8.49 km]: 6.054 ms
Testing download speed................................................................................
Download: 128.24 Mbit/s
Testing upload speed......................................................................................................
Upload: 22.88 Mbit/s&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;虽然多次测试可能会访问到不同的测试点、导致结果有区别，不过其实也大差不差了。&lt;/p&gt; &lt;p&gt;在使用时偶尔会遇到返403，不要慌，多试几下一般就好了 。&lt;/p&gt; &lt;h3&gt;iperf3&lt;/h3&gt; &lt;p&gt;如果我们并不是想测试公网网速，而是测试两个服务器之间点对点的网速。这时用   &lt;a href="https://iperf.fr/iperf-doc.php#doc"&gt;iperf3&lt;/a&gt; 工具就好。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ sudo apt install iperf3 -y # Debian 下
$ brew install iperf3        # MacOS 下&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;需要注意，除了 iperf3 之外，还有一个 iperf。这两个版本分别由不同组织开发，前后也不兼容。虽然似乎 iperf3 有坑，不过似乎功能多一点，尤其是支持了下行带宽测试（iperf 只支持上行带宽测试），所以这里还是用 iperf3。&lt;/p&gt; &lt;p&gt;iperf3 是 C/S 架构，服务端开启 server ，客户端开启 client，然后互相通信进行测速。以我在家的树莓派和一个在 HK 的 Azure 主机为例：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ iperf3 -s -p 5555                   # azure 主机上开启 server

$ iperf3 -c 104.208.65.181 -p 5555    # pi 上开启 client 并连接 server&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;测试完成后，client 上会有报告：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ iperf3 -c 104.208.65.181 -p 5555
Connecting to host 104.208.65.181, port 5555
[  5] local 192.168.1.2 port 35994 connected to 104.208.65.181 port 5555
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  8.68 MBytes  72.8 Mbits/sec    0   2.95 MBytes
[  5]   1.00-2.00   sec  1.25 MBytes  10.5 Mbits/sec  2018    252 KBytes
[  5]   2.00-3.00   sec  2.50 MBytes  21.0 Mbits/sec  1076    286 KBytes
[  5]   3.00-4.00   sec  3.75 MBytes  31.5 Mbits/sec  861    237 KBytes
[  5]   4.00-5.00   sec  2.50 MBytes  21.0 Mbits/sec   99    187 KBytes
[  5]   5.00-6.00   sec  1.25 MBytes  10.5 Mbits/sec    0    206 KBytes
[  5]   6.00-7.00   sec  2.50 MBytes  21.0 Mbits/sec    0    215 KBytes
[  5]   7.00-8.00   sec  2.50 MBytes  21.0 Mbits/sec    0    218 KBytes
[  5]   8.00-9.00   sec  2.50 MBytes  21.0 Mbits/sec    0    218 KBytes
[  5]   9.00-10.00  sec  2.50 MBytes  21.0 Mbits/sec    0    220 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  29.9 MBytes  25.1 Mbits/sec  4054             sender
[  5]   0.00-10.09  sec  26.5 MBytes  22.1 Mbits/sec                  receiver

iperf Done.&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;这里可以看出 client 对 server 的上行带宽大约是 22Mbit/sec。&lt;/p&gt; &lt;p&gt;类似的，server配置不变，client加上 -R 参数后可以测试出 server 对 client 的下行带宽：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ iperf3 -c 104.208.65.181 -p 5555 -R
Connecting to host 104.208.65.181, port 5555
Reverse mode, remote host 104.208.65.181 is sending
[  5] local 192.168.1.2 port 36000 connected to 104.208.65.181 port 5555
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  6.47 MBytes  54.3 Mbits/sec
[  5]   1.00-2.00   sec  25.7 MBytes   216 Mbits/sec
[  5]   2.00-3.00   sec  13.2 MBytes   111 Mbits/sec
[  5]   3.00-4.00   sec  16.3 MBytes   137 Mbits/sec
[  5]   4.00-5.00   sec  12.4 MBytes   104 Mbits/sec
[  5]   5.00-6.00   sec  14.4 MBytes   121 Mbits/sec
[  5]   6.00-7.00   sec  14.0 MBytes   117 Mbits/sec
[  5]   7.00-8.00   sec  13.9 MBytes   116 Mbits/sec
[  5]   8.00-9.00   sec  11.5 MBytes  96.7 Mbits/sec
[  5]   9.00-10.00  sec  11.3 MBytes  95.2 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.09  sec   142 MBytes   118 Mbits/sec  2560             sender
[  5]   0.00-10.00  sec   139 MBytes   117 Mbits/sec                  receiver

iperf Done.&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;这里可以看出 server 对 client 的下行带宽大约是 117Mbit/sec。&lt;/p&gt; &lt;h2&gt;CPU&amp;amp;内存&lt;/h2&gt; &lt;h3&gt;sysbench&lt;/h3&gt; &lt;p&gt;对于CPU和内存的性能测试，可以使用   &lt;a href="https://github.com/akopytov/sysbench"&gt;sysbench&lt;/a&gt; 工具。&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ sudo apt install sysbench -y # Debian 下
$ brew install sysbench        # MacOS 下&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;对于我的树莓派测试如下：&lt;/p&gt; &lt;p&gt;CPU单线程测试，可以看出单核每秒操作数大约1483：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ sysbench cpu --threads=1 run
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 1
Initializing random number generator from current time


Prime numbers limit: 10000

Initializing worker threads...

Threads started!

CPU speed:
    events per second:  1483.17

General statistics:
    total time:                          10.0002s
    total number of events:              14839

Latency (ms):
         min:                                    0.67
         avg:                                    0.67
         max:                                    1.88
         95th percentile:                        0.68
         sum:                                 9992.91

Threads fairness:
    events (avg/stddev):           14839.0000/0.00
    execution time (avg/stddev):   9.9929/0.00
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;内存读写测试，可以看出读写速度约是 1814MiB 每秒：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ sysbench memory run
sysbench 1.0.18 (using system LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 1
Initializing random number generator from current time


Running memory speed test with the following options:
  block size: 1KiB
  total size: 102400MiB
  operation: write
  scope: global

Initializing worker threads...

Threads started!

Total operations: 18590983 (1858174.07 per second)

18155.26 MiB transferred (1814.62 MiB/sec)


General statistics:
    total time:                          10.0001s
    total number of events:              18590983

Latency (ms):
         min:                                    0.00
         avg:                                    0.00
         max:                                    0.20
         95th percentile:                        0.00
         sum:                                 4463.57

Threads fairness:
    events (avg/stddev):           18590983.0000/0.00
    execution time (avg/stddev):   4.4636/0.00
&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;需要注意的是，对 MacOS 的 CPU benchmark 似乎有坑，测试出来的结果异常的大，不具有参考价值。&lt;/p&gt; &lt;h3&gt;md5sum&lt;/h3&gt; &lt;p&gt;虽然 sysbench 的基准测试看起来比较靠谱，但是实际环境下，真正的执行效率还跟执行的指令啥的都有挺大关系。比如，我们以执行 md5 的速度来对比 CPU 的执行效率：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;$ dd if=/dev/zero bs=1M count=1024 | md5sum
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 5.81996 s, 184 MB/s
cd573cfaace07e7949bc0c46028904ff  -&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;通过   &lt;code&gt;dd&lt;/code&gt; 命令向   &lt;code&gt;md5sum&lt;/code&gt; 持续发送 1GB 的数据进行计算，计算的速度也可以看成是 CPU 单核性能的一种指标。（考虑到管道操作是单线程，这个指令其实也只能用到一个核）&lt;/p&gt; &lt;p&gt;然后，如果我们多找几个 CPU 进行以下对比，我们就会发现一些神奇的现象：&lt;/p&gt; &lt;h4&gt;Cortex-A72（ARM）&lt;/h4&gt; &lt;ul&gt;  &lt;li&gt;sysbench 单线程：1479.99 event/s&lt;/li&gt;  &lt;li&gt;dd + md5sum：184 MB/s&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Neoverse-N1（ARM）&lt;/h4&gt; &lt;ul&gt;  &lt;li&gt;sysbench 单线程：3497.70 event/s&lt;/li&gt;  &lt;li&gt;dd + md5sum：424 MB/s&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Intel(R) Xeon(R) Platinum 8171M CPU @ 2.60GHz（x86_64）&lt;/h4&gt; &lt;ul&gt;  &lt;li&gt;sysbench 单线程：820.19 event/s&lt;/li&gt;  &lt;li&gt;dd + md5sum：409 MB/s&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Intel(R) Xeon(R) CPU E5-26xx v4（x86_64）&lt;/h4&gt; &lt;ul&gt;  &lt;li&gt;sysbench 单线程：927.74 event/s&lt;/li&gt;  &lt;li&gt;dd + md5sum：459 MB/s&lt;/li&gt;&lt;/ul&gt; &lt;h4&gt;Intel(R) Xeon(R) Platinum 8255C CPU @ 2.50GHz（x86_64）&lt;/h4&gt; &lt;ul&gt;  &lt;li&gt;sysbench 单线程：1054.30 event/s&lt;/li&gt;  &lt;li&gt;dd + md5sum：515 MB/s&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;可以发现 ARM 架构的机器在 sysbench 上表现几乎都比 X86_64 的机器好很多，但是实际跑 md5sum 却相差不大甚至差不少。&lt;/p&gt; &lt;p&gt;可见不同架构间二者的指标并不完全正相关；不过相同架构间二者的指标还是基本正相关的。&lt;/p&gt; &lt;h2&gt;参考资料&lt;/h2&gt; &lt;p&gt;  &lt;a href="https://romanrm.net/dd-benchmark"&gt;dd-benchmark&lt;/a&gt;  &lt;a href="https://man7.org/linux/man-pages/man8/hdparm.8.html"&gt; &lt;/a&gt;&lt;/p&gt; &lt;p&gt;  &lt;a href="https://man7.org/linux/man-pages/man8/hdparm.8.html"&gt;man-hdparm&lt;/a&gt;&lt;/p&gt; &lt;p&gt;  &lt;a href="https://iperf.fr/iperf-doc.php#doc"&gt;iperf&lt;/a&gt;&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>Linux Raspberry Pi</category>
      <guid isPermaLink="true">https://itindex.net/detail/62452-linux-%E4%B8%BB%E6%9C%BA-%E6%80%A7%E8%83%BD</guid>
      <pubDate>Thu, 13 Oct 2022 17:11:12 CST</pubDate>
    </item>
    <item>
      <title>【Linux】解决可恶的 “NIC Link is Down”_从善若水的博客-CSDN博客</title>
      <link>https://itindex.net/detail/62444-linux-nic-link</link>
      <description>&lt;div&gt;    &lt;p&gt;&lt;/p&gt;    &lt;div&gt;      &lt;h3&gt;文章目录&lt;/h3&gt;      &lt;ul&gt;        &lt;li&gt;          &lt;a href="https://blog.csdn.net/qq_31985307/article/details/120277739#_NIC_Link_is_Down_3"&gt;可恶的 “NIC Link is Down”&lt;/a&gt;&lt;/li&gt;        &lt;li&gt;          &lt;a href="https://blog.csdn.net/qq_31985307/article/details/120277739#_NIC_Link_is_Down_22"&gt;怎样解决 “NIC Link is Down”&lt;/a&gt;&lt;/li&gt;        &lt;li&gt;          &lt;ul&gt;            &lt;li&gt;              &lt;a href="https://blog.csdn.net/qq_31985307/article/details/120277739#1__23"&gt;1. 检查网线是否有问题&lt;/a&gt;&lt;/li&gt;            &lt;li&gt;              &lt;a href="https://blog.csdn.net/qq_31985307/article/details/120277739#2__e1000ebug_28"&gt;2. 可能是 e1000e网卡驱动的bug&lt;/a&gt;&lt;/li&gt;            &lt;li&gt;              &lt;a href="https://blog.csdn.net/qq_31985307/article/details/120277739#3_NIC_35"&gt;3. NIC出了问题&lt;/a&gt;&lt;/li&gt;            &lt;li&gt;              &lt;a href="https://blog.csdn.net/qq_31985307/article/details/120277739#4_Switch_Port__40"&gt;4. Switch Port 出了问题&lt;/a&gt;&lt;/li&gt;            &lt;li&gt;              &lt;a href="https://blog.csdn.net/qq_31985307/article/details/120277739#5_BIOS__ASPM_45"&gt;5. 尝试更新你的BIOS &amp;amp;&amp;amp; 开启ASPM模式&lt;/a&gt;&lt;/li&gt;            &lt;li&gt;              &lt;a href="https://blog.csdn.net/qq_31985307/article/details/120277739#6__flow_control_50"&gt;6. 关闭 流控（flow control）&lt;/a&gt;&lt;/li&gt;            &lt;li&gt;              &lt;a href="https://blog.csdn.net/qq_31985307/article/details/120277739#7_CPU_69"&gt;7. 更换主板与板载网卡和CPU🚑&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;    &lt;p&gt;&lt;/p&gt;    &lt;h1&gt;      &lt;a&gt;&lt;/a&gt;可恶的 “NIC Link is Down”&lt;/h1&gt;    &lt;p&gt;       前一段时间调试5G实时视频业务，网卡总是会出现      &lt;em&gt;NIC Link is Down&lt;/em&gt;的错误，一般几秒之后网卡就会恢复。但是也会遇到一些情况网卡发生      &lt;em&gt;NIC Link is Down&lt;/em&gt;之后无法自动恢复，这时候只能重新启动测试PC才能恢复。&lt;/p&gt;    &lt;p&gt;       下面是我通过dmesg抓到的错误信息：&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;May2909:10:35 server kernel: e1000e: eth0 NIC Link is Down
May2909:10:35 server kernel: e1000e: eth0 NIC Link is Up1000Mbps Full Duplex, Flow Control: Rx/Tx
May2909:10:35 server kernel: e1000e: eth0 NIC Link is Down
May2909:10:35 server kernel: e1000e: eth0 NIC Link is Up1000Mbps Full Duplex, Flow Control: Rx/Tx
May2909:10:35 server kernel: e1000e: eth0 NIC Link is Down
May2909:10:35 server kernel: e1000e: eth0 NIC Link is Up1000Mbps Full Duplex, Flow Control: Rx/Tx
May2909:10:35 server kernel: e1000e: eth0 NIC Link is Down&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;总的来说错误原因就是      &lt;strong&gt;kernel: e1000e: eth0 NIC Link is Down&lt;/strong&gt;。&lt;/p&gt;    &lt;br /&gt;    &lt;h1&gt;      &lt;a&gt;&lt;/a&gt;怎样解决 “NIC Link is Down”&lt;/h1&gt;    &lt;h2&gt;      &lt;a&gt;&lt;/a&gt;1. 检查网线是否有问题&lt;/h2&gt;    &lt;p&gt;       这是最简单的方式了，只需要替换一根网线，然后继续观察问题是否会再次出现。有些时候有问题的网线会导致这样的错误。&lt;/p&gt;    &lt;br /&gt;    &lt;h2&gt;      &lt;a&gt;&lt;/a&gt;2. 可能是 e1000e网卡驱动的bug&lt;/h2&gt;    &lt;p&gt;       可以尝试更新最新版本的 e1000e 网卡驱动，具体步骤如下：&lt;/p&gt;    &lt;ul&gt;      &lt;li&gt;Ubuntu：可以尝试通过这个脚本进行升级【        &lt;a href="https://gist.github.com/tonybruess/8249889519abd93dfba9"&gt;传送门&lt;/a&gt;】&lt;/li&gt;      &lt;li&gt;CentOS、RHEL：尝试通过这个Intel的指南进行升级【        &lt;a href="https://www.intel.com/content/www/us/en/support/articles/000005480/ethernet-products.html#build_e1e"&gt;传送门&lt;/a&gt;】&lt;/li&gt;&lt;/ul&gt;    &lt;br /&gt;    &lt;h2&gt;      &lt;a&gt;&lt;/a&gt;3. NIC出了问题&lt;/h2&gt;    &lt;p&gt;       换一个NIC再进行测试，观察问题是否再次出现。如果NIC是绑定在主板上的，那只能更换一个主板再进行测试了。&lt;/p&gt;    &lt;br /&gt;    &lt;h2&gt;      &lt;a&gt;&lt;/a&gt;4. Switch Port 出了问题&lt;/h2&gt;    &lt;p&gt;       改变 PC/Server 的交换机端口，再进行测试。你可以通过      &lt;strong&gt;ethtool&lt;/strong&gt;命令查看Linux上的网络配置与交换机上的配置是否一致。&lt;/p&gt;    &lt;br /&gt;    &lt;h2&gt;      &lt;a&gt;&lt;/a&gt;5. 尝试更新你的BIOS &amp;amp;&amp;amp; 开启ASPM模式&lt;/h2&gt;    &lt;p&gt;       根据经验如果关闭 ASPM模式也可能导致这样的问题。除此之外，保证你的BIOS版本是最新的，如果不是可以进行更新。&lt;/p&gt;    &lt;br /&gt;    &lt;h2&gt;      &lt;a&gt;&lt;/a&gt;6. 关闭 流控（flow control）&lt;/h2&gt;    &lt;p&gt;       有些时候开启 流控之后会导致一些奇怪的网络错误，可以使用命令将其关闭，并观察问题是否会再次出现，&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;ethtool-A eth0 rx off tx off&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;使用下述命令查看修改是否生效，&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;[root@CSRS:~]thtool -a eth0

Pause parametersforeth0:

Autonegotiate:  on
RX:             off
TX:             off&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;如果看到off，那么流控已经被关闭了。&lt;/p&gt;    &lt;br /&gt;    &lt;h2&gt;      &lt;a&gt;&lt;/a&gt;7. 更换主板与板载网卡和CPU🚑&lt;/h2&gt;    &lt;p&gt;       有一次我发现在 E3-1230v2上持续出现这样的问题，后来我索性将磁盘移植到一块新的 E3-1230v2上，并更换了主板（包括板载NIC）。&lt;/p&gt;    &lt;br /&gt;    &lt;p&gt;   &lt;br /&gt;&lt;/p&gt;&lt;/div&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62444-linux-nic-link</guid>
      <pubDate>Sun, 09 Oct 2022 09:52:32 CST</pubDate>
    </item>
    <item>
      <title>linux磁盘监控--iostat一点小问题和util计算公式</title>
      <link>https://itindex.net/detail/62415-linux-%E7%A3%81%E7%9B%98-%E7%9B%91%E6%8E%A7</link>
      <description>&lt;div&gt;  &lt;div&gt;   &lt;h4&gt;iostat简介&lt;/h4&gt;
   &lt;div&gt;    &lt;em&gt;&lt;/em&gt;    &lt;pre&gt;     &lt;code&gt;iostat - Report Central Processing Unit (CPU) statistics and input/output statistics for devices, partitions and network filesystems (NFS)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
   &lt;p&gt;通常用来看linux服务器io指标，也能看cpu，但是top看cpu比iostat猛，也能看网络指标NFS，但是sar又比iostat猛，所以就用来看io。&lt;/p&gt;
   &lt;p&gt;磁盘io负载通常影响线上数据落地，如果磁盘负载高，有很多请求在队列中来不及处理，导致线上数据处理延迟，因此需要个磁盘io负载的监控，笔者用的是iostat。&lt;/p&gt;
   &lt;div&gt;    &lt;em&gt;&lt;/em&gt;    &lt;pre&gt;     &lt;code&gt;(base) [work@node1 wwwroot]$ iostat -zx 
Linux 2.6.32-696.18.7.el6.x86_64 (ger-frankfurt-loget-dt-001)   12/11/2019  _x86_64_    (40 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.78    0.00    1.96    0.10    0.00   92.17

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.18     5.11    7.04   31.90   647.66  2769.29    87.76     0.05    1.22    2.55    0.93   0.24   0.92
scd0              0.00     0.00    0.00    0.00     0.00     0.00     8.00     0.00    3.79    3.79    0.00   3.76   0.00
sdb               0.00     0.15    4.95    3.63   420.92   455.76   102.17     0.06    6.83    0.25   15.82   0.10   0.08
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
   &lt;p&gt;以上命令能统计磁盘io的繁忙程度，读取util即可反应出来。but磁盘负载明显满了，告警却没有，排查发现，命令【iostat -xz】打印一次统计记录，每个盘符一条记录数据，但是这条数据却是固定的，我石化了，    &lt;br /&gt;
如下所示，第二次统计记录是真实数据。&lt;/p&gt;
   &lt;div&gt;    &lt;em&gt;&lt;/em&gt;    &lt;pre&gt;     &lt;code&gt;(base) [work@node1 wwwroot]$ iostat -zx 1
Linux 2.6.32-696.18.7.el6.x86_64 (ger-frankfurt-loget-dt-001)   12/11/2019  _x86_64_    (40 CPU)
【我是假的】
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           5.78    0.00    1.96    0.10    0.00   92.17

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.18     5.11    7.04   31.90   647.64  2768.94    87.75     0.05    1.20    2.55    0.91   0.24   0.92
scd0              0.00     0.00    0.00    0.00     0.00     0.00     8.00     0.00    3.79    3.79    0.00   3.76   0.00
sdb               0.00     0.15    4.95    3.62   420.93   455.61   102.28     0.06    6.83    0.25   15.85   0.10   0.08
【我是真的】
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          18.85    0.00    7.12   39.22    0.00   34.81

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               0.00     0.00    2.00  238.00   264.00 117144.00   489.20   138.23  738.70  660.50  739.35   4.17 100.10
sdb               0.00     5.00   15.00 1375.00   120.00 19024.00    13.77    10.85    7.81    0.00    7.89   0.06   8.30
【我是真的】
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          20.02    0.00    7.25   37.41    0.00   35.32

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               2.00     2.00    2.00   74.00   136.00 35880.00   473.89   133.12  472.54  479.00  472.36  13.14  99.90
sdb               0.00     1.00   13.00 3289.00   104.00 42992.00    13.05    26.25    7.95    0.46    7.98   0.06  19.70
【我是真的】
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          19.89    0.00    7.29   42.86    0.00   29.96

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda               1.00     1.00    7.00    6.00  1064.00  3072.00   318.15   135.67 1655.85  747.57 2715.50  76.92 100.00
sdb               0.00     0.00   14.00 2897.00   112.00 30664.00    10.57    22.76    7.82    1.14    7.85   0.06  17.90

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          22.64    0.00    7.71   32.16    0.00   37.49

Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda              12.00    36.00   22.00  614.00  7464.00 75232.00   130.03   153.18  678.43  165.18  696.82   1.57 100.00
sdb               0.00     1.00   17.00 3382.00   136.00 44016.00    12.99    29.80    8.77    0.18    8.81   0.07  22.40
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
   &lt;h4&gt;读第二次数据解决问题&lt;/h4&gt;
   &lt;blockquote&gt;
    &lt;p&gt;iostat -zx 1 2     &lt;br /&gt;
统计两次数据，取第二次的，这也是奇葩。&lt;/p&gt;
&lt;/blockquote&gt;
   &lt;h4&gt;关键指标释义--util公式&lt;/h4&gt;
   &lt;p&gt;瑕不掩瑜，小毛病虽然让人尴尬，但是看磁盘io还是iostat猛。    &lt;br /&gt;
整点关注3个指标：    &lt;br /&gt;
1、avgqu-sz：请求队列长度。    &lt;br /&gt;
2、svctm：平均io处理时长（毫秒）。    &lt;br /&gt;
3、%util：io繁忙程度，就是负载强度。&lt;/p&gt;
   &lt;p&gt;rrqm/s: 每秒对该设备的读请求被合并次数，文件系统会对读取同块(block)的请求进行合并    &lt;br /&gt;
wrqm/s: 每秒对该设备的写请求被合并次数    &lt;br /&gt;
r/s: 每秒完成的读次数    &lt;br /&gt;
w/s: 每秒完成的写次数    &lt;br /&gt;
rkB/s: 每秒读数据量(kB为单位)    &lt;br /&gt;
wkB/s: 每秒写数据量(kB为单位)    &lt;br /&gt;
avgrq-sz:平均每次IO操作的数据量(扇区数为单位)    &lt;br /&gt;
avgqu-sz: 平均等待处理的IO请求队列长度    &lt;br /&gt;
await: 平均每次IO请求等待时间(包括等待时间和处理时间，毫秒为单位)    &lt;br /&gt;
svctm: 平均每次IO请求的处理时间(毫秒为单位)    &lt;br /&gt;
%util: 采用周期内用于IO操作的时间比率，即IO队列非空的时间比率&lt;/p&gt;
   &lt;p&gt;对于以上示例输出，我们可以获取到以下信息：&lt;/p&gt;
   &lt;div&gt;    &lt;em&gt;&lt;/em&gt;    &lt;pre&gt;     &lt;code&gt;Device:         rrqm/s   wrqm/s     r/s     w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sda              12.00    36.00   22.00  614.00  7464.00 75232.00   130.03   153.18  678.43  165.18  696.82   1.57 100.00
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
   &lt;p&gt;每秒有636次IO操作(r/s+w/s)，其中以写操作为主体    &lt;br /&gt;
平均每次IO请求等待处理的时间为678.43毫秒，处理耗时为1.57毫秒    &lt;br /&gt;
等待处理的IO请求队列中，平均有153.18个请求驻留&lt;/p&gt;
   &lt;p&gt;公式&lt;/p&gt;
   &lt;blockquote&gt;
    &lt;p&gt;util = (r/s+w/s) * (svctm/1000)&lt;/p&gt;
&lt;/blockquote&gt;
   &lt;p&gt;对于上面的例子有：util = (22+614)*(1.57/1000) = 0.999&lt;/p&gt;&lt;/div&gt;  &lt;br /&gt;  &lt;br /&gt;&lt;/div&gt;
     
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62415-linux-%E7%A3%81%E7%9B%98-%E7%9B%91%E6%8E%A7</guid>
      <pubDate>Tue, 13 Sep 2022 09:40:26 CST</pubDate>
    </item>
    <item>
      <title>Linux文件系统inode详解</title>
      <link>https://itindex.net/detail/62362-linux-%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F-inode</link>
      <description>&lt;h2&gt;文件系统&lt;/h2&gt;
 &lt;p&gt;文件系统是操作系统中负责管理持久数据的子系统，说简单点，就是负责把用户的文件存到磁盘硬件中，因为即使计算机断电了，磁盘里的数据并不会丢失，所以可以持久化的保存文件。&lt;/p&gt;
 &lt;p&gt;文件系统的基本数据单位是文件，它的目的是对磁盘上的文件进行组织管理，那组织的方式不同，就会形成不同的文件系统。&lt;/p&gt;
 &lt;p&gt;Linux 最经典的一句话是：「一切皆文件」，不仅普通的文件和目录，就连块设备、管道、socket 等，也都是统一交给文件系统管理的。&lt;/p&gt;
 &lt;p&gt;Linux 文件系统会为每个文件分配两个数据结构：索引节点（index node）和目录项（directory entry），它们主要用来记录文件的元信息和目录层次结构。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="357" src="https://www.biaodianfu.com/wp-content/uploads/2022/08/inode.png" width="480"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;索引节点，也就是inode，用来记录文件的元信息，比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等。索引节点是文件的唯一标识，它们之间一一对应，也同样都会被存储在硬盘中，所以索引节点同样占用磁盘空间。&lt;/li&gt;
  &lt;li&gt;目录项，也就是dentry，用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系。多个目录项关联起来，就会形成目录结构，但它与索引节点不同的是，目录项是由内核维护的一个数据结构，不存放于磁盘，而是缓存在内存。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;由于索引节点唯一标识一个文件，而目录项记录着文件的名，所以目录项和索引节点的关系是多对一，也就是说，一个文件可以有多个目录。比如，硬链接的实现就是多个目录项中的索引节点指向同一个文件。&lt;/p&gt;
 &lt;p&gt;注意，目录也是文件，也是用索引节点唯一标识，和普通文件不同的是，普通文件在磁盘里面保存的是文件数据，而目录文件在磁盘里面保存子目录或文件。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;目录项和目录是一个东西吗？&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;虽然名字很相近，但是它们不是一个东西，目录是个文件，持久化存储在磁盘，而目录项是内核一个数据结构，缓存在内存。&lt;/p&gt;
 &lt;p&gt;如果查询目录频繁从磁盘读，效率会很低，所以内核会把已经读过的目录用目录项这个数据结构缓存在内存，下次再次读到相同的目录时，只需从内存读就可以，大大提高了文件系统的效率。&lt;/p&gt;
 &lt;p&gt;注意，目录项这个数据结构不只是表示目录，也是可以表示文件的。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;文件数据是如何存储在磁盘的呢？&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;磁盘读写的最小单位是扇区，扇区的大小只有 512字节，那么如果数据大于512字节时候，磁盘需要不停地移动磁头来查找数据，我们知道一般的文件很容易超过512字节那么如果把多个扇区合并为一个块，那么磁盘就可以提高效率了。那么磁头一次读取多个扇区就为一个块“block”（Linux上称为块，Windows上称为簇）。所以，文件系统把多个扇区组成了一个逻辑块，每次读写的最小单位就是逻辑块（数据块），Linux 中的逻辑块大小为 4KB，也就是一次性读写 8 个扇区，这将大大提高了磁盘的读写的效率。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="333" src="https://www.biaodianfu.com/wp-content/uploads/2022/08/filesystem.png" width="480"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;文件系统记录的数据，除了其自身外，还有数据的权限信息，所有者等属性，这些信息都保存在inode中，那么谁来记录inode信息和文件系统本身的信息呢，比如说文件系统的格式，inode与data的数量呢？那么就有一个超级区块（supper block）来记录这些信息了。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="601" src="https://www.biaodianfu.com/wp-content/uploads/2022/08/supper-block.png" width="720"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;superblock：记录此 filesystem 的整体信息，包括inode/block的总量、使用量、剩余量， 以及文件系统的格式与相关信息等&lt;/li&gt;
  &lt;li&gt;inode：记录文件的属性信息，可以使用stat命令查看inode信息。&lt;/li&gt;
  &lt;li&gt;block：实际文件的内容，如果一个文件大于一个块时候，那么将占用多个block，但是一个块只能存放一个文件。（因为数据是由inode指向的，如果有两个文件的数据存放在同一个块中，就会乱套了）&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;img alt="" height="254" src="https://www.biaodianfu.com/wp-content/uploads/2022/08/data.png" width="480"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;node用来指向数据block，那么只要找到inode，再由inode找到block编号，那么实际数据就能找出来了。&lt;/p&gt;
 &lt;p&gt;索引节点是存储在硬盘上的数据，为了加速文件的访问，通常会把索引节点加载到内存中。我们不可能把超级块和索引节点区全部加载到内存，这样内存肯定撑不住，所以只有当需要使用的时候，才将其加载进内存，它们加载进内存的时机是不同的：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;超级块：当文件系统挂载时进入内存；&lt;/li&gt;
  &lt;li&gt;索引节点区：当文件被访问时进入内存；&lt;/li&gt;
&lt;/ul&gt;
 &lt;h2&gt;虚拟文件系统&lt;/h2&gt;
 &lt;p&gt;文件系统的种类众多，而操作系统希望对用户提供一个统一的接口，于是在用户层与文件系统层引入了中间层，这个中间层就称为虚拟文件系统（Virtual File System，VFS）。VFS 定义了一组所有文件系统都支持的数据结构和标准接口，这样程序员不需要了解  &lt;a href="https://www.biaodianfu.com/linux-windows-mac-os-file_systems.html"&gt;文件系统&lt;/a&gt;的工作原理，只需要了解 VFS 提供的统一接口即可。在 Linux 文件系统中，用户空间、系统调用、虚拟机文件系统、缓存、文件系统以及存储之间的关系如下图：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="630" src="https://www.biaodianfu.com/wp-content/uploads/2022/08/vfs.png" width="480"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;Linux 支持的文件系统也不少，根据存储位置的不同，可以把文件系统分为三类：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;磁盘的文件系统，它是直接把数据存储在磁盘中，比如 Ext 2/3/4、XFS 等都是这类文件系统。&lt;/li&gt;
  &lt;li&gt;内存的文件系统，这类文件系统的数据不是存储在硬盘的，而是占用内存空间，我们经常用到的/proc 和 /sys 文件系统都属于这一类，读写这类文件，实际上是读写内核中相关的数据。&lt;/li&gt;
  &lt;li&gt;网络的文件系统，用来访问其他计算机主机数据的文件系统，比如 NFS、SMB 等等。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;文件系统首先要先挂载到某个目录才可以正常使用，比如 Linux 系统在启动时，会把文件系统挂载到根目录。&lt;/p&gt;
 &lt;p&gt;Linux 采用为分层的体系结构，将用户接口层、文件系统实现和存储设备的驱动程序分隔开，进而兼容不同的文件系统。虚拟文件系统（Virtual File System, VFS）是 Linux 内核中的软件层，它在内核中提供了一组标准的、抽象的文件操作，允许不同的文件系统实现共存，并向用户空间程序提供统一的文件系统接口。下面这张图展示了 Linux 虚拟文件系统的整体结构：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="391" src="https://www.biaodianfu.com/wp-content/uploads/2022/08/vfs-architecture.png" width="640"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt; &lt;/p&gt;
 &lt;p&gt;从上图可以看出，用户空间的应用程序直接、或是通过编程语言提供的库函数间接调用内核提供的 System Call 接口（如open()、write()等）执行文件操作。System Call 接口再将应用程序的参数传递给虚拟文件系统进行处理。&lt;/p&gt;
 &lt;p&gt;每个文件系统都为 VFS 实现了一组通用接口，具体的文件系统根据自己对磁盘上数据的组织方式操作相应的数据。当应用程序操作某个文件时，VFS 会根据文件路径找到相应的挂载点，得到具体的文件系统信息，然后调用该文件系统的对应操作函数。&lt;/p&gt;
 &lt;p&gt;VFS 提供了两个针对文件系统对象的缓存 INode Cache 和 DEntry Cache，它们缓存最近使用过的文件系统对象，用来加快对 INode 和 DEntry 的访问。Linux 内核还提供了 Buffer Cache 缓冲区，用来缓存文件系统和相关块设备之间的请求，减少访问物理设备的次数，加快访问速度。Buffer Cache 以 LRU 列表的形式管理缓冲区。&lt;/p&gt;
 &lt;p&gt;VFS 的好处是实现了应用程序的文件操作与具体的文件系统的解耦，使得编程更加容易：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;应用层程序只要使用 VFS 对外提供的read()、write()等接口就可以执行文件操作，不需要关心底层文件系统的实现细节；&lt;/li&gt;
  &lt;li&gt;文件系统只需要实现 VFS 接口就可以兼容 Linux，方便移植与维护；&lt;/li&gt;
  &lt;li&gt;无需关注具体的实现细节，就实现跨文件系统的文件操作。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;了解 Linux 文件系统的整体结构后，下面主要分析 Linux VFS 的技术原理。由于文件系统与设备驱动的实现非常复杂，笔者也未接触过这方面的内容，因此文中不会涉及具体文件系统的实现。&lt;/p&gt;
 &lt;h3&gt;VFS 结构&lt;/h3&gt;
 &lt;p&gt;Linux 以一组通用对象的角度看待所有文件系统，每一级对象之间的关系如下图所示：&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="427" src="https://www.biaodianfu.com/wp-content/uploads/2022/08/vfs-object.png" width="640"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;fd 与 file&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;每个进程都持有一个fd[]数组，数组里面存放的是指向file结构体的指针，同一进程的不同fd可以指向同一个file对象；&lt;/p&gt;
 &lt;p&gt;file是内核中的数据结构，表示一个被进程打开的文件，和进程相关联。当应用程序调用open()函数的时候，VFS 就会创建相应的file对象。它会保存打开文件的状态，例如文件权限、路径、偏移量等等。&lt;/p&gt;
 &lt;pre&gt;// https://elixir.bootlin.com/linux/v5.4.93/source/include/linux/fs.h#L936 结构体已删减
struct file {
    struct path                   f_path;
    struct inode                  *f_inode;
    const struct file_operations  *f_op;
    unsigned int                  f_flags;
    fmode_t                       f_mode;
    loff_t                        f_pos;
    struct fown_struct            f_owner;
}

// https://elixir.bootlin.com/linux/v5.4.93/source/include/linux/path.h#L8
struct path {
    struct vfsmount  *mnt;
    struct dentry    *dentry;
}
&lt;/pre&gt;
 &lt;p&gt;从上面的代码可以看出，文件的路径实际上是一个指向 DEntry 结构体的指针，VFS 通过 DEntry 索引到文件的位置。&lt;/p&gt;
 &lt;p&gt;除了文件偏移量f_pos是进程私有的数据外，其他的数据都来自于 INode 和 DEntry，和所有进程共享。不同进程的file对象可以指向同一个 DEntry 和 Inode，从而实现文件的共享。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;DEntry 与 INode&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;Linux文件系统会为每个文件都分配两个数据结构，目录项（DEntry, Directory Entry）和索引节点（INode, Index Node）。&lt;/p&gt;
 &lt;p&gt;DEntry 用来保存文件路径和 INode 之间的映射，从而支持在文件系统中移动。DEntry 由 VFS 维护，所有文件系统共享，不和具体的进程关联。dentry对象从根目录“/”开始，每个dentry对象都会持有自己的子目录和文件，这样就形成了文件树。举例来说，如果要访问”/home/beihai/a.txt”文件并对他操作，系统会解析文件路径，首先从“/”根目录的dentry对象开始访问，然后找到”home/“目录，其次是“beihai/”，最后找到“a.txt”的dentry结构体，该结构体里面d_inode字段就对应着该文件。&lt;/p&gt;
 &lt;pre&gt;// https://elixir.bootlin.com/linux/v5.4.93/source/include/linux/dcache.h#L89 结构体已删减
struct dentry {
    struct dentry *d_parent;     // 父目录
    struct qstr d_name;          // 文件名称
    struct inode *d_inode;       // 关联的 inode
    struct list_head d_child;    // 父目录中的子目录和文件
    struct list_head d_subdirs;  // 当前目录中的子目录和文件
}
&lt;/pre&gt;
 &lt;p&gt;每一个dentry对象都持有一个对应的inode对象，表示 Linux 中一个具体的目录项或文件。INode 包含管理文件系统中的对象所需的所有元数据，以及可以在该文件对象上执行的操作。&lt;/p&gt;
 &lt;pre&gt;// https://elixir.bootlin.com/linux/v5.4.93/source/include/linux/fs.h#L628 结构体已删减
struct inode {
    umode_t                 i_mode;          // 文件权限及类型
    kuid_t                  i_uid;           // user id
    kgid_t                  i_gid;           // group id

    const struct inode_operations    *i_op;  // inode 操作函数，如 create，mkdir，lookup，rename 等
    struct super_block      *i_sb;           // 所属的 SuperBlock

    loff_t                  i_size;          // 文件大小
    struct timespec         i_atime;         // 文件最后访问时间
    struct timespec         i_mtime;         // 文件最后修改时间
    struct timespec         i_ctime;         // 文件元数据最后修改时间（包括文件名称）
    const struct file_operations    *i_fop;  // 文件操作函数，open、write 等
    void                    *i_private;      // 文件系统的私有数据
}
&lt;/pre&gt;
 &lt;p&gt;虚拟文件系统维护了一个 DEntry Cache 缓存，用来保存最近使用的 DEntry，加速查询操作。当调用open()函数打开一个文件时，内核会第一时间根据文件路径到 DEntry Cache 里面寻找相应的 DEntry，找到了就直接构造一个file对象并返回。如果该文件不在缓存中，那么 VFS 会根据找到的最近目录一级一级地向下加载，直到找到相应的文件。期间 VFS 会缓存所有被加载生成的dentry。&lt;/p&gt;
 &lt;p&gt;INode 存储的数据存放在磁盘上，由具体的文件系统进行组织，当需要访问一个 INode 时，会由文件系统从磁盘上加载相应的数据并构造 INode。一个 INode 可能被多个 DEntry 所关联，即相当于为某一文件创建了多个文件路径（通常是为文件建立硬链接）。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;SuperBlock&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;SuperBlock 表示特定加载的文件系统，用于描述和维护文件系统的状态，由 VFS 定义，但里面的数据根据具体的文件系统填充。每个 SuperBlock 代表了一个具体的磁盘分区，里面包含了当前磁盘分区的信息，如文件系统类型、剩余空间等。SuperBlock 的一个重要成员是链表s_list，包含所有修改过的 INode，使用该链表很容易区分出来哪个文件被修改过，并配合内核线程将数据写回磁盘。SuperBlock 的另一个重要成员是s_op，定义了针对其 INode 的所有操作方法，例如标记、释放索引节点等一系列操作。&lt;/p&gt;
 &lt;pre&gt;// https://elixir.bootlin.com/linux/v5.4.93/source/include/linux/fs.h#L1425 结构体已删减
struct super_block {
    struct list_head    s_list;               // 指向链表的指针
    dev_t               s_dev;                // 设备标识符
    unsigned long       s_blocksize;          // 以字节为单位的块大小
    loff_t              s_maxbytes;           // 文件大小上限
    struct file_system_type    *s_type;       // 文件系统类型
    const struct super_operations    *s_op;   // SuperBlock 操作函数，write_inode、put_inode 等
    const struct dquot_operations    *dq_op;  // 磁盘限额函数
    struct dentry        *s_root;             // 根目录
}
&lt;/pre&gt;
 &lt;p&gt;SuperBlock 是一个非常复杂的结构，通过 SuperBlock 我们可以将一个实体文件系统挂载到 Linux 上，或者对 INode 进行增删改查操作。所以一般文件系统都会在磁盘上存储多份 SuperBlock，防止数据意外损坏导致整个分区无法读取。&lt;/p&gt;
 &lt;h3&gt;inode 内容&lt;/h3&gt;
 &lt;p&gt;inode包含很多的文件元信息，但不包含文件名，例如：字节数、属主UserID、属组GroupID、读写执行权限、时间戳等。而文件名存放在目录当中，但Linux系统内部不使用文件名，而是使用inode号码识别文件。对于系统来说文件名只是inode号码便于识别的别称。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;stat&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;查看inode信息&lt;/p&gt;
 &lt;pre&gt;[root@localhost ~]# mkdir test
[root@localhost ~]# echo &amp;quot;this is test file&amp;quot; &amp;gt; test.txt
[root@localhost ~]# stat test.txt
  File: ‘test.txt’
  Size: 18              Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 33574994    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2019-08-28 19:55:05.920240744 +0800
Modify: 2019-08-28 19:55:05.920240744 +0800
Change: 2019-08-28 19:55:05.920240744 +0800
 Birth: -
&lt;/pre&gt;
 &lt;p&gt;三个主要的时间属性：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;ctime：change time是最后一次改变文件或目录（属性）的时间，例如执行chmod，chown等命令。&lt;/li&gt;
  &lt;li&gt;atime：access time是最后一次访问文件或目录的时间。&lt;/li&gt;
  &lt;li&gt;mtime：modify time是最后一次修改文件或目录（内容）的时间。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;  &lt;strong&gt;file&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;查看文件类型&lt;/p&gt;
 &lt;pre&gt;[root@localhost ~]# file test
test: directory
[root@localhost ~]# file test.txt
test.txt: ASCII text
&lt;/pre&gt;
 &lt;p&gt;  &lt;strong&gt;inode 号码&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;表面上，用户通过文件名打开文件，实际上，系统内部将这个过程分为三步：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;系统找到这个文件名对应的inode号码；&lt;/li&gt;
  &lt;li&gt;通过inode号码，获取inode信息；&lt;/li&gt;
  &lt;li&gt;根据inode信息，找到文件数据所在的block，并读出数据。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;其实系统还要根据inode信息，看用户是否具有访问的权限，有就指向对应的数据block，没有就返回权限拒绝。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;ls -i&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;直接查看文件i节点号，也可以通过stat查看文件inode信息查看i节点号。&lt;/p&gt;
 &lt;pre&gt;[root@localhost ~]# ls -i
33574991 anaconda-ks.cfg      2086 test  33574994 test.txt
&lt;/pre&gt;
 &lt;p&gt;  &lt;strong&gt;inode 大小&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;inode也会消耗硬盘空间，所以格式化的时候，操作系统自动将硬盘分成两个区域。一个是数据区，存放文件数据；另一个是inode区，存放inode所包含的信息。每个inode的大小，一般是128字节或256字节。通常情况下不需要关注单个inode的大小，而是需要重点关注inode总数。inode总数在格式化的时候就确定了。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;df -i&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;查看硬盘分区的inode总数和已使用情况&lt;/p&gt;
 &lt;pre&gt;[root@localhost ~]# df -i
Filesystem               Inodes IUsed   IFree IUse% Mounted on
/dev/mapper/centos-root 8910848 26029 8884819    1% /
devtmpfs                 230602   384  230218    1% /dev
tmpfs                    233378     1  233377    1% /dev/shm
tmpfs                    233378   487  232891    1% /run
tmpfs                    233378    16  233362    1% /sys/fs/cgroup
/dev/sda1                524288   328  523960    1% /boot
tmpfs                    233378     1  233377    1% /run/user/0
&lt;/pre&gt;
 &lt;p&gt;  &lt;strong&gt;文件的读写&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;文件系统在打开一个文件时，要做的有：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;系统找到这个文件名对应的inode：在目录表中查找该文件名对应的项，由此得到该文件相对应的 inode 号&lt;/li&gt;
  &lt;li&gt;通过inode号，获取到磁盘中的inode信息，其中最重要的内容是磁盘地址表&lt;/li&gt;
  &lt;li&gt;通过inode信息中的磁盘地址表，文件系统把分散存放的文件物理块连接成文件的逻辑结构。在磁盘地址表中有 13 个块号，文件将以块号在磁盘地址表中出现的顺序依次读取相应的块。找到文件数据所在的block，读出数据。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;根据以上流程，我们可以发现，inode应该是有一个专门的存储区域的，以方便系统快速查找。事实上，一块磁盘创建的时候，操作系统自动将硬盘分成两个区域：存放文件数据的数据区，与存放inode信息的inode区（inode table）。&lt;/p&gt;
 &lt;p&gt;每个inode的大小一般是128B或者256B。inode节点的总数，在格式化时就给定，一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中，每个inode节点的大小为128字节，每1KB就设置一个inode，那么inode table的大小就会达到128MB，占整块硬盘的12.8%。&lt;/p&gt;
 &lt;p&gt;也就是说，每个分区的inode总数从格式化之后就固定了，因此有可能会出现存储空间没有占满，但因为小文件太多而耗尽了inode的情况。这个时候就只能清除inode占用高的文件或者目录或修改inode数量了，当然，inode的调整需要重新格式化磁盘，需要确保数据已经得到有效备份后，再进行此操作。&lt;/p&gt;
 &lt;p&gt;这时候又产生了新的问题：文件创建时要为文件分配哪一个inode号呢？即如何保证分配的inode号没有被占用？  &lt;br /&gt;
既然是”是否被占用”的问题，使用位图是最佳方案，像bmap记录block的占用情况一样。标识inode号是否被分配的位图称为inodemap简称为imap。这时要为一个文件分配inode号只需扫描imap即可知道哪一个inode号是空闲的。&lt;/p&gt;
 &lt;p&gt;(位图法就是bitmap的缩写。所谓bitmap，就是用每一位来存放某种状态，适用于大规模数据，但数据状态又不是很多的情况。)  &lt;br /&gt;
类似bmap块位图一样，inode号是预先规划好的。inode号分配后，文件删除也会释放inode号。分配和释放的inode号，像是在一个地图上挖掉一块，用完再补回来一样。  &lt;br /&gt;
imap存在着和bmap和inode table一样需要解决的问题：如果文件系统比较大，imap本身就会很大，每次存储文件都要进行扫描，会导致效率不够高。同样，优化的方式是将文件系统占用的block划分成块组，每个块组有自己的imap范围，以减少检索时间。&lt;/p&gt;
 &lt;p&gt;利用df -i命令可以查看inode数量方面的信息&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;文件的操作&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;系统对文件的操作会可能影响inode：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;复制：创建一个包含全部数据与新inode号的新文件&lt;/li&gt;
  &lt;li&gt;移动：在同一磁盘下移动时，所在目录改变，node号与实际数据存储的块的位置都不会变化。跨磁盘移动当然会删除本磁盘的数据并创建一条新的数据在另一块磁盘中。&lt;/li&gt;
  &lt;li&gt;硬链接： 同一个inode号代表的文件有多个文件名，即可以用不同的文件名访问同一份数据，但是它们指向的inode编号是相同的，并且文件元数据中链接数会增加。不可以对目录创建硬链接。&lt;/li&gt;
  &lt;li&gt;软链接： 软链接的本质是一个链接文件，其中存储的了对另一个文件的指针。所以对一个文件创建软链接，inode号不相同，创建软链接文件的链接数不会增加。可以对目录创建软链接。&lt;/li&gt;
  &lt;li&gt;删除：当删除文件时，会先检查inode中的链接数。如果链接数大于1，就只会删掉一个硬链接，不影响数据。如果链接数等于1，那么这个inode就会被释放掉，对应的inode指向的块也会被标记为空闲的（数据不会被置零，所以硬盘数据被误删除后，若没有新数据写入可恢复）。如果是软链接，原文件被删除后链接文件就变成了悬挂链接（dangling link），无法正常访问了。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;利用inode还可以删除一些文件名中有转义字符或控制字符的文件，最典型的就是开头为减号-的文件。这种无法直接用rm命令来搞，就可以先查出它们的inode编号再删除：   &lt;code&gt;find ./ -inum 10086 -exec rm {} \&lt;/code&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;特有现象&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;由于inode号码与文件名分离，导致一些Unix/Linux系统具备以下几种特有的现象。&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;文件名包含特殊字符，可能无法正常删除。这时直接删除inode，能够起到删除文件的作用；   &lt;code&gt;find ./* -inum 节点号 -delete&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;移动文件或重命名文件，只是改变文件名，不影响inode号码；&lt;/li&gt;
  &lt;li&gt;打开一个文件以后，系统就以inode号码来识别这个文件，不再考虑文件名。&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;这种情况使得软件更新变得简单，可以在不关闭软件的情况下进行更新，不需要重启。因为系统通过inode号码，识别运行中的文件，不通过文件名。更新的时候，新版文件以同样的文件名，生成一个新的inode，不会影响到运行中的文件。等到下一次运行这个软件的时候，文件名就自动指向新版文件，旧版文件的inode则被回收。&lt;/p&gt;
 &lt;p&gt;  &lt;strong&gt;inode 耗尽故障&lt;/strong&gt;&lt;/p&gt;
 &lt;p&gt;由于硬盘分区的inode总数在格式化后就已经固定，而每个文件必须有一个inode，因此就有可能发生inode节点用光，但硬盘空间还剩不少，却无法创建新文件。同时这也是一种攻击的方式，所以一些公用的文件系统就要做磁盘限额，以防止影响到系统的正常运行。至于修复，很简单，只要找出哪些大量占用i节点的文件删除就可以了。&lt;/p&gt;
 &lt;h2&gt;硬链接与软连接&lt;/h2&gt;
 &lt;p&gt;Linux系统中有一种比较特殊的文件称之为链接（link）。通俗地说，链接就是从一个文件指向另外一个文件的路径。linux中链接分为俩种，硬链接和软链接。简单来说，硬链接相当于源文件和链接文件在磁盘和内存中共享一个inode，因此，链接文件和源文件有不同的dentry，因此，这个特性决定了硬链接无法跨越文件系统，而且我们无法为目录创建硬链接。软链接和硬链接不同，首先软链接可以跨越文件系统，其次，链接文件和源文件有着不同的inode和dentry，因此，两个文件的属性和内容也截然不同，软链接文件的文件内容是源文件的文件名。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="442" src="https://www.biaodianfu.com/wp-content/uploads/2022/08/hardlink.png" width="640"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;硬链接是多个目录项中的「索引节点」指向一个文件，也就是指向同一个 inode，但是 inode 是不可能跨越文件系统的，每个文件系统都有各自的 inode 数据结构和列表，所以硬链接是不可用于跨文件系统的。由于多个目录项都是指向一个 inode，那么只有删除文件的所有硬链接以及源文件时，系统才会彻底删除该文件。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="389" src="https://www.biaodianfu.com/wp-content/uploads/2022/08/hard-link.png" width="720"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;软链接相当于重新创建一个文件，这个文件有独立的 inode，但是这个文件的内容是另外一个文件的路径，所以访问软链接的时候，实际上相当于访问到了另外一个文件，所以软链接是可以跨文件系统的，甚至目标文件被删除了，链接文件还是在的，只不过指向的文件找不到了而已。&lt;/p&gt;
 &lt;p&gt;  &lt;img alt="" height="375" src="https://www.biaodianfu.com/wp-content/uploads/2022/08/soft-link.png" width="720"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;软硬链接实现的原理不同
   &lt;ul&gt;
    &lt;li&gt;硬链接是建立一个目录项，包含文件名和文件的inode，但inode是原来文件的inode号，并不建立其所对应得数据。所以硬链接并不占用inode。&lt;/li&gt;
    &lt;li&gt;软连接也创建一个目录项，也包含文件名和文件的inode，但它的inode指向的并不是原来文件名所指向的数据的inode，而是新建一个inode，并建立数据，数据指向的是原来文件名，所以原来文件名的字符数，即为软连接所占字节数&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
  &lt;li&gt;软硬链接所能创建的目标有区别
   &lt;ul&gt;
    &lt;li&gt;因为每个分区各有一套不同的inode表，所以硬链接不能跨分区创建而软连接可以,因为软连接指向的书文件名。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
  &lt;li&gt;硬链接不能指向目录
   &lt;ul&gt;
    &lt;li&gt;如果说目录有硬链接那么可能引入死循环，但是你可能会疑问软连接也会陷入循环啊，答案当然不是，因为软连接是存在自己的数据的，可以查看自己的文件属性，既然可以判断出来软连接，那么自然不会陷入循环，并且系统在连续遇到8个符号连接后就停止遍历。但是硬链接可就不行了，因为他的inode号一致，所以就判断不出是硬链接，所以就会陷入死循环了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
 &lt;p&gt;参考链接：&lt;/p&gt;
 &lt;ul&gt;
  &lt;li&gt;   &lt;a href="https://wingsxdu.com/posts/linux/vfs/"&gt;Linux 虚拟文件系统&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;   &lt;a href="https://devconnected.com/understanding-hard-and-soft-links-on-linux/"&gt;Understanding Hard and Soft Links on Linux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
 &lt;div&gt;
  &lt;h3&gt;相关文章:&lt;/h3&gt;  &lt;ol&gt;
   &lt;li&gt;    &lt;a href="https://www.biaodianfu.com/hello-world.html" rel="bookmark" title="C&amp;#35821;&amp;#35328;&amp;#20043;Hello World&amp;#31243;&amp;#24207;&amp;#32534;&amp;#35793;"&gt;C语言之Hello World程序编译 &lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;a href="https://www.biaodianfu.com/fastfm.html" rel="bookmark" title="Python&amp;#22240;&amp;#23376;&amp;#20998;&amp;#35299;&amp;#24211;&amp;#65306;fastFM"&gt;Python因子分解库：fastFM &lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;    &lt;a href="https://www.biaodianfu.com/linux-windows-mac-os-file_systems.html" rel="bookmark" title="Linux/Windows/Mac OS&amp;#25991;&amp;#20214;&amp;#31995;&amp;#32479;"&gt;Linux/Windows/Mac OS文件系统 &lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>器→工具 工具软件 Linux</category>
      <guid isPermaLink="true">https://itindex.net/detail/62362-linux-%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F-inode</guid>
      <pubDate>Sat, 13 Aug 2022 09:50:00 CST</pubDate>
    </item>
    <item>
      <title>Linux系统安全加固指南</title>
      <link>https://itindex.net/detail/62230-linux-%E7%B3%BB%E7%BB%9F-%E5%AE%89%E5%85%A8</link>
      <description>&lt;div&gt;    &lt;p&gt;▲      &lt;strong&gt; 点击上方“分布式实验室”&lt;/strong&gt;关注公众号      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;回复“1”抽取纸质技术书&lt;/p&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;本指南旨在说明如何尽可能地加强Linux的安全性和隐私性，并且不限于任何特定的指南。&lt;/p&gt;    &lt;p&gt;免责声明：如果您不确定自己在做什么，请不要尝试在本文中使用任何内容。&lt;/p&gt;    &lt;p&gt;本指南仅关注安全性和隐私性，而不关注性能，可用性或其他内容。&lt;/p&gt;    &lt;p&gt;列出的所有命令都将需要root特权。以“$”符号开头的单词表示一个变量，不同终端之间可能会有所不同。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;1&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;选择正确的Linux发行版&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;选择一个好的Linux发行版有很多因素。&lt;/p&gt;    &lt;ul&gt;      &lt;li&gt;        &lt;p&gt;避免分发冻结程序包，因为它们在安全更新中通常很落后。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;不使用与Systemd机制的发行版。Systemd包含许多不必要的攻击面；它尝试做的事情远远超出了必要，并且超出了初始化系统应做的事情。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;使用musl作为默认的C库。Musl专注于最小化，这会导致很小的攻击面，而其他C库（例如glibc）过于复杂，容易产生漏洞。例如，与musl中的极少数漏洞相比，glibc中的一百多个漏洞已被公开披露。尽管仅靠披露的CVE本身通常是不准确的统计信息，但有时这种情况有时可以用来表示过分的问题。Musl还具有不错的漏洞利用缓解措施，尤其是其新的强化内存分配器。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;最好默认情况下使用LibreSSL而不是OpenSSL的发行版。OpenSSL包含大量完全不必要的攻击面，并且遵循不良的安全做法。例如，它仍然保持OS / 2和VMS支持这些已有数十年历史的古老操作系统。这些令人讨厌的安全做法导致了可怕的Heartbleed漏洞。LibreSSL是OpenBSD团队的OpenSSL分支，它采用了出色的编程实践并消除了很多攻击面。在LibreSSL成立的第一年内，它缓解了许多漏洞，其中包括一些高严重性的漏洞。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;p&gt;用作强化操作系统基础的最佳发行版是Gentoo Linux，因为它可以让您精确地配置系统，以达到理想的效果，这将非常有用，尤其是参考我们在后面的章节中使用更安全的编译标志。&lt;/p&gt;    &lt;p&gt;但是，由于Gentoo的巨大可用性缺陷，它对于许多人来说可能并不顺手。在这种情况下，Void Linux的Musl构建是一个很好的折衷方案。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;2&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;内核&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;内核是操作系统的核心，不幸的是很容易受到攻击。正如Brad Spengler曾经说过的那样，可以将其视为系统上最大，最易受攻击的setuid根二进制文件。因此，对内核进行尽可能多的强化非常重要。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;Stable vs LTS内核&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Linux内核以两种主要形式发布：稳定和长期支持（LTS）。稳定版本是较新的版本，而LTS发行版本是较老的稳定版本，长期以来一直受支持。选择上述任何一个发行版本都有许多后果。&lt;/p&gt;    &lt;p&gt;Linux内核未使用CVE标识安全漏洞。这意味着大多数安全漏洞的修复程序不能向后移植到LTS内核。但是稳定版本包含到目前为止进行的所有安全修复。&lt;/p&gt;    &lt;p&gt;但是，有了这些修复程序，稳定的内核将包含更多新功能，因此大大增加了内核的攻击面，并引入了大量新错误。相反，LTS内核的受攻击面较小，因为这些功能没有被不断添加。&lt;/p&gt;    &lt;p&gt;此外，稳定的内核还包括更新的强化功能，以减轻LTS内核没有的某些利用。此类功能的一些示例是Lockdown LSM和STACKLEAK GCC插件。&lt;/p&gt;    &lt;p&gt;总而言之，在选择稳定或LTS内核时需要权衡取舍。LTS内核具有较少的强化功能，并且并非当时所有的公共错误修复都已向后移植，但是通常它的攻击面更少，并且引入未知错误的可能性也较小。&lt;/p&gt;    &lt;p&gt;稳定的内核具有更多的强化功能，并且包括所有已知的错误修复，但它也具有更多的攻击面以及引入更多未知错误的机会更大。最后，最好使用较新的LTS分支（如4.19内核）。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;Sysctl&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Sysctl是允许用户配置某些内核设置并启用各种安全功能或禁用危险功能以减少攻击面的工具。要临时更改设置，您可以执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;sysctl -w $tunable = $value&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;要永久更改sysctls，您可以将要更改的sysctls添加到/etc/sysctl.conf或/etc/sysctl.d中的相应文件，具体取决于您的Linux发行版。&lt;/p&gt;    &lt;p&gt;以下是您应更改的建议sysctl设置。&lt;/p&gt;    &lt;p&gt;Kernel self-protection：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;kernel.kptr_restrict=2&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;内核指针指向内核内存中的特定位置。这些在利用内核方面可能非常有用，但是默认情况下不会隐藏内核指针，例如，通过读取/proc/kallsyms的内容即可轻松发现它们。此设置旨在减轻内核指针泄漏。另外，您可以设置kernel.kptr_restrict = 1以仅从没有CAP_SYSLOG功能的进程中隐藏内核指针。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;kernel.dmesg_restrict=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;dmesg是内核日志，它公开了大量有用的内核调试信息，但这通常会泄漏敏感信息，例如内核指针。更改上述sysctl设置会将内核日志限制为CAP_SYSLOG功能。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;kernel.printk=3 3 3 3&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;尽管dmesg_restrict的值，启动过程中内核日志仍将显示在控制台中。能够在引导过程中记录屏幕的恶意软件可能会滥用此恶意软件以获得更高的特权。此选项可防止这些信息泄漏。必须将其与下面描述的某些引导参数结合使用才能完全有效。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;kernel.unprivileged_bpf_disabled=1        &lt;br /&gt;net.core.bpf_jit_harden=2&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;eBPF暴露了很大的攻击面，因此需加以限制。这些系统将eBPF限制为CAP_BPF功能（在5.8之前的内核版本上为CAP_SYS_ADMIN），并启用JIT强化技术，例如常量绑定。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;dev.tty.ldisc_autoload=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这将加载TTY行规则限制为CAP_SYS_MODULE功能，以防止非特权的攻击者使用TIOCSETD ioctl加载易受攻击的线路规则，而该TIOCSETD ioctl之前已在许多漏洞利用中被滥用。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;vm.unprivileged_userfaultfd=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;serfaultfd() 系统调用经常被滥用以利用“事后使用(use-after-free)”缺陷。因此，该sysctl用于将此syscall限制为CAP_SYS_PTRACE功能。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;kernel.kexec_load_disabled=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;kexec是一个系统调用，用于在运行时引导另一个内核。可以滥用此功能来加载恶意内核并在内核模式下获得任意代码执行能力，因此该sysctl设置将被禁用。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;kernel.sysrq=4&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;SysRq密钥向非特权用户公开了许多潜在的危险调试功能。与通常的假设相反，SysRq不仅是物理攻击的问题，而且还可以远程触发。该sysctl的值使其可以使用户只能使用SAK密钥，这对于安全地访问root是必不可少的。或者，您可以简单地将值设置为0以完全禁用SysRq。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;kernel.unprivileged_userns_clone=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;用户名称空间是内核中的一项功能，旨在改善沙箱并使非特权用户易于访问它，但是，此功能公开了重要的内核攻击面，以进行特权升级，因此该sysctl将用户名称空间的使用限制为CAP_SYS_ADMIN功能。对于无特权的沙箱，建议使用具有很少攻击面的setuid二进制文件，以最大程度地减少特权升级的可能性。沙箱章节部分将进一步讨论此主题。&lt;/p&gt;    &lt;p&gt;请注意，尽管该sysctl仅在某些Linux发行版中存在，因为它需要内核补丁。如果您的内核不包含此补丁，则可以通过设置user.max_user_namespaces = 0来完全禁用用户名称空间（包括root用户）。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;kernel.unprivileged_userns_clone=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;用能事件会增加大量内核攻击面，并导致大量漏洞。此sysctl设置将性能事件的所有使用限制为CAP_PERFMON功能（5.8之前的内核版本为CAP_SYS_ADMIN）。&lt;/p&gt;    &lt;p&gt;请注意，此sysctl设置需要在某些发行版中具备相关的内核补丁。否则，此设置等效于kernel.perf_event_paranoid = 2，它仅限制此功能的子集。&lt;/p&gt;    &lt;p&gt;网络：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;net.ipv4.tcp_syncookies=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这有助于防止SYN泛洪攻击，这种攻击是拒绝服务攻击的一种形式，在这种攻击中，攻击者发送大量虚假的SYN请求，以尝试消耗足够的资源以使系统对合法流量不响应。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;net.ipv4.tcp_rfc1337=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这通过丢弃处于时间等待状态的套接字的RST数据包来防止time-wait状态。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;net.ipv4.conf.all.rp_filter=1        &lt;br /&gt;net.ipv4.conf.default.rp_filter=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这些启用了源验证，以验证从计算机所有网络接口接收到的数据包。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;net.ipv4.conf.all.accept_redirects=0        &lt;br /&gt;net.ipv4.conf.default.accept_redirects=0        &lt;br /&gt;net.ipv4.conf.all.secure_redirects=0        &lt;br /&gt;net.ipv4.conf.default.secure_redirects=0        &lt;br /&gt;net.ipv6.conf.all.accept_redirects=0        &lt;br /&gt;net.ipv6.conf.default.accept_redirects=0        &lt;br /&gt;net.ipv4.conf.all.send_redirects=0        &lt;br /&gt;net.ipv4.conf.default.send_redirects=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这些设置禁用了ICMP重定向，以防止中间人攻击并最大程度地减少信息泄露。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;net.ipv4.icmp_echo_ignore_all=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;此设置使您的系统忽略所有ICMP请求，以避免Smurf攻击，使设备更难以在网络上枚举，并防止通过ICMP时间戳识别时钟指纹。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;net.ipv4.conf.all.accept_source_route=0        &lt;br /&gt;net.ipv4.conf.default.accept_source_route=0        &lt;br /&gt;net.ipv6.conf.all.accept_source_route=0        &lt;br /&gt;net.ipv6.conf.default.accept_source_route=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;源路由是一种允许用户重定向网络流量的机制。由于这可用于执行中间人攻击，在中间人攻击中，出于恶意目的将流量重定向，因此上述设置将会禁用此功能。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;net.ipv6.conf.all.accept_ra=0        &lt;br /&gt;net.ipv6.conf.default.accept_ra=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;恶意的IPv6路由广告可能会导致中间人攻击，因此应将其禁用。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;net.ipv4.tcp_sack=0        &lt;br /&gt;net.ipv4.tcp_dsack=0        &lt;br /&gt;net.ipv4.tcp_fack=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;禁用TCP SACK。ACK通常被利用，并且在许多情况下是不必要的，因此如果您不需要它，则应将其禁用。&lt;/p&gt;    &lt;p&gt;用户空间：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;kernel.yama.ptrace_scope=2&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;ptrace是一个系统调用，它允许程序调试、修改和检查另一个正在运行的进程，从而使攻击者可以轻易修改其他正在运行的程序的内存。设置将ptrace的使用限制为仅具有CAP_SYS_PTRACE功能的进程。或者，将sysctl设置为3以完全禁用ptrace。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;vm.mmap_rnd_bits=32        &lt;br /&gt;vm.mmap_rnd_compat_bits=16&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;ASLR是一种常见的漏洞利用缓解措施，它可以使进程的关键部分在内存中的位置随机化。这可能会使各种各样的漏洞利用更困难，因为它们首先需要信息泄漏。上述设置增加了用于mmap ASLR的熵的位数，从而提高了其有效性。&lt;/p&gt;    &lt;p&gt;这些sysctls的值必须根据CPU体系结构进行设置。以上值与x86兼容，但其他体系结构可能有所不同。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;fs.protected_symlinks=1        &lt;br /&gt;fs.protected_hardlinks=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;仅当在可全局写入的粘性目录之外，当符号链接和关注者的所有者匹配或目录所有者与符号链接的所有者匹配时，才允许遵循符号链接。这还可以防止没有对源文件的读/写访问权限的用户创建硬链接。这两者都阻止了许多常见的TOCTOU漏洞（time-of-check-to-time-of-use）。&lt;/p&gt;    &lt;pre&gt;fs.protected_fifos=2      &lt;br /&gt;fs.protected_regular=2&lt;/pre&gt;    &lt;p&gt;这些阻止了在可能由攻击者控制的环境（例如，全局可写目录）中创建文件，从而使数据欺骗攻击更加困难。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;引导参数&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;引导参数在引导时使用引导加载程序（bootloader）将设置传递给内核。类似于sysctl，可以使用某些设置来提高安全性。引导加载程序通常在引导参数设置方式上有所不同。下面列出了一些示例，但是您应该研究特定bootloader的修改参数的必要步骤。&lt;/p&gt;    &lt;p&gt;如果使用GRUB作为引导程序，请编辑/etc /default/grub并将参数添加到GRUB_CMDLINE_LINUX_DEFAULT=line。&lt;/p&gt;    &lt;p&gt;如果使用Syslinux，请编辑/boot/syslinux/syslinux.cfg并将它们添加到APPEND行中。&lt;/p&gt;    &lt;p&gt;如果使用systemd-boot，请编辑您的加载程序条目，并将其附加到linux行的末尾。&lt;/p&gt;    &lt;p&gt;建议使用以下设置以提高安全性。&lt;/p&gt;    &lt;p&gt;Kernel self-protection：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;slab_nomerge&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这将禁用slab合并，这将通过防止覆盖合并的缓存中的对象并使其更难以影响slab缓存的布局，从而大大增加了堆利用的难度。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;slub_debug=FZ&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这些启用健全性检查（F）和重新分区（Z）。健全性检查会添加各种检查，以防止某些slab操作中的损坏。重新分区会在slab周围添加额外的区域，以检测slab何时被覆盖超过其实际大小，从而有助于检测溢出。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;init_on_alloc=1 init_on_free=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这样可以在分配和空闲时间期间将内存清零，这可以帮助减轻使用后使用的漏洞并清除内存中的敏感信息。如果您的内核版本低于5.3，则这些选项不存在。而是在上述slub_debug选项后面附加“ P”，以获得slub_debug=FZP并添加page_poison=1。由于它们实际上是一种调试功能，刚好具有一些安全性，因此它们在释放时提供的内存擦除形式较弱。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;page_alloc.shuffle=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;此选项使页分配器空闲列表随机化，从而通过降低页分配的可预测性来提高安全性，同时这也提高了性能。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;pti=on&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这将启用内核页表隔离，从而减轻崩溃并防止某些KASLR绕过。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;vsyscall=none&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这将禁用vsyscall，因为它们已过时且已被vDSO取代。 vsyscall也在内存中的固定地址上，使其成为ROP攻击的潜在目标。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;debugfs=off&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这将禁用debugfs，它会公开许多有关内核的敏感信息。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;oops=panic&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;有时某些内核漏洞利用会导致所谓的“oops”。此参数将引发内核对此类事件panic，从而防止这些攻击。但是，有时错误的驱动程序会导致无害的操作，这会导致系统崩溃，这意味着此引导参数只能在某些硬件上使用。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;module.sig_enforce=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这仅允许加载已使用有效密钥签名的内核模块，使加载恶意内核模块更加困难。&lt;/p&gt;    &lt;p&gt;这可以防止加载所有树外内核模块（包括DKMS模块），除非您已对其进行签名，这意味着诸如VirtualBox或Nvidia驱动程序之类的模块可能不可用，但根据您的设置可能并不重要。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;lockdown=confidentiality&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;内核锁定LSM可以消除用户空间代码滥用以升级为内核特权并提取敏感信息的许多方法。为了在用户空间和内核之间实现清晰的安全边界，此LSM是必需的。上面的选项在confidentiality模式（最严格的选项）中启用此功能。这意味着module.sig_enforce=1。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;mce=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这将导致内核对ECC内存中无法利用的错误panic，而这些错误可能会被利用。对于没有ECC内存的系统，这是不必要的。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;quiet loglevel=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这些参数可防止引导期间信息泄漏，并且必须与上面的kernel.printk sysctl结合使用。&lt;/p&gt;    &lt;p&gt;CPU缓解：&lt;/p&gt;    &lt;p&gt;最好启用适用于您的CPU的所有CPU缓解措施，以确保您不受已知漏洞的影响。这是启用所有内置缓解措施的列表：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;spectre_v2=on spec_store_bypass_disable=on tsx=off tsx_async_abort=full,nosmt mds=full,nosmt l1tf=full,force nosmt=force kvm.nx_huge_pages=force&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;您必须研究系统受其影响的CPU漏洞，并相应地选择上述缓解措施。请记住，您将需要安装微代码更新，以完全免受这些漏洞的影响。但所有这些操作都可能导致性能显着下降。&lt;/p&gt;    &lt;p&gt;结果：&lt;/p&gt;    &lt;p&gt;如果遵循了以上所有建议（不包括特定的CPU缓解措施），则将具有：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;slab_nomerge slub_debug=FZ init_on_alloc=1 init_on_free=1 page_alloc.shuffle=1 pti=on vsyscall=none debugfs=off oops=panic module.sig_enforce=1 lockdown=confidentiality mce=0 quiet loglevel=0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;如果将GRUB用作引导加载程序，则可能需要重新生成GRUB配置文件才能应用这些文件。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;hidepid&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;proc是一个伪文件系统，其中包含有关系统上当前正在运行的所有进程的信息。默认情况下，所有用户都可以访问此程序，这可能使攻击者可以窥探其他进程。&lt;/p&gt;    &lt;p&gt;要只允许用户看到自己的进程，而不能看到其他用户的进程，则必须使用hidepid=2，gid=proc挂载选项来挂载/proc。gid=proc将proc组从此功能中排除，因此您可以将特定的用户或进程列入白名单。添加这些选项的一种方法是编辑/etc/fstab并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;proc /proc proc nosuid,nodev,noexec,hidepid=2,gid=proc 0 0&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;systemd-logind仍然需要查看其他用户的进程，因此，要使用户会话在systemd系统上正常工作，必须创建/etc/systemd/system/systemd-logind.service.d/hidepid.conf并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;[Service]        &lt;br /&gt;SupplementaryGroups=proc        &lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;减少内核攻击面&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;最好禁用不是绝对必要的任何功能，以最大程度地减少潜在的内核攻击面。这些功能不必一定很危险，它们可以只是被删除以减少攻击面的良性代码。切勿禁用您不了解的随机事物。以下是一些可能有用的示例，具体取决于您的设置。&lt;/p&gt;    &lt;p&gt;引导参数：&lt;/p&gt;    &lt;p&gt;引导参数通常可以用来减少攻击面，这样的例子之一是：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;ipv6.disable=1&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这将禁用整个IPv6堆栈，如果您尚未迁移到该堆栈，则可能不需要该堆栈。如果正在使用的IPv6，请不要使用此引导参数。&lt;/p&gt;    &lt;p&gt;将内核模块列入黑名单：&lt;/p&gt;    &lt;p&gt;内核允许非特权的用户通过模块自动加载来间接导致某些模块被加载。这使攻击者可以自动加载易受攻击的模块，然后加以利用。一个这样的示例是CVE-2017-6074，其中攻击者可以通过启动DCCP连接来触发DCCP内核模块的加载，然后利用该内核模块中的漏洞。&lt;/p&gt;    &lt;p&gt;可以通过将文件插入/etc/modprobe.d并将指定的内核模块列入黑名单的方法，将特定的内核模块列入黑名单。&lt;/p&gt;    &lt;p&gt;Install参数告诉modprobe运行特定命令，而不是像往常一样加载模块。/bin/false是仅返回1的命令，该命令实际上不会执行任何操作。两者都告诉内核运行/bin/false 而不是加载模块，这将防止攻击者利用该模块。以下是最有可能不需要的内核模块：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;install dccp /bin/false        &lt;br /&gt;install sctp /bin/false        &lt;br /&gt;install rds /bin/false        &lt;br /&gt;install tipc /bin/false        &lt;br /&gt;install n-hdlc /bin/false        &lt;br /&gt;install ax25 /bin/false        &lt;br /&gt;install netrom /bin/false        &lt;br /&gt;install x25 /bin/false        &lt;br /&gt;install rose /bin/false        &lt;br /&gt;install decnet /bin/false        &lt;br /&gt;install econet /bin/false        &lt;br /&gt;install af_802154 /bin/false        &lt;br /&gt;install ipx /bin/false        &lt;br /&gt;install appletalk /bin/false        &lt;br /&gt;install psnap /bin/false        &lt;br /&gt;install p8023 /bin/false        &lt;br /&gt;install p8022 /bin/false        &lt;br /&gt;install can /bin/false        &lt;br /&gt;install atm /bin/false&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;特别是模糊的网络协议会增加大量的远程攻击面。此黑名单：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;DCCP — Datagram Congestion Control Protocol        &lt;br /&gt;        &lt;br /&gt;SCTP — Stream Control Transmission Protocol        &lt;br /&gt;        &lt;br /&gt;RDS — Reliable Datagram Sockets        &lt;br /&gt;        &lt;br /&gt;TIPC — Transparent Inter-process Communication        &lt;br /&gt;        &lt;br /&gt;HDLC — High-Level Data Link Control        &lt;br /&gt;        &lt;br /&gt;AX25 — Amateur X.25        &lt;br /&gt;        &lt;br /&gt;NetRom        &lt;br /&gt;        &lt;br /&gt;X25        &lt;br /&gt;        &lt;br /&gt;ROSE        &lt;br /&gt;        &lt;br /&gt;DECnet        &lt;br /&gt;        &lt;br /&gt;Econet        &lt;br /&gt;        &lt;br /&gt;af_802154 — IEEE 802.15.4        &lt;br /&gt;        &lt;br /&gt;IPX — Internetwork Packet Exchange        &lt;br /&gt;        &lt;br /&gt;AppleTalk        &lt;br /&gt;        &lt;br /&gt;PSNAP — Subnetwork Access Protocol        &lt;br /&gt;        &lt;br /&gt;p8023 — Novell raw IEEE 802.3        &lt;br /&gt;        &lt;br /&gt;p8022 — IEEE 802.2        &lt;br /&gt;        &lt;br /&gt;CAN — Controller Area Network        &lt;br /&gt;        &lt;br /&gt;ATM        &lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;    &lt;pre&gt;      &lt;p&gt;install cramfs /bin/false        &lt;br /&gt;install freevxfs /bin/false        &lt;br /&gt;install jffs2 /bin/false        &lt;br /&gt;install hfs /bin/false        &lt;br /&gt;install hfsplus /bin/false        &lt;br /&gt;install squashfs /bin/false        &lt;br /&gt;install udf /bin/false&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;将各种稀有文件系统列入黑名单。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;install cifs /bin/true        &lt;br /&gt;install nfs /bin/true        &lt;br /&gt;install nfsv3 /bin/true        &lt;br /&gt;install nfsv4 /bin/true        &lt;br /&gt;install gfs2 /bin/true&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;如果不使用网络文件系统，也可以将其列入黑名单。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;install vivid /bin/false&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;vivid driver驱动程序仅用于测试目的，并且是特权提升漏洞的原因，因此应禁用它。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;install bluetooth /bin/false        &lt;br /&gt;install btusb /bin/false&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;禁用具有安全问题历史记录的蓝牙。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;install uvcvideo /bin/false&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这会禁用网络摄像头，以防止其被用来监视您。&lt;/p&gt;    &lt;p&gt;您也可以将麦克风模块列入黑名单，但这在系统之间可能会有所不同。要查找模块的名称，请在/proc/asound/modules中查找并将其列入黑名单。例如，一个这样的模块是snd_hda_intel。&lt;/p&gt;    &lt;p&gt;请注意，尽管有时麦克风的内核模块与扬声器的模块相同。这意味着像这样禁用麦克风也可能会无意中禁用任何扬声器，虽然扬声器也有可能变成麦克风，所以这不一定是消极的结果。&lt;/p&gt;    &lt;p&gt;最好从物理上删除这些设备，或者至少在BIOS/UEFI中禁用它们。禁用内核模块并不总是那么有效。&lt;/p&gt;    &lt;p&gt;rfkill：&lt;/p&gt;    &lt;p&gt;可以通过rfkill将无线设备列入黑名单，以进一步减少远程攻击面。要将所有无线设备列入黑名单，请执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;rfkill block all&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;WiFi可以通过以下方式解锁：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;rfkill unblock wifi&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;在使用systemd的系统上，rfkill在所有会话中均保持不变，但是，在使用其他init系统的系统上，您可能必须创建一个init脚本以在引导时执行这些命令。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;其他内核指针泄漏&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;前面的部分已经防止了一些内核指针泄漏，但是还有更多泄漏。&lt;/p&gt;    &lt;p&gt;在文件系统上，/boot中存在内核映像和System.map文件。/usr/src和/{,usr/} lib/modules目录中还有其他敏感的内核信息。您应该限制这些目录的文件权限，以使它们只能由root用户读取。您还应该删除System.map文件，因为除高级调试外，它们都不需要。&lt;/p&gt;    &lt;p&gt;此外，某些日志记录守护程序（例如systemd的journalctl）包括内核日志，可用于绕过上述dmesg_restrict保护。从adm组中删除用户通常足以撤销对以下日志的访问：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;gpasswd -d $user adm&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;限制对sysfs的访问&lt;/strong&gt;    &lt;p&gt;sysfs是伪文件系统，可提供大量的内核和硬件信息。它通常安装在/sys上。sysfs导致大量信息泄漏，尤其是内核指针泄漏。Whonix的security-misc软件包包括hide-hardware-info脚本，该脚本限制访问此目录以及/proc中的一些脚本，以试图隐藏潜在的硬件标识符并防止内核指针泄漏。&lt;/p&gt;    &lt;p&gt;该脚本是可配置的，并允许基于组将特定的应用程序列入白名单。建议应用此方法，并使其在启动时使用init脚本执行。或者这样做成systemd服务[1]。&lt;/p&gt;    &lt;p&gt;为了使基本功能在使用systemd的系统上运行，必须将一些系统服务列入白名单。这可以通过创建/etc/systemd/system/user@.service.d/sysfs.conf并添加以下内容来完成：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;[Service]        &lt;br /&gt;SupplementaryGroups=sysfs&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;但是，这不能解决所有问题。许多应用程序可能仍会中断，您需要将它们正确列入白名单。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;Linux强化&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;某些发行版（例如Arch Linux）包括强化的内核程序包。它包含许多强化补丁程序和更注重安全性的内核配置。如果可能的话，建议安装它。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;Grsecurity&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Grsecurity是一组内核修补程序，可以大大提高内核安全性。这些补丁曾经可以免费获得，但是现在需要购买了。如果可用，则强烈建议您获取它。Grsecurity提供了最新的内核和用户空间保护。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;内核运行时防护&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Linux Kernel Runtime Guard（LKRG）是一个内核模块，可确保运行时内核的完整性并检测漏洞。它可以杀死整个类别的内核漏洞。但这并不是一个完美的缓解方法，因为LKRG在设计上可以绕开。它仅适用于现成的恶意软件。但是，尽管可能性不大，但LKRG本身可能会像其他任何内核模块一样公开新的漏洞。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;自编译内核&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;建议编译您自己的内核，同时启用尽可能少的内核模块和尽可能多的安全性功能，以将内核的受攻击面保持在绝对最低限度。&lt;/p&gt;    &lt;p&gt;另外，应用内核强化补丁，例如如上所述的linux-hardened或grsecurity。&lt;/p&gt;    &lt;p&gt;发行版编译的内核还具有公共内核指针/符号，这对于漏洞利用非常有用。编译自己的内核将为您提供独特的内核符号，连同kptr_restrict，dmesg_restrict和其他针对内核指针泄漏的强化措施，将使攻击者更加难以创建依赖于内核指针知识的漏洞利用程序。&lt;/p&gt;    &lt;p&gt;您就可以从Whonix的强化内核[2]中汲取灵感或使用它。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;3&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;强制访问措施&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;强制访问控制（MAC）系统对程序可以访问的内容进行细粒度的控制。这意味着您的浏览器将无权访问您的整个主目录或类似目录。&lt;/p&gt;    &lt;p&gt;最常用的MAC措施是SELinux和AppArmor。SELinux比AppArmor更安全，因为它的粒度更细。例如，它是基于inode而不是基于路径的，允许强制执行明显更严格的限制，可以过滤内核ioctl等。不幸的是，这是以难以使用和难以学习为代价的，因此某些人可能会首选AppArmor。&lt;/p&gt;    &lt;p&gt;要在内核中启用AppArmor，必须设置以下引导参数：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;apparmor=1 security=apparmor&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;要启用SELinux，请设置以下参数：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;selinux=1 security=selinux&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;请记住，仅启用MAC措施本身并不能神奇地提高安全性。您必须制定严格的政策才能充分利用它。例如，要创建AppArmor配置文件，请执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;aa-genprof $path_to_program&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;打开程序，然后像往常一样开始使用它。AppArmor将检测需要访问哪些文件，并将它们添加到配置文件中（如果您选择的话）。但是，仅凭这一点不足以提供高质量的配置文件。请参阅AppArmor文档[3]以获取更多详细信息。&lt;/p&gt;    &lt;p&gt;如果您想更进一步，则可以通过实施initramfs勾子来设置一个完整的系统MAC策略，该策略限制每个单个用户空间进程，该挂钩对init系统强制实施MAC策略。这就是Android使用SELinux的方式，以及Whonix未来将如何使用AppArmor的方式。对于加强实施最小特权原则的强大安全模型是必要的。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;4&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;沙箱&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;应用沙箱&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;沙箱可让您在隔离的环境中运行程序，该环境对系统的其余部分具有有限的访问权限或完全没有访问权限。您可以使用它们来保护应用程序安全或运行不受信任的程序。&lt;/p&gt;    &lt;p&gt;建议与AppArmor或SELinux一起在单独的用户帐户中使用Bubblewrap到沙箱程序。您也可以考虑改用gVisor，它的优点是为每个来宾提供了自己的内核。&lt;/p&gt;    &lt;p&gt;这些方法中的任何一个都可以用来创建一个功能强大的沙箱，并且暴露的攻击面最小。如果您不想自己创建沙箱，请在完成后考虑使用Whonix的sandbox-app-launcher。您不应该使用Firejail[4]。&lt;/p&gt;    &lt;p&gt;诸如Docker和LXC之类的容器解决方案经常被误导为沙盒形式。它们太宽松了，无法广泛支持各种应用程序，因此不能认为它们是强大的应用程序沙箱。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;常见沙箱逃逸&lt;/strong&gt;&lt;/p&gt;    &lt;ul&gt;      &lt;li&gt;        &lt;p&gt;PulseAudio：PulseAudio是一种常见的声音服务器，但在编写时并未考虑隔离或沙盒的问题，这使其成为重复出现的沙盒逃逸漏洞。为了防止这种情况，建议您从沙箱中阻止对PulseAudio的访问，或者从系统中完全卸载它。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;D-Bus：D-Bus是台式机Linux上最流行的进程间通信形式，但它也是沙箱逃逸的另一种常见途径，因为它允许与服务自由交互。这些漏洞的一个例子就是Firejail。您应该从沙箱中阻止对D-Bus的访问，或者通过MAC以细粒度的规则进行调解。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;GUI隔离：任何Xorg窗口都可以访问另一个窗口。这允许琐碎的键盘记录或屏幕截图程序，甚至可以记录诸如root密码之类的内容。您可以使用嵌套的X11服务器（例如Xpra或Xephyr和bubblewrap）将Xorg窗口沙箱化。默认情况下，Wayland将窗口彼此隔离，这将是一个比Xorg更好的选择，尽管Wayland可能不如Xorg普遍可用，因为它在开发中较早。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;ptrace：如前所述，ptrace是一个系统调用，可能会被滥用破坏在沙箱外部运行的进程。为避免这种情况，您可以通过sysctl启用内核YAMA ptrace限制，也可以在seccomp过滤器中将ptrace syscall列入黑名单。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;TIOCSTI：TIOCSTI是一个ioctl，它允许注入终端命令，并为攻击者提供了一种简单的机制，可以在同一用户会话内的其他进程之间横向移动。可以通过将seccomp过滤器中的ioctl列入黑名单或使用bubblewrap的--new-session参数来缓解这种攻击。&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;Systemd沙箱：虽然不建议使用systemd，但有些系统可能无法切换。这些人至少可以使用沙盒服务，因此他们只能访问所需的内容。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;p&gt;这是一个沙箱化systemd服务的示例：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;[Service]        &lt;br /&gt;CapabilityBoundingSet=CAP_NET_BIND_SERVICE        &lt;br /&gt;ProtectSystem=strict        &lt;br /&gt;ProtectHome=true        &lt;br /&gt;ProtectKernelTunables=true        &lt;br /&gt;ProtectKernelModules=true        &lt;br /&gt;ProtectControlGroups=true        &lt;br /&gt;ProtectKernelLogs=true        &lt;br /&gt;ProtectHostname=true        &lt;br /&gt;ProtectClock=true        &lt;br /&gt;ProtectProc=invisible        &lt;br /&gt;ProcSubset=pid        &lt;br /&gt;PrivateTmp=true        &lt;br /&gt;PrivateUsers=yes        &lt;br /&gt;PrivateDevices=true        &lt;br /&gt;MemoryDenyWriteExecute=true        &lt;br /&gt;NoNewPrivileges=true        &lt;br /&gt;LockPersonality=true        &lt;br /&gt;RestrictRealtime=true        &lt;br /&gt;RestrictSUIDSGID=true        &lt;br /&gt;RestrictAddressFamilies=AF_INET        &lt;br /&gt;RestrictNamespaces=yes        &lt;br /&gt;SystemCallFilter=write read openat close brk fstat lseek mmap mprotect munmap rt_sigaction rt_sigprocmask ioctl nanosleep select access execve getuid arch_prctl set_tid_address set_robust_list prlimit64 pread64 getrandom        &lt;br /&gt;SystemCallArchitectures=native        &lt;br /&gt;UMask=0077        &lt;br /&gt;IPAddressDeny=any        &lt;br /&gt;AppArmorProfile=/etc/apparmor.d/usr.bin.example&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;所有选项的说明：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;CapabilityBoundingSet=— Specifies the capabilitiesthe process is given.        &lt;br /&gt;        &lt;br /&gt;ProtectHome=true— Makes all home directories inaccessible.        &lt;br /&gt;        &lt;br /&gt;ProtectKernelTunables=true— Mounts kernel tunables such as those modified throughsysctlas read-only.        &lt;br /&gt;        &lt;br /&gt;ProtectKernelModules=true— Denies module loading and unloading.        &lt;br /&gt;        &lt;br /&gt;ProtectControlGroups=true— Mounts all control group hierarchies as read-only.        &lt;br /&gt;        &lt;br /&gt;ProtectKernelLogs=true— Prevents accessing the kernel logs.        &lt;br /&gt;        &lt;br /&gt;ProtectHostname=true— Prevents changes to the system hostname.        &lt;br /&gt;        &lt;br /&gt;ProtectClock— Prevents changes to the system clock.        &lt;br /&gt;        &lt;br /&gt;ProtectProc=invisible— Hides all outside processes.        &lt;br /&gt;        &lt;br /&gt;ProcSubset=pid— Permits access to only the pid subset of/proc.        &lt;br /&gt;        &lt;br /&gt;PrivateTmp=true— Mounts an empty tmpfs over/tmpand/var/tmp, therefore hiding their previous contents.        &lt;br /&gt;        &lt;br /&gt;PrivateUsers=true— Sets up an empty user namespace to hide other user accounts on the system.        &lt;br /&gt;        &lt;br /&gt;PrivateDevices=true— Creates a new/devmount with minimal devices present.        &lt;br /&gt;        &lt;br /&gt;MemoryDenyWriteExecute=true— Enforces a memory W^X policy.        &lt;br /&gt;        &lt;br /&gt;NoNewPrivileges=true— Prevents escalating privileges.        &lt;br /&gt;        &lt;br /&gt;LockPersonality=true— Locks down thepersonality()syscall to prevent switching execution domains.        &lt;br /&gt;        &lt;br /&gt;RestrictRealtime=true— Prevents attempts to enable realtime scheduling.        &lt;br /&gt;        &lt;br /&gt;RestrictSUIDSGID=true— Prevents executing setuid or setgid binaries.        &lt;br /&gt;        &lt;br /&gt;RestrictAddressFamilies=AF_INET— Restricts the usable socket address families to IPv4 only (AF_INET).        &lt;br /&gt;        &lt;br /&gt;RestrictNamespaces=true— Prevents creating any new namespaces.        &lt;br /&gt;        &lt;br /&gt;SystemCallFilter=...— Restricts the allowed syscalls to the absolute minimum. If you aren&amp;apos;t willing to maintain your own custom seccomp filter, then systemd provides many [predefined system call sets](https://www.freedesktop.org/software/systemd/man/systemd.exec.html#System Call Filtering) that you can use.@system-servicewill be suitable for many use cases.        &lt;br /&gt;        &lt;br /&gt;SystemCallArchitectures=native— Prevents executing syscalls from other CPU architectures.        &lt;br /&gt;        &lt;br /&gt;UMask=0077— Sets the umaskto a more restrictive value.        &lt;br /&gt;        &lt;br /&gt;IPAddressDeny=any— Blocks all incoming and outgoing traffic to/from any IP address. SetIPAddressAllow=to configure a whitelist. Alternatively, setup a network namespace withPrivateNetwork=true.        &lt;br /&gt;        &lt;br /&gt;AppArmorProfile=...— Runs the process under the specified AppArmor profile.&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;您不能仅将此示例配置复制到您的配置中，每种服务的要求各不相同，并且必须针对每种服务微调沙箱。要了解有关您可以设置的所有选项的更多信息，请阅读systemd.exec手册页[5]。&lt;/p&gt;    &lt;p&gt;如果您使用的系统不是systemd而是init，那么可以使用bubblewrap轻松复制所有这些选项。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;gVisor&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;普通沙箱固有地与主机共享同一内核。您信任我们已经评估为不安全的内核，可以正确限制这些程序。由于主机内核的整个攻击面已完全暴露，因此沙盒中的内核利用程序可以绕过任何限制。已经进行了一些努力来限制使用seccomp的攻击面，但不足以完全解决此问题。&lt;/p&gt;    &lt;p&gt;GVisor是解决此问题的方法。它为每个应用程序提供了自己的内核，该内核以内存安全的语言重新实现了Linux内核的大部分系统调用，从而提供了明显更强的隔离性。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;虚拟机&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;虽然不是传统的“沙盒”，但虚拟机通过虚拟化全新系统来分离进程，从而提供了非常强大的隔离性。KVM是内核模块，它允许内核充当管理程序，而QEMU是利用KVM的仿真器。Virt-manager和GNOME Boxs都是良好且易于使用的GUI，用于管理KVM / QEMU虚拟机。不建议使用Virtualbox的原因[6]有很多。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;5&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;强化内存分配器&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;hardened_malloc是一种硬化的内存分配器，可为堆内存损坏漏洞提供实质性的保护。它很大程度上基于OpenBSD的malloc设计，但具有许多改进。&lt;/p&gt;    &lt;p&gt;可以通过LD_PRELOAD环境变量针对每个应用程序使用hardened_malloc。例如，假设您编译的库位于/usr/lib/libhardened_malloc.so，则可以执行：&lt;/p&gt;    &lt;pre&gt;LD_PRELOAD=&amp;quot;/usr/lib/libhardened_malloc.so&amp;quot; $program&lt;/pre&gt;    &lt;p&gt;通过全局预加载该库，也可以在系统范围内使用它，这是使用它的推荐方法。为此，请编辑/etc/ld.so.preload并插入：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;/usr/lib/libhardened_malloc.so&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;尽管大多数应用程序都可以正常工作，但hardened_malloc可能会破坏某些应用程序。建议使用以下选项编译hardened_malloc以最大程度地减少损坏：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;CONFIG_SLAB_QUARANTINE_RANDOM_LENGTH=0 CONFIG_SLAB_QUARANTINE_QUEUE_LENGTH=0 CONFIG_GUARD_SLABS_INTERVAL=8&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;您还应该使用sysctl设置以下内容，以适应hardened_malloc创建的大量保护页：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;vm.max_map_count=524240&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;Whonix项目[7]为基于Debian的发行版提供了hardened_malloc软件包。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;6&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;强化编译标志&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;编译自己的程序可以带来很多好处，因为它使您能够优化程序的安全性。但是，执行完全相反的操作并降低安全性很容易，如果您不确定自己在做什么，请跳过本节。在基于源的发行版（例如Gentoo）上，这将是最简单的，但也可以在其他发行版上这样做。&lt;/p&gt;    &lt;p&gt;某些编译选项可用于添加其他漏洞利用缓解措施，从而消除整个类别的常见漏洞。您可能听说过常规保护，例如位置独立可执行文件，堆栈粉碎保护程序，立即绑定，只读重定位和FORTIFY_SOURCE，但是本节将不做介绍，因为它们已被广泛采用。相反，它将讨论诸如控制流完整性和影子堆栈之类的现代漏洞利用缓解措施。&lt;/p&gt;    &lt;p&gt;本节涉及主要用C或C ++编写的本机程序。您必须使用Clang编译器，因为这些功能在GCC上不可用。请记住，由于未广泛采用这些缓解措施，因此某些应用程序在启用它们后可能无法运行。&lt;/p&gt;    &lt;p&gt;控制流完整性（CFI）是一种缓解漏洞利用的方法，旨在防止诸如ROP或JOP之类的代码重用攻击。由于更广泛采用的缓解措施（例如NX）使过时的利用技术过时了，因此使用这些技术利用了很大一部分漏洞。Clang支持细粒度的前沿CFI，这意味着它可以有效缓解JOP攻击。Clang的CFI本身并不能减轻ROP；您还必须使用下面记录的单独机制。要启用此功能，必须应用以下编译标志：-flto -fvisibility=hidden -fsanitize=cfi&lt;/p&gt;    &lt;p&gt;影子堆栈通过将程序复制到其他隐藏堆栈中来保护程序的返回地址。然后比较主堆栈和影子堆栈中的返回地址，看两者是否不同。如果是这样，则表明存在攻击，程序将中止，从而减轻了ROP攻击。Clang具有称为ShadowCallStack的功能，可以完成此操作，但是，仅在ARM64上可用。要启用此功能，必须应用以下编译标志：-fsanitize=shadow-call-stack&lt;/p&gt;    &lt;p&gt;如果上述ShadowCallStack不是一个选项，则可以选择使用具有相似目标的SafeStack。但是，不幸的是，此功能有许多漏洞，因此效果不甚理想。如果仍然希望启用此功能，则必须应用以下编译标志：-fsanitize=safe-stack&lt;/p&gt;    &lt;p&gt;最常见的内存损坏漏洞之一是未初始化的内存。Clang有一个选项可以使用零或特定模式自动初始化变量。建议将变量初始化为零，因为使用其他模式比利用漏洞缓解功能更适合发现错误。要启用此功能，必须应用以下编译标志：-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang 但该选项的存在目前正在辩论[8]中。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;7&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;内存安全语言&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;用内存安全语言编写的程序会自动受到保护，免受各种安全漏洞的影响，这些安全漏洞包括缓冲区溢出，未初始化的变量，售后使用等。Microsoft和Google的安全研究人员进行的研究证明，已发现的大多数漏洞都是内存安全问题。这样的内存安全语言的示例包括Rust，Swift和Java，而内存不安全语言的示例包括C和C ++。如果可行，应使用内存安全替代品替换尽可能多的程序。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;8&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;Root账户&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;root可以执行任何操作，并且可以访问您的整个系统。因此，应尽可能将其锁定，以使攻击者无法轻松获得root用户访问权限。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;/etc/securetty&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;/etc/securetty文件指定允许您以root用户身份登录的位置。该文件应保留为空，以便任何人都不能从终端上这样做。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;限制su&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;su可让您从终端切换用户。默认情况下，它尝试以root用户身份登录。要将su的使用限制在wheel组中，请编辑/etc/pam.d/su和/etc/pam.d/su-l并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;auth required pam_wheel.so use_uid&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;您应该在wheel组中拥有尽可能少的用户。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;锁定root账户&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;要锁定root帐户以防止任何人以root身份登录，请执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;passwd -l root&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;在执行此操作之前，请确保您具有获取根的替代方法（例如，从活动USB引导并更改为文件系统的chroot），以免您无意中将自己锁定在系统之外。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;拒绝通过SSH的远程root登陆&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;为了防止某人通过SSH以root身份登录，请编辑/etc/ssh/sshd_config并添加：&lt;/p&gt;    &lt;pre&gt;PermitRootLogin no&lt;/pre&gt;    &lt;strong&gt;增加散列回合数&lt;/strong&gt;    &lt;p&gt;您可以增加shadow使用的哈希回合数，从而通过迫使攻击者计算更多的哈希值来破解您的密码，从而提高哈希密码的安全性。默认情况下，shadow使用5000次回合，但是您可以将其增加到任意数量。尽管配置的回合越多，登录速度就越慢。编辑/etc/pam.d/passwd并添加回合选项。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;password required pam_unix.so sha512 shadow nullok rounds=65536&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这使shadow执行65536次散列回合。&lt;/p&gt;    &lt;p&gt;应用此设置后，密码不会自动重新加密，因此您需要使用以下方法重置密码：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;passwd $username&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;限制Xorg root访问&lt;/strong&gt;    &lt;p&gt;默认情况下，某些发行版以root用户身份运行Xorg，这是一个问题，因为Xorg包含大量古老而又复杂的代码，这增加了巨大的攻击面，并使其更有可能拥有可以获取root特权的漏洞利用程序。要阻止它作为root用户执行，请编辑/etc/X11/Xwrapper.config并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;needs_root_rights = no&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;安全访问root&lt;/strong&gt;    &lt;p&gt;恶意软件可以使用多种方法来嗅探root帐户的密码。因此，访问根帐户的传统方式是不安全的，最好根本不访问根，但这实际上是不可行的。本节详细介绍了访问根帐户的最安全方法。在安装操作系统后，应立即应用这些说明，以确保该软件不含恶意软件。&lt;/p&gt;    &lt;p&gt;您绝对不能使用普通用户帐户访问root，因为root可能已被盗用。您也不能直接登录到根帐户。通过执行以下操作，创建一个单独的“管理员”用户帐户，该帐户仅用于访问root用户，而不能用于访问其他用户：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;useradd admin&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;执行并来设置一个非常强的密码：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;passwd admin&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;仅允许该帐户使用您首选的权限提升机制。例如，如果使用sudo，则通过执行以下命令来添加sudoers异常：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;visudo -f /etc/sudoers.d/admin-account&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;然后输入：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;admin ALL=(ALL) ALL&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;确保没有其他帐户可以访问sudo（或您的首选机制）&lt;/p&gt;    &lt;p&gt;现在，要实际登录到该帐户，请先重新启动-例如，这可以防止受损的窗口管理器执行登录欺骗。当提供登录提示时，请通过按键盘上的以下组合键来激活安全注意键：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;Alt + SysRq + k&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这将杀死当前虚拟控制台上的所有应用程序，从而克服登录欺骗攻击。现在，您可以安全地登录到您的管理员帐户，并使用root用户执行任务。完成后，注销管理员帐户，然后重新登录到非特权用户帐户。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;9&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;防火墙&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;防火墙可以控制传入和传出的网络流量，并且可以用来阻止或允许某些类型的流量。除非有特殊原因，否则应始终阻止所有传入流量。建议设置严格的iptables或nftables防火墙。火墙必须针对您的系统进行微调，并且没有一个适合所有防火墙的规则集。建议您熟悉创建防火墙规则。Arch Wiki[9]和手册页[10]都是很好的资源。&lt;/p&gt;    &lt;p&gt;这是基本iptables配置的示例，该配置禁止所有传入的网络流量：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;*filter        &lt;br /&gt;:INPUT DROP [0:0]        &lt;br /&gt;:FORWARD DROP [0:0]        &lt;br /&gt;:OUTPUT ACCEPT [0:0]        &lt;br /&gt;:TCP - [0:0]        &lt;br /&gt;:UDP - [0:0]        &lt;br /&gt;-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT        &lt;br /&gt;-A INPUT -i lo -j ACCEPT        &lt;br /&gt;-A INPUT -m conntrack --ctstate INVALID -j DROP        &lt;br /&gt;-A INPUT -p udp -m conntrack --ctstate NEW -j UDP        &lt;br /&gt;-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP        &lt;br /&gt;-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable        &lt;br /&gt;-A INPUT -p tcp -j REJECT --reject-with tcp-reset        &lt;br /&gt;-A INPUT -j REJECT --reject-with icmp-proto-unreachable        &lt;br /&gt;COMMIT&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;但是，您不应尝试在实际系统上使用此示例。它仅适用于某些台式机系统。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;10&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;身份标识&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;为了保护隐私，最好最大程度地减少可追溯到您的信息量。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;主机名和用户名&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;请勿在主机名或用户名中添加唯一标识的内容。将它们保留为通用名称，例如“host”和“user”，以便它们无法识别您。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;Timezones / Locales / Keymaps&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;如果可能，应将您的时区设置为“ UTC”，将区域设置和键盘映射设置为“ US”。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;机器ID&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;一个独一无二的机器ID被存储在/var/lib/dbus/machine-id （systemd系统是保存在/etc/machine-id）这些应编辑为通用名称，例如Whonix ID。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;b08dfa6083e7567a1921a715000001fb&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;MAC地址欺骗&lt;/strong&gt;    &lt;p&gt;MAC地址是分配给网络接口控制器（NIC）的唯一标识符。每次您连接到网络时（WIFI或以太网）则您的MAC地址已暴露。这使人们可以使用它来跟踪您并在本地网络上唯一地标识您。&lt;/p&gt;    &lt;p&gt;但您不应该完全随机化MAC地址。拥有完全随机的MAC地址是显而易见的，并且会对您脱颖而出的行为产生不利影响。&lt;/p&gt;    &lt;p&gt;MAC地址的OUI（组织唯一标识符）部分标识芯片组的制造商。对MAC地址的这一部分进行随机化处理可能会为您提供以前从未使用过的OUI，数十年来从未使用过的OUI或在您所在的地区极为罕见的OUI，因此使您脱颖而出，很明显地表明您在欺骗MAC地址。&lt;/p&gt;    &lt;p&gt;MAC地址的末尾标识您的特定设备，并且可以用来跟踪您的设备。仅对MAC地址的这一部分进行随机化可防止您被跟踪，同时仍使MAC地址看起来可信。&lt;/p&gt;    &lt;p&gt;要欺骗这些地址，请首先执行以下命令找出您的网络接口名称：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;ip a&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;接下来，安装macchanger并执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;macchanger -e $network_interface&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;要在每次引导时随机分配MAC地址，您应该为您的特定初始化系统创建一个初始化脚本。这是systemd的一个示例：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;[Unit]        &lt;br /&gt;Description=macchanger on eth0        &lt;br /&gt;Wants=network-pre.target        &lt;br /&gt;Before=network-pre.target        &lt;br /&gt;BindsTo=sys-subsystem-net-devices-eth0.device        &lt;br /&gt;After=sys-subsystem-net-devices-eth0.device        &lt;br /&gt;        &lt;br /&gt;[Service]        &lt;br /&gt;ExecStart=/usr/bin/macchanger -e eth0        &lt;br /&gt;Type=oneshot        &lt;br /&gt;        &lt;br /&gt;[Install]        &lt;br /&gt;WantedBy=multi-user.target&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;上面的示例在启动时欺骗了eth0接口的MAC地址。将eth0替换为您的网络接口。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;时间攻击&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;几乎每个系统都有不同的时间。这可用于时钟偏斜指纹攻击，几毫秒的差异足以使用户被暴露识别。&lt;/p&gt;    &lt;p&gt;ICMP时间戳：&lt;/p&gt;    &lt;p&gt;ICMP时间戳会在查询答复中泄漏系统时间。阻止这些攻击的最简单方法是利用防火墙阻止传入连接，或者使内核忽略ICMP请求。&lt;/p&gt;    &lt;p&gt;TCP时间戳：&lt;/p&gt;    &lt;p&gt;TCP时间戳也会泄漏系统时间。内核尝试通过对每个连接使用随机偏移量来解决此问题，但这不足以解决问题。因此应该禁用TCP时间戳，可以通过使用sysctl设置以下内容来完成：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;net.ipv4.tcp_timestamps=0&lt;/p&gt;&lt;/pre&gt;TCP初始化序号：    &lt;p&gt;TCP初始序列号（ISN）是泄漏系统时间的另一种方法。为了减轻这种情况，您必须安装tirdad内核模块，该模块会生成用于连接的随机ISN。&lt;/p&gt;    &lt;p&gt;时间同步：&lt;/p&gt;    &lt;p&gt;时间同步对于匿名性和安全性至关重要。错误的系统时钟可能使您遭受时钟偏斜指纹攻击，或者可以用来为您提供过时的HTTPS证书，从而绕过证书到期或吊销。&lt;/p&gt;    &lt;p&gt;最流行的时间同步方法NTP是不安全的，因为它未经加密和未经身份验证，因此攻击者可以轻易地拦截和修改请求。NTP还会以NTP时间戳格式泄漏本地系统时间，该格式可用于时钟偏斜指纹识别，如前所述。&lt;/p&gt;    &lt;p&gt;因此，您应该卸载所有NTP客户端并禁用systemd-timesyncd（如果正在使用）。您可以通过安全连接（HTTPS或最好是Torion服务）连接到受信任的网站，而不是NTP，并从HTTP标头中提取当前时间。达到此目的的工具是sdwdate或我自己的安全时间同步工具。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;按键指纹&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;可以通过他们在键盘上输入键的方式来对人进行指纹识别。您可以通过键入速度，在两次按键之间的暂停，每次按键被按下和释放的确切时间等方式来唯一地进行指纹识别。可以使用KeyTrac在线进行测试。&lt;/p&gt;    &lt;p&gt;Kloak是一种工具，旨在通过混淆按键和释放事件之间的时间间隔来克服这种跟踪方法。当按键被按下时，它会引入随机延迟，然后由应用程序选择。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;11&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;文件权限&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;默认情况下，文件的权限是非常宽松的。您应该在整个系统中搜索权限不当的文件和目录，并对其进行限制。例如，在诸如Debian之类的某些发行版中，用户的Home目录是全局可读的。&lt;/p&gt;    &lt;p&gt;这可以通过执行以下操作来限制：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;chmod 700 /home/$user&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;另外一些示例是/boot，/usr /src和/ {,usr /} lib/modules 它们包含内核映像，System.map和其他各种文件，所有这些文件都可能泄漏有关内核的敏感信息。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;chmod 700 /boot /usr/src /lib/modules /usr/lib/modules&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;在基于Debian的发行版中，必须使用dpkg-statoverride保留文件许可权。否则，它们将在更新期间被覆盖。&lt;/p&gt;    &lt;p&gt;Whonix的SUID Disabler和Permission Hardener会自动应用本节中详细介绍的步骤。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;setuid / setgid&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;Setuid / SUID允许用户使用二进制文件所有者的特权执行二进制文件。这通常用于允许非特权用户使用通常仅为root用户保留的某些功能。因此，许多SUID二进制文件都有特权升级安全漏洞的历史记录。Setgid / SGID类似，但适用于组而不是用户。要使用setuid或setgid位查找系统上的所有二进制文件，请执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;find / -type f \( -perm -4000 -o -perm -2000 \)&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;然后，您应该删除不使用的程序上的所有不必要的setuid / setgid位，或将其替换为功能。要删除setuid位，请执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;chmod u-s $path_to_program&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;要删除setgid位，执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;chmod g-s $path_to_program&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;要向文件添加功能，请执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;setcap $capability+ep $path_to_program&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;或者，要删除不必要的功能，请执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;setcap -r $path_to_program&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;umask&lt;/strong&gt;    &lt;p&gt;umask设置新创建文件的默认文件权限。默认的umask是0022，它不是很安全，因为它为系统上的每个用户提供了对新创建文件的读取访问权限。要使所有者以外的任何人都不可读新文件，请编辑/etc/profile并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;umask 0077&lt;/p&gt;&lt;/pre&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;12&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;核心转储&lt;/strong&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;核心转储包含特定时间（通常是该程序崩溃时）该程序的已记录内存。它们可能包含敏感信息，例如密码和加密密钥，因此必须将其禁用。&lt;/p&gt;    &lt;p&gt;禁用它们的方法主要有三种：sysctl，systemd和ulimit。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;sysctl&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;通过sysctl设置以下设置：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;kernel.core_pattern=|/bin/false&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;systemd&lt;/strong&gt;    &lt;p&gt;创建/etc/systemd/coredump.conf.d/disable.conf并添加如下内容：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;[Coredump]        &lt;br /&gt;Storage=none&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;ulimit&lt;/strong&gt;    &lt;p&gt;编辑/etc/security/limits.conf并添加如下内容：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;* hard core 0&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;setuid进程&lt;/strong&gt;    &lt;p&gt;即使在进行了这些设置之后，以提升的特权运行的进程仍可能会转储其内存。&lt;/p&gt;    &lt;p&gt;为了防止他们这样做，请通过sysctl设置以下内容：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;fs.suid_dumpable=0&lt;/p&gt;&lt;/pre&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;13&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;Swap&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;与核心转储类似，交换或分页将部分内存复制到磁盘，其中可能包含敏感信息。应该将内核配置为仅在绝对必要时进行交换，相应的sysctl设置：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;vm.swappiness=1&lt;/p&gt;&lt;/pre&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;14&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;PAM&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;PAM是用于用户身份验证的框架。这就是您登录时使用的机制。您可以通过要求使用强密码或在失败的登录尝试后强制执行延迟验证来使其更加安全。&lt;/p&gt;    &lt;p&gt;要强制使用强密码，可以使用pam_pwquality。它强制执行密码的可配置策略。例如，如果您希望密码至少包含16个字符（最小），与旧密码（difok）至少6个不同的字符，至少3个数字（dcredit），至少2个大写字母（ucredit），至少2个字符小写字母（lcredit）和至少3个其他字符（ocredit），然后编辑/etc/pam.d/passwd并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;password required pam_pwquality.so retry=2 minlen=16 difok=6 dcredit=-3 ucredit=-2 lcredit=-2 ocredit=-3 enforce_for_root        &lt;br /&gt;password required pam_unix.so use_authtok sha512 shadow&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;要强制执行延迟验证，可以使用pam_faildelay。要在两次失败的登录尝试之间添加至少4秒的延迟以阻止暴力破解尝试，请编辑/etc/pam.d/system-login并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;auth optional pam_faildelay.so delay=4000000&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;4000000 是4秒（以微秒为单位）。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;15&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;Microcode更新&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;Microcode更新对于修复关键的CPU漏洞（如Meltdown和Spectre等）至关重要。大多数发行版都将这些发行版包含在其软件仓库中，例如Arch Linux和Debian。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;16&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;IPv6隐私扩展&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;IPv6地址是从计算机的MAC地址生成的，从而使您的IPv6地址是唯一的，并直接绑定到计算机。隐私扩展会生成一个随机的IPv6地址，以减轻这种形式的跟踪。请注意，如果您开启了MAC地址欺骗机制或禁用了IPv6，则无需执行这些步骤。&lt;/p&gt;    &lt;p&gt;要启用这些功能，请通过sysctl设置以下设置：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;net.ipv6.conf.all.use_tempaddr=2        &lt;br /&gt;net.ipv6.conf.default.use_tempaddr=2&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;NetworkManager&lt;/strong&gt;    &lt;p&gt;要为NetworkManager启用隐私扩展，请编辑/etc/NetworkManager/NetworkManager.conf并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;[connection]        &lt;br /&gt;ipv6.ip6-privacy=2&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;systemd-networkd&lt;/strong&gt;    &lt;p&gt;要为systemd-networkd启用隐私扩展，请创建/etc/systemd/network/ipv6-privacy.conf并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;[Network]        &lt;br /&gt;IPv6PrivacyExtensions=kernel&lt;/p&gt;&lt;/pre&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;17&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;分区和挂载选项&lt;/strong&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;文件系统应分为多个分区，以对其权限进行细粒度控制。可以添加不同的安装选项以限制可以执行的操作：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;nodev - 禁止使用设备        &lt;br /&gt;        &lt;br /&gt;nosuid - 禁止setuid或setgid位        &lt;br /&gt;        &lt;br /&gt;noexec - 禁止执行任何二进制文件&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;这些安装选项应在/etc/fstab中尽可能设置。如果您不能使用单独的分区，请创建绑定挂载。一个更安全的/etc/fstab的示例：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;/        /          ext4    defaults                              1 1        &lt;br /&gt;/home    /home      ext4    defaults,nosuid,noexec,nodev          1 2        &lt;br /&gt;/tmp     /tmp       ext4    defaults,bind,nosuid,noexec,nodev     1 2        &lt;br /&gt;/var     /var       ext4    defaults,bind,nosuid                  1 2        &lt;br /&gt;/boot    /boot      ext4    defaults,nosuid,noexec,nodev          1 2&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;请注意，可以通过shell脚本绕过noexec[11]。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;18&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;熵&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;熵基本上反应操作系统信息收集的随机程度，对于诸如加密之类的事情至关重要。因此，最好通过安装其他随机数生成器（如haveged和jitterentropy）从各种来源收集尽可能多的熵。&lt;/p&gt;    &lt;p&gt;为了使jitterentropy正确运行，必须通过创建/usr/lib/modules-load.d/jitterentropy.conf并添加以下内容尽早加载内核模块：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;jitterentropy_rng&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;RDRAND&lt;/strong&gt;    &lt;p&gt;RDRAN是提供随机数的CPU指令。如果可用，内核会自动将其用作熵源。但是由于它是专有的并且是CPU本身的一部分，因此无法审核和验证其安全性。您甚至无法对代码进行反向工程。该RNG以前曾遭受过漏洞的攻击，其中有些可能是后门攻击。通过设置以下引导参数可以不信任此功能：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;random.trust_cpu=off&lt;/p&gt;&lt;/pre&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;19&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;以root身份编辑文件&lt;/strong&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;建议不要以root用户身份运行普通的文本编辑器。大多数文本编辑器可以做的不仅仅是简单地编辑文本文件，而且还可以被利用。例如，以root身份打开vi并输入：sh。现在，您具有一个可以访问整个系统的root shell，攻击者可以轻松利用该shell。&lt;/p&gt;    &lt;p&gt;解决方案是使用sudoedit。这会将文件复制到一个临时位置，以普通用户身份打开文本编辑器，编辑该临时文件并以root用户身份覆盖原始文件。这样，实际的编辑器就不会以root身份运行。要使用sudoedit，执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;sudoedit $path_to_file&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;默认情况下，它使用vi，但是可以通过EDITOR或SUDO_EDITOR环境变量来切换默认编辑器。例如，要使用nano，请执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;EDITOR=nano sudoedit $path_to_file&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;可以在/etc/environment中全局设置此环境变量。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;20&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;特定发行版的安全强化&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;HTTP包管理器镜像&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;默认情况下，Linux发行版通常使用HTTP或HTTP和HTTPS镜像的混合来从其软件存储库下载软件包。人们认为这很好，因为程序包管理器会在安装前验证程序包的签名。但是，从历史上看，已经有很多绕过此方法的地方。您应将软件包管理器配置为从HTTPS镜像专门下载以进行深度防御。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;APT seccomp-bpf&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;自软件包管理器Debian Buster以来，APT已支持可选的seccomp-bpf过滤。这限制了允许执行APT的系统调用，这可能严重限制攻击者尝试利用APT中的漏洞时对系统造成危害的能力。要启用此功能，请创建/etc/apt/apt.conf.d/40sandbox并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;APT::Sandbox::Seccomp &amp;quot;true&amp;quot;;&lt;/p&gt;&lt;/pre&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;21&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;物理安全&lt;/strong&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;全盘加密可确保对驱动器上的所有数据进行加密，并且不会被物理攻击者读取。大多数发行版都支持在安装过程中启用加密，请确保设置了强密码。您也可以使用dm-crypt手动加密驱动器。&lt;/p&gt;    &lt;p&gt;请注意，全盘加密不包括/boot，这样仍然可以修改内核、引导加载程序和其他关键文件。为了完全防止篡改，您还必须实施经过验证的引导。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;BIOS / UEFI强化&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;如果您仍在使用旧版BIOS，则应迁移到UEFI，以利用较新的安全功能。大多数BIOS或UEFI实现都支持设置密码。最好启用它并设置一个非常强壮的密码。虽然这是很弱的保护，因为重置密码很简单。它通常存储在易失性内存中，因此攻击者只需要能够卸下CMOS电池几秒钟，或者他们就可以使用某些主板上的跳线将其重置。&lt;/p&gt;    &lt;p&gt;您还应该禁用所有未使用的设备和引导选项，例如USB引导，以减少攻击面。&lt;/p&gt;    &lt;p&gt;别忽略BIOS或UEFI的更新，确保将其更新。将其与常规操作系统更新一样重要。&lt;/p&gt;    &lt;p&gt;此外，请参阅《NSA的硬件和固件安全指南[12]》&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;Bootloader密码&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;引导加载程序会在引导过程的早期执行，并负责加载操作系统。保护它非常重要，否则，它可能会被篡改。例如，本地攻击者可以通过在启动时使用init=/bin/bash作为内核参数来轻松获得root shell，该命令告诉内核执行/bin/bash而不是常规的init系统。您可以通过为引导加载程序设置密码来防止这种情况。仅设置引导程序密码不足以完全保护它。还必须按照以下说明设置经过验证的启动。&lt;/p&gt;    &lt;p&gt;Grub：&lt;/p&gt;    &lt;p&gt;要为GRUB设置密码，请执行：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;grub-mkpasswd-pbkdf2&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;输入您的密码，该密码将生成一个字符串。它将类似于“ grub.pbkdf2.sha512.10000.C4009... “ 。创建/etc/grub.d/40_password并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;set superusers=&amp;quot;$username&amp;quot;        &lt;br /&gt;password_pbkdf2 $username $password&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;用grub-mkpasswd-pbkdf2生成的字符串替换“ $ password”。“ $ username”将用于被允许使用GRUB命令行，编辑菜单项和执行任何菜单项的超级用户。对于大多数人来说，这只是“root”。&lt;/p&gt;    &lt;p&gt;重新生成您的配置文件，GRUB现在将受到密码保护。&lt;/p&gt;    &lt;p&gt;要仅限制编辑引导参数并访问GRUB控制台，同时仍然允许您引导，请编辑 /boot/grub/grub.cfg并在 “menuentry &amp;apos;$OSName&amp;apos; ”旁边添加“ --unrestricted”参数。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;menuentry &amp;apos;Arch Linux&amp;apos; --unrestricted&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;您将需要再次重新生成配置文件以应用此更改。&lt;/p&gt;    &lt;p&gt;Syslinux：&lt;/p&gt;    &lt;p&gt;Syslinux可以设置主密码或菜单密码。引导任何条目都需要主密码，而引导特定条目仅需要菜单密码。&lt;/p&gt;    &lt;p&gt;要为Syslinux设置主密码，请编辑/boot/syslinux/syslinux.cfg并添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;MENU MASTER PASSWD $password&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;要设置菜单密码，请编辑/boot/syslinux/syslinux.cfg，并在带有您要密码保护的项目的标签内，添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;MENU PASSWD $password&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;将“$password”替换为您要设置的密码。&lt;/p&gt;    &lt;p&gt;这些密码可以是纯文本，也可以使用MD5，SHA-1，SHA-256或SHA-512进行散列。建议先使用强哈希算法（例如SHA-256或SHA-512）对密码进行哈希处理，以避免将其存储为明文形式。&lt;/p&gt;    &lt;p&gt;systemd-boot：&lt;/p&gt;    &lt;p&gt;systemd-boot具有防止在引导时编辑内核参数的选项。在loader.conf文件中，添加：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;editor no&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;systemd-boot并不正式支持保护内核参数编辑器的密码，但是您可以使用systemd-boot-password来实现。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;验证引导&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;经过验证的引导通过密码验证来确保引导链和基本系统的完整性。这可用于确保物理攻击者无法修改设备上的软件。&lt;/p&gt;    &lt;p&gt;如果没有经过验证的引导，则一旦获得物理访问权限，就可以轻松绕过上述所有预防措施。经过验证的引导不仅像许多人认为的那样是为了物理安全。它还可以用于防止远程恶意软件持久化——如果攻击者设法破坏了整个系统并获得了很高的特权，则经过验证的引导将在重新引导后还原其更改，并确保它们无法持久化。&lt;/p&gt;    &lt;p&gt;经过验证的最常见的引导实现是UEFI安全引导，但是它本身并不是一个完整的实现，因为它仅会验证引导加载程序和内核，这意味着可以通过以下方法：&lt;/p&gt;    &lt;p&gt;仅UEFI安全启动就没有一成不变的信任根，因此物理攻击者仍然可以刷新设备的固件。为了减轻这种情况，请结合使用UEFI安全启动和Intel Boot Guard或AMD Secure Boot。&lt;/p&gt;    &lt;p&gt;远程攻击者（或不使用加密的物理攻击者）可以简单地修改操作系统的任何其他特权部分。例如，如果他们有修改内核的特权，那么他们也可以修改/sbin/init来有效地获得相同的结果。因此，仅验证内核和引导加载程序不会对远程攻击者产生任何影响。为了减轻这种情况，您必须使用dm-verity验证基本操作系统，尽管由于传统Linux发行版的布局，这非常困难且笨拙。&lt;/p&gt;    &lt;p&gt;通常，很难在传统Linux上实现可靠的经过验证的引导实现。&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;USBs&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;USB设备为物理攻击提供了重要的攻击面。例如BadUSB和Stuxnet是此类攻击的范例。最佳实践是禁止所有新连接的USB且仅将受信任设备列入白名单，USBGuard对此非常有用。&lt;/p&gt;    &lt;p&gt;您也可以将nousb用作内核引导参数，以禁用内核中的所有USB支持。可以sysctl设置kernel.deny_new_usb=1&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;DMA攻击&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;直接内存访问（DMA）攻击涉及通过插入某些物理设备来完全访问所有系统内存。这可以通过控制设备可访问的内存区域的IOMMU或将特别易受攻击的内核模块列入黑名单来缓解。&lt;/p&gt;    &lt;p&gt;要启用IOMMU，请设置以下内核引导参数：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;intel_iommu=on amd_iommu=on&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;您只需要为特定的CPU制造商启用该选项，但同时启用这两个选项就没有问题。&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;efi=disable_early_pci_dma&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;通过在非常早的启动过程中禁用所有PCI桥接器上的busmaster位，此选项可修复上述IOMMU中的漏洞[13]。&lt;/p&gt;    &lt;p&gt;此外，Thunderbolt和FireWire通常容易受到DMA攻击。要禁用它们，请将这些内核模块列入黑名单：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;install firewire-core /bin/false        &lt;br /&gt;install thunderbolt /bin/false&lt;/p&gt;&lt;/pre&gt;    &lt;strong&gt;冷启动攻击&lt;/strong&gt;    &lt;p&gt;当攻击者在擦除RAM中的数据之前对其进行分析时，就会发生冷启动攻击。使用现代RAM时，冷启动攻击不太实用，因为RAM通常会在几秒钟或几分钟内清除，除非将其放入冷却液（如液氮或冷冻机）中。攻击者必须在几秒钟内将设备中的RAM棒拔出并将其暴露于液氮中，而且确保用户不会注意到。&lt;/p&gt;    &lt;p&gt;如果冷启动攻击是威胁模型的一部分，请在关机后保护计算机几分钟，以确保没有人可以访问您的RAM记忆棒。您也可以将RAM棒焊接到主板上，以使其更难以卡住。如果使用笔记本电脑，请取出电池，然后直接用充电电缆供电。关机后请拔出电缆，以确保RAM彻底断电无法访问。&lt;/p&gt;    &lt;p&gt;在内核自我保护启动参数部分中，空闲时内存清零选项将用零覆盖内存中的敏感数据。此外，强化的内存分配器可以通过CONFIG_ZERO_ON_FREE配置选项清除用户空间堆内存中的敏感数据。尽管如此，某些数据仍可能保留在内存中。&lt;/p&gt;    &lt;p&gt;此外，现代内核还包括复位攻击缓解措施，该命令可命令固件在关机时擦除数据，尽管这需要固件支持。&lt;/p&gt;    &lt;p&gt;确保正常关闭计算机，以使上述缓解措施可以开始。&lt;/p&gt;    &lt;p&gt;如果以上都不适用您的威胁模型，则可以实施Tails的内存擦除过程，该过程将擦除大部分内存（视频内存除外），并且已被证明是有效的。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;22&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;最佳实践&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;一旦对系统进行了尽可能多的加固，就应该遵循良好的隐私和安全性惯例：&lt;/p&gt;    &lt;p&gt;禁用或删除不需要的东西以最小化攻击面。&lt;/p&gt;    &lt;br /&gt;    &lt;p&gt;保持更新。配置cron任务或init脚本以每天更新系统。&lt;/p&gt;    &lt;p&gt;不要泄漏有关您或您的系统的任何信息，无论它看起来多么渺小。&lt;/p&gt;    &lt;p&gt;遵循常规的安全和隐私建议[14]&lt;/p&gt;    &lt;p&gt;尽管已经进行了强化，但您必须记住Linux仍然是一个有缺陷的操作系统，没有任何强化可以完全修复它。&lt;/p&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;23&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;其他指南&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;您应该进行尽可能多的研究，而不要依赖单一的信息来源。最大的安全问题之一就是用户。这些是我认为有价值的其他指南的链接：&lt;/p&gt;    &lt;ul&gt;      &lt;li&gt;        &lt;p&gt;https://wiki.archlinux.org/index.php/Security&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;https://www.whonix.org/wiki/Documentation&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;https://apps.nsa.gov/iaarchive/library/ia-guidance/security-configuration/operating-systems/guide-to-the-secure-configuration-of-red-hat-enterprise.cfm&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project/Recommended_Settings&lt;/p&gt;&lt;/li&gt;      &lt;li&gt;        &lt;p&gt;https://github.com/a13xp0p0v/kconfig-hardened-check/&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;24&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;术语&lt;/strong&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;您可能需要重新生成GRUB配置，以应用对引导加载程序所做的某些更改。在不同的发行版之间，执行此操作的步骤有时可能会有所不同。例如，在诸如Arch Linux之类的发行版上，应通过执行以下命令来重新生成配置文件：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;grub-mkconfig -o $path_to_grub_config&lt;/p&gt;&lt;/pre&gt;    &lt;p&gt;“$path_to_grub_config”取决于您如何设置系统。它通常是/boot/grub/grub.cfg或/boot/EFI/grub/grub.cfg，但是在执行此命令之前，请务必确保正确。&lt;/p&gt;    &lt;p&gt;另外，在Debian或Ubuntu等发行版上，您应该执行以下命令：&lt;/p&gt;    &lt;pre&gt;      &lt;p&gt;update-grub&lt;/p&gt;&lt;/pre&gt;    &lt;em&gt;      &lt;br /&gt;—&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;        &lt;strong&gt; &lt;/strong&gt;&lt;/strong&gt;&lt;/em&gt;    &lt;em&gt;      &lt;strong&gt;25&lt;/strong&gt;&lt;/em&gt;     &lt;em&gt;—&lt;/em&gt;    &lt;br /&gt;    &lt;strong&gt;能力&lt;/strong&gt;    &lt;p&gt;&lt;/p&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;在Linux内核中，“ root特权”分为各种不同的能力（capabilities）。这在应用最小特权原则时很有帮助——可以给它们仅授予特定的子集，而不是授予进程总的root特权。例如，如果程序只需要设置系统时间，则只需要CAP_SYS_TIME而不是root所有能力。这会限制可能造成的损害，但是，您仍必须谨慎授予能力，因为无论如何，其中许多能力可能会被滥用以获取完整的root特权。&lt;/p&gt;    &lt;p&gt;相关链接：&lt;/p&gt;    &lt;ol&gt;      &lt;li&gt;https://github.com/Whonix/security-misc/blob/master/lib/systemd/system/hide-hardware-info.service&lt;/li&gt;      &lt;li&gt;https://www.whonix.org/wiki/Hardened-kernel&lt;/li&gt;      &lt;li&gt;https://gitlab.com/apparmor/apparmor/-/wikis/Documentation&lt;/li&gt;      &lt;li&gt;https://madaidans-insecurities.github.io/linux.html#firejail&lt;/li&gt;      &lt;li&gt;https://www.freedesktop.org/software/systemd/man/systemd.exec.html&lt;/li&gt;      &lt;li&gt;https://www.whonix.org/wiki/KVM#Why_Use_KVM_Over_VirtualBox.3F&lt;/li&gt;      &lt;li&gt;https://www.whonix.org/wiki/Hardened_Malloc&lt;/li&gt;      &lt;li&gt;https://lists.llvm.org/pipermail/cfe-dev/2020-April/065221.html&lt;/li&gt;      &lt;li&gt;https://wiki.archlinux.org/index.php/Iptables&lt;/li&gt;      &lt;li&gt;https://linux.die.net/man/8/iptables&lt;/li&gt;      &lt;li&gt;https://chromium.googlesource.com/chromiumos/docs/+/master/security/noexec_shell_scripts.md&lt;/li&gt;      &lt;li&gt;https://github.com/nsacyber/Hardware-and-Firmware-Security-Guidance&lt;/li&gt;      &lt;li&gt;https://mjg59.dreamwidth.org/54433.html&lt;/li&gt;      &lt;li&gt;https://madaidans-insecurities.github.io/security-privacy-advice.html&lt;/li&gt;&lt;/ol&gt;    &lt;br /&gt;推荐阅读：《    &lt;a href="https://mp.weixin.qq.com/s?__biz=MzA5OTAyNzQ2OA==&amp;mid=2649753582&amp;idx=1&amp;sn=ca11857d3381f8f8d53efdd260731b71&amp;chksm=888c388dbffbb19b9298488fc1819e48ee5541b683e55fb810c70ffcca5c562610a296f63d9c&amp;scene=21#wechat_redirect" target="_blank"&gt;今年5月，Linux内核的C语言版本将从C89升级至C11&lt;/a&gt;》    &lt;hr&gt;&lt;/hr&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;点击下方卡片关注&lt;/strong&gt;      &lt;strong&gt;分布式实验室&lt;/strong&gt;      &lt;strong&gt;，和&lt;/strong&gt;      &lt;strong&gt;我们&lt;/strong&gt;      &lt;strong&gt;一起&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;关注分布式最佳实践&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;      &lt;img width="20px"&gt;&lt;/img&gt;&lt;/p&gt;    &lt;p&gt;      &lt;strong&gt;▲&lt;/strong&gt;      &lt;strong&gt; 点击上方卡片关注分布式实验室，掌握前沿分布式技术&lt;/strong&gt;&lt;/p&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;新的一年，想一起学习K8s、考CKA证书吗？来，这里有最好的学习方案，线下3天封闭式培训，15人小班课，考不过免费复训。Kubernetes实战班上海站3月25日开班，扫描下方二维码了解详情。&lt;/p&gt;    &lt;p&gt;      &lt;img&gt;&lt;/img&gt;&lt;/p&gt;&lt;/div&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/62230-linux-%E7%B3%BB%E7%BB%9F-%E5%AE%89%E5%85%A8</guid>
      <pubDate>Sat, 30 Apr 2022 21:10:32 CST</pubDate>
    </item>
    <item>
      <title>Linux 打算合併 /dev/random 與 /dev/urandom 遇到的問題</title>
      <link>https://itindex.net/detail/62186-linux-dev-random</link>
      <description>&lt;p&gt;在   &lt;a href="https://news.ycombinator.com/"&gt;Hacker News&lt;/a&gt; 上看到「  &lt;a href="https://news.ycombinator.com/item?id=30848973"&gt;Problems emerge for a unified /dev/*random (lwn.net)&lt;/a&gt;」的，原文是「  &lt;a href="https://lwn.net/Articles/889452/"&gt;Problems emerge for a unified /dev/*random&lt;/a&gt;」(付費內容，但是可以透過 Hacker News 上的連結直接看)。&lt;/p&gt;
 &lt;p&gt;標題提到的兩個 device 的性質會需要一些背景知識，可以參考維基百科上面「  &lt;a href="https://en.wikipedia.org/wiki//dev/random"&gt;/dev/random&lt;/a&gt;」這篇的說明，兩個都是   &lt;a href="https://en.wikipedia.org/wiki/Cryptographically-secure_pseudorandom_number_generator"&gt;CSPRNG&lt;/a&gt;，主要的分別在於   &lt;code&gt;/dev/urandom&lt;/code&gt; 通常不會 block：&lt;/p&gt;
 &lt;blockquote&gt;  &lt;p&gt;The    &lt;code&gt;/dev/urandom&lt;/code&gt; device typically was never a blocking device, even if the pseudorandom number generator seed was not fully initialized with entropy since boot.&lt;/p&gt;&lt;/blockquote&gt;
 &lt;p&gt;而   &lt;code&gt;/dev/random&lt;/code&gt; 不保證不會 block，有可能會因為 entropy 不夠而卡住：&lt;/p&gt;
 &lt;blockquote&gt;  &lt;p&gt;   &lt;code&gt;/dev/random&lt;/code&gt; typically blocked if there was less entropy available than requested; more recently (see below, different OS&amp;apos;s differ) it usually blocks at startup until sufficient entropy has been gathered, then unblocks permanently.&lt;/p&gt;&lt;/blockquote&gt;
 &lt;p&gt;然後順便講一下，因為這是 crypto 相關的設計修改，加上是 kernel level 的界面，安全性以及相容性都會是很在意的點，而 Hacker News 上的討論裡面很多是不太在意這些的，你會看到很多「很有趣」的想法在上面討論 XDDD&lt;/p&gt;
 &lt;p&gt;回到原來的文章，Jason A. Donenfeld (Linux kernel 裡 RNG maintainer 之一，不過近期比較知名的事情還是   &lt;a href="https://www.wireguard.com/"&gt;WireGuard&lt;/a&gt; 的發明人) 最近不斷的在改善 Linux kernel 裡面這塊架構，這次打算直接拿   &lt;code&gt;/dev/random&lt;/code&gt; 換掉   &lt;code&gt;/dev/urandom&lt;/code&gt;：「  &lt;a href="https://lwn.net/Articles/884875/"&gt;Uniting the Linux random-number devices&lt;/a&gt;」。&lt;/p&gt;
 &lt;p&gt;不過換完後   &lt;a href="https://www.google.com/"&gt;Google&lt;/a&gt; 的 Guenter Roeck 就在抱怨在   &lt;a href="https://www.qemu.org/"&gt;QEMU&lt;/a&gt; 環境裡面炸掉了：&lt;/p&gt;
 &lt;blockquote&gt;  &lt;p&gt;This patch (or a later version of it) made it into mainline and causes a large number of qemu boot test failures for various architectures (arm, m68k, microblaze, sparc32, xtensa are the ones I observed). Common denominator is that boot hangs at &amp;quot;Saving random seed:&amp;quot;. A sample bisect log is attached. Reverting this patch fixes the problem.&lt;/p&gt;&lt;/blockquote&gt;
 &lt;p&gt;他透過   &lt;a href="https://git-scm.com/docs/git-bisect"&gt;git bisect&lt;/a&gt; 找到發生問題的 commit，另外從卡住的訊息也可以大概猜到在虛擬機下 entropy 不太夠。&lt;/p&gt;
 &lt;p&gt;另外從他們三個 (加上   &lt;a href="https://en.wikipedia.org/wiki/Linus_Torvalds"&gt;Linus&lt;/a&gt;) 在 mailing list 上面討論的訊息可以看到不少交流：「  &lt;a href="https://lwn.net/ml/linux-kernel/YjoC5kQMqyC%2F3L5Y@zx2c4.com/"&gt;Re: [PATCH v1] random: block in /dev/urandom&lt;/a&gt;」，包括嘗試「餵」entropy 進   &lt;code&gt;/dev/urandom&lt;/code&gt; 的 code...&lt;/p&gt;
 &lt;p&gt;後續看起來還會有一些嘗試，但短期內看起來應該還是會先分開...&lt;/p&gt;
&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>Computer Linux Murmuring OS Security</category>
      <guid isPermaLink="true">https://itindex.net/detail/62186-linux-dev-random</guid>
      <pubDate>Sun, 03 Apr 2022 12:33:00 CST</pubDate>
    </item>
    <item>
      <title>Metasploit Framework 6.1.32+20220303 (macOS, Linux, Windows) -- 渗透测试框架</title>
      <link>https://itindex.net/detail/62141-metasploit-framework-macos</link>
      <description>&lt;p&gt;请访问原文链接：  &lt;a href="https://sysin.org/blog/metasploit-framework-6/" title="Metasploit Framework 6.1.32+20220303 (macOS, Linux, Windows) -- &amp;#28183;&amp;#36879;&amp;#27979;&amp;#35797;&amp;#26694;&amp;#26550;"&gt;Metasploit Framework 6.1.32+20220303 (macOS, Linux, Windows) -- 渗透测试框架&lt;/a&gt;，查看最新版。原创作品，转载请保留出处。&lt;/p&gt; &lt;p&gt;作者主页：  &lt;a href="https://sysin.org"&gt;www.sysin.org&lt;/a&gt;&lt;/p&gt; &lt;p&gt;  &lt;img alt="img" src="https://www.metasploit.com/includes/images/metasploit-logo.svg"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://sysin.org/#&amp;#19990;&amp;#30028;&amp;#19978;&amp;#26368;&amp;#24191;&amp;#27867;&amp;#20351;&amp;#29992;&amp;#30340;&amp;#28183;&amp;#36879;&amp;#27979;&amp;#35797;&amp;#26694;&amp;#26550;" title="&amp;#19990;&amp;#30028;&amp;#19978;&amp;#26368;&amp;#24191;&amp;#27867;&amp;#20351;&amp;#29992;&amp;#30340;&amp;#28183;&amp;#36879;&amp;#27979;&amp;#35797;&amp;#26694;&amp;#26550;"&gt;&lt;/a&gt;世界上最广泛使用的渗透测试框架&lt;/h2&gt; &lt;p&gt;知识就是力量，尤其是当它被分享时。作为开源社区和 Rapid7 之间的合作，Metasploit 帮助安全团队做的不仅仅是验证漏洞、管理安全评估和提高安全意识；它使防守队员能够始终领先比赛一步（或两步）。&lt;/p&gt; &lt;p&gt;  &lt;img alt="dashboard" src="https://res.cloudinary.com/spiralyze/image/upload/f_auto/RAPID7/1401:%20Metasploit%20Trial%20-%20Redesign/Dashboard_1440.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://sysin.org/#&amp;#29256;&amp;#26412;&amp;#27604;&amp;#36739;" title="&amp;#29256;&amp;#26412;&amp;#27604;&amp;#36739;"&gt;&lt;/a&gt;版本比较&lt;/h2&gt; &lt;h3&gt;  &lt;a href="https://sysin.org/#Open-Source-Metasploit-Framework" title="Open Source: Metasploit Framework"&gt;&lt;/a&gt;Open Source: Metasploit Framework&lt;/h3&gt; &lt;p&gt;  &lt;a href="https://github.com/rapid7/metasploit-framework/wiki/Nightly-Installers" rel="noopener" target="_blank"&gt;Download&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;  &lt;a href="https://sysin.org/#Commercial-Support-Metasploit-Pro" title="Commercial Support: Metasploit Pro"&gt;&lt;/a&gt;Commercial Support: Metasploit Pro&lt;/h3&gt; &lt;p&gt;  &lt;img alt="metasploit-editions-compare" src="https://sysin.org/metasploit-editions-compare.webp"&gt;&lt;/img&gt;&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://sysin.org/#&amp;#19979;&amp;#36733;&amp;#22320;&amp;#22336;" title="&amp;#19979;&amp;#36733;&amp;#22320;&amp;#22336;"&gt;&lt;/a&gt;下载地址&lt;/h2&gt; &lt;p&gt;macOS：metasploit-framework-VERSION.x86_64.pkg  &lt;br /&gt;Windows：metasploit-framework-VERSION-x64.msi  &lt;br /&gt;Linux deb x64：metasploit-framework_VERSION_amd64.deb  &lt;br /&gt;Linux deb x86：metasploit-framework_VERSION_i386.deb  &lt;br /&gt;Linux deb arm64：metasploit-framework_VERSION_arm64.deb  &lt;br /&gt;Linux rpm x64：metasploit-framework-VERSION.el6.x86_64.rpm&lt;/p&gt; &lt;p&gt;百度网盘链接：  &lt;a href="https://pan.baidu.com/s/14jnv2S4EhzdHr3cWnwfNJA" rel="noopener" target="_blank"&gt;https://pan.baidu.com/s/14jnv2S4EhzdHr3cWnwfNJA&lt;/a&gt;  提取码：17p9&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>Download macOS Linux Windows Security</category>
      <guid isPermaLink="true">https://itindex.net/detail/62141-metasploit-framework-macos</guid>
      <pubDate>Fri, 04 Mar 2022 15:03:00 CST</pubDate>
    </item>
    <item>
      <title>Linux性能：为什么你应该添加交换空间swap</title>
      <link>https://itindex.net/detail/61885-linux-%E6%80%A7%E8%83%BD-%E4%BA%A4%E6%8D%A2</link>
      <description>&lt;img alt="Linux&amp;#24615;&amp;#33021;&amp;#65306;&amp;#20026;&amp;#20160;&amp;#20040;&amp;#20320;&amp;#24212;&amp;#35813;&amp;#28155;&amp;#21152;&amp;#20132;&amp;#25442;&amp;#31354;&amp;#38388;swap" src="https://www.myfreax.com/content/images/2021/11/linux-swap.jpeg"&gt;&lt;/img&gt; &lt;p&gt;我们知道使用Linux交换空间而不是 RAM（内存）会严重降低性能。那么，有人可能会问，既然我有足够多的可用内存，删除交换空间不是更好吗？简短的回答是不会。启用交换空间会带来性能优势，即使您有足够多的内存。&lt;/p&gt; &lt;p&gt;即使安装了足够多的服务器内存，您也会经常发现在长时间正常运行后会使用交换空间。请参阅以下来自具有大约一个月正常运行时间的实时聊天服务器的示例：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;              total        used        free      shared  buff/cache   available
Mem:           3.7G        1.0G        445M         84M        2.2G        2.2G
Swap:          1.8G        308M        1.5G&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;  &lt;strong&gt;   &lt;code&gt;free -h&lt;/code&gt;&lt;/strong&gt;这里的输出显示使用了 308M 的交换空间。当我运行swapping检查时，没有迹象表明正在进行或不合时宜的swap I/O活动。此外，kswap服务并没有消耗太多 CPU 时间。实际上，在top（按 CPU 时间排序的顶级进程）中找不到kswap进程。为了确认，我使用了  &lt;a href="https://www.myfreax.com/ps-command-in-linux/"&gt;ps命令&lt;/a&gt;：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;ps -A | grep kswap
40 ? 00:00: 29 kswapd0&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;...所以在这种情况下，与许多情况一样，swap使用不会降低Linux服务器的性能。现在，让我们看看交换空间实际上如何改善Linux服务器性能。&lt;/p&gt; &lt;h2&gt;在具有足够RAM的系统上交换空间的优点&lt;/h2&gt; &lt;img alt="Linux&amp;#24615;&amp;#33021;&amp;#65306;&amp;#20026;&amp;#20160;&amp;#20040;&amp;#20320;&amp;#24212;&amp;#35813;&amp;#28155;&amp;#21152;&amp;#20132;&amp;#25442;&amp;#31354;&amp;#38388;swap" src="https://www.myfreax.com/content/images/2021/11/image-11.png"&gt;&lt;/img&gt; &lt;p&gt;即使仍有可用的 RAM，Linux系统使用一些swap也是正常的并且是一件好事。Linux 内核会将  &lt;strong&gt;   &lt;em&gt;几乎从未使用过的内存页面&lt;/em&gt;&lt;/strong&gt;移动到交换空间中，以确保在内存中为更频繁使用的内存页面提供更多可缓存空间（一个页面就是一块内存）。当内核被迫不断地将内存页面移入和移出内存和交换空间swap时，交换使用会成为一个性能问题。&lt;/p&gt; &lt;p&gt;另一个优点是swap让管理员有时间对低内存问题做出反应。我们经常会注意到服务器运行缓慢，并且在登录时会注意到大量交换。如果没有交换（如下一节所述），内存不足会产生更加突然和严重的连锁反应。所以我会建议将交换空间设置为您最大进程的大小。比如mysql在my.cnf中配置的内存。&lt;/p&gt; &lt;p&gt;有些人建议不要交换或交换大小略大于总RAM。如果您能为此提出正当理由，那么这可能是您的选择。但是，这在服务器上几乎不是这种情况，您应该在您的决定与  &lt;strong&gt;Swap&lt;/strong&gt;对您的特定应用程序的影响之间取得平衡。  &lt;strong&gt;Swap不会改变服务器所需的 RAM 量&lt;/strong&gt;。它旨在改善系统的性能。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;总结：&lt;/strong&gt;  &lt;br /&gt;— 即使仍有可用的RAM，Linux内核也会将几乎从未使用过的内存页移动到交换空间中。  &lt;br /&gt;— 最好换出一段时间不活动的内存页，将经常使用的数据保留在缓存中，这应该发生在服务器最空闲的时候，这是内核的目标。  &lt;br /&gt;— 避免将交换空间设置得太大，否则会导致性能问题、中断或响应时间延长。&lt;/p&gt; &lt;h2&gt;当可用内存不足时，交换空间与不使用交换空间&lt;/h2&gt; &lt;p&gt;与上面的情况不同，如果您没有足够的内存，则在任何内存需求高峰期间，交换将被频繁使用并且明显更多。如果您没有足够的内存并且没有交换空间，这通常会导致无法为需要更多内存页的请求分配内存。作为最后的手段，内核将部署   &lt;a href="http://www.oracle.com/technetwork/articles/servers-storage-dev/oom-killer-1911807.html" rel="noopener noreferrer"&gt;OOM杀手&lt;/a&gt;来攻击高内存进程（通常是 MySQL、java 等）。&lt;/p&gt; &lt;p&gt;要更详细地了解Linux交换空间  &lt;strong&gt;Swap&lt;/strong&gt;，请阅读  &lt;a href="https://www.kernel.org/" rel="noopener noreferrer"&gt;Kernel.org&lt;/a&gt;文档中的  &lt;a href="https://www.kernel.org/doc/gorman/html/understand/understand014.html" rel="noopener noreferrer"&gt;交换管理&lt;/a&gt;和Page Frame  &lt;a href="https://www.kernel.org/doc/gorman/html/understand/understand013.html" rel="noopener noreferrer"&gt;回收&lt;/a&gt;章节。如果您的交换空间“已使用”始终为“0”，那么您确实有大量自由可用的 RAM，在这种情况下，删除交换空间可能是最好的。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;总结：&lt;/strong&gt;  &lt;br /&gt;—   &lt;strong&gt;Swap&lt;/strong&gt; I/O的扩展性很差。如果仅在服务器空闲时无法交换内存页，则应调整或禁用  &lt;strong&gt;Swap&lt;/strong&gt;。  &lt;br /&gt;— 禁用  &lt;strong&gt;Swap&lt;/strong&gt;后，性能问题会很快变得明显，OOM杀手可能会抓住你！:)&lt;/p&gt; &lt;p&gt;为了进行比较，以下是在同一服务器上使用来自  &lt;a href="https://sourceforge.net/projects/procps-ng/files/Production/" rel="noopener noreferrer"&gt;procps-ng-3.3.1&lt;/a&gt;的旧版free的输出：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;             total       used       free     shared    buffers     cached
Mem:          3.7G       3.3G       445M         0B       4.2M       1.7G
-/+ buffers/cache:       1.6G       2.1G
Swap:         1.8G       308M       1.5G&lt;/code&gt;&lt;/pre&gt; &lt;h2&gt;内核缓存压力和交换&lt;/h2&gt; &lt;p&gt;现在您已启用交换。考虑按照以下指南调整服务器的缓存压力和swap   &lt;a href="https://access.redhat.com/solutions/103833" rel="noopener noreferrer"&gt;vm.swappiness&lt;/a&gt;。&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;vfs_cache_pressure &lt;/strong&gt; – 控制内核回收内存的频率，用于缓存目录和inode对象。（默认值 = 100，推荐值 50 到 200）&lt;/p&gt; &lt;p&gt;  &lt;strong&gt;swappiness – &lt;/strong&gt;此值用于定义内核交换内存页面的积极程度。较高的值会增加攻击性；较低的值会减少交换量。（默认值 = 60，推荐值在 1 到 60 之间）删除 0 值的交换，但在大多数情况下通常不推荐。&lt;/p&gt; &lt;p&gt;要编辑，您可以在  &lt;strong&gt;/etc/sysctl.conf&lt;/strong&gt;文件中添加或替换这些行 。例如，如果您在升级前内存不足，您可以尝试以下操作：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;vm.swappiness=10
vm.vfs_cache_pressure=200&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;这将增加缓存压力，这似乎有些适得其反，因为缓存对性能有好处。但是，过于频繁的交换会显着降低服务器的整体性能。因此，不在内存中保留尽可能多的缓存将有助于减少交换活动。此外，将 vm.swappiness设置为10或低至 1，将减少磁盘交换。&lt;/p&gt; &lt;p&gt;在具有大量可用内存的服务器上，使用以下命令：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;vm.swappiness=10
vm.vfs_cache_pressure=50&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;这将降低缓存压力。由于缓存对性能有好处，我们希望将缓存数据在内存中保留更长时间。由于缓存会变大，我们仍然希望减少交换以不增加交换 I/O。&lt;/p&gt; &lt;p&gt;要使用这些命令检查当前值，请使用：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;sudo cat /proc/sys/vm/swappiness
sudo cat /proc/sys/vm/vfs_cache_pressure&lt;/code&gt;&lt;/pre&gt; &lt;p&gt;要在不重新启动的情况下临时启用这些设置，请使用以下命令：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;sudo sysctl -w vm.swappiness=10
sudo sysctl -w vm.vfs_cache_pressure=50&lt;/code&gt;&lt;/pre&gt; &lt;a href="https://www.myfreax.com/tag/swap/"&gt;  &lt;div&gt;   &lt;div&gt;swap - myfreax&lt;/div&gt;   &lt;div&gt;&lt;/div&gt;   &lt;div&gt;    &lt;img alt="Linux&amp;#24615;&amp;#33021;&amp;#65306;&amp;#20026;&amp;#20160;&amp;#20040;&amp;#20320;&amp;#24212;&amp;#35813;&amp;#28155;&amp;#21152;&amp;#20132;&amp;#25442;&amp;#31354;&amp;#38388;swap" src="https://www.myfreax.com/assets/images/favicon-192.png?v=fe03fbbefe"&gt;&lt;/img&gt;myfreax 15 Dec 2020 • 4 min readmyfreax&lt;/div&gt;&lt;/div&gt;  &lt;div&gt;   &lt;img alt="Linux&amp;#24615;&amp;#33021;&amp;#65306;&amp;#20026;&amp;#20160;&amp;#20040;&amp;#20320;&amp;#24212;&amp;#35813;&amp;#28155;&amp;#21152;&amp;#20132;&amp;#25442;&amp;#31354;&amp;#38388;swap" src="https://www.myfreax.com/content/images/size/w600/2020/12/how-to-add-swap-space-on-ubuntu-20-04.jpg"&gt;&lt;/img&gt;&lt;/div&gt;&lt;/a&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>linux swap 交换空间 性能 内存</category>
      <guid isPermaLink="true">https://itindex.net/detail/61885-linux-%E6%80%A7%E8%83%BD-%E4%BA%A4%E6%8D%A2</guid>
      <pubDate>Tue, 09 Nov 2021 14:08:02 CST</pubDate>
    </item>
    <item>
      <title>Burp Suite Pro 2021.10 (macOS, Linux) -- 查找、发现和利用漏洞</title>
      <link>https://itindex.net/detail/61867-burp-suite-pro</link>
      <description>&lt;p&gt;请访问原文链接：  &lt;a href="https://sysin.org/blog/burp-suite-pro-2021/" title="Burp Suite Pro 2021 (macOS, Linux) -- &amp;#26597;&amp;#25214;&amp;#12289;&amp;#21457;&amp;#29616;&amp;#21644;&amp;#21033;&amp;#29992;&amp;#28431;&amp;#27934;"&gt;Burp Suite Pro 2021 (macOS, Linux) -- 查找、发现和利用漏洞&lt;/a&gt;，查看最新版。原创作品，转载请保留出处。&lt;/p&gt; &lt;p&gt;作者：gc(at)sysin.org，主页：  &lt;a href="https://sysin.org"&gt;www.sysin.org&lt;/a&gt;&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://sysin.org/#&amp;#31616;&amp;#20171;" title="&amp;#31616;&amp;#20171;"&gt;&lt;/a&gt;简介&lt;/h2&gt; &lt;p&gt;Burp Suite Professional 是一套用于测试 web 安全性的高级工具集 —- 所有这些都在一个产品中。从一个基本的拦截代理到尖端的 Burp 扫描器，使用 Burp Suite Pro，正确的工具只需点击一下就可以了。&lt;/p&gt; &lt;p&gt;我们强大的自动化让您有更多的机会做您最擅长的，而 Burp Suite 处理容易实现的目标。先进的手动工具将帮助你识别目标更微妙的盲点。&lt;/p&gt; &lt;p&gt;Burp Suite Pro 是由一个研究团队开发的。这意味着在我们发布之前，发现成果已经包含在我们的最新更新中。我们的 pentesting 工具将使您的工作更快，同时让您了解最新的攻击向量。&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://sysin.org/#&amp;#21151;&amp;#33021;&amp;#20171;&amp;#32461;" title="&amp;#21151;&amp;#33021;&amp;#20171;&amp;#32461;"&gt;&lt;/a&gt;功能介绍&lt;/h2&gt; &lt;h3&gt;  &lt;a href="https://sysin.org/#Manual-penetration-testing-features-&amp;#25163;&amp;#21160;&amp;#28183;&amp;#36879;&amp;#27979;&amp;#35797;&amp;#21151;&amp;#33021;" title="Manual penetration testing features &amp;#25163;&amp;#21160;&amp;#28183;&amp;#36879;&amp;#27979;&amp;#35797;&amp;#21151;&amp;#33021;"&gt;&lt;/a&gt;Manual penetration testing features 手动渗透测试功能&lt;/h3&gt; &lt;p&gt;  &lt;img alt="Burp Suite Pro proxy interception" src="https://portswigger.net/burp/pro/features/images/proxy-interception.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Intercept everything your browser sees&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;A powerful proxy/history lets you modify all HTTP(S) communications passing through your browser.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Manage recon data&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;All target data is aggregated and stored in a target site map - with filtering and annotation functions.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Expose hidden attack surface&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Find hidden target functionality with an advanced automatic discovery function for “invisible” content.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Test for clickjacking attacks&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Generate and confirm clickjacking attacks for potentially vulnerable web pages, with specialist tooling.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Work with WebSockets&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;WebSockets messages get their own specific history - allowing you to view and modify them.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Break HTTPS effectively&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Proxy even secure HTTPS traffic. Installing your unique CA certificate removes associated browser security warnings.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Manually test for out-of-band vulnerabilities&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Make use of a dedicated client to incorporate Burp Suite’s out-of-band (OAST) capabilities during manual testing.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Speed up granular workflows&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Modify and reissue individual HTTP and WebSocket messages, and analyze the response - within a single window.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Quickly assess your target&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Determine the size of your target application. Auto-enumeration of static and dynamic URLs, and URL parameters.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Assess token strength&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Easily test the quality of randomness in data items intended to be unpredictable (e.g. tokens).&lt;/p&gt; &lt;hr&gt;&lt;/hr&gt; &lt;h3&gt;  &lt;a href="https://sysin.org/#Advanced-custom-automated-attacks-&amp;#39640;&amp;#32423;-&amp;#33258;&amp;#23450;&amp;#20041;&amp;#33258;&amp;#21160;&amp;#25915;&amp;#20987;" title="Advanced/custom automated attacks &amp;#39640;&amp;#32423;/&amp;#33258;&amp;#23450;&amp;#20041;&amp;#33258;&amp;#21160;&amp;#25915;&amp;#20987;"&gt;&lt;/a&gt;Advanced/custom automated attacks 高级/自定义自动攻击&lt;/h3&gt; &lt;ul&gt;  &lt;li&gt;Faster brute-forcing and fuzzing&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Deploy custom sequences of HTTP requests containing multiple payload sets. Radically reduce time spent on many tasks.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Query automated attack results&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Capture automated results in customized tables, then filter and annotate to find interesting entries/improve subsequent attacks.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Construct CSRF exploits&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Easily generate CSRF proof-of-concept attacks. Select any suitable request to generate exploit HTML.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Facilitate deeper manual testing&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;See reflected/stored inputs even when a bug is not confirmed. Facilitates testing for issues like XSS.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Scan as you browse&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The option to passively scan every request you make, or to perform active scans on specific URLs.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Automatically modify HTTP messages&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Settings to automatically modify responses. Match and replace rules for both responses and requests.&lt;/p&gt; &lt;p&gt;  &lt;img alt="Burp Suite Pro Intruder payload positions" src="https://portswigger.net/burp/pro/features/images/payload.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;hr&gt;&lt;/hr&gt; &lt;h3&gt;  &lt;a href="https://sysin.org/#Automated-scanning-for-vulnerabilities-&amp;#33258;&amp;#21160;&amp;#25195;&amp;#25551;&amp;#28431;&amp;#27934;" title="Automated scanning for vulnerabilities &amp;#33258;&amp;#21160;&amp;#25195;&amp;#25551;&amp;#28431;&amp;#27934;"&gt;&lt;/a&gt;Automated scanning for vulnerabilities 自动扫描漏洞&lt;/h3&gt; &lt;p&gt;  &lt;img alt="Burp Suite Pro scan results" src="https://portswigger.net/burp/pro/features/images/scan-results.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Harness pioneering AST technology&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;High signal: low noise. Scan with pioneering, friction-free,   &lt;a href="https://portswigger.net/burp/application-security-testing/oast" rel="noopener" target="_blank"&gt;out-of-band-application security testing (OAST)&lt;/a&gt;.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Conquer client-side attack surfaces&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Hybrid AST and built-in JavaScript analysis engine help to find holes in client-side attack surfaces.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Fuel vulnerability coverage with research&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Cutting-edge scan logic from PortSwigger Research combines with coverage of over 100 generic bugs.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Fine-tune scan control&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Get fine-grained control, with a user-driven scanning methodology. Or, run “point-and-click” scans.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Remediate bugs effectively&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Custom descriptions and step-by-step remediation advice for every bug, from   &lt;a href="https://portswigger.net/research" rel="noopener" target="_blank"&gt;PortSwigger Research&lt;/a&gt;.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Configure scan behavior&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Customize what you audit, and how. Skip specific checks, fine-tune insertion points, and much more.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Navigate difficult applications&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Crawl more complex targets. Burp Suite’s crawler identifies locations based on content - not just URL.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Effectively apply IAST&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Source identification and vulnerability reporting simplified, with optional code instrumentation.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Experience browser-driven scanning&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Browser-driven scanning is already striding toward better coverage of tricky targets like AJAX-heavy single page apps.&lt;/p&gt; &lt;hr&gt;&lt;/hr&gt; &lt;h3&gt;  &lt;a href="https://sysin.org/#Productivity-tools-&amp;#29983;&amp;#20135;&amp;#21147;&amp;#24037;&amp;#20855;" title="Productivity tools &amp;#29983;&amp;#20135;&amp;#21147;&amp;#24037;&amp;#20855;"&gt;&lt;/a&gt;Productivity tools 生产力工具&lt;/h3&gt; &lt;ul&gt;  &lt;li&gt;Deep-dive message analysis&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Show follow-up, analysis, reference, discovery, and remediation in a feature-rich HTTP editor.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Utilize both built-in and custom configurations&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Access predefined configurations for common tasks, or save and reuse custom configurations.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Multiply project options&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Auto-save all working projects to disk, and add configurations to pre-saved projects.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Make code more readable&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Automatically pretty-print code formats including JSON, JavaScript, CSS, HTML, and XML.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Easily remediate scan results&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;See source, discovery, contents, and remediation, for every bug, with aggregated application data.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Simplify scan reporting&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Customize with HTML/XML formats. Report all evidence identified, including issue details.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Speed up data transformation&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Decode or encode data, with multiple built-in operations (e.g. Hex, Octal, Base64).&lt;/p&gt; &lt;p&gt;  &lt;img alt="Burp Suite Pro pretty-printing" src="https://portswigger.net/burp/pro/features/images/pretty-print.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;hr&gt;&lt;/hr&gt; &lt;h3&gt;  &lt;a href="https://sysin.org/#Extensions-&amp;#25193;&amp;#23637;" title="Extensions &amp;#25193;&amp;#23637;"&gt;&lt;/a&gt;Extensions 扩展&lt;/h3&gt; &lt;p&gt;  &lt;img alt="PortSwigger BApp Store" src="https://portswigger.net/burp/pro/features/images/bapp-store.png"&gt;&lt;/img&gt;&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Create custom extensions&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Extender API ensures universal adaptability. Code custom extensions to make Burp work for you.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Logger++&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;For in-depth vulnerability detail, ordered and arranged in an easily accessible table, make use of   &lt;a href="https://portswigger.net/bappstore/470b7057b86f41c396a97903377f3d81" rel="noopener" target="_blank"&gt;Logger++&lt;/a&gt;.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Autorize&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;When testing for authorization vulnerabilities, save time and perform repeat requests with   &lt;a href="https://portswigger.net/bappstore/f9bbac8c4acf4aefa4d7dc92a991af2f" rel="noopener" target="_blank"&gt;Autorize&lt;/a&gt;.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Turbo Intruder&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Configured in Python, with a custom HTTP stack,   &lt;a href="https://portswigger.net/bappstore/9abaa233088242e8be252cd4ff534988" rel="noopener" target="_blank"&gt;Turbo Intruder&lt;/a&gt; can unleash thousands of requests per second.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;J2EE Scan&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Expand your Java-specific vulnerability catalogue and hunt the most niche bugs, with   &lt;a href="https://portswigger.net/bappstore/7ec6d429fed04cdcb6243d8ba7358880" rel="noopener" target="_blank"&gt;J2EEScan&lt;/a&gt;.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Access the extension library&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The   &lt;a href="https://portswigger.net/bappstore" rel="noopener" target="_blank"&gt;BApp Store&lt;/a&gt; customizes and extends capabilities. Over 250 extensions, written and tested by Burp users.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Upload Scanner&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Adapt Burp Scanner’s attacks by uploading and testing multiple file-type payloads, with   &lt;a href="https://portswigger.net/bappstore/b2244cbb6953442cb3c82fa0a0d908fa" rel="noopener" target="_blank"&gt;Upload Scanner&lt;/a&gt;.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;AuthMatrix&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Run   &lt;a href="https://portswigger.net/bappstore/30d8ee9f40c041b0bfec67441aad158e" rel="noopener" target="_blank"&gt;AuthMatrix&lt;/a&gt; with Autorize to define your access-level vulnerability authorization check.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Param Miner&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Quickly find unkeyed inputs with   &lt;a href="https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943" rel="noopener" target="_blank"&gt;Param Miner&lt;/a&gt; - can guess up to 65,000 parameter names per second.&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;Backslash Powered Scanner&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Find research-grade bugs, and bridge human intuition and automation, with   &lt;a href="https://portswigger.net/bappstore/9cff8c55432a45808432e26dbb2b41d8" rel="noopener" target="_blank"&gt;Backslash Powered Scanner&lt;/a&gt;.&lt;/p&gt; &lt;h2&gt;  &lt;a href="https://sysin.org/#&amp;#19979;&amp;#36733;&amp;#22320;&amp;#22336;" title="&amp;#19979;&amp;#36733;&amp;#22320;&amp;#22336;"&gt;&lt;/a&gt;下载地址&lt;/h2&gt; &lt;p&gt;官方版本：Professional / Community 2021.10  &lt;br /&gt;  百度网盘链接：  &lt;a href="https://pan.baidu.com/s/1jlqpII0Ibu2jwrk82je3JA" rel="noopener" target="_blank"&gt;https://pan.baidu.com/s/1jlqpII0Ibu2jwrk82je3JA&lt;/a&gt;  提取码：pjtm&lt;/p&gt; &lt;p&gt;本站特别版：今天刚刚发布，需要测试验证后更新。&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;Burp Suite Pro for macOS    &lt;br /&gt;百度网盘链接：&lt;/p&gt;   &lt;p&gt;集成 keygen，直接运行，无需额外安装 Java    &lt;br /&gt;    &lt;img alt="burp-dmg" src="https://sysin.org/burp-dmg.png"&gt;&lt;/img&gt;&lt;/p&gt;   &lt;p&gt;修复原版图标，Big Sur 图标适配    &lt;br /&gt;    &lt;img alt="burp-icon" src="https://sysin.org/burp-icon.png"&gt;&lt;/img&gt;&lt;/p&gt;   &lt;p&gt;已知问题：首次运行窗口会变得非常小，拖拽，下次启动即可正常。应用程序运行显示的图标是 java 的图标，比较丑陋，因为破解使用 java loader 导致。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;Burp Suite Pro for Linux    &lt;br /&gt;百度网盘链接：&lt;/p&gt;   &lt;p&gt;安装：    &lt;code&gt;chmod +x burpsuitepro-linux-2021.10.bin &amp;amp;&amp;amp; sudo ./burpsuitepro-linux-2021.10.bin&lt;/code&gt;&lt;/p&gt;   &lt;p&gt;集成安装、注册和卸载    &lt;br /&gt;    &lt;img alt="burp-install" src="https://sysin.org/burp-install.png"&gt;&lt;/img&gt;&lt;/p&gt;   &lt;p&gt;主界面一览    &lt;br /&gt;    &lt;img alt="burp-main" src="https://sysin.org/burp-main.png"&gt;&lt;/img&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>Security macOS Linux HTTP</category>
      <guid isPermaLink="true">https://itindex.net/detail/61867-burp-suite-pro</guid>
      <pubDate>Tue, 02 Nov 2021 10:34:22 CST</pubDate>
    </item>
    <item>
      <title>有哪些 Linux 平板电脑可供选择</title>
      <link>https://itindex.net/detail/61853-linux-%E5%B9%B3%E6%9D%BF%E7%94%B5%E8%84%91-%E9%80%89%E6%8B%A9</link>
      <description>&lt;p&gt;  &lt;img height="720" src="https://img.linux.net.cn/data/attachment/album/202110/28/180114mism33m44sibmsc9.jpg" width="1280"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;有很多   &lt;a href="https://linux.cn/article-13672-1.html"&gt;基于 Linux 的笔记本电脑&lt;/a&gt;，也有   &lt;a href="https://itsfoss.com/linux-based-mini-pc/"&gt;预装了 Linux 的迷你 PC&lt;/a&gt;，而市场上还有一些   &lt;a href="https://linux.cn/article-13711-1.html"&gt;基于 Linux 的智能手机&lt;/a&gt;。&lt;/p&gt;
 &lt;p&gt;那平板电脑呢？有没有一些不错的基于 Linux 的平板电脑？这可能不能用一句话说清楚。&lt;/p&gt;
 &lt;p&gt;许多仅使用 Linux 的系统制造商专注于制造台式电脑。这主要是由于触摸设备上的 Linux 体验与安卓和 iOS 提供的体验相距甚远。&lt;/p&gt;
 &lt;p&gt;但这是否意味着你不能在平板电脑上使用 Linux？并非如此。对于早期尝试用户和 DIY 爱好者来说，还有一些选择的。让我们来看看在这些 Linux 平板电脑中，你有哪些选择。&lt;/p&gt;
 &lt;h3&gt;Ubuntu Touch&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="BQ &amp;#24179;&amp;#26495;&amp;#30005;&amp;#33041;&amp;#19978;&amp;#30340; Ubuntu Touch &amp;#25805;&amp;#20316;&amp;#31995;&amp;#32479;" src="https://img.linux.net.cn/data/attachment/album/202110/28/172722ryjylnnfjdmx3nia.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;好吧！这不是一个平板电脑，而是一个操作系统。但它确实让你可以在一些旧的安卓平板电脑上安装一个适合触摸操作的 Ubuntu 版本。&lt;/p&gt;
 &lt;p&gt;注意“一些”这个词。Ubuntu Touch 官方   &lt;a href="https://devices.ubuntu-touch.io/"&gt;支持&lt;/a&gt; Nexus 7、联想 M10、Xperia Z4 和 BQ Aquaris 平板。你甚至可以尝试在你的其他平板电脑上安装 Ubuntu Touch。它可能无法 100% 工作，但仍然非常有用。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://ubuntu-touch.io/"&gt;Ubuntu Touch&lt;/a&gt; 是 Ubuntu 团队的一个项目，但是他们   &lt;a href="https://itsfoss.com/ubuntu-unity-shutdown/"&gt;在 2017 年中止了它&lt;/a&gt;。  &lt;a href="https://ubports.com/"&gt;UBports&lt;/a&gt; 承担了继续这个项目的责任，他们在有限的资源下做的很棒。&lt;/p&gt;
 &lt;p&gt;总而言之，如果你喜欢各种实验，想让你的旧安卓平板电脑获得新生，Ubuntu Touch 可能是你的周末项目。&lt;/p&gt;
 &lt;h3&gt;PineTab&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="PineTab" src="https://img.linux.net.cn/data/attachment/album/202110/28/172723lwqchszh6oisigbh.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;Pine64 始于其单板计算机 Pine A64，以作为   &lt;a href="https://itsfoss.com/raspberry-pi-alternatives/"&gt;树莓派的替代品&lt;/a&gt;。随着时间的推移，它推出了几个 Pine 品牌的产品。这份名单里包括低调的   &lt;a href="https://itsfoss.com/pinetime-linux-smartwatch/"&gt;PineTime 智能手表&lt;/a&gt;、PineBook 笔记本电脑、PinePhone 智能手机和 PineTab 平板电脑。&lt;/p&gt;
 &lt;p&gt;这些 Pine 设备通常价格低廉，并允许用户对这些小设备进行完全控制。这种可魔改的特性帮助它聚集了一大批开源 DIY 爱好者的粉丝。&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://pine64.com/product/pinetab-10-1-linux-tablet-with-detached-backlit-keyboard/?v=0446c16e2e66"&gt;PineTab&lt;/a&gt; 基本上使用了与带有触摸屏和键盘的 Pine64 单板计算机相同的组件。它不是看起来最漂亮的平板电脑，也不打算成为这样的。&lt;/p&gt;
 &lt;p&gt;它的规格很一般，有一个高清 IPS 电容式触摸屏、全志 A64 芯片组、四核 CPU 和 2GB 内存。&lt;/p&gt;
 &lt;p&gt;它无法与 iPad 或 Galaxy Tab 竞争，但它允许你安装你选择的发行版，并按你的要求进行配置。&lt;/p&gt;
 &lt;p&gt;请记住，Pine 的库存有限，所以如果你能看到这个设备可以购买，那你很幸运。&lt;/p&gt;
 &lt;h3&gt;PineNote&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="PineNote" src="https://img.linux.net.cn/data/attachment/album/202110/28/172724eh0plmm9bg0ql27g.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;另一个 Pine 设备，与你在上一节看到的 PineTab 略有不同。&lt;/p&gt;
 &lt;p&gt;PineTab 是一款用于浏览互联网、使用应用程序和玩游戏的 Linux 平板电脑，而   &lt;a href="https://www.pine64.org/pinenote/"&gt;PineNote&lt;/a&gt; 是用来做笔记和阅读书籍和文件的。&lt;/p&gt;
 &lt;p&gt;它有一个电子墨水显示屏，你可能在 Kindle 等电子书阅读器上见过。除了电子书阅读器之外，PineNote 还可以你用 Wacom 笔做笔记。&lt;/p&gt;
 &lt;p&gt;PineNote 拥有四核 Rockchip、多点触控电子墨水面板、4GB 内存和 128GB eMMC 存储。它也是为数不多的价格高于通常的 399 美元的平板点之一。&lt;/p&gt;
 &lt;p&gt;请记住，PineNote 正处于早期开发阶段，只接受开发者的订单。&lt;/p&gt;
 &lt;h3&gt;RasPad&lt;/h3&gt;
 &lt;p&gt;  &lt;img alt="RasPad" src="https://img.linux.net.cn/data/attachment/album/202110/28/172725ecwcc4ccnwc4vdnq.jpg"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;  &lt;a href="https://raspad.com/products/raspadv3"&gt;RasPad&lt;/a&gt; 是一个用于树莓派设备的套件，可以把它变成一个基于触摸功能的设备。与普通的平板不同，这不是一个扁平的设备，而是有一个楔形的身体。这使得它更容易在办公桌上使用。&lt;/p&gt;
 &lt;p&gt;RasPad 是专门为树莓派设备创建的，你可以轻松使用它的大部分端口。它有一个专门的 RasPad 操作系统，但你可以自由使用常规的树莓派操作系统或 Ubuntu 或任何其他适合树莓派的操作系统。在选择操作系统时请考虑触控友好性。&lt;/p&gt;
 &lt;p&gt;请记住，树莓派设备不包括在套件中。你必须要单独购买。&lt;/p&gt;
 &lt;h3&gt;你的选择是什么？&lt;/h3&gt;
 &lt;p&gt;我知道我们离一个优秀的 Linux 平板电脑还很远，但它们至少可以和市场上的安卓平板电脑竞争。至少我们有一些可用的选择，这也是一线希望。&lt;/p&gt;
 &lt;p&gt;你是否已经拥有以上列出的设备之一了？你的体验如何？&lt;/p&gt;
 &lt;p&gt;如果你只能选择其中之一，那么你选择哪一款 Linux 平板电脑？&lt;/p&gt;
 &lt;hr&gt;&lt;/hr&gt;
 &lt;p&gt;via:   &lt;a href="https://itsfoss.com/linux-tablets/"&gt;https://itsfoss.com/linux-tablets/&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;作者：  &lt;a href="https://itsfoss.com/author/abhishek/"&gt;Abhishek Prakash&lt;/a&gt; 选题：  &lt;a href="https://github.com/lujun9972"&gt;lujun9972&lt;/a&gt; 译者：  &lt;a href="https://github.com/wxy"&gt;wxy&lt;/a&gt; 校对：  &lt;a href="https://github.com/wxy"&gt;wxy&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;本文由   &lt;a href="https://github.com/LCTT/TranslateProject"&gt;LCTT&lt;/a&gt; 原创编译，  &lt;a href="https://linux.cn/"&gt;Linux中国&lt;/a&gt; 荣誉推出&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/61853-linux-%E5%B9%B3%E6%9D%BF%E7%94%B5%E8%84%91-%E9%80%89%E6%8B%A9</guid>
      <pubDate>Thu, 28 Oct 2021 17:27:00 CST</pubDate>
    </item>
    <item>
      <title>关于 Linux 内核的 30 件你不知道的事</title>
      <link>https://itindex.net/detail/61744-linux-%E5%86%85%E6%A0%B8-%E7%9F%A5%E9%81%93</link>
      <description>&lt;blockquote&gt;
  &lt;p&gt;Linux 内核今年 30 岁了。&lt;/p&gt;
&lt;/blockquote&gt;
 &lt;p&gt;  &lt;img height="1080" src="https://img.linux.net.cn/data/attachment/album/202108/27/150006o152rdghq0zqr02f.jpg" title="30 years" width="1920"&gt;&lt;/img&gt;&lt;/p&gt;
 &lt;p&gt;Linux 内核今年 30 岁了。这开创性的开源软件的三个十年，让用户能够运行自由软件，让他们能从运行的应用程序中学习，让他们能与朋友分享他们所学到的知识。有人认为，如果没有 Linux 内核，我们如今所享受的   &lt;a href="https://opensource.com/article/18/1/creative-commons-real-world"&gt;开源文化&lt;/a&gt; 和自由软件的累累硕果，可能就不会应时而出现。如果没有 Linux 作为催化剂，苹果、微软和谷歌所开源的那些就不可能开源。Linux 作为一种现象，对开源文化、软件开发和用户体验的影响，是怎么强调都不为过的，但所有这一切，都滥觞于一个 Linux 内核。&lt;/p&gt;
 &lt;p&gt;Linux 内核是启动计算机、并识别和确保计算机内外所连接的所有组件之间通信的软件。这些对于大多数用户从未想过，更不用说能理解的代码，Linux 内核有很多令人惊讶的地方。以下是 Linux 内核在其三十年生命中每一年的一件事。顺序无关。&lt;/p&gt;
 &lt;ol&gt;
  &lt;li&gt;Linux 是第一个具有 USB 3.0 驱动的操作系统。Sarah Sharp 在 2009 年 6 月 7 日宣布她的 USB 3.0 设备的驱动程序可以使用了，她的代码被包含在内核 2.6.31 版本中。&lt;/li&gt;
  &lt;li&gt;当某些事件发生时，内核会将自己标记为“受污染”，这在以后的故障排除中可能有用。运行一个“被污染”的内核并不是什么问题。但如果出现错误，首先要做的是在一个没有被污染的内核上重现该问题。&lt;/li&gt;
  &lt;li&gt;你可以指定一个主机名或域名作为    &lt;code&gt;ip=&lt;/code&gt; 内核命令行选项的一部分，Linux 会保留它，而不是用 DHCP 或 BOOTP 提供的主机名或域名来覆盖它。例如，   &lt;code&gt;ip=::::myhostname::dhcp&lt;/code&gt; 设置主机名    &lt;code&gt;myhostname&lt;/code&gt;。&lt;/li&gt;
  &lt;li&gt;在文本启动过程中，可以选择显示黑白的、16 色的或 224 色的 Tux 徽标之一。&lt;/li&gt;
  &lt;li&gt;在娱乐业中，DRM 是一种用来防止访问媒介的技术。然而，在 Linux 内核中，DRM 指的是直接渲染管理器Direct Rendering Manager，它指的是用于与对接显卡的 GPU 的库（   &lt;code&gt;libdrm&lt;/code&gt;）和驱动程序。&lt;/li&gt;
  &lt;li&gt;能够在不重启的情况下给 Linux 内核打补丁。&lt;/li&gt;
  &lt;li&gt;如果你自己编译内核，你可以将文本控制台配置为超过 80 列宽。&lt;/li&gt;
  &lt;li&gt;Linux 内核提供了内置的 FAT、exFAT 和 NTFS（读和写）支持。&lt;/li&gt;
  &lt;li&gt;Wacom 平板电脑和许多类似设备的驱动程序都内置在内核中。&lt;/li&gt;
  &lt;li&gt;大多数内核高手使用    &lt;code&gt;git send-email&lt;/code&gt; 来提交补丁。&lt;/li&gt;
  &lt;li&gt;内核使用一个叫做    &lt;a href="https://opensource.com/article/19/11/document-python-sphinx"&gt;Sphinx&lt;/a&gt; 的文档工具链，它是用 Python 编写的。&lt;/li&gt;
  &lt;li&gt;Hamlib 提供了具有标准化 API 的共享库，可以通过你的 Linux 电脑控制业余无线电设备。&lt;/li&gt;
  &lt;li&gt;我们鼓励硬件制造商帮助开发 Linux 内核，以确保兼容性。这样就可以直接处理硬件，而不必从制造商那里下载驱动程序。直接成为内核一部分的驱动程序也会自动从新版本内核的性能和安全改进中受益。&lt;/li&gt;
  &lt;li&gt;内核中包含了许多树莓派模块（Pi Hats）的驱动程序。&lt;/li&gt;
  &lt;li&gt;netcat 乐队发布了一张只能作为    &lt;a href="https://github.com/usrbinnc/netcat-cpi-kernel-module"&gt;Linux 内核模块&lt;/a&gt; 播放的专辑。&lt;/li&gt;
  &lt;li&gt;受 netcat 发布专辑的启发，人们又开发了一个    &lt;a href="https://github.com/FlaviaR/Netcat-Music-Kernel-Expansion"&gt;把你的内核变成一个音乐播放器&lt;/a&gt; 的模块。&lt;/li&gt;
  &lt;li&gt;Linux 内核的功能支持许多 CPU 架构：ARM、ARM64、IA-64、 m68k、MIPS、Nios II、PA-RISC、OpenRISC、PowerPC、s390、 Sparc、x86、Xtensa 等等。&lt;/li&gt;
  &lt;li&gt;2001 年，Linux 内核成为第一个    &lt;a href="http://www.x86-64.org/pipermail/announce/2001-June/000020.html"&gt;以长模式运行的 x86-64 CPU 架构&lt;/a&gt;。&lt;/li&gt;
  &lt;li&gt;Linux 3.4 版引入了 x32 ABI，允许开发者编译在 64 位模式下运行的代码，而同时只使用 32 位指针和数据段。&lt;/li&gt;
  &lt;li&gt;内核支持许多不同的文件系统，包括 Ext2、Ext3、Ext4、JFS、XFS、GFS2、GCFS2、BtrFS、NILFS2、NFS、Overlay FS、UDF 等等。&lt;/li&gt;
  &lt;li&gt;虚拟文件系统Virtual File System（VFS）是 Linux 内核中的一个软件层，为用户运行的应用程序提供文件系统接口。它也是内核的一个抽象层，以便不同的文件系统实现可以共存。&lt;/li&gt;
  &lt;li&gt;Linux 内核包括一个实体的盲文输出设备的驱动程序。&lt;/li&gt;
  &lt;li&gt;在 2.6.29 版本的内核中，启动时的 Tux 徽标被替换为 “Tuz”，以提高人们对当时影响澳大利亚的塔斯马尼亚魔鬼Tasmanian Devil（即袋獾）种群的一种侵袭性癌症的认识。&lt;/li&gt;
  &lt;li&gt;控制组Control Groups（cgroups）是容器（Docker、Podman、Kubernetes 等的基础技术）能够存在的原因。&lt;/li&gt;
  &lt;li&gt;曾经花了大量的法律行动来解放 CIFS，以便将其纳入内核中，而今天，CIFS 模块已被内置于内核，以实现对 SMB 的支持。这使得 Linux 可以挂载微软的远程共享和基于云的文件共享。&lt;/li&gt;
  &lt;li&gt;对于计算机来说，产生一个真正的随机数是出了名的困难（事实上，到目前为止是不可能的）。   &lt;code&gt;hw_random&lt;/code&gt; 框架可以利用你的 CPU 或主板上的特殊硬件功能，尽量改进随机数的生成。&lt;/li&gt;
  &lt;li&gt;   &lt;em&gt;操作系统抖动&lt;/em&gt; 是应用程序遇到的干扰，它是由后台进程的调度方式和系统处理异步事件（如中断）的方式的冲突引起的。像这些问题在内核文档中都有详细的讨论，可以帮助面向 Linux 开发的程序员写出更聪明的代码。&lt;/li&gt;
  &lt;li&gt;   &lt;code&gt;make menuconfig&lt;/code&gt; 命令可以让你在编译前使用 GUI 来配置内核。   &lt;code&gt;Kconfig&lt;/code&gt; 语言定义了内核配置选项。&lt;/li&gt;
  &lt;li&gt;对于基本的 Linux 服务器，可以实施一个    &lt;em&gt;看门狗&lt;/em&gt; 系统来监控服务器的健康状况。在健康检查间隔中，   &lt;code&gt;watchdog&lt;/code&gt; 守护进程将数据写入一个特殊的    &lt;code&gt;watchdog&lt;/code&gt; 内核设备，以防止系统重置。如果看门狗不能成功记录，系统就会被重置。有许多看门狗硬件的实现，它们对远程任务关键型计算机（如发送到火星上的计算机）至关重要。&lt;/li&gt;
  &lt;li&gt;在火星上有一个 Linux 内核的副本，虽然它是在地球上开发的。&lt;/li&gt;
&lt;/ol&gt;
 &lt;hr&gt;&lt;/hr&gt;
 &lt;p&gt;via:   &lt;a href="https://opensource.com/article/21/8/linux-kernel"&gt;https://opensource.com/article/21/8/linux-kernel&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;作者：  &lt;a href="https://opensource.com/users/seth"&gt;Seth Kenlon&lt;/a&gt; 选题：  &lt;a href="https://github.com/lujun9972"&gt;lujun9972&lt;/a&gt; 译者：  &lt;a href="https://github.com/wxy"&gt;wxy&lt;/a&gt; 校对：  &lt;a href="https://github.com/wxy"&gt;wxy&lt;/a&gt;&lt;/p&gt;
 &lt;p&gt;本文由   &lt;a href="https://github.com/LCTT/TranslateProject"&gt;LCTT&lt;/a&gt; 原创编译，  &lt;a href="https://linux.cn/"&gt;Linux中国&lt;/a&gt; 荣誉推出&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/61744-linux-%E5%86%85%E6%A0%B8-%E7%9F%A5%E9%81%93</guid>
      <pubDate>Fri, 27 Aug 2021 15:00:16 CST</pubDate>
    </item>
    <item>
      <title>Kubernetes组件问题排查思路 – 十点运维吧-Linux|Kubernetes|Docker|Prometheus|Python|Golang|云原生|SRE</title>
      <link>https://itindex.net/detail/61726-kubernetes-%E9%97%AE%E9%A2%98-%E8%BF%90%E7%BB%B4</link>
      <description>&lt;p&gt;Kubernetes的基础组件就像一栋房子的地基，它们的重要性不言而喻。作为Kubernetes集群的维护者，经常会遇到组件的问题，那平时是怎么去定位解决的呢？&lt;/p&gt;  &lt;p&gt;这里简要分析一下我的排查思路。&lt;/p&gt;  &lt;ul&gt;    &lt;li&gt;通过集群的状态，找到故障的节点或者组件&lt;/li&gt;    &lt;li&gt;分析组件的日志&lt;/li&gt;    &lt;li&gt;使用pprof分析组件的具体性能&lt;/li&gt;&lt;/ul&gt;  &lt;h3&gt;确定范围&lt;/h3&gt;  &lt;p&gt;Kubernetes的基础组件不多，而且部署也非常简单，所以在定义范围的时候还是很容易的，比如我们在使用    &lt;code&gt;kubectl get nodes&lt;/code&gt;的时候，如果某个节点的状态是    &lt;code&gt;NotReady&lt;/code&gt;，我们脑海中是不是会出现两种可能？    &lt;br /&gt;（1）节点的kubelet组件有问题    &lt;br /&gt;（2）节点的网络组件有问题&lt;/p&gt;  &lt;p&gt;这样一来，大体方向已经确定了，然后就是做排除法了。&lt;/p&gt;  &lt;p&gt;这里为何说是排除法？因为在解决问题的途中，我们通常会采用    &lt;code&gt;先假设再验证&lt;/code&gt;的方式进行，先把所以可能的因素列出来，然后一个一个的去验证去排除，直到解决问题。&lt;/p&gt;  &lt;h3&gt;分析日志&lt;/h3&gt;  &lt;p&gt;日志分析是故障排查最直接的方式，大部分问题都能从日志里体现出来，Kubernetes的组件日志查看方式通常有两种：&lt;/p&gt;  &lt;ul&gt;    &lt;li&gt;通过systemd启动的服务，使用      &lt;code&gt;journalctl -l -u xxxx&lt;/code&gt;&lt;/li&gt;    &lt;li&gt;使用静态pod启动的服务，使用      &lt;code&gt;kubectl logs -n kube-system $PODNAME --tail 100&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;当然，很多时候不仅仅是分析它本身的问题，我们还会关注周边的问题，比如基础设施的CPU、内存、IO等情况，这样进行综合考虑来找出问题。&lt;/p&gt;  &lt;h3&gt;性能分析&lt;/h3&gt;  &lt;p&gt;为什么把性能分析放到最后呢？&lt;/p&gt;  &lt;p&gt;对于大部分人来说，并不擅长，也不喜欢分析组件的性能。第一是时间比较长，第二是要对各个性能指标有一定的了解，第三是学习成本比较大。&lt;/p&gt;  &lt;p&gt;众所周知，Kubernetes的版本迭代比较快，基本一年会发2-3个版本，如此快的迭代速度，不排除一些版本中存在BUG，存在一些性能问题。所以在实在没招的情况下，可以尝试对其组件的性能进行分析。&lt;/p&gt;  &lt;p&gt;Kubernetes是使用Golang开发，而Golang的pprof是性能分析的利器，提供交互式界面和UI图形化，比较直观，可以很方便的找出问题。除此之外，还可以使用go-torch将profile数据生成火焰图，这样会更直观。&lt;/p&gt;  &lt;p&gt;Kubernetes的组件都可以使用    &lt;code&gt;pprof&lt;/code&gt;进行性能分析，界面在    &lt;code&gt;host:port/debug/pprof/&lt;/code&gt;。&lt;/p&gt;  &lt;h4&gt;pprof的常用方式&lt;/h4&gt;  &lt;h5&gt;使用交互式命令&lt;/h5&gt;  &lt;ol&gt;    &lt;li&gt;查看堆栈调用信息&lt;/li&gt;&lt;/ol&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;go tool pprof http://localhost:8001/debug/pprof/heap&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;ol start="2"&gt;    &lt;li&gt;查看 30 秒内的 CPU 信息&lt;/li&gt;&lt;/ol&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;go tool pprof http://localhost:8001/debug/pprof/profile?seconds=30&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;ol start="3"&gt;    &lt;li&gt;查看 goroutine 阻塞&lt;/li&gt;&lt;/ol&gt;  &lt;pre&gt;    &lt;code&gt;go tool pprof http://localhost:8001/debug/pprof/block&lt;/code&gt;&lt;/pre&gt;  &lt;ol start="4"&gt;    &lt;li&gt;收集 5 秒内的执行路径&lt;/li&gt;&lt;/ol&gt;  &lt;pre&gt;    &lt;code&gt;go tool pprof http://localhost:8001/debug/pprof/trace?seconds=5&lt;/code&gt;&lt;/pre&gt;  &lt;ol start="5"&gt;    &lt;li&gt;争用互斥持有者的堆栈跟踪&lt;/li&gt;&lt;/ol&gt;  &lt;pre&gt;    &lt;code&gt;go tool pprof http://localhost:8001/debug/pprof/mutex&lt;/code&gt;&lt;/pre&gt;  &lt;h5&gt;通过UI界面&lt;/h5&gt;  &lt;p&gt;UI分析工具使用起来相对比较麻烦，我们需要先导出文件，然后再使用    &lt;code&gt;go tool&lt;/code&gt;工具起服务进行分析。&lt;/p&gt;  &lt;p&gt;比如我们导出kube-scheduler的堆栈信息。&lt;/p&gt;  &lt;pre&gt;    &lt;code&gt;curl -sK -v http://localhost:10251/debug/pprof/heap &amp;gt; heap.out&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;然后使用go tool工具起一个服务，如下：&lt;/p&gt;  &lt;pre&gt;    &lt;code&gt;go tool pprof -http=0.0.0.0:8989 heap.out&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;然后就可以在浏览器上看到具体的堆栈信息图了。    &lt;br /&gt;    &lt;img alt="image.png" src="https://www.coolops.cn/../static/images/blogs/1618820063688-fefa3320-7277-4d82-b526-43e97fb5af57.png"&gt;&lt;/img&gt;    &lt;br /&gt;注意，这里需要在服务端安装    &lt;code&gt;graphviz&lt;/code&gt;组件，各种操作系统的安装方式见[3]。&lt;/p&gt;  &lt;p&gt;UI界面主要的菜单以及其功能简要介绍如下：&lt;/p&gt;  &lt;ul&gt;    &lt;li&gt;VIEW：查看模式      &lt;ul&gt;        &lt;li&gt;Top：从高到底排序查看&lt;/li&gt;        &lt;li&gt;Graph：默认的模式，以关系图形式查看&lt;/li&gt;        &lt;li&gt;Flame Graph：以火焰图形式查看&lt;/li&gt;        &lt;li&gt;Peek：排序查看，展示的信息更多&lt;/li&gt;        &lt;li&gt;Source：排序查看，带源码标注&lt;/li&gt;        &lt;li&gt;Disassemble：现实所有总量&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;    &lt;li&gt;SAMPLE：为VIEW提供查看模式      &lt;ul&gt;        &lt;li&gt;alloc_objects：已分配的对象总量（不管是否已释放&lt;/li&gt;        &lt;li&gt;alloc_space：已分配的内存总量（不管是否已释放）&lt;/li&gt;        &lt;li&gt;inuse_objects： 已分配但尚未释放的对象数量&lt;/li&gt;        &lt;li&gt;inuse_sapce：已分配但尚未释放的内存数量&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;    &lt;li&gt;REFINE：提供筛选能力&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;上面简单介绍了pprof的基本使用方法，下面就Kubernetes的各个组件进行简单的分析，这里只就CPU信息进    &lt;br /&gt;行获取以及展示。&lt;/p&gt;  &lt;p&gt;注意：由于版本原因，有的版本默认开启了pprof，有的版本则没有，如果没有开启的，需要自行去开启，参数基本都是    &lt;code&gt;profiling: true&lt;/code&gt;，具体的信息可以到官网进行查看[4]。&lt;/p&gt;  &lt;h4&gt;分析kube-apiserver&lt;/h4&gt;  &lt;p&gt;（1）使用kubectl proxy启动一个代理&lt;/p&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;kubectl proxy&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;（2）另起一个终端，获取CPU信息&lt;/p&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;curl -sK -v  http://localhost:8001/debug/pprof/profile &amp;gt;apiserver-cpu.out&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;（3）使用go tool工具启动服务&lt;/p&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;go tool pprof -http=0.0.0.0:8989 apiserver-cpu.out&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;（4）在浏览器上进行查看    &lt;br /&gt;    &lt;img alt="image.png" src="https://www.coolops.cn/../static/images/blogs/1618822052073-c866ba6f-83a6-475a-9901-99e51ca9aabe.png"&gt;&lt;/img&gt;&lt;/p&gt;  &lt;h4&gt;分析kube-scheduler&lt;/h4&gt;  &lt;p&gt;（1）获取CPU的信息&lt;/p&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;curl -sK -v  http://localhost:10251/debug/pprof/profile &amp;gt;scheduler-cpu.out&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;（2）使用go tool工具启动服务&lt;/p&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;go tool pprof -http=0.0.0.0:8989 scheduler-cpu.out&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;（3）在浏览器进行查看    &lt;br /&gt;    &lt;img alt="image.png" src="https://www.coolops.cn/../static/images/blogs/1618821673849-10ffe3e8-725e-46db-820a-818e66eb2c26.png"&gt;&lt;/img&gt;&lt;/p&gt;  &lt;h4&gt;分析kube-controller-manager&lt;/h4&gt;  &lt;p&gt;（1）获取CPU的信息&lt;/p&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;curl -sK -v  http://localhost:10252/debug/pprof/profile &amp;gt;controller-cpu.out&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;（2）使用go tool工具启动服务&lt;/p&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;go tool pprof -http=0.0.0.0:8989 controller-cpu.out&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;（3）在浏览器进行查看    &lt;br /&gt;    &lt;img alt="image.png" src="https://www.coolops.cn/../static/images/blogs/1618822217264-9a69c8f8-8345-4cb9-a6f3-c251eeab2ca9.png"&gt;&lt;/img&gt;&lt;/p&gt;  &lt;h4&gt;分析kubelet&lt;/h4&gt;  &lt;p&gt;（1）使用kubectl proxy启动一个代理&lt;/p&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;kubectl proxy&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;（2）另起一个终端，获取CPU信息&lt;/p&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;curl -sK -v  http://127.0.0.1:8001/api/v1/nodes/k8s-node04-138/proxy/debug/pprof/profile &amp;gt;kubelet-cpu.out&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;（3）使用go tool工具启动服务&lt;/p&gt;  &lt;div&gt;    &lt;div&gt;      &lt;table&gt;        &lt;tr&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;          &lt;td&gt;            &lt;pre&gt;              &lt;code&gt;go tool pprof -http=0.0.0.0:8989 kubelet-cpu.out&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;（4）在浏览器上进行查看    &lt;br /&gt;    &lt;img alt="image.png" src="https://www.coolops.cn/../static/images/blogs/1618822746545-e7479e65-6c17-460d-8813-40dd207d3082.png"&gt;&lt;/img&gt;&lt;/p&gt;  &lt;p&gt;能够抓到具体的性能数据才是第一步，后续的具体分析才会帮助我们找到问题。&lt;/p&gt;  &lt;h3&gt;文档&lt;/h3&gt;  &lt;ul&gt;    &lt;li&gt;[1]      &lt;a href="https://github.com/google/pprof"&gt;https://github.com/google/pprof&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;[2]      &lt;a href="https://github.com/uber-archive/go-torch"&gt;https://github.com/uber-archive/go-torch&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;[3]      &lt;a href="https://www.graphviz.org/download/#linux"&gt;http://www.graphviz.org/download/#linux&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;[4]      &lt;a href="https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-apiserver/"&gt;https://kubernetes.io/zh/docs/reference/command-line-tools-reference/kube-apiserver/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/61726-kubernetes-%E9%97%AE%E9%A2%98-%E8%BF%90%E7%BB%B4</guid>
      <pubDate>Mon, 23 Aug 2021 18:36:29 CST</pubDate>
    </item>
    <item>
      <title>linux grep 查看大日志文件</title>
      <link>https://itindex.net/detail/61517-linux-grep-%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6</link>
      <description>&lt;div&gt;  &lt;blockquote&gt;
   &lt;p&gt;这是我参与更文挑战的第7天，活动详情查看：    &lt;a href="https://juejin.cn/post/6967194882926444557" target="_blank"&gt;更文挑战&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
  &lt;blockquote&gt;
   &lt;p&gt;如果❤️我的文章有帮助，欢迎点赞、关注。这是对我继续技术创作最大的鼓励。&lt;/p&gt;
&lt;/blockquote&gt;
  &lt;h1&gt;linux grep 查看大日志文件&lt;/h1&gt;
  &lt;h2&gt;场景&lt;/h2&gt;
  &lt;p&gt;今天隔离还在继续，在家办公。忽然下午午工作群里发来一个    &lt;code&gt;mysql&lt;/code&gt; 机器io/负载上升的预警，异常发生在    &lt;code&gt;15：45 ~ 16：00&lt;/code&gt; 之间。为了事后为了查明原因，需要翻看慢查询日志    &lt;code&gt;slow.log&lt;/code&gt; 才发现日志 8G 多... 故事就这样开始了
   &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5237bc1977654f0f8f4ea07fd249dd2b~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
  &lt;p&gt;怎么办呢。第一个想到的就是常用    &lt;code&gt;grep&lt;/code&gt; 匹配关键字&lt;/p&gt;
  &lt;h2&gt;grep 关键字&lt;/h2&gt;
  &lt;p&gt;grep 常用于    &lt;code&gt;关键字&lt;/code&gt; 匹配文件文本信息。   &lt;br /&gt;
但关键字从哪里来呢，可以命令    &lt;code&gt;head slow3306_9110.log&lt;/code&gt; 查看下检索文件的   &lt;code&gt;内容结构&lt;/code&gt;
   &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6ec4548f9cd1419bbc20e4b41937cb59~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
  &lt;p&gt;因为异常发生在    &lt;code&gt;15：45 ~ 16：00&lt;/code&gt; 之间，我就可以这样写&lt;/p&gt;
  &lt;blockquote&gt;
   &lt;p&gt;grep -n &amp;apos;Time: 210607 15:[45-59]&amp;apos; slow3306_9110.log&lt;/p&gt;
&lt;/blockquote&gt;
  &lt;p&gt;时间    &lt;code&gt;15：45&lt;/code&gt; 至    &lt;code&gt;15：59&lt;/code&gt; 之间内容，但这样匹配只能看到时间，这明显不是我们想要的
   &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2f96732f67bf4818a389cba0db72cff2~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
  &lt;h3&gt;grep 显示匹配行附近内容&lt;/h3&gt;
  &lt;ul&gt;
   &lt;li&gt;A -&amp;gt; After&lt;/li&gt;
   &lt;li&gt;B -&amp;gt; Before&lt;/li&gt;
   &lt;li&gt;C -&amp;gt; Context&lt;/li&gt;
&lt;/ul&gt;
  &lt;p&gt;举个例子：&lt;/p&gt;
  &lt;blockquote&gt;
   &lt;p&gt;    &lt;code&gt;grep -A5 &amp;apos;Time: 210607 15:[45-59]&amp;apos; slow3306_9110.log&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
  &lt;p&gt;就能把匹配    &lt;code&gt;Time: 210607&lt;/code&gt; 行的   &lt;code&gt;下面 5 行&lt;/code&gt;也显示出来。
   &lt;img alt="&amp;#22270;&amp;#29255;&amp;#25551;&amp;#36848;" src="https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2be5fc47bb104e83af80478879f9bd7b~tplv-k3u1fbpfcp-zoom-1.image"&gt;&lt;/img&gt;&lt;/p&gt;
  &lt;h3&gt;grep 多关键字搜索&lt;/h3&gt;
  &lt;p&gt;但这时我们有会发现，   &lt;code&gt;Query_time: 0.925375&lt;/code&gt; 查询时间有大有小。我现在在查故障明细是只想看    &lt;code&gt;查询消耗时间大的&lt;/code&gt;。&lt;/p&gt;
  &lt;p&gt;所以这里就需要用到    &lt;code&gt;grep 多关键字搜索&lt;/code&gt;&lt;/p&gt;
  &lt;h4&gt;匹配多个关键字（且）&lt;/h4&gt;
  &lt;p&gt;管道符连接    &lt;code&gt;多个条件&lt;/code&gt; 实现关键字    &lt;code&gt;且关系&lt;/code&gt; 匹配：&lt;/p&gt;
  &lt;blockquote&gt;
   &lt;p&gt;grep -A5 &amp;apos;Time: 210607 15:[45-59]&amp;apos; slow3306_9110.log | grep &amp;apos;Query_time: (\d[2-5])&amp;apos;&lt;/p&gt;
&lt;/blockquote&gt;
  &lt;p&gt;同一行同时满足两个条件（   &lt;code&gt;Time&lt;/code&gt;、   &lt;code&gt;Query_time&lt;/code&gt;）才能够匹配。&lt;/p&gt;
  &lt;p&gt;不过这里也必须说明：   &lt;code&gt;因为上图内容格式中，Time 和 Query_time 不在同一列&lt;/code&gt;，所以上诉命令只是这个演示。实际只能匹配    &lt;code&gt;同一行同时满足两个条件&lt;/code&gt; 内容&lt;/p&gt;
  &lt;h4&gt;grep -E 匹配多个关键字（或）&lt;/h4&gt;
  &lt;blockquote&gt;
   &lt;p&gt;grep -E &amp;quot;word1|word2|word3&amp;quot; file.txt&lt;/p&gt;
&lt;/blockquote&gt;
  &lt;p&gt;匹配文件中 同一行包含 word1、word2、word3 之一&lt;/p&gt;
  &lt;h3&gt;总结&lt;/h3&gt;
  &lt;p&gt;总结下来。&lt;/p&gt;
  &lt;ul&gt;
   &lt;li&gt;由于多行无法同时命中     &lt;code&gt;时间 15：45 至 15：59&lt;/code&gt; 和     &lt;code&gt;查询时间在 2~5位整数之间&lt;/code&gt;。&lt;/li&gt;
   &lt;li&gt;另外由于文件太大，grep 一次就能跑个 3、4 分钟实际体验并不好&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/61517-linux-grep-%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6</guid>
      <pubDate>Mon, 07 Jun 2021 15:52:26 CST</pubDate>
    </item>
    <item>
      <title>Linux - 系统指标 CPU load - 简书</title>
      <link>https://itindex.net/detail/61498-linux-%E7%B3%BB%E7%BB%9F-%E6%8C%87%E6%A0%87</link>
      <description>&lt;h2&gt;cpu load&lt;/h2&gt;  &lt;p&gt;cpu load通常做为一个机器负载的衡量指标&lt;/p&gt;  &lt;p&gt;    &lt;strong&gt;cpu load是对使用或者等待cpu进程的统计&lt;/strong&gt;(数量的累加)。每一个使用(using)或者等待(waiting)CPU的进程(process)，都会使load值+1。    &lt;br /&gt;每一个结束的(teminates)进程，都会使load值-1。&lt;/p&gt;  &lt;p&gt;所谓使用CPU的进程，是指状态为    &lt;code&gt;running&lt;/code&gt;的进程，或者说是在cpu run queue里的进程。    &lt;br /&gt;所谓等待CPU的进程，是指状态为    &lt;code&gt;runnable&lt;/code&gt;的进程，或者说是在cpu ready queue里的进程。&lt;/p&gt;  &lt;p&gt;大部分Unix操作系统只计算    &lt;code&gt;running&lt;/code&gt;和    &lt;code&gt;runnable&lt;/code&gt;的进程。但是Linux系统除了上述两种状态进行，还计算    &lt;code&gt;uninterruptible sleep&lt;/code&gt;状态的进程(通常是在等待磁盘IO)。因此，如果有很多进程被block在IO处，Linux系统显示的load会被Unix系统高一些。举个例子，如果有进程由于NFS服务挂掉或者USB设备太慢而block住的话，会显示一个奇怪的现象：    &lt;strong&gt;cpu使用率不高，但是cpu load很高&lt;/strong&gt;。&lt;/p&gt;  &lt;h3&gt;cpu load average&lt;/h3&gt;  &lt;p&gt;通常，我们关注的不是cpu load，而是cpu load average这个指标。&lt;/p&gt;  &lt;p&gt;所有的Unix和类Unix操作系统，都有3    &lt;strong&gt;个&amp;quot;load average&amp;quot;&lt;/strong&gt;的统计指标。分别表示    &lt;strong&gt;1分钟、5分钟和15分钟&lt;/strong&gt;内的cpu负载均值。&lt;/p&gt;  &lt;p&gt;使用    &lt;code&gt;uptime&lt;/code&gt;命令是查看cpu负载最简单的命令：&lt;/p&gt;  &lt;blockquote&gt;    &lt;p&gt;$      &lt;strong&gt;uptime&lt;/strong&gt;      &lt;br /&gt;14:34:03 up 10:43,  4 users,  load average: 0.06, 0.11, 0.09&lt;/p&gt;&lt;/blockquote&gt;  &lt;p&gt;当然，    &lt;code&gt;w&lt;/code&gt;和    &lt;code&gt;top&lt;/code&gt;命令也包含cpu load信息。&lt;/p&gt;  &lt;p&gt;top命令：&lt;/p&gt;  &lt;br /&gt;  &lt;div&gt;    &lt;div&gt;      &lt;div&gt;&lt;/div&gt;      &lt;div&gt;        &lt;img&gt;&lt;/img&gt;&lt;/div&gt;&lt;/div&gt;    &lt;div&gt;image.png&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;w命令：&lt;/p&gt;  &lt;br /&gt;  &lt;div&gt;    &lt;div&gt;      &lt;div&gt;&lt;/div&gt;      &lt;div&gt;        &lt;img&gt;&lt;/img&gt;&lt;/div&gt;&lt;/div&gt;    &lt;div&gt;image.png&lt;/div&gt;&lt;/div&gt;  &lt;h3&gt;load average的意义&lt;/h3&gt;  &lt;p&gt;load average是个无量纲的，大致可认为是cpu进程队列中进程的数量和cpu可处理能力的比值。比如cpu最多同时能处理10个进程，&lt;/p&gt;  &lt;ul&gt;    &lt;li&gt;如果队列中进程数量为5，load average为50%，说明cpu还没达到负载上限&lt;/li&gt;    &lt;li&gt;如果队列中进程数量为10，load average为100%，说明刚好达到负载上限&lt;/li&gt;    &lt;li&gt;如果队列中进程数量为15，load average为150%，说明超出了cpu的处理能力&lt;/li&gt;&lt;/ul&gt;  &lt;p&gt;单个cpu的load average为0.7以上时，需要注意是否快达到了服务能力的瓶颈。&lt;/p&gt;  &lt;h2&gt;cpu load和cpu utilization&lt;/h2&gt;  &lt;p&gt;cpu load(cpu负载)相较于cpu utilization(cpu使用率)更能反映机器的负载情况。&lt;/p&gt;  &lt;p&gt;因为，假如有两个配置相同的机器，一个机器cpu utilization是50%，另一个是70%，我们可以认为70%的机器负载比50%的高。但是如果两个机器的cpu use都是100%的话，谁的负载更高，就不得而知了。而cpu load是可以反映出来的。&lt;/p&gt;  &lt;p&gt;比如两个机器的per cpu load分别是1.5和1.8，但是他们的cpu use都是100%。但是我们依旧可以知道哪台机器负载更高。&lt;/p&gt;  &lt;p&gt;假如在一个单核机器上，load average是&amp;quot;1.73 0.60 7.98&amp;quot;，那么可以大致这么解释：&lt;/p&gt;  &lt;ul&gt;    &lt;li&gt;在过去1分钟中，系统负载超额73%。(1.73个runnable进程，但是有0.73个进程需要等待)&lt;/li&gt;    &lt;li&gt;在过去5分钟中，系统负载有40%空闲&lt;/li&gt;    &lt;li&gt;在过去15分钟中，系统负载超额698%。(7.98个runnable进程，但是有6.98个需要等待)&lt;/li&gt;&lt;/ul&gt;  &lt;h2&gt;参考&lt;/h2&gt;  &lt;ul&gt;    &lt;li&gt;      &lt;a href="https://en.wikipedia.org/wiki/Load_(computing)" rel="nofollow" target="_blank"&gt;wikipedia - Load (computing)&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;      &lt;a href="http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages" rel="nofollow" target="_blank"&gt;Understanding Linux CPU Load - when should you be worried?&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;      &lt;a href="http://www.blogjava.net/cenwenchu/archive/2008/06/30/211712.html" rel="nofollow" target="_blank"&gt;理解Load Average做好压力测试&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/61498-linux-%E7%B3%BB%E7%BB%9F-%E6%8C%87%E6%A0%87</guid>
      <pubDate>Thu, 03 Jun 2021 19:20:28 CST</pubDate>
    </item>
    <item>
      <title>Linux系统安全强化指南</title>
      <link>https://itindex.net/detail/61392-linux-%E7%B3%BB%E7%BB%9F-%E5%AE%89%E5%85%A8</link>
      <description>&lt;br /&gt;本指南旨在说明如何尽可能地加强Linux的安全性和隐私性，并且不限于任何特定的指南。 &lt;br /&gt;
 &lt;br /&gt;免责声明：如果您不确定自己在做什么，请不要尝试在本文中使用任何内容。 &lt;br /&gt;
 &lt;br /&gt;本指南仅关注安全性和隐私性，而不关注性能，可用性或其他内容。列出的所有命令都将需要root特权。以“$”符号开头的单词表示一个变量，不同终端之间可能会有所不同。 &lt;br /&gt;
 &lt;h3&gt;选择正确的Linux发行版&lt;/h3&gt;选择一个好的Linux发行版有很多因素。 &lt;br /&gt;
 &lt;ul&gt;  &lt;li&gt;避免分发冻结程序包，因为它们在安全更新中通常很落后。&lt;/li&gt;  &lt;li&gt;不使用与Systemd机制的发行版。 Systemd包含许多不必要的攻击面；它尝试做的事情远远超出了必要，并且超出了初始化系统应做的事情。&lt;/li&gt;  &lt;li&gt;使用musl作为默认的C库。 Musl专注于最小化，这会导致很小的攻击面，而其他C库（例如glibc）过于复杂，容易产生漏洞。例如，与musl中的极少数漏洞相比，glibc中的一百多个漏洞已被公开披露。尽管仅靠披露的CVE本身通常是不准确的统计信息，但有时这种情况有时可以用来表示过分的问题。 Musl还具有不错的漏洞利用缓解措施，尤其是其新的强化内存分配器。&lt;/li&gt;  &lt;li&gt;最好默认情况下使用LibreSSL而不是OpenSSL的发行版。OpenSSL包含大量完全不必要的攻击面，并且遵循不良的安全做法。例如，它仍然保持OS / 2和VMS支持这些已有数十年历史的古老操作系统。这些令人讨厌的安全做法导致了可怕的Heartbleed漏洞。LibreSSL是OpenBSD团队的OpenSSL分支，它采用了出色的编程实践并消除了很多攻击面。在LibreSSL成立的第一年内，它缓解了许多漏洞，其中包括一些高严重性的漏洞。&lt;/li&gt;&lt;/ul&gt; &lt;br /&gt;
 &lt;br /&gt;用作强化操作系统基础的最佳发行版是Gentoo Linux，因为它可以让您精确地配置系统，以达到理想的效果，这将非常有用，尤其是参考我们在后面的章节中使用更安全的编译标志。 &lt;br /&gt;
 &lt;br /&gt;但是，由于Gentoo的巨大可用性缺陷，它对于许多人来说可能并不顺手。在这种情况下，Void Linux的Musl构建是一个很好的折衷方案。 &lt;br /&gt;
 &lt;h3&gt;内核&lt;/h3&gt;内核是操作系统的核心，不幸的是很容易受到攻击。正如Brad Spengler曾经说过的那样，可以将其视为系统上最大，最易受攻击的setuid根二进制文件。因此，对内核进行尽可能多的强化非常重要。 &lt;br /&gt;
 &lt;h4&gt;Stable vs LTS内核&lt;/h4&gt;Linux内核以两种主要形式发布：稳定和长期支持（LTS）。稳定版本是较新的版本，而LTS发行版本是较老的稳定版本，长期以来一直受支持。选择上述任何一个发行版本都有许多后果。 &lt;br /&gt;
 &lt;br /&gt;Linux内核未使用CVE标识安全漏洞。这意味着大多数安全漏洞的修复程序不能向后移植到LTS内核。但是稳定版本包含到目前为止进行的所有安全修复。 &lt;br /&gt;
 &lt;br /&gt;但是，有了这些修复程序，稳定的内核将包含更多新功能，因此大大增加了内核的攻击面，并引入了大量新错误。相反，LTS内核的受攻击面较小，因为这些功能没有被不断添加。 &lt;br /&gt;
 &lt;br /&gt;此外，稳定的内核还包括更新的强化功能，以减轻LTS内核没有的某些利用。此类功能的一些示例是Lockdown LSM和STACKLEAK GCC插件。 &lt;br /&gt;
 &lt;br /&gt;总而言之，在选择稳定或LTS内核时需要权衡取舍。LTS内核具有较少的强化功能，并且并非当时所有的公共错误修复都已向后移植，但是通常它的攻击面更少，并且引入未知错误的可能性也较小。稳定的内核具有更多的强化功能，并且包括所有已知的错误修复，但它也具有更多的攻击面以及引入更多未知错误的机会更大。最后，最好使用较新的LTS分支（如4.19内核）。 &lt;br /&gt;
 &lt;h4&gt;Sysctl&lt;/h4&gt;Sysctl是允许用户配置某些内核设置并启用各种安全功能或禁用危险功能以减少攻击面的工具。要临时更改设置，您可以执行： &lt;br /&gt;
 &lt;pre&gt;sysctl -w $tunable = $value  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
要永久更改sysctls，您可以将要更改的sysctls添加到/etc/sysctl.conf或/etc/sysctl.d中的相应文件，具体取决于您的Linux发行版。 &lt;br /&gt;
 &lt;br /&gt;以下是您应更改的建议sysctl设置。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;Kernel self-protection&lt;/strong&gt; &lt;br /&gt;
 &lt;pre&gt;kernel.kptr_restrict=2  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
内核指针指向内核内存中的特定位置。这些在利用内核方面可能非常有用，但是默认情况下不会隐藏内核指针，例如，通过读取/proc/kallsyms的内容即可轻松发现它们。此设置旨在减轻内核指针泄漏。另外，您可以设置kernel.kptr_restrict = 1以仅从没有CAP_SYSLOG功能的进程中隐藏内核指针。 &lt;br /&gt;
 &lt;pre&gt;kernel.dmesg_restrict=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
dmesg是内核日志，它公开了大量有用的内核调试信息，但这通常会泄漏敏感信息，例如内核指针。更改上述sysctl设置会将内核日志限制为CAP_SYSLOG功能。 &lt;br /&gt;
 &lt;pre&gt;kernel.printk=3 3 3 3  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
尽管dmesg_restrict的值，启动过程中内核日志仍将显示在控制台中。能够在引导过程中记录屏幕的恶意软件可能会滥用此恶意软件以获得更高的特权。此选项可防止这些信息泄漏。必须将其与下面描述的某些引导参数结合使用才能完全有效。 &lt;br /&gt;
 &lt;pre&gt;kernel.unprivileged_bpf_disabled=1    &lt;br /&gt;
net.core.bpf_jit_harden=2  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
eBPF暴露了很大的攻击面，因此需加以限制。这些系统将eBPF限制为CAP_BPF功能（在5.8之前的内核版本上为CAP_SYS_ADMIN），并启用JIT强化技术，例如常量绑定。 &lt;br /&gt;
 &lt;pre&gt;dev.tty.ldisc_autoload=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这将加载TTY行规则限制为CAP_SYS_MODULE功能，以防止非特权的攻击者使用TIOCSETD ioctl加载易受攻击的线路规则，而该TIOCSETD ioctl之前已在许多漏洞利用中被滥用。 &lt;br /&gt;
 &lt;pre&gt;vm.unprivileged_userfaultfd=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
userfaultfd() 系统调用经常被滥用以利用“事后使用(use-after-free)”缺陷。因此，该sysctl用于将此syscall限制为CAP_SYS_PTRACE功能。 &lt;br /&gt;
 &lt;pre&gt;kernel.kexec_load_disabled=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
kexec是一个系统调用，用于在运行时引导另一个内核。可以滥用此功能来加载恶意内核并在内核模式下获得任意代码执行能力，因此该sysctl设置将被禁用。 &lt;br /&gt;
 &lt;pre&gt;kernel.sysrq=4  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
SysRq密钥向非特权用户公开了许多潜在的危险调试功能。与通常的假设相反，SysRq不仅是物理攻击的问题，而且还可以远程触发。该sysctl的值使其可以使用户只能使用SAK密钥，这对于安全地访问root是必不可少的。或者，您可以简单地将值设置为0以完全禁用SysRq。 &lt;br /&gt;
 &lt;pre&gt;kernel.unprivileged_userns_clone=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
用户名称空间是内核中的一项功能，旨在改善沙箱并使非特权用户易于访问它，但是，此功能公开了重要的内核攻击面，以进行特权升级，因此该sysctl将用户名称空间的使用限制为CAP_SYS_ADMIN功能。对于无特权的沙箱，建议使用具有很少攻击面的setuid二进制文件，以最大程度地减少特权升级的可能性。沙箱章节部分将进一步讨论此主题。 &lt;br /&gt;
 &lt;br /&gt;请注意，尽管该sysctl仅在某些Linux发行版中存在，因为它需要内核补丁。如果您的内核不包含此补丁，则可以通过设置user.max_user_namespaces = 0来完全禁用用户名称空间（包括root用户）。 &lt;br /&gt;
 &lt;pre&gt;kernel.perf_event_paranoid=3  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
性能事件会增加大量内核攻击面，并导致大量漏洞。此sysctl设置将性能事件的所有使用限制为CAP_PERFMON功能（5.8之前的内核版本为CAP_SYS_ADMIN）。 &lt;br /&gt;
 &lt;br /&gt;请注意，此sysctl设置需要在某些发行版中具备相关的内核补丁。否则，此设置等效于kernel.perf_event_paranoid = 2，它仅限制此功能的子集。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;网络&lt;/strong&gt; &lt;br /&gt;
 &lt;pre&gt;net.ipv4.tcp_syncookies=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这有助于防止SYN泛洪攻击，这种攻击是拒绝服务攻击的一种形式，在这种攻击中，攻击者发送大量虚假的SYN请求，以尝试消耗足够的资源以使系统对合法流量不响应。 &lt;br /&gt;
 &lt;pre&gt;net.ipv4.tcp_rfc1337=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这通过丢弃处于时间等待状态的套接字的RST数据包来防止time-wait状态。 &lt;br /&gt;
 &lt;pre&gt;net.ipv4.conf.all.rp_filter=1    &lt;br /&gt;
net.ipv4.conf.default.rp_filter=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这些启用了源验证，以验证从计算机所有网络接口接收到的数据包。 &lt;br /&gt;
 &lt;pre&gt;net.ipv4.conf.all.accept_redirects=0    &lt;br /&gt;
net.ipv4.conf.default.accept_redirects=0    &lt;br /&gt;
net.ipv4.conf.all.secure_redirects=0    &lt;br /&gt;
net.ipv4.conf.default.secure_redirects=0    &lt;br /&gt;
net.ipv6.conf.all.accept_redirects=0    &lt;br /&gt;
net.ipv6.conf.default.accept_redirects=0    &lt;br /&gt;
net.ipv4.conf.all.send_redirects=0    &lt;br /&gt;
net.ipv4.conf.default.send_redirects=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这些设置禁用了ICMP重定向，以防止中间人攻击并最大程度地减少信息泄露。 &lt;br /&gt;
 &lt;pre&gt;net.ipv4.icmp_echo_ignore_all=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
此设置使您的系统忽略所有ICMP请求，以避免Smurf攻击，使设备更难以在网络上枚举，并防止通过ICMP时间戳识别时钟指纹。 &lt;br /&gt;
 &lt;pre&gt;net.ipv4.conf.all.accept_source_route=0    &lt;br /&gt;
net.ipv4.conf.default.accept_source_route=0    &lt;br /&gt;
net.ipv6.conf.all.accept_source_route=0    &lt;br /&gt;
net.ipv6.conf.default.accept_source_route=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
源路由是一种允许用户重定向网络流量的机制。由于这可用于执行中间人攻击，在中间人攻击中，出于恶意目的将流量重定向，因此上述设置将会禁用此功能。 &lt;br /&gt;
 &lt;pre&gt;net.ipv6.conf.all.accept_ra=0    &lt;br /&gt;
net.ipv6.conf.default.accept_ra=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
恶意的IPv6路由广告可能会导致中间人攻击，因此应将其禁用。 &lt;br /&gt;
 &lt;pre&gt;net.ipv4.tcp_sack=0    &lt;br /&gt;
net.ipv4.tcp_dsack=0    &lt;br /&gt;
net.ipv4.tcp_fack=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
禁用TCP SACK。ACK通常被利用，并且在许多情况下是不必要的，因此如果您不需要它，则应将其禁用。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;用户空间&lt;/strong&gt; &lt;br /&gt;
 &lt;pre&gt;kernel.yama.ptrace_scope=2  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
ptrace是一个系统调用，它允许程序调试、修改和检查另一个正在运行的进程，从而使攻击者可以轻易修改其他正在运行的程序的内存。设置将ptrace的使用限制为仅具有CAP_SYS_PTRACE功能的进程。或者，将sysctl设置为3以完全禁用ptrace。 &lt;br /&gt;
 &lt;pre&gt;vm.mmap_rnd_bits=32    &lt;br /&gt;
vm.mmap_rnd_compat_bits=16  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
ASLR是一种常见的漏洞利用缓解措施，它可以使进程的关键部分在内存中的位置随机化。这可能会使各种各样的漏洞利用更困难，因为它们首先需要信息泄漏。上述设置增加了用于mmap ASLR的熵的位数，从而提高了其有效性。 &lt;br /&gt;
 &lt;br /&gt;这些sysctls的值必须根据CPU体系结构进行设置。以上值与x86兼容，但其他体系结构可能有所不同。 &lt;br /&gt;
 &lt;pre&gt;fs.protected_symlinks=1    &lt;br /&gt;
fs.protected_hardlinks=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
仅当在可全局写入的粘性目录之外，当符号链接和关注者的所有者匹配或目录所有者与符号链接的所有者匹配时，才允许遵循符号链接。这还可以防止没有对源文件的读/写访问权限的用户创建硬链接。这两者都阻止了许多常见的TOCTOU漏洞（time-of-check-to-time-of-use）。 &lt;br /&gt;
 &lt;pre&gt;fs.protected_fifos=2    &lt;br /&gt;
fs.protected_regular=2  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这些阻止了在可能由攻击者控制的环境（例如，全局可写目录）中创建文件，从而使数据欺骗攻击更加困难。 &lt;br /&gt;
 &lt;h4&gt;引导参数&lt;/h4&gt;引导参数在引导时使用引导加载程序（bootloader）将设置传递给内核。类似于sysctl，可以使用某些设置来提高安全性。引导加载程序通常在引导参数设置方式上有所不同。下面列出了一些示例，但是您应该研究特定bootloader的修改参数的必要步骤。 &lt;br /&gt;
 &lt;br /&gt;如果使用GRUB作为引导程序，请编辑/etc /default/grub并将参数添加到GRUB_CMDLINE_LINUX_DEFAULT=line。 &lt;br /&gt;
 &lt;br /&gt;如果使用Syslinux，请编辑/boot/syslinux/syslinux.cfg并将它们添加到APPEND行中。 &lt;br /&gt;
 &lt;br /&gt;如果使用systemd-boot，请编辑您的加载程序条目，并将其附加到linux行的末尾。 &lt;br /&gt;
 &lt;br /&gt;建议使用以下设置以提高安全性。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;Kernel self-protection&lt;/strong&gt; &lt;br /&gt;
 &lt;pre&gt;slab_nomerge  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这将禁用slab合并，这将通过防止覆盖合并的缓存中的对象并使其更难以影响slab缓存的布局，从而大大增加了堆利用的难度。 &lt;br /&gt;
 &lt;pre&gt;slub_debug=FZ  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这些启用健全性检查（F）和重新分区（Z）。健全性检查会添加各种检查，以防止某些slab操作中的损坏。重新分区会在slab周围添加额外的区域，以检测slab何时被覆盖超过其实际大小，从而有助于检测溢出。 &lt;br /&gt;
 &lt;pre&gt;init_on_alloc=1 init_on_free=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这样可以在分配和空闲时间期间将内存清零，这可以帮助减轻使用后使用的漏洞并清除内存中的敏感信息。如果您的内核版本低于5.3，则这些选项不存在。而是在上述slub_debug选项后面附加“ P”，以获得slub_debug=FZP并添加page_poison=1。由于它们实际上是一种调试功能，刚好具有一些安全性，因此它们在释放时提供的内存擦除形式较弱。 &lt;br /&gt;
 &lt;pre&gt;page_alloc.shuffle=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
此选项使页分配器空闲列表随机化，从而通过降低页分配的可预测性来提高安全性，同时这也提高了性能。 &lt;br /&gt;
 &lt;pre&gt;pti=on  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这将启用内核页表隔离，从而减轻崩溃并防止某些KASLR绕过。 &lt;br /&gt;
 &lt;pre&gt;vsyscall=none  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这将禁用vsyscall，因为它们已过时且已被vDSO取代。 vsyscall也在内存中的固定地址上，使其成为ROP攻击的潜在目标。 &lt;br /&gt;
 &lt;pre&gt;debugfs=off  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这将禁用debugfs，它会公开许多有关内核的敏感信息。 &lt;br /&gt;
 &lt;pre&gt;oops=panic  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
有时某些内核漏洞利用会导致所谓的“oops”。此参数将引发内核对此类事件panic，从而防止这些攻击。但是，有时错误的驱动程序会导致无害的操作，这会导致系统崩溃，这意味着此引导参数只能在某些硬件上使用。 &lt;br /&gt;
 &lt;pre&gt;module.sig_enforce=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这仅允许加载已使用有效密钥签名的内核模块，使加载恶意内核模块更加困难。 &lt;br /&gt;
 &lt;br /&gt;这可以防止加载所有树外内核模块（包括DKMS模块），除非您已对其进行签名，这意味着诸如VirtualBox或Nvidia驱动程序之类的模块可能不可用，但根据您的设置可能并不重要。 &lt;br /&gt;
 &lt;pre&gt;lockdown=confidentiality  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
内核锁定LSM可以消除用户空间代码滥用以升级为内核特权并提取敏感信息的许多方法。为了在用户空间和内核之间实现清晰的安全边界，此LSM是必需的。上面的选项在confidentiality模式（最严格的选项）中启用此功能。这意味着module.sig_enforce=1。 &lt;br /&gt;
 &lt;pre&gt;mce=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这将导致内核对ECC内存中无法利用的错误panic，而这些错误可能会被利用。对于没有ECC内存的系统，这是不必要的。 &lt;br /&gt;
 &lt;pre&gt;quiet loglevel=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这些参数可防止引导期间信息泄漏，并且必须与上面的kernel.printk sysctl结合使用。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;CPU缓解&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;最好启用适用于您的CPU的所有CPU缓解措施，以确保您不受已知漏洞的影响。这是启用所有内置缓解措施的列表： &lt;br /&gt;
 &lt;pre&gt;spectre_v2=on spec_store_bypass_disable=on tsx=off tsx_async_abort=full,nosmt mds=full,nosmt l1tf=full,force nosmt=force kvm.nx_huge_pages=force  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
您必须研究系统受其影响的CPU漏洞，并相应地选择上述缓解措施。请记住，您将需要安装微代码更新，以完全免受这些漏洞的影响。但所有这些操作都可能导致性能显着下降。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;结果&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;如果遵循了以上所有建议（不包括特定的CPU缓解措施），则将具有： &lt;br /&gt;
 &lt;pre&gt;slab_nomerge slub_debug=FZ init_on_alloc=1 init_on_free=1 page_alloc.shuffle=1 pti=on vsyscall=none debugfs=off oops=panic module.sig_enforce=1 lockdown=confidentiality mce=0 quiet loglevel=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
如果将GRUB用作引导加载程序，则可能需要重新生成GRUB配置文件才能应用这些文件。 &lt;br /&gt;
 &lt;h4&gt;hidepid&lt;/h4&gt;/proc是一个伪文件系统，其中包含有关系统上当前正在运行的所有进程的信息。默认情况下，所有用户都可以访问此程序，这可能使攻击者可以窥探其他进程。要只允许用户看到自己的进程，而不能看到其他用户的进程，则必须使用hidepid=2，gid=proc挂载选项来挂载/proc。gid=proc将proc组从此功能中排除，因此您可以将特定的用户或进程列入白名单。添加这些选项的一种方法是编辑/etc/fstab并添加： &lt;br /&gt;
 &lt;pre&gt;proc /proc proc nosuid,nodev,noexec,hidepid=2,gid=proc 0 0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
systemd-logind仍然需要查看其他用户的进程，因此，要使用户会话在systemd系统上正常工作，必须创建/etc/systemd/system/systemd-logind.service.d/hidepid.conf并添加： &lt;br /&gt;
 &lt;pre&gt;[Service]    &lt;br /&gt;
SupplementaryGroups=proc  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;减少内核攻击面&lt;/h4&gt;最好禁用不是绝对必要的任何功能，以最大程度地减少潜在的内核攻击面。这些功能不必一定很危险，它们可以只是被删除以减少攻击面的良性代码。切勿禁用您不了解的随机事物。以下是一些可能有用的示例，具体取决于您的设置。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;引导参数&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;引导参数通常可以用来减少攻击面，这样的例子之一是： &lt;br /&gt;
 &lt;pre&gt;ipv6.disable=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这将禁用整个IPv6堆栈，如果您尚未迁移到该堆栈，则可能不需要该堆栈。如果正在使用的IPv6，请不要使用此引导参数。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;将内核模块列入黑名单&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;内核允许非特权的用户通过模块自动加载来间接导致某些模块被加载。这使攻击者可以自动加载易受攻击的模块，然后加以利用。一个这样的示例是CVE-2017-6074，其中攻击者可以通过启动DCCP连接来触发DCCP内核模块的加载，然后利用该内核模块中的漏洞。 &lt;br /&gt;
 &lt;br /&gt;可以通过将文件插入/etc/modprobe.d并将指定的内核模块列入黑名单的方法，将特定的内核模块列入黑名单。 &lt;br /&gt;
 &lt;br /&gt;Install参数告诉modprobe运行特定命令，而不是像往常一样加载模块。 /bin/false是仅返回1的命令，该命令实际上不会执行任何操作。两者都告诉内核运行/bin/false 而不是加载模块，这将防止攻击者利用该模块。以下是最有可能不需要的内核模块： &lt;br /&gt;
 &lt;pre&gt;install dccp /bin/false    &lt;br /&gt;
install sctp /bin/false    &lt;br /&gt;
install rds /bin/false    &lt;br /&gt;
install tipc /bin/false    &lt;br /&gt;
install n-hdlc /bin/false    &lt;br /&gt;
install ax25 /bin/false    &lt;br /&gt;
install netrom /bin/false    &lt;br /&gt;
install x25 /bin/false    &lt;br /&gt;
install rose /bin/false    &lt;br /&gt;
install decnet /bin/false    &lt;br /&gt;
install econet /bin/false    &lt;br /&gt;
install af_802154 /bin/false    &lt;br /&gt;
install ipx /bin/false    &lt;br /&gt;
install appletalk /bin/false    &lt;br /&gt;
install psnap /bin/false    &lt;br /&gt;
install p8023 /bin/false    &lt;br /&gt;
install p8022 /bin/false    &lt;br /&gt;
install can /bin/false    &lt;br /&gt;
install atm /bin/false  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
特别是模糊的网络协议会增加大量的远程攻击面。此黑名单： &lt;br /&gt;
 &lt;ul&gt;  &lt;li&gt;DCCP — Datagram Congestion Control Protocol&lt;/li&gt;  &lt;li&gt;SCTP — Stream Control Transmission Protocol&lt;/li&gt;  &lt;li&gt;RDS — Reliable Datagram Sockets&lt;/li&gt;  &lt;li&gt;TIPC — Transparent Inter-process Communication&lt;/li&gt;  &lt;li&gt;HDLC — High-Level Data Link Control&lt;/li&gt;  &lt;li&gt;AX25 — Amateur X.25&lt;/li&gt;  &lt;li&gt;NetRom&lt;/li&gt;  &lt;li&gt;X25&lt;/li&gt;  &lt;li&gt;ROSE&lt;/li&gt;  &lt;li&gt;DECnet&lt;/li&gt;  &lt;li&gt;Econet&lt;/li&gt;  &lt;li&gt;af_802154 — IEEE 802.15.4&lt;/li&gt;  &lt;li&gt;IPX — Internetwork Packet Exchange&lt;/li&gt;  &lt;li&gt;AppleTalk&lt;/li&gt;  &lt;li&gt;PSNAP — Subnetwork Access Protocol&lt;/li&gt;  &lt;li&gt;p8023 — Novell raw IEEE 802.3&lt;/li&gt;  &lt;li&gt;p8022 — IEEE 802.2&lt;/li&gt;  &lt;li&gt;CAN — Controller Area Network&lt;/li&gt;  &lt;li&gt;ATM&lt;/li&gt;&lt;/ul&gt; &lt;br /&gt;
 &lt;br /&gt; &lt;pre&gt;install cramfs /bin/false    &lt;br /&gt;
install freevxfs /bin/false    &lt;br /&gt;
install jffs2 /bin/false    &lt;br /&gt;
install hfs /bin/false    &lt;br /&gt;
install hfsplus /bin/false    &lt;br /&gt;
install squashfs /bin/false    &lt;br /&gt;
install udf /bin/false  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
将各种稀有文件系统列入黑名单。 &lt;br /&gt;
 &lt;pre&gt;install cifs /bin/true    &lt;br /&gt;
install nfs /bin/true    &lt;br /&gt;
install nfsv3 /bin/true    &lt;br /&gt;
install nfsv4 /bin/true    &lt;br /&gt;
install gfs2 /bin/true  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
如果不使用网络文件系统，也可以将其列入黑名单。 &lt;br /&gt;
 &lt;pre&gt;install vivid /bin/false  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
vivid driver[1]驱动程序仅用于测试目的，并且是特权提升漏洞的原因，因此应禁用它。 &lt;br /&gt;
 &lt;pre&gt;install bluetooth /bin/false    &lt;br /&gt;
install btusb /bin/false  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
禁用具有安全问题历史记录的蓝牙。 &lt;br /&gt;
 &lt;pre&gt;install uvcvideo /bin/false  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这会禁用网络摄像头，以防止其被用来监视您。 &lt;br /&gt;
 &lt;br /&gt;您也可以将麦克风模块列入黑名单，但这在系统之间可能会有所不同。要查找模块的名称，请在/proc/asound/modules中查找并将其列入黑名单。例如，一个这样的模块是snd_hda_intel。 &lt;br /&gt;
 &lt;br /&gt;请注意，尽管有时麦克风的内核模块与扬声器的模块相同。这意味着像这样禁用麦克风也可能会无意中禁用任何扬声器，虽然扬声器也有可能变成麦克风，所以这不一定是消极的结果。 &lt;br /&gt;
 &lt;br /&gt;最好从物理上删除这些设备，或者至少在BIOS/UEFI中禁用它们。禁用内核模块并不总是那么有效。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;rfkill&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;可以通过rfkill将无线设备列入黑名单，以进一步减少远程攻击面。要将所有无线设备列入黑名单，请执行： &lt;br /&gt;
 &lt;pre&gt;rfkill block all  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
WiFi可以通过以下方式解锁： &lt;br /&gt;
 &lt;pre&gt;rfkill unblock wifi  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
在使用systemd的系统上，rfkill在所有会话中均保持不变，但是，在使用其他init系统的系统上，您可能必须创建一个init脚本以在引导时执行这些命令。 &lt;br /&gt;
 &lt;h4&gt;其他内核指针泄漏&lt;/h4&gt;前面的部分已经防止了一些内核指针泄漏，但是还有更多泄漏。 &lt;br /&gt;
 &lt;br /&gt;在文件系统上，/boot中存在内核映像和System.map文件。/usr/src和/{,usr/} lib/modules目录中还有其他敏感的内核信息。您应该限制这些目录的文件权限，以使它们只能由root用户读取。您还应该删除System.map文件，因为除高级调试外，它们都不需要。 &lt;br /&gt;
 &lt;br /&gt;此外，某些日志记录守护程序（例如systemd的journalctl）包括内核日志，可用于绕过上述dmesg_restrict保护。从adm组中删除用户通常足以撤销对以下日志的访问： &lt;br /&gt;
 &lt;pre&gt;gpasswd -d $user adm  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;限制对sysfs的访问&lt;/h4&gt;sysfs是伪文件系统，可提供大量的内核和硬件信息。它通常安装在/sys上。 sysfs导致大量信息泄漏，尤其是内核指针泄漏。Whonix的security-misc软件包包括hide-hardware-info脚本，该脚本限制访问此目录以及/proc中的一些脚本，以试图隐藏潜在的硬件标识符并防止内核指针泄漏。该脚本是可配置的，并允许基于组将特定的应用程序列入白名单。建议应用此方法，并使其在启动时使用init脚本执行。或者 &lt;a href="https://github.com/Whonix/security-misc/blob/master/lib/systemd/system/hide-hardware-info.service"&gt;这样做成systemd服务&lt;/a&gt;。 &lt;br /&gt;
 &lt;br /&gt;为了使基本功能在使用systemd的系统上运行，必须将一些系统服务列入白名单。这可以通过创建/etc/systemd/system/user@.service.d/sysfs.conf并添加以下内容来完成： &lt;br /&gt;
 &lt;pre&gt;[Service]    &lt;br /&gt;
SupplementaryGroups=sysfs  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
但是，这不能解决所有问题。许多应用程序可能仍会中断，您需要将它们正确列入白名单。 &lt;br /&gt;
 &lt;h4&gt;Linux强化&lt;/h4&gt;某些发行版（例如Arch Linux）包括强化的内核程序包。它包含许多强化补丁程序和更注重安全性的内核配置。如果可能的话，建议安装它。 &lt;br /&gt;
 &lt;h4&gt;Grsecurity&lt;/h4&gt;Grsecurity是一组内核修补程序，可以大大提高内核安全性。这些补丁曾经可以免费获得，但是现在需要购买了。如果可用，则强烈建议您获取它。Grsecurity提供了最新的内核和用户空间保护。 &lt;br /&gt;
 &lt;h4&gt;内核运行时防护&lt;/h4&gt;Linux Kernel Runtime Guard（LKRG）是一个内核模块，可确保运行时内核的完整性并检测漏洞。它可以杀死整个类别的内核漏洞。但这并不是一个完美的缓解方法，因为LKRG在设计上可以绕开。它仅适用于现成的恶意软件。但是，尽管可能性不大，但LKRG本身可能会像其他任何内核模块一样公开新的漏洞。 &lt;br /&gt;
 &lt;h4&gt;自编译内核&lt;/h4&gt;建议编译您自己的内核，同时启用尽可能少的内核模块和尽可能多的安全性功能，以将内核的受攻击面保持在绝对最低限度。 &lt;br /&gt;
 &lt;br /&gt;另外，应用内核强化补丁，例如如上所述的linux-hardened或grsecurity。 &lt;br /&gt;
 &lt;br /&gt;发行版编译的内核还具有公共内核指针/符号，这对于漏洞利用非常有用。编译自己的内核将为您提供独特的内核符号，连同kptr_restrict，dmesg_restrict和其他针对内核指针泄漏的强化措施，将使攻击者更加难以创建依赖于内核指针知识的漏洞利用程序。 &lt;br /&gt;
 &lt;br /&gt;您就可以从Whonix的强化内核中汲取灵感或使用它。 &lt;br /&gt;
 &lt;h3&gt;强制访问措施&lt;/h3&gt;强制访问控制（MAC）系统对程序可以访问的内容进行细粒度的控制。这意味着您的浏览器将无权访问您的整个主目录或类似目录。 &lt;br /&gt;
 &lt;br /&gt;最常用的MAC措施是SELinux和AppArmor。SELinux比AppArmor更安全，因为它的粒度更细。例如，它是基于inode而不是基于路径的，允许强制执行明显更严格的限制，可以过滤内核ioctl等。不幸的是，这是以难以使用和难以学习为代价的，因此某些人可能会首选AppArmor。 &lt;br /&gt;
 &lt;br /&gt;要在内核中启用AppArmor，必须设置以下引导参数： &lt;br /&gt;
 &lt;pre&gt;apparmor=1 security=apparmor  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
要启用SELinux，请设置以下参数： &lt;br /&gt;
 &lt;pre&gt;selinux=1 security=selinux  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
请记住，仅启用MAC措施本身并不能神奇地提高安全性。您必须制定严格的政策才能充分利用它。例如，要创建AppArmor配置文件，请执行： &lt;br /&gt;
 &lt;pre&gt;aa-genprof $path_to_program  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
打开程序，然后像往常一样开始使用它。AppArmor将检测需要访问哪些文件，并将它们添加到配置文件中（如果您选择的话）。但是，仅凭这一点不足以提供高质量的配置文件。请参阅AppArmor文档[5]以获取更多详细信息。 &lt;br /&gt;
 &lt;br /&gt;如果您想更进一步，则可以通过实施initramfs勾子来设置一个完整的系统MAC策略，该策略限制每个单个用户空间进程，该挂钩对init系统强制实施MAC策略。这就是Android使用SELinux的方式，以及Whonix未来将如何使用AppArmor的方式。对于加强实施最小特权原则的强大安全模型是必要的。 &lt;br /&gt;
 &lt;h3&gt;沙箱&lt;/h3&gt; &lt;h4&gt;应用沙箱&lt;/h4&gt;沙箱可让您在隔离的环境中运行程序，该环境对系统的其余部分具有有限的访问权限或完全没有访问权限。您可以使用它们来保护应用程序安全或运行不受信任的程序。 &lt;br /&gt;
 &lt;br /&gt;建议与AppArmor或SELinux一起在单独的用户帐户中使用Bubblewrap[6]到沙箱程序。您也可以考虑改用gVisor，它的优点是为每个来宾提供了自己的内核。 &lt;br /&gt;
 &lt;br /&gt;这些方法中的任何一个都可以用来创建一个功能强大的沙箱，并且暴露的攻击面最小。如果您不想自己创建沙箱，请在完成后考虑使用Whonix的sandbox-app-launcher。您不应该使用Firejail。 &lt;br /&gt;
 &lt;br /&gt;诸如Docker和LXC之类的容器解决方案经常被误导为沙盒形式。它们太宽松了，无法广泛支持各种应用程序，因此不能认为它们是强大的应用程序沙箱。 &lt;br /&gt;
 &lt;h4&gt;常见沙箱逃逸&lt;/h4&gt; &lt;strong&gt;PulseAudio&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;PulseAudio是一种常见的声音服务器，但在编写时并未考虑隔离或沙盒的问题，这使其成为重复出现的沙盒逃逸漏洞。为了防止这种情况，建议您从沙箱中阻止对PulseAudio的访问，或者从系统中完全卸载它。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;D-Bus&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;D-Bus是台式机Linux上最流行的进程间通信形式，但它也是沙箱逃逸的另一种常见途径，因为它允许与服务自由交互。这些漏洞的一个例子就是Firejail。您应该从沙箱中阻止对D-Bus的访问，或者通过MAC以细粒度的规则进行调解。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;GUI隔离&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;任何Xorg窗口都可以访问另一个窗口。这允许琐碎的键盘记录或屏幕截图程序，甚至可以记录诸如root密码之类的内容。您可以使用嵌套的X11服务器（例如Xpra或Xephyr和bubblewrap）将Xorg窗口沙箱化。默认情况下，Wayland将窗口彼此隔离，这将是一个比Xorg更好的选择，尽管Wayland可能不如Xorg普遍可用，因为它在开发中较早。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;ptrace&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;如前所述，ptrace是一个系统调用，可能会被滥用破坏在沙箱外部运行的进程。为避免这种情况，您可以通过sysctl启用内核YAMA ptrace限制，也可以在seccomp过滤器中将ptrace syscall列入黑名单。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;TIOCSTI&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;TIOCSTI是一个ioctl，它允许注入终端命令，并为攻击者提供了一种简单的机制，可以在同一用户会话内的其他进程之间横向移动。可以通过将seccomp过滤器中的ioctl列入黑名单或使用bubblewrap的--new-session参数来缓解这种攻击。 &lt;br /&gt;
 &lt;h4&gt;Systemd沙箱&lt;/h4&gt;虽然不建议使用systemd，但有些系统可能无法切换。这些人至少可以使用沙盒服务，因此他们只能访问所需的内容。这是一个沙箱化systemd服务的示例： &lt;br /&gt;
 &lt;pre&gt;[Service]    &lt;br /&gt;
CapabilityBoundingSet=CAP_NET_BIND_SERVICE    &lt;br /&gt;
ProtectSystem=strict    &lt;br /&gt;
ProtectHome=true    &lt;br /&gt;
ProtectKernelTunables=true    &lt;br /&gt;
ProtectKernelModules=true    &lt;br /&gt;
ProtectControlGroups=true    &lt;br /&gt;
ProtectKernelLogs=true    &lt;br /&gt;
ProtectHostname=true    &lt;br /&gt;
ProtectClock=true    &lt;br /&gt;
ProtectProc=invisible    &lt;br /&gt;
ProcSubset=pid    &lt;br /&gt;
PrivateTmp=true    &lt;br /&gt;
PrivateUsers=yes    &lt;br /&gt;
PrivateDevices=true    &lt;br /&gt;
MemoryDenyWriteExecute=true    &lt;br /&gt;
NoNewPrivileges=true    &lt;br /&gt;
LockPersonality=true    &lt;br /&gt;
RestrictRealtime=true    &lt;br /&gt;
RestrictSUIDSGID=true    &lt;br /&gt;
RestrictAddressFamilies=AF_INET    &lt;br /&gt;
RestrictNamespaces=yes    &lt;br /&gt;
SystemCallFilter=write read openat close brk fstat lseek mmap mprotect munmap rt_sigaction rt_sigprocmask ioctl nanosleep select access execve getuid arch_prctl set_tid_address set_robust_list prlimit64 pread64 getrandom    &lt;br /&gt;
SystemCallArchitectures=native    &lt;br /&gt;
UMask=0077    &lt;br /&gt;
IPAddressDeny=any    &lt;br /&gt;
AppArmorProfile=/etc/apparmor.d/usr.bin.example  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
所有选项的说明： &lt;br /&gt;
 &lt;ul&gt;  &lt;li&gt;   &lt;code&gt;CapabilityBoundingSet=&lt;/code&gt;— Specifies the  capabilities[8]the process is given.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;ProtectHome=true&lt;/code&gt;— Makes all home directories inaccessible.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;ProtectKernelTunables=true&lt;/code&gt;— Mounts kernel tunables such as those modified through   &lt;code&gt;sysctl&lt;/code&gt;as read-only.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;ProtectKernelModules=true&lt;/code&gt;— Denies module loading and unloading.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;ProtectControlGroups=true&lt;/code&gt;— Mounts all control group hierarchies as read-only.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;ProtectKernelLogs=true&lt;/code&gt;— Prevents accessing the kernel logs.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;ProtectHostname=true&lt;/code&gt;— Prevents changes to the system hostname.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;ProtectClock&lt;/code&gt;— Prevents changes to the system clock.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;ProtectProc=invisible&lt;/code&gt;— Hides all outside processes.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;ProcSubset=pid&lt;/code&gt;— Permits access to only the pid subset of   &lt;code&gt;/proc&lt;/code&gt;.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;PrivateTmp=true&lt;/code&gt;— Mounts an empty tmpfs over   &lt;code&gt;/tmp&lt;/code&gt;and   &lt;code&gt;/var/tmp&lt;/code&gt;, therefore hiding their previous contents.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;PrivateUsers=true&lt;/code&gt;— Sets up an empty user namespace to hide other user accounts on the system.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;PrivateDevices=true&lt;/code&gt;— Creates a new   &lt;code&gt;/dev&lt;/code&gt;mount with minimal devices present.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;MemoryDenyWriteExecute=true&lt;/code&gt;— Enforces a memory W^X policy.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;NoNewPrivileges=true&lt;/code&gt;— Prevents escalating privileges.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;LockPersonality=true&lt;/code&gt;— Locks down the   &lt;code&gt;personality()&lt;/code&gt;syscall to prevent switching execution domains.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;RestrictRealtime=true&lt;/code&gt;— Prevents attempts to enable realtime scheduling.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;RestrictSUIDSGID=true&lt;/code&gt;— Prevents executing setuid or setgid binaries.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;RestrictAddressFamilies=AF_INET&lt;/code&gt;— Restricts the usable socket address families to IPv4 only (   &lt;code&gt;AF_INET&lt;/code&gt;).&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;RestrictNamespaces=true&lt;/code&gt;— Prevents creating any new namespaces.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;SystemCallFilter=...&lt;/code&gt;— Restricts the allowed syscalls to the absolute minimum. If you aren&amp;apos;t willing to maintain your own custom seccomp filter, then systemd provides many    &lt;a href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html#System%20Call%20Filtering"&gt;predefined system call sets&lt;/a&gt; that you can use.   &lt;code&gt;@system-service&lt;/code&gt;will be suitable for many use cases.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;SystemCallArchitectures=native&lt;/code&gt;— Prevents executing syscalls from other CPU architectures.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;UMask=0077&lt;/code&gt;— Sets the  umask[9]to a more restrictive value.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;IPAddressDeny=any&lt;/code&gt;— Blocks all incoming and outgoing traffic to/from any IP address. Set   &lt;code&gt;IPAddressAllow=&lt;/code&gt;to configure a whitelist. Alternatively, setup a network namespace with   &lt;code&gt;PrivateNetwork=true&lt;/code&gt;.&lt;/li&gt;  &lt;li&gt;   &lt;code&gt;AppArmorProfile=...&lt;/code&gt;— Runs the process under the specified AppArmor profile.&lt;/li&gt;&lt;/ul&gt; &lt;br /&gt;
 &lt;br /&gt;您不能仅将此示例配置复制到您的配置中，每种服务的要求各不相同，并且必须针对每种服务微调沙箱。要了解有关您可以设置的所有选项的更多信息，请阅读 &lt;a href="https://www.freedesktop.org/software/systemd/man/systemd.exec.html"&gt;systemd.exec手册页&lt;/a&gt;。 &lt;br /&gt;
 &lt;br /&gt;如果您使用的系统不是systemd而是init，那么可以使用bubblewrap轻松复制所有这些选项。 &lt;br /&gt;
 &lt;h4&gt;gVisor&lt;/h4&gt;普通沙箱固有地与主机共享同一内核。您信任我们已经评估为不安全的内核，可以正确限制这些程序。由于主机内核的整个攻击面已完全暴露，因此沙盒中的内核利用程序可以绕过任何限制。已经进行了一些努力来限制使用seccomp的攻击面，但不足以完全解决此问题。 &lt;br /&gt;
 &lt;br /&gt;GVisor是解决此问题的方法。它为每个应用程序提供了自己的内核，该内核以内存安全的语言重新实现了Linux内核的大部分系统调用，从而提供了明显更强的隔离性。 &lt;br /&gt;
 &lt;h4&gt;虚拟机&lt;/h4&gt;虽然不是传统的“沙盒”，但虚拟机通过虚拟化全新系统来分离进程，从而提供了非常强大的隔离性。KVM是内核模块，它允许内核充当管理程序，而QEMU是利用KVM的仿真器。Virt-manager和GNOME Boxs都是良好且易于使用的GUI，用于管理KVM / QEMU虚拟机。不建议使用Virtualbox的原因有很多。 &lt;br /&gt;
 &lt;h3&gt;强化内存分配器&lt;/h3&gt;hardened_malloc是一种硬化的内存分配器，可为堆内存损坏漏洞提供实质性的保护。它很大程度上基于OpenBSD的malloc设计，但具有许多改进。 &lt;br /&gt;
 &lt;br /&gt;可以通过LD_PRELOAD环境变量针对每个应用程序使用hardened_malloc。例如，假设您编译的库位于/usr/lib/libhardened_malloc.so，则可以执行： &lt;br /&gt;
 &lt;pre&gt;LD_PRELOAD=&amp;quot;/usr/lib/libhardened_malloc.so&amp;quot; $program  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
通过全局预加载该库，也可以在系统范围内使用它，这是使用它的推荐方法。为此，请编辑/etc/ld.so.preload并插入： &lt;br /&gt;
 &lt;pre&gt;/usr/lib/libhardened_malloc.so  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
尽管大多数应用程序都可以正常工作，但hardened_malloc可能会破坏某些应用程序。建议使用以下选项编译hardened_malloc以最大程度地减少损坏： &lt;br /&gt;
 &lt;pre&gt;CONFIG_SLAB_QUARANTINE_RANDOM_LENGTH=0 CONFIG_SLAB_QUARANTINE_QUEUE_LENGTH=0 CONFIG_GUARD_SLABS_INTERVAL=8  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
您还应该使用sysctl设置以下内容，以适应hardened_malloc创建的大量保护页： &lt;br /&gt;
 &lt;pre&gt;vm.max_map_count=524240  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
Whonix项目为基于Debian的发行版提供了hardened_malloc软件包。 &lt;br /&gt;
 &lt;h3&gt;强化编译标志&lt;/h3&gt;编译自己的程序可以带来很多好处，因为它使您能够优化程序的安全性。但是，执行完全相反的操作并降低安全性很容易，如果您不确定自己在做什么，请跳过本节。在基于源的发行版（例如Gentoo）上，这将是最简单的，但也可以在其他发行版上这样做。 &lt;br /&gt;
 &lt;br /&gt;某些编译选项可用于添加其他漏洞利用缓解措施，从而消除整个类别的常见漏洞。您可能听说过常规保护，例如位置独立可执行文件，堆栈粉碎保护程序，立即绑定，只读重定位和FORTIFY_SOURCE，但是本节将不做介绍，因为它们已被广泛采用。相反，它将讨论诸如控制流完整性和影子堆栈之类的现代漏洞利用缓解措施。 &lt;br /&gt;
 &lt;br /&gt;本节涉及主要用C或C ++编写的本机程序。您必须使用Clang编译器，因为这些功能在GCC上不可用。请记住，由于未广泛采用这些缓解措施，因此某些应用程序在启用它们后可能无法运行。 &lt;br /&gt;
 &lt;br /&gt;控制流完整性（CFI）是一种缓解漏洞利用的方法，旨在防止诸如ROP或JOP之类的代码重用攻击。由于更广泛采用的缓解措施（例如NX）使过时的利用技术过时了，因此使用这些技术利用了很大一部分漏洞。Clang支持细粒度的前沿CFI，这意味着它可以有效缓解JOP攻击。Clang的CFI本身并不能减轻ROP；您还必须使用下面记录的单独机制。要启用此功能，必须应用以下编译标志：  &lt;br /&gt;
 &lt;pre&gt;-flto -fvisibility=hidden -fsanitize=cfi  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
影子堆栈通过将程序复制到其他隐藏堆栈中来保护程序的返回地址。然后比较主堆栈和影子堆栈中的返回地址，看两者是否不同。如果是这样，则表明存在攻击，程序将中止，从而减轻了ROP攻击。Clang具有称为ShadowCallStack的功能，可以完成此操作，但是，仅在ARM64上可用。要启用此功能，必须应用以下编译标志： &lt;br /&gt;
 &lt;pre&gt;-fsanitize=shadow-call-stack  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
如果上述ShadowCallStack不是一个选项，则可以选择使用具有相似目标的SafeStack。但是，不幸的是，此功能有许多漏洞，因此效果不甚理想。如果仍然希望启用此功能，则必须应用以下编译标志： &lt;br /&gt;
 &lt;pre&gt;-fsanitize=safe-stack  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
最常见的内存损坏漏洞之一是未初始化的内存。Clang有一个选项可以使用零或特定模式自动初始化变量。建议将变量初始化为零，因为使用其他模式比利用漏洞缓解功能更适合发现错误。要启用此功能，必须应用以下编译标志： &lt;br /&gt;
 &lt;pre&gt;-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
但该选项的存在目前正在 &lt;a href="https://lists.llvm.org/pipermail/cfe-dev/2020-April/065221.html"&gt;辩论&lt;/a&gt;中。 &lt;br /&gt;
 &lt;h3&gt;内存安全语言&lt;/h3&gt;用内存安全语言编写的程序会自动受到保护，免受各种安全漏洞的影响，这些安全漏洞包括缓冲区溢出，未初始化的变量，售后使用等。Microsoft和Google的安全研究人员进行的研究证明，已发现的大多数漏洞都是内存安全问题。这样的内存安全语言的示例包括Rust，Swift和Java，而内存不安全语言的示例包括C和C ++。如果可行，应使用内存安全替代品替换尽可能多的程序。 &lt;br /&gt;
 &lt;h3&gt;Root账户&lt;/h3&gt;root可以执行任何操作，并且可以访问您的整个系统。因此，应尽可能将其锁定，以使攻击者无法轻松获得root用户访问权限。 &lt;br /&gt;
 &lt;h4&gt;/etc/securetty&lt;/h4&gt;/etc/securetty文件指定允许您以root用户身份登录的位置。该文件应保留为空，以便任何人都不能从终端上这样做。 &lt;br /&gt;
 &lt;h4&gt;限制su&lt;/h4&gt;su可让您从终端切换用户。默认情况下，它尝试以root用户身份登录。要将su的使用限制在wheel组中，请编辑/etc/pam.d/su和/etc/pam.d/su-l并添加： &lt;br /&gt;
 &lt;pre&gt;auth required pam_wheel.so use_uid  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
您应该在wheel组中拥有尽可能少的用户。 &lt;br /&gt;
 &lt;h4&gt;锁定root账户&lt;/h4&gt;要锁定root帐户以防止任何人以root身份登录，请执行： &lt;br /&gt;
 &lt;pre&gt;passwd -l root  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
在执行此操作之前，请确保您具有获取根的替代方法（例如，从活动USB引导并更改为文件系统的chroot），以免您无意中将自己锁定在系统之外。 &lt;br /&gt;
 &lt;h4&gt;拒绝通过SSH的远程root登陆&lt;/h4&gt;为了防止某人通过SSH以root身份登录，请编辑/etc/ssh/sshd_config并添加： &lt;br /&gt;
 &lt;pre&gt;PermitRootLogin no  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;增加散列回合数&lt;/h4&gt;您可以增加shadow使用的哈希回合数，从而通过迫使攻击者计算更多的哈希值来破解您的密码，从而提高哈希密码的安全性。默认情况下，shadow使用5000次回合，但是您可以将其增加到任意数量。尽管配置的回合越多，登录速度就越慢。编辑/etc/pam.d/passwd并添加回合选项。 &lt;br /&gt;
 &lt;pre&gt;password required pam_unix.so sha512 shadow nullok rounds=65536  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这使shadow执行65536次散列回合。 &lt;br /&gt;
 &lt;br /&gt;应用此设置后，密码不会自动重新加密，因此您需要使用以下方法重置密码： &lt;br /&gt;
 &lt;pre&gt;passwd $username  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;限制Xorg root访问&lt;/h4&gt;默认情况下，某些发行版以root用户身份运行Xorg，这是一个问题，因为Xorg包含大量古老而又复杂的代码，这增加了巨大的攻击面，并使其更有可能拥有可以获取root特权的漏洞利用程序。要阻止它作为root用户执行，请编辑/etc/X11/Xwrapper.config并添加： &lt;br /&gt;
 &lt;pre&gt;needs_root_rights = no  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;安全访问root&lt;/h4&gt;恶意软件可以使用多种方法来嗅探root帐户的密码。因此，访问根帐户的传统方式是不安全的，最好根本不访问根，但这实际上是不可行的。本节详细介绍了访问根帐户的最安全方法。在安装操作系统后，应立即应用这些说明，以确保该软件不含恶意软件。 &lt;br /&gt;
 &lt;br /&gt;您绝对不能使用普通用户帐户访问root，因为root可能已被盗用。您也不能直接登录到根帐户。通过执行以下操作，创建一个单独的“管理员”用户帐户，该帐户仅用于访问root用户，而不能用于访问其他用户： &lt;br /&gt;
 &lt;pre&gt;useradd admin  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
执行并来设置一个非常强的密码： &lt;br /&gt;
 &lt;pre&gt;passwd admin  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
仅允许该帐户使用您首选的权限提升机制。例如，如果使用sudo，则通过执行以下命令来添加sudoers异常： &lt;br /&gt;
 &lt;pre&gt;visudo -f /etc/sudoers.d/admin-account  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
然后输入： &lt;br /&gt;
 &lt;pre&gt;admin ALL=(ALL) ALL  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
确保没有其他帐户可以访问sudo（或您的首选机制） &lt;br /&gt;
 &lt;br /&gt;现在，要实际登录到该帐户，请先重新启动-例如，这可以防止受损的窗口管理器执行登录欺骗。当提供登录提示时，请通过按键盘上的以下组合键来激活安全注意键： &lt;br /&gt;
 &lt;pre&gt;Alt + SysRq + k  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
这将杀死当前虚拟控制台上的所有应用程序，从而克服登录欺骗攻击。现在，您可以安全地登录到您的管理员帐户，并使用root用户执行任务。完成后，注销管理员帐户，然后重新登录到非特权用户帐户。 &lt;br /&gt;
 &lt;h3&gt;防火墙&lt;/h3&gt;防火墙可以控制传入和传出的网络流量，并且可以用来阻止或允许某些类型的流量。除非有特殊原因，否则应始终阻止所有传入流量。建议设置严格的iptables或nftables防火墙。火墙必须针对您的系统进行微调，并且没有一个适合所有防火墙的规则集。建议您熟悉创建防火墙规则。Arch Wiki[14]和手册页[15]都是很好的资源。 &lt;br /&gt;
 &lt;br /&gt;这是基本iptables配置的示例，该配置禁止所有传入的网络流量： &lt;br /&gt;
 &lt;pre&gt;*filter    &lt;br /&gt;
:INPUT DROP [0:0]    &lt;br /&gt;
:FORWARD DROP [0:0]    &lt;br /&gt;
:OUTPUT ACCEPT [0:0]    &lt;br /&gt;
:TCP - [0:0]    &lt;br /&gt;
:UDP - [0:0]    &lt;br /&gt;
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT    &lt;br /&gt;
-A INPUT -i lo -j ACCEPT    &lt;br /&gt;
-A INPUT -m conntrack --ctstate INVALID -j DROP    &lt;br /&gt;
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP    &lt;br /&gt;
-A INPUT -p tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP    &lt;br /&gt;
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable    &lt;br /&gt;
-A INPUT -p tcp -j REJECT --reject-with tcp-reset    &lt;br /&gt;
-A INPUT -j REJECT --reject-with icmp-proto-unreachable    &lt;br /&gt;
COMMIT  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
但是，您不应尝试在实际系统上使用此示例。它仅适用于某些台式机系统。 &lt;br /&gt;
 &lt;h3&gt;身份标识&lt;/h3&gt;为了保护隐私，最好最大程度地减少可追溯到您的信息量。 &lt;br /&gt;
 &lt;h4&gt;主机名和用户名&lt;/h4&gt;请勿在主机名或用户名中添加唯一标识的内容。将它们保留为通用名称，例如“host”和“user”，以便它们无法识别您。 &lt;br /&gt;
 &lt;h4&gt;Timezones / Locales / Keymaps&lt;/h4&gt;如果可能，应将您的时区设置为“ UTC”，将区域设置和键盘映射设置为“ US”。 &lt;br /&gt;
 &lt;h4&gt;机器ID&lt;/h4&gt;一个独一无二的机器ID被存储在/var/lib/dbus/machine-id （systemd系统是保存在/etc/machine-id）这些应编辑为通用名称，例如Whonix ID： &lt;br /&gt;
 &lt;pre&gt;b08dfa6083e7567a1921a715000001fb  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;MAC地址欺骗&lt;/h4&gt;MAC地址是分配给网络接口控制器（NIC）的唯一标识符。每次您连接到网络时（WIFI或以太网）则您的MAC地址已暴露。这使人们可以使用它来跟踪您并在本地网络上唯一地标识您。 &lt;br /&gt;
 &lt;br /&gt;但您不应该完全随机化MAC地址。拥有完全随机的MAC地址是显而易见的，并且会对您脱颖而出的行为产生不利影响。 &lt;br /&gt;
 &lt;br /&gt;MAC地址的OUI（组织唯一标识符）部分标识芯片组的制造商。对MAC地址的这一部分进行随机化处理可能会为您提供以前从未使用过的OUI，数十年来从未使用过的OUI或在您所在的地区极为罕见的OUI，因此使您脱颖而出，很明显地表明您在欺骗MAC地址。 &lt;br /&gt;
 &lt;br /&gt;MAC地址的末尾标识您的特定设备，并且可以用来跟踪您的设备。仅对MAC地址的这一部分进行随机化可防止您被跟踪，同时仍使MAC地址看起来可信。 &lt;br /&gt;
 &lt;br /&gt;要欺骗这些地址，请首先执行以下命令找出您的网络接口名称： &lt;br /&gt;
 &lt;pre&gt;ip a  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
接下来，安装macchanger并执行： &lt;br /&gt;
 &lt;pre&gt;macchanger -e $network_interface  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
要在每次引导时随机分配MAC地址，您应该为您的特定初始化系统创建一个初始化脚本。这是systemd的一个示例： &lt;br /&gt;
 &lt;pre&gt;[Unit]    &lt;br /&gt;
Description=macchanger on eth0    &lt;br /&gt;
Wants=network-pre.target    &lt;br /&gt;
Before=network-pre.target    &lt;br /&gt;
BindsTo=sys-subsystem-net-devices-eth0.device    &lt;br /&gt;
After=sys-subsystem-net-devices-eth0.device    &lt;br /&gt;
  &lt;br /&gt;
[Service]    &lt;br /&gt;
ExecStart=/usr/bin/macchanger -e eth0    &lt;br /&gt;
Type=oneshot    &lt;br /&gt;
  &lt;br /&gt;
[Install]    &lt;br /&gt;
WantedBy=multi-user.target  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
上面的示例在启动时欺骗了eth0接口的MAC地址。将eth0替换为您的网络接口。 &lt;br /&gt;
 &lt;h4&gt;时间攻击&lt;/h4&gt;几乎每个系统都有不同的时间。这可用于时钟偏斜指纹攻击，几毫秒的差异足以使用户被暴露识别。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;ICMP时间戳&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;ICMP时间戳会在查询答复中泄漏系统时间。阻止这些攻击的最简单方法是利用防火墙阻止传入连接，或者使内核忽略ICMP请求。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;TCP时间戳&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;TCP时间戳也会泄漏系统时间。内核尝试通过对每个连接使用随机偏移量来解决此问题，但这不足以解决问题。因此应该禁用TCP时间戳，可以通过使用sysctl设置以下内容来完成： &lt;br /&gt;
 &lt;pre&gt;net.ipv4.tcp_timestamps=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;strong&gt;TCP初始化序号&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;TCP初始序列号（ISN）是泄漏系统时间的另一种方法。为了减轻这种情况，您必须安装tirdad内核模块，该模块会生成用于连接的随机ISN。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;时间同步&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;时间同步对于匿名性和安全性至关重要。错误的系统时钟可能使您遭受时钟偏斜指纹攻击，或者可以用来为您提供过时的HTTPS证书，从而绕过证书到期或吊销。 &lt;br /&gt;
 &lt;br /&gt;最流行的时间同步方法NTP是不安全的，因为它未经加密和未经身份验证，因此攻击者可以轻易地拦截和修改请求。NTP还会以NTP时间戳格式泄漏本地系统时间，该格式可用于时钟偏斜指纹识别，如前所述。 &lt;br /&gt;
 &lt;br /&gt;因此，您应该卸载所有NTP客户端并禁用systemd-timesyncd（如果正在使用）。您可以通过安全连接（HTTPS或最好是Torion服务）连接到受信任的网站，而不是NTP，并从HTTP标头中提取当前时间。达到此目的的工具是sdwdate或我自己的安全时间同步工具。 &lt;br /&gt;
 &lt;h4&gt;按键指纹&lt;/h4&gt;可以通过他们在键盘上输入键的方式来对人进行指纹识别。您可以通过键入速度，在两次按键之间的暂停，每次按键被按下和释放的确切时间等方式来唯一地进行指纹识别。可以使用KeyTrac在线进行测试。 &lt;br /&gt;
 &lt;br /&gt;Kloak是一种工具，旨在通过混淆按键和释放事件之间的时间间隔来克服这种跟踪方法。当按键被按下时，它会引入随机延迟，然后由应用程序选择。 &lt;br /&gt;
 &lt;h3&gt;文件权限&lt;/h3&gt;默认情况下，文件的权限是非常宽松的。您应该在整个系统中搜索权限不当的文件和目录，并对其进行限制。例如，在诸如Debian之类的某些发行版中，用户的Home目录是全局可读的。 &lt;br /&gt;
 &lt;br /&gt;这可以通过执行以下操作来限制： &lt;br /&gt;
 &lt;pre&gt;chmod 700 /home/$user  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
另外一些示例是/boot，/usr /src和/ {,usr /} lib/modules 它们包含内核映像，System.map和其他各种文件，所有这些文件都可能泄漏有关内核的敏感信息。 &lt;br /&gt;
 &lt;pre&gt;chmod 700 /boot /usr/src /lib/modules /usr/lib/modules  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
在基于Debian的发行版中，必须使用dpkg-statoverride保留文件许可权。否则，它们将在更新期间被覆盖。 &lt;br /&gt;
 &lt;br /&gt;Whonix的SUID Disabler和Permission Hardener[22]会自动应用本节中详细介绍的步骤。 &lt;br /&gt;
 &lt;h4&gt;setuid / setgid&lt;/h4&gt;Setuid / SUID允许用户使用二进制文件所有者的特权执行二进制文件。这通常用于允许非特权用户使用通常仅为root用户保留的某些功能。因此，许多SUID二进制文件都有特权升级安全漏洞的历史记录。 Setgid / SGID类似，但适用于组而不是用户。要使用setuid或setgid位查找系统上的所有二进制文件，请执行： &lt;br /&gt;
 &lt;pre&gt;find / -type f \( -perm -4000 -o -perm -2000 \)  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
然后，您应该删除不使用的程序上的所有不必要的setuid / setgid位，或将其替换为功能。要删除setuid位，请执行： &lt;br /&gt;
 &lt;pre&gt;chmod u-s $path_to_program  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
要删除setgid位，执行： &lt;br /&gt;
 &lt;pre&gt;chmod g-s $path_to_program  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
要向文件添加功能，请执行： &lt;br /&gt;
 &lt;pre&gt;setcap $capability+ep $path_to_program  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
或者，要删除不必要的功能，请执行： &lt;br /&gt;
 &lt;pre&gt;setcap -r $path_to_program  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;umask&lt;/h4&gt;umask设置新创建文件的默认文件权限。默认的umask是0022，它不是很安全，因为它为系统上的每个用户提供了对新创建文件的读取访问权限。要使所有者以外的任何人都不可读新文件，请编辑/etc/profile并添加： &lt;br /&gt;
 &lt;pre&gt;umask 0077  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h3&gt;核心转储&lt;/h3&gt;核心转储包含特定时间（通常是该程序崩溃时）该程序的已记录内存。它们可能包含敏感信息，例如密码和加密密钥，因此必须将其禁用。 &lt;br /&gt;
 &lt;br /&gt;禁用它们的方法主要有三种：sysctl，systemd和ulimit &lt;br /&gt;
 &lt;h4&gt;sysctl&lt;/h4&gt;通过sysctl设置以下设置： &lt;br /&gt;
 &lt;pre&gt;kernel.core_pattern=|/bin/false  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;systemd&lt;/h4&gt;创建/etc/systemd/coredump.conf.d/disable.conf并添加如下内容： &lt;br /&gt;
 &lt;pre&gt;[Coredump]    &lt;br /&gt;
Storage=none  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;ulimit&lt;/h4&gt;编辑/etc/security/limits.conf并添加如下内容： &lt;br /&gt;
 &lt;pre&gt;* hard core 0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;setuid进程&lt;/h4&gt;即使在进行了这些设置之后，以提升的特权运行的进程仍可能会转储其内存。 &lt;br /&gt;
 &lt;br /&gt;为了防止他们这样做，请通过sysctl设置以下内容： &lt;br /&gt;
 &lt;pre&gt;fs.suid_dumpable=0  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h3&gt;Swap&lt;/h3&gt;与核心转储类似，交换或分页将部分内存复制到磁盘，其中可能包含敏感信息。应该将内核配置为仅在绝对必要时进行交换，相应的sysctl设置： &lt;br /&gt;
 &lt;pre&gt;vm.swappiness=1  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h3&gt;PAM&lt;/h3&gt;PAM是用于用户身份验证的框架。这就是您登录时使用的机制。您可以通过要求使用强密码或在失败的登录尝试后强制执行延迟验证来使其更加安全。 &lt;br /&gt;
 &lt;br /&gt;要强制使用强密码，可以使用pam_pwquality。它强制执行密码的可配置策略。例如，如果您希望密码至少包含16个字符（最小），与旧密码（difok）至少6个不同的字符，至少3个数字（dcredit），至少2个大写字母（ucredit），至少2个字符小写字母（lcredit）和至少3个其他字符（ocredit），然后编辑/etc/pam.d/passwd并添加： &lt;br /&gt;
 &lt;pre&gt;password required pam_pwquality.so retry=2 minlen=16 difok=6 dcredit=-3 ucredit=-2 lcredit=-2 ocredit=-3 enforce_for_root    &lt;br /&gt;
password required pam_unix.so use_authtok sha512 shadow  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
要强制执行延迟验证，可以使用pam_faildelay。要在两次失败的登录尝试之间添加至少4秒的延迟以阻止暴力破解尝试，请编辑/etc/pam.d/system-login并添加： &lt;br /&gt;
 &lt;pre&gt;auth optional pam_faildelay.so delay=4000000  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
4000000 是4秒（以微秒为单位）。 &lt;br /&gt;
 &lt;h3&gt;Microcode更新&lt;/h3&gt;Microcode更新对于修复关键的CPU漏洞（如Meltdown和Spectre等）至关重要。大多数发行版都将这些发行版包含在其软件仓库中，例如Arch Linux和Debian。 &lt;br /&gt;
 &lt;h3&gt;IPv6隐私扩展&lt;/h3&gt;IPv6地址是从计算机的MAC地址生成的，从而使您的IPv6地址是唯一的，并直接绑定到计算机。隐私扩展会生成一个随机的IPv6地址，以减轻这种形式的跟踪。请注意，如果您开启了MAC地址欺骗机制或禁用了IPv6，则无需执行这些步骤。 &lt;br /&gt;
 &lt;br /&gt;要启用这些功能，请通过sysctl设置以下设置： &lt;br /&gt;
 &lt;pre&gt;net.ipv6.conf.all.use_tempaddr=2    &lt;br /&gt;
net.ipv6.conf.default.use_tempaddr=2  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;NetworkManager&lt;/h4&gt;要为NetworkManager启用隐私扩展，请编辑/etc/NetworkManager/NetworkManager.conf并添加： &lt;br /&gt;
 &lt;pre&gt;[connection]    &lt;br /&gt;
ipv6.ip6-privacy=2  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;systemd-networkd&lt;/h4&gt;要为systemd-networkd启用隐私扩展，请创建/etc/systemd/network/ipv6-privacy.conf并添加： &lt;br /&gt;
 &lt;pre&gt;[Network]    &lt;br /&gt;
IPv6PrivacyExtensions=kernel  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h3&gt;分区和挂载选项&lt;/h3&gt;文件系统应分为多个分区，以对其权限进行细粒度控制。可以添加不同的安装选项以限制可以执行的操作： &lt;br /&gt;
 &lt;ul&gt;  &lt;li&gt;nodev - 禁止使用设备&lt;/li&gt;  &lt;li&gt;nosuid - 禁止setuid或setgid位&lt;/li&gt;  &lt;li&gt;noexec - 禁止执行任何二进制文件&lt;/li&gt;&lt;/ul&gt; &lt;br /&gt;
 &lt;br /&gt;这些安装选项应在/etc/fstab中尽可能设置。如果您不能使用单独的分区，请创建绑定挂载。一个更安全的/etc/fstab的示例： &lt;br /&gt;
 &lt;pre&gt;/        /          ext4    defaults                              1 1    &lt;br /&gt;
/home    /home      ext4    defaults,nosuid,noexec,nodev          1 2    &lt;br /&gt;
/tmp     /tmp       ext4    defaults,bind,nosuid,noexec,nodev     1 2    &lt;br /&gt;
/var     /var       ext4    defaults,bind,nosuid                  1 2    &lt;br /&gt;
/boot    /boot      ext4    defaults,nosuid,noexec,nodev          1 2  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
请注意，可以通过shell脚本绕过noexec。 &lt;br /&gt;
 &lt;h3&gt;熵&lt;/h3&gt;熵基本上反应操作系统信息收集的随机程度，对于诸如加密之类的事情至关重要。因此，最好通过安装其他随机数生成器（如haveged和jitterentropy）从各种来源收集尽可能多的熵。 &lt;br /&gt;
 &lt;br /&gt;为了使jitterentropy正确运行，必须通过创建/usr/lib/modules-load.d/jitterentropy.conf并添加以下内容尽早加载内核模块： &lt;br /&gt;
 &lt;pre&gt;jitterentropy_rng  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;RDRAND&lt;/h4&gt;RDRAN是提供随机数的CPU指令。如果可用，内核会自动将其用作熵源。但是由于它是专有的并且是CPU本身的一部分，因此无法审核和验证其安全性。您甚至无法对代码进行反向工程。该RNG以前曾遭受过漏洞的攻击，其中有些可能是后门攻击。通过设置以下引导参数可以不信任此功能： &lt;br /&gt;
 &lt;pre&gt;random.trust_cpu=off  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h3&gt;以root身份编辑文件&lt;/h3&gt;建议不要以root用户身份运行普通的文本编辑器。大多数文本编辑器可以做的不仅仅是简单地编辑文本文件，而且还可以被利用。例如，以root身份打开vi并输入：sh。现在，您具有一个可以访问整个系统的root shell，攻击者可以轻松利用该shell。 &lt;br /&gt;
 &lt;br /&gt;解决方案是使用sudoedit。这会将文件复制到一个临时位置，以普通用户身份打开文本编辑器，编辑该临时文件并以root用户身份覆盖原始文件。这样，实际的编辑器就不会以root身份运行。要使用sudoedit，执行： &lt;br /&gt;
 &lt;pre&gt;sudoedit $path_to_file  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
默认情况下，它使用vi，但是可以通过EDITOR或SUDO_EDITOR环境变量来切换默认编辑器。例如，要使用nano，请执行： &lt;br /&gt;
 &lt;pre&gt;EDITOR=nano sudoedit $path_to_file  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
可以在/etc/environment中全局设置此环境变量。 &lt;br /&gt;
 &lt;h3&gt;特定发行版的安全强化&lt;/h3&gt; &lt;h4&gt;HTTP包管理器镜像&lt;/h4&gt;默认情况下，Linux发行版通常使用HTTP或HTTP和HTTPS镜像的混合来从其软件存储库下载软件包。人们认为这很好，因为程序包管理器会在安装前验证程序包的签名。但是，从历史上看，已经有很多绕过此方法的地方。您应将软件包管理器配置为从HTTPS镜像专门下载以进行深度防御。 &lt;br /&gt;
 &lt;h4&gt;APT seccomp-bpf&lt;/h4&gt;自软件包管理器Debian Buster以来，APT已支持可选的seccomp-bpf过滤。这限制了允许执行APT的系统调用，这可能严重限制攻击者尝试利用APT中的漏洞时对系统造成危害的能力。要启用此功能，请创建/etc/apt/apt.conf.d/40sandbox并添加： &lt;br /&gt;
 &lt;pre&gt;APT::Sandbox::Seccomp &amp;quot;true&amp;quot;;  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h3&gt;物理安全&lt;/h3&gt;全盘加密可确保对驱动器上的所有数据进行加密，并且不会被物理攻击者读取。大多数发行版都支持在安装过程中启用加密，请确保设置了强密码。您也可以使用dm-crypt[28]手动加密驱动器。 &lt;br /&gt;
 &lt;br /&gt;请注意，全盘加密不包括/boot，这样仍然可以修改内核、引导加载程序和其他关键文件。为了完全防止篡改，您还必须实施经过验证的引导。 &lt;br /&gt;
 &lt;h4&gt;BIOS / UEFI强化&lt;/h4&gt;如果您仍在使用旧版BIOS，则应迁移到UEFI，以利用较新的安全功能。大多数BIOS或UEFI实现都支持设置密码。最好启用它并设置一个非常强壮的密码。虽然这是很弱的保护，因为重置密码很简单。它通常存储在易失性内存中，因此攻击者只需要能够卸下CMOS电池几秒钟，或者他们就可以使用某些主板上的跳线将其重置。 &lt;br /&gt;
 &lt;br /&gt;您还应该禁用所有未使用的设备和引导选项，例如USB引导，以减少攻击面。 &lt;br /&gt;
 &lt;br /&gt;别忽略BIOS或UEFI的更新，确保将其更新。将其与常规操作系统更新一样重要。 &lt;br /&gt;
 &lt;br /&gt;此外，请参阅《 &lt;a href="https://github.com/nsacyber/Hardware-and-Firmware-Security-Guidance"&gt;NSA的硬件和固件安全指南&lt;/a&gt;》。 &lt;br /&gt;
 &lt;h4&gt;Bootloader密码&lt;/h4&gt;引导加载程序会在引导过程的早期执行，并负责加载操作系统。保护它非常重要，否则，它可能会被篡改。例如，本地攻击者可以通过在启动时使用init=/bin/bash作为内核参数来轻松获得root shell，该命令告诉内核执行/bin/bash而不是常规的init系统。您可以通过为引导加载程序设置密码来防止这种情况。仅设置引导程序密码不足以完全保护它。还必须按照以下说明设置经过验证的启动。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;Grub&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;要为GRUB设置密码，请执行： &lt;br /&gt;
 &lt;pre&gt;grub-mkpasswd-pbkdf2  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
输入您的密码，该密码将生成一个字符串。它将类似于“ grub.pbkdf2.sha512.10000.C4009... ”。创建/etc/grub.d/40_password并添加： &lt;br /&gt;
 &lt;pre&gt;set superusers=&amp;quot;$username&amp;quot;    &lt;br /&gt;
password_pbkdf2 $username $password  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
用grub-mkpasswd-pbkdf2生成的字符串替换“$username”将用于被允许使用GRUB命令行，编辑菜单项和执行任何菜单项的超级用户。对于大多数人来说，这只是“root”。 &lt;br /&gt;
 &lt;br /&gt;重新生成您的配置文件，GRUB现在将受到密码保护。 &lt;br /&gt;
 &lt;br /&gt;要仅限制编辑引导参数并访问GRUB控制台，同时仍然允许您引导，请编辑 /boot/grub/grub.cfg并在 “menuentry &amp;apos;$OSName&amp;apos; ”旁边添加“ --unrestricted”参数。 &lt;br /&gt;
 &lt;pre&gt;menuentry &amp;apos;Arch Linux&amp;apos; --unrestricted  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
您将需要再次重新生成配置文件以应用此更改。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;Syslinux&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;Syslinux可以设置主密码或菜单密码。引导任何条目都需要主密码，而引导特定条目仅需要菜单密码。 &lt;br /&gt;
 &lt;br /&gt;要为Syslinux设置主密码，请编辑/boot/syslinux/syslinux.cfg并添加： &lt;br /&gt;
 &lt;pre&gt;MENU MASTER PASSWD $password  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
要设置菜单密码，请编辑/boot/syslinux/syslinux.cfg，并在带有您要密码保护的项目的标签内，添加： &lt;br /&gt;
 &lt;pre&gt;MENU PASSWD $password  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
将“ $password”替换为您要设置的密码。 &lt;br /&gt;
 &lt;br /&gt;这些密码可以是纯文本，也可以使用MD5，SHA-1，SHA-256或SHA-512进行散列。建议先使用强哈希算法（例如SHA-256或SHA-512）对密码进行哈希处理，以避免将其存储为明文形式。 &lt;br /&gt;
 &lt;br /&gt; &lt;strong&gt;systemd-boot&lt;/strong&gt; &lt;br /&gt;
 &lt;br /&gt;systemd-boot具有防止在引导时编辑内核参数的选项。在loader.conf文件中，添加： &lt;br /&gt;
 &lt;pre&gt;editor no  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
systemd-boot并不正式支持保护内核参数编辑器的密码，但是您可以使用systemd-boot-password来实现[30]。 &lt;br /&gt;
 &lt;h4&gt;验证引导&lt;/h4&gt;经过验证的引导通过密码验证来确保引导链和基本系统的完整性。这可用于确保物理攻击者无法修改设备上的软件。 &lt;br /&gt;
 &lt;br /&gt;如果没有经过验证的引导，则一旦获得物理访问权限，就可以轻松绕过上述所有预防措施。经过验证的引导不仅像许多人认为的那样是为了物理安全。它还可以用于防止远程恶意软件持久化——如果攻击者设法破坏了整个系统并获得了很高的特权，则经过验证的引导将在重新引导后还原其更改，并确保它们无法持久化。 &lt;br /&gt;
 &lt;br /&gt;经过验证的最常见的引导实现是UEFI安全引导，但是它本身并不是一个完整的实现，因为它仅会验证引导加载程序和内核，这意味着可以通过以下方法： &lt;br /&gt;
 &lt;ul&gt;  &lt;li&gt;仅UEFI安全启动就没有一成不变的信任根，因此物理攻击者仍然可以刷新设备的固件。为了减轻这种情况，请结合使用UEFI安全启动和Intel Boot Guard或AMD Secure Boot。&lt;/li&gt;  &lt;li&gt;远程攻击者（或不使用加密的物理攻击者）可以简单地修改操作系统的任何其他特权部分。例如，如果他们有修改内核的特权，那么他们也可以修改/sbin/init来有效地获得相同的结果。因此，仅验证内核和引导加载程序不会对远程攻击者产生任何影响。为了减轻这种情况，您必须使用dm-verity[31]验证基本操作系统，尽管由于传统Linux发行版的布局，这非常困难且笨拙。&lt;/li&gt;&lt;/ul&gt; &lt;br /&gt;
 &lt;br /&gt;通常，很难在传统Linux上实现可靠的经过验证的引导实现。 &lt;br /&gt;
 &lt;h4&gt;USBs&lt;/h4&gt;USB设备为物理攻击提供了重要的攻击面。例如BadUSB和Stuxnet是此类攻击的范例。最佳实践是禁止所有新连接的USB且仅将受信任设备列入白名单，USBGuard对此非常有用。 &lt;br /&gt;
 &lt;br /&gt;您也可以将nousb用作内核引导参数，以禁用内核中的所有USB支持。可以sysctl设置kernel.deny_new_usb=1 &lt;br /&gt;
 &lt;h4&gt;DMA攻击&lt;/h4&gt;直接内存访问（DMA）攻击涉及通过插入某些物理设备来完全访问所有系统内存。这可以通过控制设备可访问的内存区域的IOMMU或将特别易受攻击的内核模块列入黑名单来缓解。 &lt;br /&gt;
 &lt;br /&gt;要启用IOMMU，请设置以下内核引导参数： &lt;br /&gt;
 &lt;pre&gt;intel_iommu=on amd_iommu=on  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
您只需要为特定的CPU制造商启用该选项，但同时启用这两个选项就没有问题。 &lt;br /&gt;
 &lt;pre&gt;efi=disable_early_pci_dma  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
通过在非常早的启动过程中禁用所有PCI桥接器上的busmaster位，此选项可修复上述IOMMU中的漏洞。 &lt;br /&gt;
 &lt;br /&gt;此外，Thunderbolt和FireWire通常容易受到DMA攻击。要禁用它们，请将这些内核模块列入黑名单： &lt;br /&gt;
 &lt;pre&gt;install firewire-core /bin/false    &lt;br /&gt;
install thunderbolt /bin/false  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h4&gt;冷启动攻击&lt;/h4&gt;当攻击者在擦除RAM中的数据之前对其进行分析时，就会发生冷启动攻击。使用现代RAM时，冷启动攻击不太实用，因为RAM通常会在几秒钟或几分钟内清除，除非将其放入冷却液（如液氮或冷冻机）中。攻击者必须在几秒钟内将设备中的RAM棒拔出并将其暴露于液氮中，而且确保用户不会注意到。 &lt;br /&gt;
 &lt;br /&gt;如果冷启动攻击是威胁模型的一部分，请在关机后保护计算机几分钟，以确保没有人可以访问您的RAM记忆棒。您也可以将RAM棒焊接到主板上，以使其更难以卡住。如果使用笔记本电脑，请取出电池，然后直接用充电电缆供电。关机后请拔出电缆，以确保RAM彻底断电无法访问。 &lt;br /&gt;
 &lt;br /&gt;在内核自我保护启动参数部分中，空闲时内存清零选项将用零覆盖内存中的敏感数据。此外，强化的内存分配器可以通过CONFIG_ZERO_ON_FREE配置选项清除用户空间堆内存中的敏感数据。尽管如此，某些数据仍可能保留在内存中。 &lt;br /&gt;
 &lt;br /&gt;此外，现代内核还包括复位攻击缓解措施，该命令可命令固件在关机时擦除数据，尽管这需要固件支持。 &lt;br /&gt;
 &lt;br /&gt;确保正常关闭计算机，以使上述缓解措施可以开始。 &lt;br /&gt;
 &lt;br /&gt;如果以上都不适用您的威胁模型，则可以实施Tails的内存擦除过程，该过程将擦除大部分内存（视频内存除外），并且已被证明是有效的。 &lt;br /&gt;
 &lt;h3&gt;最佳实践&lt;/h3&gt;一旦对系统进行了尽可能多的加固，就应该遵循良好的隐私和安全性惯例： &lt;br /&gt;
 &lt;ul&gt;  &lt;li&gt;禁用或删除不需要的东西以最小化攻击面。&lt;/li&gt;  &lt;li&gt;保持更新。配置cron任务或init脚本以每天更新系统。&lt;/li&gt;  &lt;li&gt;不要泄漏有关您或您的系统的任何信息，无论它看起来多么渺小。&lt;/li&gt;  &lt;li&gt;遵循常规的安全和隐私建议&lt;/li&gt;&lt;/ul&gt; &lt;br /&gt;
 &lt;br /&gt;尽管已经进行了强化，但您必须记住Linux仍然是一个有缺陷的操作系统，没有任何强化可以完全修复它。 &lt;br /&gt;
 &lt;h3&gt;其他指南&lt;/h3&gt;您应该进行尽可能多的研究，而不要依赖单一的信息来源。最大的安全问题之一就是用户。这些是我认为有价值的其他指南的链接： &lt;br /&gt;
 &lt;br /&gt;Arch Linux Security wiki page： &lt;a href="https://wiki.archlinux.org/index.php/Security" rel="nofollow" target="_blank"&gt;https://wiki.archlinux.org/index.php/Security&lt;/a&gt; &lt;br /&gt;
 &lt;br /&gt;Whonix Documentation： &lt;a href="https://www.whonix.org/wiki/Documentation" rel="nofollow" target="_blank"&gt;https://www.whonix.org/wiki/Documentation&lt;/a&gt; &lt;br /&gt;
 &lt;br /&gt;NSA RHEL 5 Hardening Guide(稍有过时，但仍包含有用的信息）： &lt;a href="https://apps.nsa.gov/iaarchive/library/ia-guidance/security-configuration/operating-systems/guide-to-the-secure-configuration-of-red-hat-enterprise.cfm" rel="nofollow" target="_blank"&gt;https://apps.nsa.gov/iaarchive ... e.cfm&lt;/a&gt; &lt;br /&gt;
 &lt;br /&gt;KSPP recommended kernel settings： &lt;a href="https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project/Recommended_Settings" rel="nofollow" target="_blank"&gt;https://kernsec.org/wiki/index ... tings&lt;/a&gt; &lt;br /&gt;
 &lt;br /&gt;kconfig-hardened-check： &lt;a href="https://github.com/a13xp0p0v/kconfig-hardened-check/" rel="nofollow" target="_blank"&gt;https://github.com/a13xp0p0v/k ... heck/&lt;/a&gt; &lt;br /&gt;
 &lt;h3&gt;术语&lt;/h3&gt;您可能需要重新生成GRUB配置，以应用对引导加载程序所做的某些更改。在不同的发行版之间，执行此操作的步骤有时可能会有所不同。例如，在诸如Arch Linux之类的发行版上，应通过执行以下命令来重新生成配置文件： &lt;br /&gt;
 &lt;pre&gt;grub-mkconfig -o $path_to_grub_config  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
&amp;quot;$path_to_grub_config&amp;quot; 取决于您如何设置系统。它通常是/boot/grub/grub.cfg或/boot/EFI/grub/grub.cfg，但是在执行此命令之前，请务必确保正确。 &lt;br /&gt;
 &lt;br /&gt;另外，在Debian或Ubuntu等发行版上，您应该执行以下命令： &lt;br /&gt;
 &lt;pre&gt;update-grub  &lt;br /&gt;
&lt;/pre&gt; &lt;br /&gt;
 &lt;h3&gt;能力&lt;/h3&gt;在Linux内核中，“ root特权”分为各种不同的能力（capabilities）。这在应用最小特权原则时很有帮助——可以给它们仅授予特定的子集，而不是授予进程总的root特权。例如，如果程序只需要设置系统时间，则只需要CAP_SYS_TIME而不是root所有能力。这会限制可能造成的损害，但是，您仍必须谨慎授予能力，因为无论如何，其中许多能力可能会被滥用以获取完整的root特权。 &lt;br /&gt;
 &lt;br /&gt;译文链接： &lt;a href="https://blog.gaochao.me/post/645734976535543808/linux" rel="nofollow" target="_blank"&gt;https://blog.gaochao.me/post/6 ... linux&lt;/a&gt;系统安全强化指南
                                
                                                            &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/61392-linux-%E7%B3%BB%E7%BB%9F-%E5%AE%89%E5%85%A8</guid>
      <pubDate>Sat, 08 May 2021 03:29:30 CST</pubDate>
    </item>
    <item>
      <title>Linux上TCP的几个内核参数调优 - 无毁的湖光-Al - 博客园</title>
      <link>https://itindex.net/detail/60772-linux-tcp-%E5%86%85%E6%A0%B8</link>
      <description>&lt;div&gt;    &lt;p&gt;Linux作为一个强大的操作系统，提供了一系列内核参数供我们进行调优。光TCP的调优参数就有50多个。在和线上问题斗智斗勇的过程中，笔者积累了一些在内网环境应该进行调优的参数。在此分享出来，希望对大家有所帮助。&lt;/p&gt;    &lt;h2&gt;调优清单&lt;/h2&gt;    &lt;p&gt;好了，在这里先列出调优清单。请记住，这里只是笔者在内网进行TCP内核参数调优的经验，仅供参考。同时，笔者还会在余下的博客里面详细解释了为什么要进行这些调优！&lt;/p&gt;    &lt;table&gt;      &lt;tr&gt;        &lt;th&gt;序号&lt;/th&gt;        &lt;th&gt;内核参数&lt;/th&gt;        &lt;th&gt;值&lt;/th&gt;        &lt;th&gt;备注&lt;/th&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;1.1&lt;/td&gt;        &lt;td&gt;/proc/sys/net/ipv4/tcp_max_syn_backlog&lt;/td&gt;        &lt;td&gt;2048&lt;/td&gt;        &lt;td&gt;&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;1.2&lt;/td&gt;        &lt;td&gt;/proc/sys/net/core/somaxconn&lt;/td&gt;        &lt;td&gt;2048&lt;/td&gt;        &lt;td&gt;&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;1.3&lt;/td&gt;        &lt;td&gt;/proc/sys/net/ipv4/tcp_abort_on_overflow&lt;/td&gt;        &lt;td&gt;1&lt;/td&gt;        &lt;td&gt;&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;2.1&lt;/td&gt;        &lt;td&gt;/proc/sys/net/ipv4/tcp_tw_recycle&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;NAT环境必须为0&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;2.2&lt;/td&gt;        &lt;td&gt;/proc/sys/net/ipv4/tcp_tw_reuse&lt;/td&gt;        &lt;td&gt;1&lt;/td&gt;        &lt;td&gt;&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;3.1&lt;/td&gt;        &lt;td&gt;/proc/sys/net/ipv4/tcp_syn_retries&lt;/td&gt;        &lt;td&gt;3&lt;/td&gt;        &lt;td&gt;&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;3.2&lt;/td&gt;        &lt;td&gt;/proc/sys/net/ipv4/tcp_retries2&lt;/td&gt;        &lt;td&gt;5&lt;/td&gt;        &lt;td&gt;&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;3.3&lt;/td&gt;        &lt;td&gt;/proc/sys/net/ipv4/tcp_slow_start_after_idle&lt;/td&gt;        &lt;td&gt;0&lt;/td&gt;        &lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;    &lt;h2&gt;tcp_max_syn_backlog,somaxconn,tcp_abort_on_overflow&lt;/h2&gt;    &lt;p&gt;tcp_max_syn_backlog,somaxconn,tcp_abort_on_overflow这三个参数是关于      &lt;br /&gt;内核TCP连接缓冲队列的设置。如果应用层来不及将已经三次握手建立成功的TCP连接从队列中取出,溢出了这个缓冲队列(全连接队列)之后就会丢弃这个连接。如下图所示:      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-6da3083f11a90a9feb67b624b3dbc0516f5.png"&gt;&lt;/img&gt;      &lt;br /&gt;从而产生一些诡异的现象,这个现象诡异之处就在于，是在TCP第三次握手的时候丢弃连接      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-232e6f0b58a6fc20750e283c16a7266a16c.png"&gt;&lt;/img&gt;      &lt;br /&gt;就如图中所示,第二次握手的SYNACK发送给client端了。所以就会出现client端认为连接成功，而Server端确已经丢弃了这个连接的现象！由于无法感知到Server已经丢弃了连接。      &lt;br /&gt;所以如果没有心跳的话，只有在发出第一个请求后，Server才会发送一个reset端通知这个连接已经被丢弃了，建立连接后第二天再用，也会报错！所以我们要调大Backlog队列！&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;echo 2048 &amp;gt; /proc/sys/net/ipv4/tcp_max_syn_backlog
echo 2048 &amp;gt; /proc/sys/net/core/somaxconn&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;当然了，为了尽量避免第一笔调用失败问题，我们也同时要设置&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;echo 1 &amp;gt; /proc/sys/net/ipv4/tcp_abort_on_overflow&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;设置这个值以后，Server端内核就会在这个连接被溢出之后发送一个reset包给client端。      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-c189ee4aff83b8b59d6fde2400409785c82.png"&gt;&lt;/img&gt;      &lt;br /&gt;如果我们的client端是NIO的话，就可以收到一个socket close的事件以感知到连接被关闭！      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-bba3483f0ab178e3787ac2b2c2eb02175ce.png"&gt;&lt;/img&gt;&lt;/p&gt;    &lt;h3&gt;注意Java默认的Backlog是50&lt;/h3&gt;    &lt;p&gt;这个TCP Backlog的队列大小值是min(tcp_max_syn_backlog,somaxconn,应用层设置的backlog),而Java如果不做额外设置，Backlog默认值仅仅只有50。C语言在使用listen调用的时候需要传进Backlog参数。&lt;/p&gt;    &lt;h2&gt;tcp_tw_recycle&lt;/h2&gt;    &lt;p&gt;tcp_tw_recycle这个参数一般是用来抑制TIME_WAIT数量的,但是它有一个副作用。即在tcp_timestamps开启(Linux默认开启)，tcp_tw_recycle会经常导致下面这种现象。      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-ce85027edb38411a93f0601ae25f4f4bdec.png"&gt;&lt;/img&gt;      &lt;br /&gt;也即，如果你的Server开启了tcp_tw_recycle，那么别人如果通过NAT之类的调用你的Server的话，NAT后面的机器只有一台机器能正常工作，其它情况大概率失败。具体原因呢由下图所示:      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-cfd1f05447cf1af3fc9a369b3ad64791188.png"&gt;&lt;/img&gt;      &lt;br /&gt;在tcp_tw_recycle=1同时tcp_timestamps(默认开启的情况下),对同一个IP的连接会做这样的限制，也即之前后建立的连接的时间戳必须要大于之前建立连接的最后时间戳，但是经过NAT的一个IP后面是不同的机器，时间戳相差极大，就会导致内核直接丢弃时间戳较低的连接的现象。由于这个参数导致的问题，高版本内核已经去掉了这个参数。如果考虑TIME_WAIT问题，可以考虑设置一下&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;echo 1 &amp;gt; /proc/sys/net/ipv4/tcp_tw_reuse&lt;/code&gt;&lt;/pre&gt;    &lt;h2&gt;tcp_syn_retries&lt;/h2&gt;    &lt;p&gt;这个参数值得是client发送SYN如果server端不回复的话，重传SYN的次数。对我们的直接影响呢就是connet建立连接时的超时时间。当然Java通过一些C原生系统调用的组合使得我们可以进行超时时间的设置。在Linux里面默认设置是5,下面给出建议值3和默认值5之间的超时时间。&lt;/p&gt;    &lt;table&gt;      &lt;tr&gt;        &lt;th&gt;tcp_syn_retries&lt;/th&gt;        &lt;th&gt;timeout&lt;/th&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;1&lt;/td&gt;        &lt;td&gt;min(so_sndtimeo,3s)&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;2&lt;/td&gt;        &lt;td&gt;min(so_sndtimeo,7s)&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;3&lt;/td&gt;        &lt;td&gt;min(so_sndtimeo,15s)&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;4&lt;/td&gt;        &lt;td&gt;min(so_sndtimeo,31s)&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;5&lt;/td&gt;        &lt;td&gt;min(so_sndtimeo,63s)&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;    &lt;p&gt;下图给出了，重传和超时情况的对应图:      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-8b379a49d7842e738e9109216e9bee401e4.png"&gt;&lt;/img&gt;      &lt;br /&gt;当然了，不同内核版本的超时时间可能不一样，因为初始RTO在内核小版本间都会有细微的变化。所以，有时候在抓包时候可能会出现（3,6,12......)这样的序列。当然Java的API有超时时间:&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;java:
 // 函数调用中携带有超时时间
 public void connect(SocketAddress endpoint, int timeout) ;&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;所以，对于Java而言，这个内核参数的设置没有那么重要。但是，有些代码可能会有忘了设置timeout的情况，例如某个版本的Kafka就是，所以它在我们一些混沌测试的情况下，容灾恢复的时间会达到一分多钟，主要时间就是卡在connect上面-_-!，而这时我们的tcp_syn_retries设置的是5，也即超时时间63s。减少这个恢复时间的手段就是:&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;echo 3 &amp;gt; /proc/sys/net/ipv4/tcp_syn_retries&lt;/code&gt;&lt;/pre&gt;    &lt;h2&gt;tcp_retries2&lt;/h2&gt;    &lt;p&gt;tcp_retries2这个参数表面意思是在传输过程中tcp的重传次数。但在某个版本之后Linux内核仅仅用这个tcp_retries2来计算超时时间，在这段时间的重传次数纯粹由RTO等环境因素决定，重传超时时间在5/15下的表现为:&lt;/p&gt;    &lt;table&gt;      &lt;tr&gt;        &lt;th&gt;tcp_retries2&lt;/th&gt;        &lt;th&gt;对端无响应&lt;/th&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;5&lt;/td&gt;        &lt;td&gt;25.6s-51.2s根据动态rto定&lt;/td&gt;&lt;/tr&gt;      &lt;tr&gt;        &lt;td&gt;15&lt;/td&gt;        &lt;td&gt;924.6s-1044.6s根据动态rto定&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;    &lt;p&gt;如果我们在应用层设置的Socket所有ReadTimeout都很小的话(例如3s),这个内核参数调整是没有必要的。但是，笔者经常发现有的系统，因为一两个慢的接口或者SQL，所以将ReadTimeout设的很大的情况。      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-836bf2508c1ef79051dcf203193fa1bd21e.png"&gt;&lt;/img&gt;      &lt;br /&gt;平常这种情况是没有问题的，因为慢请求频率很低，不会对系统造成什么风险。但是，物理机突然宕机时候的情况就不一样了，由于ReadTimeOut设置的过大，导致所有落到这台宕机的机器都会在min(ReadTimeOut,(924.6s-1044.6s)(Linux默认tcp_retries2是15))后才能从read系统调用返回。假设ReadTimeout设置了个5min，系统总线程数是200，那么只要5min内有200个请求落到宕机的server就会使A系统失去响应！      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-f49993bf00d4386cc7dcc011adc208306a5.png"&gt;&lt;/img&gt;      &lt;br /&gt;但如果将tcp_retries2设置为5,那么超时返回时间即为min(ReadTimeOut 5min,25.6-51.2s),也就是30s左右，极大的缓解了这一情况。&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;echo 5 &amp;gt; /proc/sys/net/ipv4/tcp_retries2&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;但是针对这种现象，最好要做资源上的隔离,例如线程上的隔离或者机器级的隔离。      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-17eb5135546ea57fb6ba0677e8c51db2aa5.png"&gt;&lt;/img&gt;&lt;/p&gt;    &lt;p&gt;golang的goroutine调度模型就可以很好的解决线程资源不够的问题，但缺点是goroutine里面不能有阻塞的系统调用，不然也会和上面一样，但仅仅对于系统之间互相调用而言，都是非阻塞IO,所以golang做微服务还是非常Nice的。当然了我大Java用纯IO事件触发编写代码也不会有问题，就是对心智负担太高-_-!&lt;/p&gt;    &lt;h3&gt;物理机突然宕机和进程宕不一样&lt;/h3&gt;    &lt;p&gt;值得注意的是，物理机宕机和进程宕但内核还存在表现完全不一样。      &lt;br /&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-4c0648fd58d526fb941ba608cccd52b7783.png"&gt;&lt;/img&gt;      &lt;br /&gt;仅仅进程宕而内核存活，那么内核会立马发送reset给对端，从而不会卡住A系统的线程资源。&lt;/p&gt;    &lt;h2&gt;tcp_slow_start_after_idle&lt;/h2&gt;    &lt;p&gt;还有一个可能需要调整的参数是tcp_slow_start_after_idle，Linux默认是1，即开启状态。开启这个参数后，我们的TCP拥塞窗口会在一个RTO时间空闲之后重置为初始拥塞窗口(CWND)大小，这无疑大幅的减少了长连接的优势。对应Linux源码为:&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;static void tcp_event_data_sent(struct tcp_sock *tp,
				struct sk_buff *skb, struct sock *sk){
	// 如果开启了start_after_idle,而且这次发送的时间-上次发送的时间&amp;gt;一个rto，就重置tcp拥塞窗口
	if (sysctl_tcp_slow_start_after_idle &amp;amp;&amp;amp;
	    (!tp-&amp;gt;packets_out &amp;amp;&amp;amp; (s32)(now - tp-&amp;gt;lsndtime) &amp;gt; icsk-&amp;gt;icsk_rto))
		tcp_cwnd_restart(sk, __sk_dst_get(sk));
}&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;      &lt;img alt="" src="https://oscimg.oschina.net/oscnet/up-24851b36ef38c48271a8b9295d0b2dc3eca.png"&gt;&lt;/img&gt;      &lt;br /&gt;关闭这个参数后，无疑会提高某些请求的传输速度(在带宽够的情况下)。&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;echo 0 &amp;gt; /proc/sys/net/ipv4/tcp_slow_start_after_idle&lt;/code&gt;&lt;/pre&gt;    &lt;p&gt;当然了，Linux启用这个参数也是有理由的，如果我们的网络情况是时刻在变化的，例如拿个手机到处移动，那么将拥塞窗口重置确实是个不错的选项。但是就我们内网系统间调用而言，是不太必要的了。&lt;/p&gt;    &lt;h2&gt;初始CWND大小&lt;/h2&gt;    &lt;p&gt;毫无疑问，新建连接之后的初始TCP拥塞窗口大小也直接影响到我们的请求速率。在Linux2.6.32源码中，其初始拥塞窗口是(2-4个)mss大小，对应于内网估计也就是(2.8-5.6K)(MTU 1500)，这个大小对于某些大请求可能有点捉襟见肘。      &lt;br /&gt;在Linux 2.6.39以上或者某些RedHat维护的小版本中已经把CWND      &lt;br /&gt;增大到RFC 6928所规定的的10段，也就是在内网里面估计14K左右(MTU 1500)。&lt;/p&gt;    &lt;pre&gt;      &lt;code&gt;Linux 新版本
/* TCP initial congestion window */
#define TCP_INIT_CWND		10&lt;/code&gt;&lt;/pre&gt;    &lt;h2&gt;   &lt;br /&gt;&lt;/h2&gt;    &lt;h2&gt;总结&lt;/h2&gt;    &lt;p&gt;Linux提供了一大堆内参参数供我们进行调优，其默认设置的参数在很多情况下并不是最佳实践，所以我们需要潜心研究，找到最适合当前环境的组合。&lt;/p&gt;&lt;/div&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/60772-linux-tcp-%E5%86%85%E6%A0%B8</guid>
      <pubDate>Wed, 22 Jul 2020 10:28:44 CST</pubDate>
    </item>
    <item>
      <title>TCP CLOSE_WAIT 过多解决方案-Smurf Linux运维-51CTO博客</title>
      <link>https://itindex.net/detail/60714-tcp-close-wait</link>
      <description>&lt;div&gt;    &lt;p&gt;一、“多半是程序的原因”？这个还是交给程序猿吧&lt;/p&gt;    &lt;p&gt;二、linux 下 CLOSE_WAIT过多的解决方法&lt;/p&gt;    &lt;p&gt;情景描述：系统产生大量“Too many open files” &lt;/p&gt;    &lt;p&gt;原因分析：在服务器与客户端通信过程中，因服务器发生了socket未关导致的closed_wait发生，致使监听port打开的句柄数到了1024个，且均处于close_wait的状态，最终造成配置的port被占满出现“Too many open files”，无法再进行通信。 &lt;/p&gt;    &lt;p&gt;close_wait状态出现的原因是被动关闭方未关闭socket造成&lt;/p&gt;    &lt;p&gt;解决办法：有两种措施可行 &lt;/p&gt;    &lt;p&gt;一、解决： &lt;/p&gt;    &lt;p&gt;原因是因为调用ServerSocket类的accept()方法和Socket输入流的read()方法时会引起线程阻塞，所以应该用setSoTimeout()方法设置超时（缺省的设置是0，即超时永远不会发生）；超时的判断是累计式的，一次设置后，每次调用引起的阻塞时间都从该值中扣除，直至另一次超时设置或有超时异常抛出。 &lt;/p&gt;    &lt;p&gt;比如，某种服务需要三次调用read()，超时设置为1分钟，那么如果某次服务三次read()调用的总时间超过1分钟就会有异常抛出，如果要在同一个Socket上反复进行这种服务，就要在每次服务之前设置一次超时。 &lt;/p&gt;    &lt;p&gt;二、规避： &lt;/p&gt;    &lt;p&gt;调整系统参数，包括句柄相关参数和TCP/IP的参数； &lt;/p&gt;    &lt;p&gt;注意： &lt;/p&gt;    &lt;p&gt;/proc/sys/fs/file-max 是整个系统可以打开的文件数的限制，由sysctl.conf控制； &lt;/p&gt;    &lt;p&gt;ulimit修改的是当前shell和它的子进程可以打开的文件数的限制，由limits.conf控制； &lt;/p&gt;    &lt;p&gt;lsof是列出系统所占用的资源,但是这些资源不一定会占用打开文件号的；比如：共享内存,信号量,消息队列,内存映射等,虽然占用了这些资源,但不占用打开文件号； &lt;/p&gt;    &lt;p&gt;因此，需要调整的是当前用户的子进程打开的文件数的限制，即limits.conf文件的配置； &lt;/p&gt;    &lt;p&gt;如果cat /proc/sys/fs/file-max值为65536或甚至更大，不需要修改该值； &lt;/p&gt;    &lt;p&gt;若ulimit -a ；其open files参数的值小于4096（默认是1024), 则采用如下方法修改open files参数值为8192；方法如下： &lt;/p&gt;    &lt;p&gt;1.使用root登陆，修改文件/etc/security/limits.conf &lt;/p&gt;    &lt;pre&gt;vim /etc/security/limits.conf&lt;/pre&gt;    &lt;p&gt; 添加       &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;xxx - nofile 8192 &lt;/p&gt;    &lt;p&gt;xxx 是一个用户，如果是想所有用户生效的话换成 * ，设置的数值与硬件配置有关，别设置太大了。 &lt;/p&gt;    &lt;pre&gt;#&amp;lt;domain&amp;gt;     &amp;lt;type&amp;gt;   &amp;lt;item&amp;gt;       &amp;lt;value&amp;gt;
*         soft    nofile    8192 
*         hard    nofile    8192&lt;/pre&gt;    &lt;p&gt;#所有的用户每个进程可以使用8192个文件描述符。       &lt;br /&gt;&lt;/p&gt;    &lt;p&gt;2.使这些限制生效 &lt;/p&gt;    &lt;p&gt;确定文件/etc/pam.d/login 和/etc/pam.d/sshd包含如下行： &lt;/p&gt;    &lt;p&gt;session required pam_limits.so &lt;/p&gt;    &lt;p&gt;然后用户重新登陆一下即可生效。 &lt;/p&gt;    &lt;p&gt;3. 在bash下可以使用ulimit -a 参看是否已经修改： &lt;/p&gt;    &lt;p&gt;一、 修改方法：（暂时生效,重新启动服务器后,会还原成默认值） &lt;/p&gt;    &lt;pre&gt;sysctl -w net.ipv4.tcp_keepalive_time=600   
sysctl -w net.ipv4.tcp_keepalive_probes=2 
sysctl -w net.ipv4.tcp_keepalive_intvl=2&lt;/pre&gt;    &lt;p&gt;注意：Linux的内核参数调整的是否合理要注意观察，看业务高峰时候效果如何。 &lt;/p&gt;    &lt;p&gt;二、 若做如上修改后，可起作用；则做如下修改以便永久生效。 &lt;/p&gt;    &lt;p&gt;vi /etc/sysctl.conf &lt;/p&gt;    &lt;p&gt;若配置文件中不存在如下信息，则添加： &lt;/p&gt;    &lt;pre&gt;net.ipv4.tcp_keepalive_time = 1800 
net.ipv4.tcp_keepalive_probes = 3 
net.ipv4.tcp_keepalive_intvl = 15&lt;/pre&gt;    &lt;p&gt;编辑完 /etc/sysctl.conf,要重启network 才会生效 &lt;/p&gt;    &lt;p&gt;/etc/rc.d/init.d/network restart &lt;/p&gt;    &lt;p&gt;然后，执行sysctl命令使修改生效，基本上就算完成了。 &lt;/p&gt;    &lt;p&gt;------------------------------------------------------------ &lt;/p&gt;    &lt;p&gt;修改原因： &lt;/p&gt;    &lt;p&gt;当客户端因为某种原因先于服务端发出了FIN信号，就会导致服务端被动关闭，若服务端不主动关闭socket发FIN给Client，此时服务端Socket会处于CLOSE_WAIT状态（而不是LAST_ACK状态）。通常来说，一个CLOSE_WAIT会维持至少2个小时的时间（系统默认超时时间的是7200秒，也就是2小时）。如果服务端程序因某个原因导致系统造成一堆CLOSE_WAIT消耗资源，那么通常是等不到释放那一刻，系统就已崩溃。因此，解决这个问题的方法还可以通过修改TCP/IP的参数来缩短这个时间，于是修改tcp_keepalive_*系列参数： &lt;/p&gt;    &lt;p&gt;tcp_keepalive_time： &lt;/p&gt;    &lt;p&gt;/proc/sys/net/ipv4/tcp_keepalive_time &lt;/p&gt;    &lt;p&gt;INTEGER，默认值是7200(2小时) &lt;/p&gt;    &lt;p&gt;当keepalive打开的情况下，TCP发送keepalive消息的频率。建议修改值为1800秒。 &lt;/p&gt;    &lt;p&gt;tcp_keepalive_probes：INTEGER &lt;/p&gt;    &lt;p&gt;/proc/sys/net/ipv4/tcp_keepalive_probes &lt;/p&gt;    &lt;p&gt;INTEGER，默认值是9 &lt;/p&gt;    &lt;p&gt;TCP发送keepalive探测以确定该连接已经断开的次数。(注意:保持连接仅在SO_KEEPALIVE套接字选项被打开是才发送.次数默认不需要修改,当然根据情形也可以适当地缩短此值.设置为5比较合适) &lt;/p&gt;    &lt;p&gt;tcp_keepalive_intvl：INTEGER &lt;/p&gt;    &lt;p&gt;/proc/sys/net/ipv4/tcp_keepalive_intvl &lt;/p&gt;    &lt;p&gt;INTEGER，默认值为75 &lt;/p&gt;    &lt;p&gt;当探测没有确认时，重新发送探测的频度。探测消息发送的频率（在认定连接失效之前，发送多少个TCP的keepalive探测包）。乘以tcp_keepalive_probes就得到对于从开始探测以来没有响应的连接杀除的时间。默认值为75秒，也就是没有活动的连接将在大约11分钟以后将被丢弃。(对于普通应用来说,这个值有一些偏大,可以根据需要改小.特别是web类服务器需要改小该值,15是个比较合适的值) &lt;/p&gt;    &lt;p&gt; &lt;/p&gt;    &lt;p&gt;1. 系统不再出现“Too many open files”报错现象。 &lt;/p&gt;    &lt;p&gt;2. 处于TIME_WAIT状态的sockets不会激长。 &lt;/p&gt;    &lt;p&gt;在 Linux 上可用以下语句看了一下服务器的TCP状态(连接状态数量统计)： &lt;/p&gt;    &lt;pre&gt;netstat -n| awk &amp;apos;/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}&amp;apos;&lt;/pre&gt;    &lt;p&gt;      &lt;br /&gt;&lt;/p&gt;&lt;/div&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/60714-tcp-close-wait</guid>
      <pubDate>Sat, 27 Jun 2020 10:51:47 CST</pubDate>
    </item>
    <item>
      <title>redis进程OOM被linux内核kill问题调查 - 简书</title>
      <link>https://itindex.net/detail/60675-redis-%E8%BF%9B%E7%A8%8B-oom</link>
      <description>&lt;h2&gt;【发现问题】&lt;/h2&gt;  &lt;p&gt;运维人员收到zabbix告警说codis集群usa-9节点所在机器，原swap 4G 空间只剩下80k。其立即登录该机器增加了约6G的swap空间。&lt;/p&gt;  &lt;pre&gt;    &lt;code&gt;Lack of free swap space on USARN-H-Host-Linux-172.24.19.59: PROBLEM (Value: 80 KB) 2019.11.13 14:47:34&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;接着收到某个应用的500错误告警，错误堆栈里提到codis该usa-9节点 “JedisConnectionException: Unexpected end of stream”，再次登录usa-9拿到 linux的系统日志如下：&lt;/p&gt;  &lt;pre&gt;    &lt;code&gt;Nov 13 14:56:19 vm-centos6 kernel: codis-server invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Nov 13 14:56:19 vm-centos6 kernel: codis-server cpuset=/ mems_allowed=0
Nov 13 14:56:19 vm-centos6 kernel: Pid: 4492, comm: codis-server Not tainted 2.6.32-504.el6.x86_64 #1
Nov 13 14:56:19 vm-centos6 kernel: Call Trace:
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff810d40c1&amp;gt;] ? cpuset_print_task_mems_allowed+0x91/0xb0
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff81127300&amp;gt;] ? dump_header+0x90/0x1b0
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff8122ea2c&amp;gt;] ? security_real_capable_noaudit+0x3c/0x70
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff81127782&amp;gt;] ? oom_kill_process+0x82/0x2a0
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff811276c1&amp;gt;] ? select_bad_process+0xe1/0x120
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff81127bc0&amp;gt;] ? out_of_memory+0x220/0x3c0
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff811344df&amp;gt;] ? __alloc_pages_nodemask+0x89f/0x8d0
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff8116c69a&amp;gt;] ? alloc_pages_current+0xaa/0x110
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff811246f7&amp;gt;] ? __page_cache_alloc+0x87/0x90
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff811240de&amp;gt;] ? find_get_page+0x1e/0xa0
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff81125697&amp;gt;] ? filemap_fault+0x1a7/0x500
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff8114eae4&amp;gt;] ? __do_fault+0x54/0x530
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff8114f0b7&amp;gt;] ? handle_pte_fault+0xf7/0xb00
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff814470e1&amp;gt;] ? sock_aio_read+0x1a1/0x1b0
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff810a2bbb&amp;gt;] ? __remove_hrtimer+0x3b/0xb0
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff8114fcea&amp;gt;] ? handle_mm_fault+0x22a/0x300
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff811d68e0&amp;gt;] ? ep_send_events_proc+0x0/0x110
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff8104d0d8&amp;gt;] ? __do_page_fault+0x138/0x480
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff8152ffbe&amp;gt;] ? do_page_fault+0x3e/0xa0
Nov 13 14:56:19 vm-centos6 kernel: [&amp;lt;ffffffff8152d375&amp;gt;] ? page_fault+0x25/0x30
Nov 13 14:56:19 vm-centos6 kernel: Mem-Info:
Nov 13 14:56:19 vm-centos6 kernel: Node 0 DMA per-cpu:
Nov 13 14:56:19 vm-centos6 kernel: CPU    0: hi:    0, btch:   1 usd:   0
Nov 13 14:56:19 vm-centos6 kernel: CPU    1: hi:    0, btch:   1 usd:   0
Nov 13 14:56:19 vm-centos6 kernel: CPU    2: hi:    0, btch:   1 usd:   0
Nov 13 14:56:19 vm-centos6 kernel: CPU    3: hi:    0, btch:   1 usd:   0
Nov 13 14:56:19 vm-centos6 kernel: Node 0 DMA32 per-cpu:
Nov 13 14:56:19 vm-centos6 kernel: CPU    0: hi:  186, btch:  31 usd:   0
Nov 13 14:56:19 vm-centos6 kernel: CPU    1: hi:  186, btch:  31 usd:   0
Nov 13 14:56:19 vm-centos6 kernel: CPU    2: hi:  186, btch:  31 usd:   0
Nov 13 14:56:19 vm-centos6 kernel: CPU    3: hi:  186, btch:  31 usd:   0
Nov 13 14:56:19 vm-centos6 kernel: Node 0 Normal per-cpu:
Nov 13 14:56:19 vm-centos6 kernel: CPU    0: hi:  186, btch:  31 usd:  35
Nov 13 14:56:19 vm-centos6 kernel: CPU    1: hi:  186, btch:  31 usd:   3
Nov 13 14:56:19 vm-centos6 kernel: CPU    2: hi:  186, btch:  31 usd:  59
Nov 13 14:56:19 vm-centos6 kernel: CPU    3: hi:  186, btch:  31 usd: 184
Nov 13 14:56:19 vm-centos6 kernel: active_anon:4040530 inactive_anon:451920 isolated_anon:0
Nov 13 14:56:19 vm-centos6 kernel: active_file:3492 inactive_file:4985 isolated_file:0
Nov 13 14:56:19 vm-centos6 kernel: unevictable:0 dirty:2037 writeback:1387 unstable:0
Nov 13 14:56:19 vm-centos6 kernel: free:35841 slab_reclaimable:2943 slab_unreclaimable:7727
Nov 13 14:56:19 vm-centos6 kernel: mapped:296 shmem:73 pagetables:13459 bounce:0
Nov 13 14:56:19 vm-centos6 kernel: Node 0 DMA free:15668kB min:52kB low:64kB high:76kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15276kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
Nov 13 14:56:19 vm-centos6 kernel: lowmem_reserve[]: 0 3000 18150 18150
Nov 13 14:56:19 vm-centos6 kernel: Node 0 DMA32 free:71556kB min:11160kB low:13948kB high:16740kB active_anon:2063844kB inactive_anon:519380kB active_file:656kB inactive_file:1132kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:3072160kB mlocked:0kB dirty:660kB writeback:0kB mapped:120kB shmem:0kB slab_reclaimable:628kB slab_unreclaimable:68kB kernel_stack:0kB pagetables:204kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:2688 all_unreclaimable? yes
Nov 13 14:56:19 vm-centos6 kernel: lowmem_reserve[]: 0 0 15150 15150
Nov 13 14:56:19 vm-centos6 kernel: Node 0 Normal free:56140kB min:56364kB low:70452kB high:84544kB active_anon:14098276kB inactive_anon:1288300kB active_file:13312kB inactive_file:18808kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15513600kB mlocked:0kB dirty:7488kB writeback:5548kB mapped:1064kB shmem:292kB slab_reclaimable:11144kB slab_unreclaimable:30840kB kernel_stack:2184kB pagetables:53632kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:52256 all_unreclaimable? yes
Nov 13 14:56:19 vm-centos6 kernel: lowmem_reserve[]: 0 0 0 0
Nov 13 14:56:19 vm-centos6 kernel: Node 0 DMA: 1*4kB 2*8kB 2*16kB 2*32kB 1*64kB 1*128kB 0*256kB 0*512kB 1*1024kB 1*2048kB 3*4096kB = 15668kB
Nov 13 14:56:19 vm-centos6 kernel: Node 0 DMA32: 2308*4kB 391*8kB 210*16kB 146*32kB 62*64kB 37*128kB 26*256kB 22*512kB 18*1024kB 3*2048kB 0*4096kB = 71592kB
Nov 13 14:56:19 vm-centos6 kernel: Node 0 Normal: 756*4kB 706*8kB 494*16kB 330*32kB 170*64kB 89*128kB 21*256kB 3*512kB 0*1024kB 0*2048kB 0*4096kB = 56320kB
Nov 13 14:56:19 vm-centos6 kernel: 65997 total pagecache pages
Nov 13 14:56:19 vm-centos6 kernel: 57354 pages in swap cache
Nov 13 14:56:19 vm-centos6 kernel: Swap cache stats: add 46466585, delete 46409231, find 15690882/21869217
Nov 13 14:56:19 vm-centos6 kernel: Free swap  = 0kB
Nov 13 14:56:19 vm-centos6 kernel: Total swap = 4063228kB
Nov 13 14:56:19 vm-centos6 kernel: 4718576 pages RAM
Nov 13 14:56:19 vm-centos6 kernel: 117970 pages reserved
Nov 13 14:56:19 vm-centos6 kernel: 9305 pages shared
Nov 13 14:56:19 vm-centos6 kernel: 4551285 pages non-shared
Nov 13 14:56:19 vm-centos6 kernel: [ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name
Nov 13 14:56:19 vm-centos6 kernel: [  514]     0   514     2729        1   1     -17         -1000 udevd
Nov 13 14:56:19 vm-centos6 kernel: [  837]     0   837     2729        1   1     -17         -1000 udevd
Nov 13 14:56:19 vm-centos6 kernel: [ 1272]     0  1272    62838      313   3       0             0 vmtoolsd
Nov 13 14:56:19 vm-centos6 kernel: [ 1310]     0  1310    15023        6   2       0             0 VGAuthService
Nov 13 14:56:19 vm-centos6 kernel: [ 1386]     0  1386    23283       40   0     -17         -1000 auditd
Nov 13 14:56:19 vm-centos6 kernel: [ 1406]     0  1406    62464      692   2       0             0 rsyslogd
Nov 13 14:56:19 vm-centos6 kernel: [ 1436]     0  1436     4589       36   0       0             0 irqbalance
Nov 13 14:56:19 vm-centos6 kernel: [ 1452]    32  1452     4744       18   2       0             0 rpcbind
Nov 13 14:56:19 vm-centos6 kernel: [ 1472]    29  1472     5837        2   0       0             0 rpc.statd
Nov 13 14:56:19 vm-centos6 kernel: [ 1589]    81  1589     5394       47   2       0             0 dbus-daemon
Nov 13 14:56:19 vm-centos6 kernel: [ 1621]     0  1621     1020        1   0       0             0 acpid
Nov 13 14:56:19 vm-centos6 kernel: [ 1631]    68  1631     9521      162   2       0             0 hald
Nov 13 14:56:19 vm-centos6 kernel: [ 1632]     0  1632     5099        2   1       0             0 hald-runner
Nov 13 14:56:19 vm-centos6 kernel: [ 1664]     0  1664     5629        2   3       0             0 hald-addon-inpu
Nov 13 14:56:19 vm-centos6 kernel: [ 1674]    68  1674     4501        2   0       0             0 hald-addon-acpi
Nov 13 14:56:19 vm-centos6 kernel: [ 1689]     0  1689     2728        1   3     -17         -1000 udevd
Nov 13 14:56:19 vm-centos6 kernel: [ 1695]     0  1695    96534       43   1       0             0 automount
Nov 13 14:56:19 vm-centos6 kernel: [ 1823]     0  1823    20332       28   0       0             0 master
Nov 13 14:56:19 vm-centos6 kernel: [ 1846]    89  1846    20398       24   2       0             0 qmgr
Nov 13 14:56:19 vm-centos6 kernel: [ 1849]     0  1849    28661        2   3       0             0 abrtd
Nov 13 14:56:19 vm-centos6 kernel: [ 1862]     0  1862    29342       24   2       0             0 crond
Nov 13 14:56:19 vm-centos6 kernel: [ 1876]     0  1876     5394        7   0       0             0 atd
Nov 13 14:56:19 vm-centos6 kernel: [ 1889]     0  1889    19879        2   0       0             0 login
Nov 13 14:56:19 vm-centos6 kernel: [ 1891]     0  1891     1016        2   3       0             0 mingetty
Nov 13 14:56:19 vm-centos6 kernel: [ 1893]     0  1893     1016        2   0       0             0 mingetty
Nov 13 14:56:19 vm-centos6 kernel: [ 1895]     0  1895     1016        2   2       0             0 mingetty
Nov 13 14:56:19 vm-centos6 kernel: [ 1897]     0  1897     1016        2   0       0             0 mingetty
Nov 13 14:56:19 vm-centos6 kernel: [ 1899]     0  1899     1016        2   1       0             0 mingetty
Nov 13 14:56:19 vm-centos6 kernel: [ 1996]     0  1996   521256       57   0       0             0 console-kit-dae
Nov 13 14:56:19 vm-centos6 kernel: [ 2063]     0  2063    27076        2   1       0             0 bash
Nov 13 14:56:19 vm-centos6 kernel: [29526]     0 29526    25812       47   1       0             0 ping
Nov 13 14:56:19 vm-centos6 kernel: [ 4492]     0  4492  6354569  4432393   1       0             0 codis-server
Nov 13 14:56:19 vm-centos6 kernel: [25500]     0 25500   133214      139   0       0             0 SFTMonitor
Nov 13 14:56:19 vm-centos6 kernel: [25501]     0 25501   222155      168   1       0             0 SFTServer
Nov 13 14:56:19 vm-centos6 kernel: [19596]     0 19596    16672       22   2     -17         -1000 sshd
Nov 13 14:56:19 vm-centos6 kernel: [26159]   500 26159     4441       10   3       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26161]   500 26161     4441      132   0       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26162]   500 26162     4441       49   0       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26163]   500 26163     4441       49   2       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26164]   500 26164     4441       49   2       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26165]   500 26165     4441       49   0       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26166]   500 26166     4441       49   0       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26167]   500 26167     4441       49   2       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26168]   500 26168     4441       49   3       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26169]   500 26169     4441       49   1       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26170]   500 26170     4441       49   2       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26171]   500 26171     4441       49   0       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26172]   500 26172     4441       49   2       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26174]   500 26174     4441       49   2       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [26175]   500 26175     4441       49   2       0             0 zabbix_agentd
Nov 13 14:56:19 vm-centos6 kernel: [23868]    38 23868     7683       44   2       0             0 ntpd
Nov 13 14:56:19 vm-centos6 kernel: [ 3221]    89  3221    20352      231   2       0             0 pickup
Nov 13 14:56:19 vm-centos6 kernel: [ 3463]     0  3463    24592      291   2       0             0 sshd
Nov 13 14:56:19 vm-centos6 kernel: [ 3466]     0  3466    27087      145   0       0             0 bash
Nov 13 14:56:19 vm-centos6 kernel: [ 3490]     0  3490    26297       51   0       0             0 dd
Nov 13 14:56:19 vm-centos6 kernel: Out of memory: Kill process 4492 (codis-server) score 941 or sacrifice child
Nov 13 14:56:19 vm-centos6 kernel: Killed process 4492, UID 0, (codis-server) total-vm:25418276kB, anon-rss:17729176kB, file-rss:396kB
//这是运维收到机器原4G swap只剩80k告警时，立即去增加了约6G swap空间产生的日志，但redis进程已经在20秒前被kill掉了
Nov 13 14:56:39 vm-centos6 kernel: Adding 5999996k swap on /home/swap/swapfile.  Priority:-2 extents:8 across:6499708k&lt;/code&gt;&lt;/pre&gt;  &lt;h2&gt;【分析问题】&lt;/h2&gt;  &lt;p&gt;redis实例被系统内核关闭掉了，系统日志最重要的就是一头一尾两句：&lt;/p&gt;  &lt;pre&gt;    &lt;code&gt;codis-server invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Killed process 4492, UID 0, (codis-server) total-vm:25418276kB, anon-rss:17729176kB, file-rss:396kB&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;redis进程申请4K内存空间时（order=0所以是2^0页也就是4k），系统内存不足触发了oom-killer，最后被选中kill的就是redis进程自己。    &lt;br /&gt;参考    &lt;a href="https://www.jianshu.com/p/c2e7d36829af" target="_blank"&gt;https://www.jianshu.com/p/c2e7d36829af&lt;/a&gt;的内存结构，mask(0x201da)的最低2位 &amp;quot;10&amp;quot;=2是会Allocate from ZONE_HIGHMEM，但在64位系统中是没有highmem区的，实际是从normal区请求内存。从日志得知“Node 0 Normal free:56140kB min:56364kB”，normal区当前可用56140kB小于最低限制56364kB，由此触发的oom-killer。&lt;/p&gt;  &lt;p&gt;codis-monitor监控对该节点的内存使用告警阈值为65%，maxmemory=12G，所以在K-V使用内存到 12G * 65% = 7.8G 时会发出告警。但节点被kill时并没有发出告警，也就是说K-V使用的内存还不到 7.8G，机器总内存 18G  swap区当时 4G，没有别的什么进程能消耗内存。    &lt;br /&gt;从日志可以看到“anon-rss:17729176kB”，redis节点被关闭时占用内存约16.9G，一边说redis占用内存16.9G耗光了内存导致OOM，一边说redis的K-V数据量不超过7.8G。    &lt;br /&gt;于是调查anon-rss的含义，RSS是说从操作系统角度来看分配给进程的内存。又核对codis-monitor的65%是怎么设置的，原来是针对info命令打印出来的 used_memory 实际K-V数据所使用内存，info命令还有 used_memory_rss 字段表示操作系统分配给redis所占用的内存，used_memory_rss 能大于 used_memory 表示内存碎片率即另一个字段 mem_fragmentation_ratio。&lt;/p&gt;  &lt;p&gt;至此理解阈值告警的used_memory字段和系统层面分配的used_memory_rss字段后，可以得知这两个现象描述的是不同维度的事情，初步猜测是内存碎片过大，导致redis总占用内存超过机器内存总量，先于K-V存储数据达到告警阈值。&lt;/p&gt;  &lt;h2&gt;【验证问题】&lt;/h2&gt;  &lt;p&gt;由于该usa-9节点redis已重启无法追溯问题现场，于是遍历了usa集群的其他redis节点来验证初步猜测。    &lt;br /&gt;1）usa-2节点&lt;/p&gt;  &lt;pre&gt;    &lt;code&gt;[root@usa-idc-micen-codis-app2 ~]# top -c
 PID USER      PR  NI  VIRT  RES  SHR S   %CPU   %MEM    TIME+    COMMAND                                                                                                                                                                         
4498 root      20   0 26.9g  17g    884 S      4.3        96.9   23255:49  /opt/xyz/codis202/bin/codis-server *:8998&lt;/code&gt;&lt;/pre&gt;  &lt;pre&gt;    &lt;code&gt;[root@usa-idc-micen-codis-app2 ~]# free -m
                       total       used        free     shared   buffers   cached
Mem:                   17971      17784        187       0         8        19
-/+ buffers/cache:     17755        215
Swap:                   3967       2553       1414&lt;/code&gt;&lt;/pre&gt;  &lt;pre&gt;    &lt;code&gt;xxx.xxx.xxx.xxx:8998&amp;gt; info
# Memory
used_memory_human:6.63G
used_memory_rss_human:17.00G
mem_fragmentation_ratio:2.57&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;2）usa-4节点&lt;/p&gt;  &lt;pre&gt;    &lt;code&gt;[root@usa-idc-micen-codis-app4 log]# top -c
  PID USER      PR  NI  VIRT    RES    SHR   S     %CPU    %MEM    TIME+     COMMAND                                                                                                                                                                         
 9297 root      20   0   11.2g   10g   1076   S       3.0          59.5     1780:23   /opt/xyz/codis202/bin/codis-server *:8998&lt;/code&gt;&lt;/pre&gt;  &lt;pre&gt;    &lt;code&gt;[root@usa-idc-micen-codis-app4 log]# free -m
                        total       used       free     shared    buffers     cached
Mem:                    17971      17751        219        0        138        5184
-/+ buffers/cache:      12429       5542
Swap:                    3967        631        3336&lt;/code&gt;&lt;/pre&gt;  &lt;pre&gt;    &lt;code&gt;xxx.xxx.xxx.xxx:8998&amp;gt; info
# Memory
used_memory_human:7.63G
used_memory_rss_human:10.44G
mem_fragmentation_ratio:1.37&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;3）usa-1节点&lt;/p&gt;  &lt;pre&gt;    &lt;code&gt;[root@usa-idc-micen-codis-app1 ~]# top -c
 PID  USER    PR  NI   VIRT   RES   SHR  S   %CPU   %MEM    TIME+     COMMAND                                                                                                                                                                         
4617 root      20   0   29.8g  15g   876   S      3.0       89.8     22864:35   /opt/xyz/codis202/bin/codis-server *:8998&lt;/code&gt;&lt;/pre&gt;  &lt;pre&gt;    &lt;code&gt;[root@usa-idc-micen-codis-app1 ~]# free -m
                      total       used         free     shared    buffers     cached
Mem:                  17971       17813        158        0         30         97
-/+ buffers/cache:    17685        285
Swap:                 11780        4239       7541&lt;/code&gt;&lt;/pre&gt;  &lt;pre&gt;    &lt;code&gt;xxx.xxx.xxx.xxx:8998&amp;gt; info
# Memory
used_memory_human:6.61G
used_memory_rss_human:15.74G
mem_fragmentation_ratio:2.38&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;    &lt;strong&gt;总结：&lt;/strong&gt;    &lt;br /&gt;    &lt;strong&gt;1）usa-2节点状况最接近OOM的usa-9节点，K-V数据存储6.63G但包含内存碎片的总内存占用17G，内存碎片惊人的达到了10G以上，相当于存储6G数据但浪费10G内存不可用，碎片率2.57远远超过业界建议的1.5。间接验证了usa-9节点是因为内存碎片过大，总占用内存达到物理内存上限，申请新内存页失败导致OOM。&lt;/strong&gt;    &lt;br /&gt;    &lt;strong&gt;2）top命令查看到的进程常驻内存RES，应该就是info命令查看到的redis包含碎片的占用内存used_memory_rss，也即是内核日志kill时的清理出来的内存anon-rss。&lt;/strong&gt;    &lt;br /&gt;    &lt;strong&gt;3）除了usa-4节点状况健康：碎片率1.37低于1.5、剩余内存5G、swap区几乎没用，其他节点碎片量和碎片率过大、内存剩余无几、swap区大量使用。尤其是usa-2节点离OOM不远，但其能在悬崖边游走而没有掉下去，是因为上面提到的K-V存储内存65%阈值告警对redis所做的保护只读不写，让包含碎片的总占用内存没有超过物理内存总量，但usa-9节点就没这么好运。&lt;/strong&gt;&lt;/p&gt;  &lt;h2&gt;【解决问题】&lt;/h2&gt;  &lt;p&gt;1）保守治疗就是让redis节点不容易OOM。一是增加swap区加大物理内存耗尽的容忍度，降低触发oom-killer的机会；二是调低K-V存储告警阈值从65%到60%让保护提前生效，从而降低包含碎片的内存占用总量超过物理内存的风险。    &lt;br /&gt;2）有效治疗就是清理内存碎片，redis4.0之后具备了清理能力，但目前使用的redis3.2只能通过关机重启，加入新机器节点逐步迁移slot，迁移完成之后关闭重启旧节点。困难有三个：一是缺乏自动运维手段，逐个slot手工迁移费时；二是之前缺乏项目组对redis的使用约束，里面会存放有大key，迁移这些slot时带来的停顿项目组可不会接受；三是缺乏使用约束，项目组很可能把redis当db使用，这些被重度使用的slot所在节点会有master-slave保证高可用（几乎都不开持久化），如果迁移slot时在缺乏新的slave备份的情况下出现redis挂掉数据丢失，项目组完全无法接受。    &lt;br /&gt;3）长期治疗就是降低内存碎片，要求项目组对使用到的所有key补上TTL，一小时或一星期都行，让过期key能被清理，从而降低内存使用量和内存碎片量。但完全没项目组认领的key，只能暂时留在redis内，后期用脚本遍历对没有TTL的key补默认TTL。&lt;/p&gt;  &lt;h2&gt;【思考问题】&lt;/h2&gt;  &lt;p&gt;1）内存碎片是如何产生的？    &lt;br /&gt;可以确定的是频繁的对key set新值。比如整数集合（intSet）数据结构，假设以连续int16空间存储多个小整数，一旦加入一个2字节以上的大整数时，所有小整数都会升级成int32或int64的空间，之后再把这个大整数删除，所有小整数可不会降级回到int16，于是有一半以上的内存空间被浪费了。另外假设set keyA 1m_str，之后再set keyA int_val，空余出来的内存是否能释放，有待验证。&lt;/p&gt;  &lt;h2&gt;【待思考项】&lt;/h2&gt;  &lt;p&gt;1）redis启用持久化时，fork子进程需要同redis进程相等的内存空间（实际上copy-on-write不会真使用完全一样多的内存空间），如果只分配45%物理内存给redis进程，剩余留给持久化子进程可不划算。所以推荐的是打开内核参数 vm.overcommit_memory = 1，让分配内存空间给fork子进程时，由swap区来担保分配。redis启动日志也能看到这条警告：&lt;/p&gt;  &lt;pre&gt;    &lt;code&gt;# WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add &amp;apos;vm.overcommit_memory = 1&amp;apos; to /etc/sysctl.conf and then reboot or run the command &amp;apos;sysctl vm.overcommit_memory=1&amp;apos; for this to take effect.&lt;/code&gt;&lt;/pre&gt;  &lt;p&gt;vm.overcommit_memory 默认是0，也就是说redis进程申请内存只能从物理剩余内存中申请，不会去使用swap区。那top命令查看usa-2节点显示的VIRT=26.9g是怎么计算出来的？&lt;/p&gt;
    &lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/60675-redis-%E8%BF%9B%E7%A8%8B-oom</guid>
      <pubDate>Mon, 15 Jun 2020 07:54:52 CST</pubDate>
    </item>
    <item>
      <title>Linux Namespace 浅析</title>
      <link>https://itindex.net/detail/60299-linux-namespace</link>
      <description>&lt;p&gt;目前Linux内核总共支持以下6种Namespace：&lt;/p&gt; &lt;ul&gt;  &lt;li&gt;   &lt;p&gt;IPC：隔离System V IPC和POSIX消息队列。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;Network：隔离网络资源。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;Mount：隔离文件系统挂载点。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;PID：隔离进程ID。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;UTS：隔离主机名和域名。&lt;/p&gt;&lt;/li&gt;  &lt;li&gt;   &lt;p&gt;User：隔离用户ID和组ID。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Linux对Namespace的操作，主要是通过clone、setns和unshare这3个系统调用来完成的，clone创建新进程时，接收一个叫flags的参数，这些flag包括  &lt;code&gt;CLONE_NEWNS、CLONE_NEWIPC、CLONE_NEWUTS、CLONE_NEWNET（Mount namespace）、CLONE_NEWPID&lt;/code&gt;和  &lt;code&gt;CLONE_NEWUSER&lt;/code&gt;，用于创建新的namespace，这样clone创建出来新进程之后就属于新的namespace了，后续新进程创建的进程默认属于同一namespace。&lt;/p&gt; &lt;p&gt;如果想要给已存在进程设置新的namespace，可通过unshare函数（  &lt;code&gt;long unshare(unsigned long flags)&lt;/code&gt;）完成设置，其入参flags表示新的namespace。当想要给已存在进程设置已存在的namespace，可通过setns函数（  &lt;code&gt;int setns(int fd, int nstype)&lt;/code&gt;）来完成设置，每个进程在procfs目录下存储其相关的namespace信息，可找到已存在的namesapce，然后通过setns设置即可：&lt;/p&gt; &lt;pre&gt;  &lt;code&gt;[root@centos ~]# ls -l /proc/10401/ns   &lt;br /&gt;总用量 0   &lt;br /&gt;lrwxrwxrwx 1 root root 0 1月  12 11:36 ipc -&amp;gt; ipc:[4026531839]   &lt;br /&gt;lrwxrwxrwx 1 root root 0 1月  12 11:36 mnt -&amp;gt; mnt:[4026531840]   &lt;br /&gt;lrwxrwxrwx 1 root root 0 1月  12 11:36 net -&amp;gt; net:[4026531956]   &lt;br /&gt;lrwxrwxrwx 1 root root 0 1月  12 11:36 pid -&amp;gt; pid:[4026531836]   &lt;br /&gt;lrwxrwxrwx 1 root root 0 1月  12 11:36 user -&amp;gt; user:[4026531837]   &lt;br /&gt;lrwxrwxrwx 1 root root 0 1月  12 11:36 uts -&amp;gt; uts:[4026531838]   &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt; &lt;blockquote&gt;  &lt;p&gt;上述每个虚拟文件对应该进程所处的namespace，如果其他进程想进入该namespace，open该虚拟文件获取到fd，然后传给setns函数的fd入参即可，注意虚拟文件type和nstype要对应上。&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;  &lt;strong&gt;目前Linux内核总共支持以下6种Namespace，分别是IPC、Network、Mount、PID、UTS、User&lt;/strong&gt;：&lt;/p&gt; &lt;h2&gt;IPC&lt;/h2&gt; &lt;p&gt;IPC也就是进程间通信，Linux下有多种进程间通信，比如socket、共享内存、Posix消息队列和SystemV IPC等，这里的IPC namespace针对的是SystemV IPC和Posix消息队列，其会用标识符表示不同的消息队列，进程间通过找到标识符对应的消息队列来完成通信，IPC namespace做的事情就是相同的标识符在不同namespace上对应不同的消息队列，这样不同namespace的进程无法完成进程间通信。&lt;/p&gt; &lt;h2&gt;Network&lt;/h2&gt; &lt;p&gt;Network Namespace隔离网络资源，每个Network Namespace都有自己的网络设备、IP地址、路由表、/proc/net目录、端口号等。每个Network Namespace会有一个loopback设备（除此之外不会有任何其他网络设备）。因此用户需要在这里面做自己的网络配置。IP工具已经支持Network Namespace，可以通过它来为新的Network Namespace配置网络功能。&lt;/p&gt; &lt;h2&gt;Mount&lt;/h2&gt; &lt;p&gt;Mount namesapce用户隔离文件系统挂载点，每个进程能看到的文件系统都记录在/proc/xx/mounts里。在创建了一个新的Mount Namespace后，进程系统对文件系统挂载/卸载的动作就不会影响到其他Namespace。&lt;/p&gt; &lt;h2&gt;PID&lt;/h2&gt; &lt;p&gt;PID Namespace用于隔离进程PID号，这样一来，不同的Namespace里的进程PID号就可以是一样的了。当创建一个PID Namespace时，第一个进程的PID号是1，也就是init进程。init进程有一些特殊之处，例如init进程需要负责回收所有孤儿进程的资源。另外，发送给init进程的任何信号都会被屏蔽，即使发送的是SIGKILL信号，也就是说，在容器内无法“杀死”init进程。&lt;/p&gt; &lt;blockquote&gt;  &lt;p&gt;注意，但是当用ps命令查看系统的进程时，会发现竟然可以看到host的所有进程：&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;  &lt;img&gt;&lt;/img&gt;&lt;/p&gt; &lt;blockquote&gt;  &lt;p&gt;这是因为ps命令是从procfs读取信息的，而procfs并没有得到隔离。虽然能看到这些进程，但由于它们其实是在另一个PID Namespace中，因此无法向这些进程发送信号。&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;UTS&lt;/h2&gt; &lt;p&gt;UTS Namespace用于对主机名和域名进行隔离，也就是uname系统调用使用的结构体structutsname里的nodename和domainname这两个字段，UTS这个名字也是由此而来的。为什么需要uts namespace呢，因为为主机名可以用来代替IP地址，比如局域网通过主机名访问机器。&lt;/p&gt; &lt;h2&gt;User&lt;/h2&gt; &lt;p&gt;User Namespace用来隔离用户资源，比如一个进程在Namespace里的用户和组ID与它在host里的ID可以不一样，这样可以做到，一个host的普通用户可以在该容器（user namespace）下拥有root权限，但是它的特权被限定在容器内。（容器内的这类root用户，实际上还是有很多特权操作不能执行，基本上如果这个特权操作会影响到其他容器或者host，就不会被允许）&lt;/p&gt; &lt;h2&gt;小结&lt;/h2&gt; &lt;p&gt;一般namespace都是和cgroup结合来使用的，但是直接操作Namespace和Cgroup并不是很容易，因此docker的出现就显得有必要了，Docker通过Libcontainer来处理这些底层的事情。这样一来，Docker只需要简单地调用Libcontainer的API，就能将完整的容器搭建起来。而作为Docker的用户，就更不用操心这些事情了，只需要通过一两条简单的Docker命令启动容器即可。&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category>dev</category>
      <guid isPermaLink="true">https://itindex.net/detail/60299-linux-namespace</guid>
      <pubDate>Tue, 14 Jan 2020 00:00:00 CST</pubDate>
    </item>
    <item>
      <title>如何排查 Linux 机器是否已经被入侵？</title>
      <link>https://itindex.net/detail/59814-linux-%E6%9C%BA%E5%99%A8-%E5%85%A5%E4%BE%B5</link>
      <description>&lt;p&gt;
	  &lt;a href="http://www.phpxs.com/" target="_blank"&gt;背景信息&lt;/a&gt;：以下情况是在CentOS 6.9的系统中查看的，其它Linux发行版类似。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	1  &lt;a href="http://www.phpxs.com/" target="_blank"&gt;.入侵者可能&lt;/a&gt;会删除机器的日志信息，可以查看日志信息是否还存在或者是否被清空，相关命令示例：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/2679d1d91ed0db11f19344f92873403b.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	2.入侵者可能创建一个新的存放用户名及密码文件，可以查看/etc/passwd及/etc/shadow文件，相关命令示例：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/59f2d8fa8503730acd3d83fc6a5b4f9b.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	3.入侵者可能修改用户名及密码文件，可以查看/etc/passwd及/etc/shadow文件内容进行鉴别，相关命令示例：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/6cdc58b3ef09bf68b53b5464eb028c5e.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	4.查看机器最近成功登陆的事件和最后一次不成功的登陆事件，对应日志“/var/log/lastlog”，相关命令示例：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/14f34e5d348fb99d20f37e6f98098d8d.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	5.查看机器当前登录的全部用户，对应日志文件“/var/run/utmp”，相关命令示例：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/1b4e43cc66c5a912061887b4c02ecd98.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	6.查看机器创建以来登陆过的用户，对应日志文件“/var/log/wtmp”，相关命令示例：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/f6a4c14868eaa55784081ec0668b2ce2.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	7.查看机器所有用户的连接时间（小时），对应日志文件“/var/log/wtmp”，相关命令示例：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/75fb7fe8801f783c247cd54ed4bdf686.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	8.如果发现机器产生了异常流量，可以使用命令“tcpdump”抓取网络包查看流量情况或者使用工具”iperf”查看流量情况。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	9.可以查看/var/log/secure日志文件，尝试发现入侵者的信息，相关命令示例：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/79f4b933628a737758020bfbdd997685.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	10.查询异常进程所对应的执行脚本文件
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	a.top命令查看异常进程对应的PID
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/4a2942e7663263836a05a285e6196835.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	b.在虚拟文件系统目录查找该进程的可执行文件
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/796e02e3cab2863ebd321c0fde897539.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	11.如果确认机器已经被入侵，重要文件已经被删除，可以尝试找回被删除的文件。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	当进程打开了某个文件时，只要该进程保持打开该文件，即使将其删除，它依然存在于磁盘中。这意味着，进程并不知道文件已经被删除，它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外，这个文件是不可见的，因为已经删除了其相应的目录索引节点。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	在/proc 目录下，其中包含了反映内核和进程树的各种文件。/proc目录挂载的是在内存中所映射的一块区域，所以这些文件和目录并不存在于磁盘中，因此当我们对这些文件进行读取和写入时，实际上是在从内存中获取相关信息。大多数与 lsof 相关的信息都存储于以进程的 PID 命名的目录中，即 /proc/1234 中包含的是 PID 为 1234 的进程的信息。每个进程目录中存在着各种文件，它们可以使得应用程序简单地了解进程的内存空间、文件描述符列表、指向磁盘上的文件的符号链接和其他系统信息。lsof 程序使用该信息和其他关于内核内部状态的信息来产生其输出。所以lsof 可以显示进程的文件描述符和相关的文件名等信息。也就是我们通过访问进程的文件描述符可以找到该文件的相关信息。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	当系统中的某个文件被意外地删除了，只要这个时候系统中还有进程正在访问该文件，那么我们就可以通过lsof从/proc目录下恢复该文件的内容。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	假设入侵者将/var/log/secure文件删除掉了，尝试将/var/log/secure文件恢复的方法可以参考如下：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	a.查看/var/log/secure文件，发现已经没有该文件。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/b1541c07b0022648d256de38f92ea8a7.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	b.使用lsof命令查看当前是否有进程打开/var/log/secure，
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/887e1b0f889bc75d2fc34550ea0005ff.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	c.从上面的信息可以看到 PID 1264（rsyslogd）打开文件的文件描述符为4。同时还可以看到/var/log/ secure已经标记为被删除了。因此我们可以在/proc/1264/fd/4（fd下的每个以数字命名的文件表示进程对应的文件描述符）中查看相应的信息，如下：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/5d79c6c1dfa2b96bd31a1e63fa381ec3.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	d.从上面的信息可以看出，查看/proc/1264/fd/4就可以得到所要恢复的数据。如果可以通过文件描述符查看相应的数据，那么就可以使用I/O重定向将其重定向到文件中，如：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/041a1d6ab936c02f62645744c055e8e6.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	e.再次查看/var/log/secure，发现该文件已经存在。对于许多应用程序，尤其是日志文件和数据库，这种恢复删除文件的方法非常有用。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201907/10/b741d10e4f6547315a3f99acdcba94b1.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/59814-linux-%E6%9C%BA%E5%99%A8-%E5%85%A5%E4%BE%B5</guid>
      <pubDate>Wed, 10 Jul 2019 08:00:00 CST</pubDate>
    </item>
    <item>
      <title>linux 启动流程分析</title>
      <link>https://itindex.net/detail/59753-linux-%E5%88%86%E6%9E%90</link>
      <description>&lt;p&gt;
	今天，一起探讨操作系统的启动流程。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/41d569766113f3e35dec05fc2924f422.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	这个部分比较有意思。因为在BIOS阶段，计算机的行为基本上被写死了，程序员可以做的事情并不多；但是，一旦进入操作系统，程序员几乎可以定制所有方面。所以，这个部分与程序员的关系更密切。
&lt;/p&gt;
 &lt;p&gt;
	我主要关心的是Linux操作系统，它是目前服务器端的主流操作系统。下面的内容针对的是Debian发行版，因为我对其他发行版不够熟悉。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
加载内核
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	操作系统接管硬件以后，首先读入 /boot 目录下的内核文件。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/017039c30f226cd0af79af6b2008ec4a.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	以我的电脑为例，/boot 目录下面大概是这样一些文件：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;

&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/7cc748aca8a5aee708c2c209fc25d99c.png"&gt;&lt;/img&gt;  &lt;br /&gt;

&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
启动初始化进程
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	内核文件加载以后，就开始运行第一个程序 /sbin/init，它的作用是初始化系统环境。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/46976f9ed12e05798fb786b56c68d76f.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	由于init是第一个运行的程序，它的进程编号（pid）就是1。其他所有进程都从它衍生，都是它的子进程。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
确定运行级别
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	许多程序需要开机启动。它们在Windows叫做&amp;quot;服务&amp;quot;（service），在Linux就叫做&amp;quot;守护进程&amp;quot;（daemon）。
&lt;/p&gt;
 &lt;p&gt;
	init进程的一大任务，就是去运行这些开机启动的程序。但是，不同的场合需要启动不同的程序，比如用作服务器时，需要启动Apache，用作桌面就不需要。Linux允许为不同的场合，分配不同的开机启动程序，这就叫做&amp;quot;运行级别&amp;quot;（runlevel）。也就是说，启动时根据&amp;quot;运行级别&amp;quot;，确定要运行哪些程序。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/c79f752f900a3765e6a7b13cd98d6e0d.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	Linux预置七种运行级别（0-6）。一般来说，0是关机，1是单用户模式（也就是维护模式），6是重启。运行级别2-5，各个发行版不太一样，对于Debian来说，都是同样的多用户模式（也就是正常模式）。
&lt;/p&gt;
 &lt;p&gt;
	init进程首先读取文件 /etc/inittab，它是运行级别的设置文件。如果你打开它，可以看到第一行是这样的：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/b1ac01bcbedd23f3bebc9f3a34c3f96f.png"&gt;&lt;/img&gt;　　
&lt;/p&gt;
 &lt;p&gt;
	initdefault的值是2，表明系统启动时的运行级别为2。如果需要指定其他级别，可以手动修改这个值。
&lt;/p&gt;
 &lt;p&gt;
	那么，运行级别2有些什么程序呢，系统怎么知道每个级别应该加载哪些程序呢？......回答是每个运行级别在/etc目录下面，都有一个对应的子目录，指定要加载的程序。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/a41190854dc6c67893387ebd41d7aac4.png"&gt;&lt;/img&gt;  &lt;br /&gt;

&lt;/p&gt;
 &lt;p&gt;
	上面目录名中的&amp;quot;rc&amp;quot;，表示run command（运行程序），最后的d表示directory（目录）。下面让我们看看 /etc/rc2.d 目录中到底指定了哪些程序。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/d6c21bcdfd5c6ab07bb0f56ffe77a476.png"&gt;&lt;/img&gt;  &lt;br /&gt;

&lt;/p&gt;
 &lt;p&gt;
	可以看到，除了第一个文件README以外，其他文件名都是&amp;quot;字母S+两位数字+程序名&amp;quot;的形式。字母S表示Start，也就是启动的意思（启动脚本的运行参数为start），如果这个位置是字母K，就代表Kill（关闭），即如果从其他运行级别切换过来，需要关闭的程序（启动脚本的运行参数为stop）。
&lt;/p&gt;
 &lt;p&gt;
	后面的两位数字表示处理顺序，数字越小越早处理，所以第一个启动的程序是motd，然后是rpcbing、nfs......数字相同时，则按照程序名的字母顺序启动，所以rsyslog会先于sudo启动。
&lt;/p&gt;
 &lt;p&gt;
	这个目录里的所有文件（除了README），就是启动时要加载的程序。如果想增加或删除某些程序，不建议手动修改 /etc/rcN.d 目录，最好是用一些专门命令进行管理（参考这里和这里）。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
加载开机启动程序
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	前面提到，七种预设的&amp;quot;运行级别&amp;quot;各自有一个目录，存放需要开机启动的程序。不难想到，如果多个&amp;quot;运行级别&amp;quot;需要启动同一个程序，那么这个程序的启动脚本，就会在每一个目录里都有一个拷贝。这样会造成管理上的困扰：如果要修改启动脚本，岂不是每个目录都要改一遍？
&lt;/p&gt;
 &lt;p&gt;
	Linux的解决办法，就是七个 /etc/rcN.d 目录里列出的程序，都设为链接文件，指向另外一个目录 /etc/init.d ，真正的启动脚本都统一放在这个目录中。init进程逐一加载开机启动程序，其实就是运行这个目录里的启动脚本。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/618dc2bc6b46e423148ff3934b396878.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	下面就是链接文件真正的指向。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/5f72153d31ad9dc5bce4397f95d6a329.png"&gt;&lt;/img&gt;  &lt;br /&gt;

&lt;/p&gt;
 &lt;p&gt;
	这样做的另一个好处，就是如果你要手动关闭或重启某个进程，直接到目录 /etc/init.d 中寻找启动脚本即可。比如，我要重启Apache服务器，就运行下面的命令：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/097f10aea5c641c9434335a297c957bb.png"&gt;&lt;/img&gt;  &lt;br /&gt;

&lt;/p&gt;
 &lt;p&gt;
	/etc/init.d 这个目录名最后一个字母d，是directory的意思，表示这是一个目录，用来与程序 /etc/init 区分。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
用户登录
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	开机启动程序加载完毕以后，就要让用户登录了。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/7c34d9d74086be79763ea44ed37ee6c2.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	一般来说，用户的登录方式有三种：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/0db0f62008415829a1859c1404445d41.png"&gt;&lt;/img&gt;  &lt;br /&gt;

&lt;/p&gt;
 &lt;p&gt;
	这三种情况，都有自己的方式对用户进行认证。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;strong&gt;（1）&lt;/strong&gt;命令行登录：init进程调用getty程序（意为get teletype），让用户输入用户名和密码。输入完成后，再调用login程序，核对密码（Debian还会再多运行一个身份核对程序/etc/pam.d/login）。如果密码正确，就从文件 /etc/passwd 读取该用户指定的shell，然后启动这个shell。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;strong&gt;（2）&lt;/strong&gt;ssh登录：这时系统调用sshd程序（Debian还会再运行/etc/pam.d/ssh ），取代getty和login，然后启动shell。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;strong&gt;（3）&lt;/strong&gt;图形界面登录：init进程调用显示管理器，Gnome图形界面对应的显示管理器为gdm（GNOME Display Manager），然后用户输入用户名和密码。如果密码正确，就读取/etc/gdm3/Xsession，启动用户的会话。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
进入login shell
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	所谓shell，简单说就是命令行界面，让用户可以直接与操作系统对话。用户登录时打开的shell，就叫做login shell。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/28ebdef116bf9f2c2f85fb9864e4dbb8.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	Debian默认的shell是Bash，它会读入一系列的配置文件。上一步的三种情况，在这一步的处理，也存在差异。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;strong&gt;（1）&lt;/strong&gt;命令行登录：首先读入 /etc/profile，这是对所有用户都有效的配置；然后依次寻找下面三个文件，这是针对当前用户的配置。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/4779033d6e96de64c8aa6e756c18a05d.png"&gt;&lt;/img&gt;  &lt;br /&gt;

&lt;/p&gt;
 &lt;p&gt;
	需要注意的是，这三个文件只要有一个存在，就不再读入后面的文件了。比如，要是 ~/.bash_profile 存在，就不会再读入后面两个文件了。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;strong&gt;（2）&lt;/strong&gt;ssh登录：与第一种情况完全相同。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;strong&gt;（3）&lt;/strong&gt;图形界面登录：只加载 /etc/profile 和 ~/.profile。也就是说，~/.bash_profile 不管有没有，都不会运行。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
打开non-login shell
 &lt;p&gt;
	  &lt;br /&gt;
&lt;/p&gt;
 &lt;p&gt;
	老实说，上一步完成以后，Linux的启动过程就算结束了，用户已经可以看到命令行提示符或者图形界面了。但是，为了内容的完整，必须再介绍一下这一步。
&lt;/p&gt;
 &lt;p&gt;
	用户进入操作系统以后，常常会再手动开启一个shell。这个shell就叫做 non-login shell，意思是它不同于登录时出现的那个shell，不读取/etc/profile和.profile等配置文件。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/78e026923969f04a46955366d5587663.jpg"&gt;&lt;/img&gt;
&lt;/p&gt;
 &lt;p&gt;
	non-login shell的重要性，不仅在于它是用户最常接触的那个shell，还在于它会读入用户自己的bash配置文件 ~/.bashrc。大多数时候，我们对于bash的定制，都是写在这个文件里面的。
&lt;/p&gt;
 &lt;p&gt;
	你也许会问，要是不进入 non-login shell，岂不是.bashrc就不会运行了，因此bash 也就不能完成定制了？事实上，Debian已经考虑到这个问题了，请打开文件 ~/.profile，可以看到下面的代码：
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/309b34cd40c4095782a9582fa1af0b4d.png"&gt;&lt;/img&gt;  &lt;br /&gt;

&lt;/p&gt;
 &lt;p&gt;
	上面代码先判断变量 $BASH_VERSION 是否有值，然后判断主目录下是否存在 .bashrc 文件，如果存在就运行该文件。第三行开头的那个点，是source命令的简写形式，表示运行某个文件，写成&amp;quot;source ~/.bashrc&amp;quot;也是可以的。
&lt;/p&gt;
 &lt;p&gt;
	因此，只要运行～/.profile文件，～/.bashrc文件就会连带运行。但是上一节的第一种情况提到过，如果存在～/.bash_profile文件，那么有可能不会运行～/.profile文件。解决这个问题很简单，把下面代码写入.bash_profile就行了。
&lt;/p&gt;
 &lt;p&gt;
	  &lt;img alt="" src="http://www.phpxs.com/uploads/201906/27/f7928c4a9ee3574185d6807697e5e3b0.png"&gt;&lt;/img&gt;　
&lt;/p&gt;
 &lt;p&gt;
	这样一来，不管是哪种情况，.bashrc都会执行，用户的设置可以放心地都写入这个文件了。
&lt;/p&gt;
 &lt;p&gt;
	Bash的设置之所以如此繁琐，是由于历史原因造成的。早期的时候，计算机运行速度很慢，载入配置文件需要很长时间，Bash的作者只好把配置文件分成了几个部分，阶段性载入。系统的通用设置放在 /etc/profile，用户个人的、需要被所有子进程继承的设置放在.profile，不需要被继承的设置放在.bashrc。
&lt;/p&gt;
 &lt;p&gt;
	顺便提一下，除了Linux以外， Mac OS X 使用的shell也是Bash。但是，它只加载.bash_profile，然后在.bash_profile里面调用.bashrc。而且，不管是ssh登录，还是在图形界面里启动shell窗口，都是如此。
&lt;/p&gt;&lt;div&gt; &lt;a href="https://itindex.net/"  title="IT 资讯"&gt;&lt;img src="https://itindex.net/images/iconWarning.gif" title="IT 资讯" border="0"/&gt; &lt;/a&gt;</description>
      <category />
      <guid isPermaLink="true">https://itindex.net/detail/59753-linux-%E5%88%86%E6%9E%90</guid>
      <pubDate>Thu, 27 Jun 2019 08:00:00 CST</pubDate>
    </item>
  </channel>
</rss>

