在 Ubuntu 和 Debian 上启用双因子身份验证的三种备选方案
如何为你的 SSH 服务器安装三种不同的双因子身份验证方案。如今，安全比以往更加重要，保护 SSH 服务器是作为系统管理员可以做的最为重要的事情之一。传统地，这意味着禁用密码身份验证而改用 SSH 密钥。无疑这是你首先应该做的，但这并不意味着 SSH 无法变得更加安全。双因子身份验证就是指需要两种身份验证才能登录。可以是密码和 SSH 密钥，也可以是密钥和第三方服务，比如 Google。这意味着单个验证方法的泄露不会危及服务器。以下指南是为 SSH 启用双因子验证的三种方式。当你修改 SSH 配置时，总是要确保有一个连接到服务器的第二终端。第二终端意味着你可以修复你在 SSH 配置中犯的任何错误。打开的终端将一直保持，即便 SSH 服务重启。SSH 密钥和密码SSH 支持对登录要求不止一个身份验证方法。在 /etc/sh/sshd_config 中的 SSH 服务器配置文件中的 AuthenticationMethods 选项中设置了身份验证方法。当在 /etc/ssh/sshd_config 中添加下一行时，SSH 需要提交一个 SSH 密钥，然后提示输入密码:AuthenticationMethods "publickey,password"如果你想要根据使用情况设置这些方法，那么请使用以下附加配置:Match User jsmith AuthenticationMethods "publickey,password"当你已经编辑或保存了新的 sshd_config 文件，你应该通过运行以下程序来确保你没有犯任何错误：sshd -t任何导致 SSH 不能启动的语法或其他错误都将在这里标记出来。当 ssh-t 运行时没有错误，使用 systemctl 重新启动 SSH：systemctl restart sshd现在，你可以使用新终端登录，以核实你会被提示输入密码并需要 SSH 密钥。如果你用 ssh-v，例如：ssh -v jsmith@example.com你将可以看到登录的每一步。注意，如果你确实将密码设置成必需的身份验证方法，你要确保将 PasswordAuthentication 选项设置成 yes。使用 Google Authenticator 的 SSHGoogle 在 Google 自己的产品上使用的双因子身份验证系统可以集成到你的 SSH 服务器中。如果你已经使用了Google Authenticator，那么此方法将非常方便。虽然 libpam-google-authenticator 是由 Google 编写的，但它是开源的。此外，Google Authenticator 是由 Google 编写的，但并不需要 Google 帐户才能工作。多亏了 Sitaram Chamarty 的贡献。如果你还没有在手机上安装和配置 Google Authenticator，请参阅 这里的说明。首先，我们需要在服务器上安装 Google Authenticatior 安装包。以下命令将更新你的系统并安装所需的软件包：apt-get update apt-get upgrade apt-get install libpam-google-authenticator现在，我们需要在你的手机上使用 Google Authenticatior APP 注册服务器。这是通过首先运行我们刚刚安装的程序完成的:google-authenticator运行这个程序时，会问到几个问题。你应该以适合你的设置的方式回答，然而，最安全的选项是对每个问题回答 y。如果以后需要更改这些选项，您可以简单地重新运行 google-authenticator 并选择不同的选项。当你运行 google-authenticator 时，一个二维码会被打印到终端上，有些代码看起来像这样:Your new secret key is: VMFY27TYDFRDNKFY Your verification code is 259652 Your emergency scratch codes are: 96915246 70222983 31822707 25181286 28919992你应该将所有这些代码记录到一个像密码管理器一样安全的位置。“scratch codes” 是单一的使用代码，即使你的手机不可用，它总是允许你访问。要将服务器注册到 Authenticator APP 中，只需打开应用程序并点击右下角的红色加号即可。然后选择扫描条码选项，扫描打印到终端的二维码。你的服务器和应用程序现在连接。回到服务器上，我们现在需要编辑用于 SSH 的 PAM (可插入身份验证模块)，以便它使用我们刚刚安装的身份验证器安装包。PAM 是独立系统，负责 Linux 服务器上的大多数身份验证。需要修改的 SSH PAM 文件位于 /etc/pam.d/sshd ，用以下命令编辑:nano /etc/pam.d/sshd在文件顶部添加以下行:auth required pam_google_authenticator.so此外，我们还需要注释掉一行，这样 PAM 就不会提示输入密码。改变这行：# Standard Un*x authentication. @include common-auth为如下：# Standard Un*x authentication. # @include common-auth接下来，我们需要编辑 SSH 服务器配置文件： nano /etc/ssh/sshd\_config “` 改变这一行： ChallengeResponseAuthentication no 为： ChallengeResponseAuthentication yes 接下来，添加以下代码行来启用两个身份验证方案：SSH 密钥和谷歌认证器（键盘交互）： AuthenticationMethods "publickey,keyboard-interactive" 在重新加载 SSH 服务器之前，最好检查一下在配置中没有出现任何错误。执行以下命令： sshd -t 如果没有标识出任何错误，用新的配置重载 SSH： systemctl reload sshd.service 现在一切都应该开始工作了。现在，当你登录到你的服务器时，你将需要使用 SSH 密钥，并且当你被提示输入： Verification code: 打开 Authenticator APP 并输入为您的服务器显示的 6 位代码。 ### Authy [Authy](https://authy.com/) 是一个双重身份验证服务，与 Google 一样，它提供基于时间的代码。然而，Authy 不需要手机，因为它提供桌面和平板客户端。它们还支持离线身份验证，不需要 Google 帐户。 你需要从应用程序商店安装 Authy 应用程序，或 Authy [下载页面](https://authy.com/download/)所链接的桌面客户端。 安装完应用程序后，需要在服务器上使用 API 密钥。这个过程需要几个步骤: 1. 在[这里](https://www.authy.com/signup)注册一个账户。 2. 向下滚动到 “Authy” 部分。 3. 在帐户上启用双因子认证（2FA）。 4. 回 “Authy” 部分。 5. 为你的服务器创建一个新的应用程序。 6. 从新应用程序的 “General Settings” 页面顶部获取 API 密钥。你需要 “PRODUCTION API KEY”旁边的眼睛符号来显示密钥。如图： ![](/data/attachment/album/201811/06/204801eiomcb42ngo2w8cn.png) 在某个安全的地方记下 API 密钥。 现在，回到服务器，以 root 身份运行以下命令： curl -O 'https://raw.githubusercontent.com/authy/authy-ssh/master/authy-ssh'bash authy-ssh install /usr/local/bin 当提示时输入 API 键。如果输入错误，你始终可以编辑 `/usr/local/bin/authy-ssh` 再添加一次。 Authy 现已安装。但是，在为用户启用它之前，它不会开始工作。启用 Authy 的命令有以下形式： /usr/local/bin/authy-ssh enable root 登录的一些示例细节： /usr/local/bin/authy-ssh enable root john@example.com 44 20822536476 如果一切顺利，你会看到： User was registered 现在可以通过运行以下命令来测试 Authy： authy-ssh test 最后，重载 SSH 实现新的配置： systemctl reload sshd.service Authy 现在正在工作，SSH 需要它才能登录。 现在，当你登录时，你将看到以下提示: Authy Token (type 'sms' to request a SMS token): 你可以输入手机或桌面客户端的 Authy APP 上的代码。或者你可以输入 `sms`， Authy 会给你发送一条带有登录码的短信。 可以通过运行以下命令卸载 Authy： /usr/local/bin/authy-ssh uninstall --- via: <https://bash-prompt.net/guides/ssh-2fa/> 作者：[Elliot Cooper](https://bash-prompt.net) 译者：[cielllll](https://github.com/cielllll) 校对：[wxy](https://github.com/wxy)
Telnet，是系统管理员登录远程服务器的一种协议和工具。然而，由于所有的通信都没有加密，包括密码，都是明文发送的。Telnet 在 SSH 被开发出来之后就基本弃用了。登录远程服务器，你可能不会也从未考虑过它。但这并不意味着 telnet 命令在调试远程连接问题时不是一个实用的工具。本教程中，我们将探索使用 telnet 解决所有常见问题：“我怎么又连不上啦？”这种讨厌的问题通常会在安装了像 Web服务器、邮件服务器、ssh 服务器、Samba 服务器等诸如此类的事之后遇到，用户无法连接服务器。telnet 不会解决问题但可以很快缩小问题的范围。telnet 用来调试网络问题的简单命令和语法：telnet <hostname or IP> <port> 因为 telnet 最初通过端口建立连接不会发送任何数据，适用于任何协议，包括加密协议。连接问题服务器有四个可能会遇到的主要问题。我们会研究这四个问题，研究它们意味着什么以及如何解决。本教程默认已经在 samba.example.com 安装了 Samba 服务器而且本地客户无法连上服务器。Error 1 - 连接挂起首先，我们需要试着用 telnet 连接 Samba 服务器。使用下列命令 (Samba 监听端口445)：telnet samba.example.com 445 有时连接会莫名停止：telnet samba.example.com 445 Trying 172.31.25.31... 这意味着 telnet 没有收到任何回应来建立连接。有两个可能的原因：你和服务器之间有个路由器宕掉了。防火墙拦截了你的请求。为了排除第 1 点，对服务器上进行一个快速 mtr samba.example.com 。如果服务器是可达的，那么便是防火墙（注意：防火墙总是存在的）。首先用 iptables -L -v -n 命令检查服务器本身有没有防火墙，没有的话你能看到以下内容：iptables -L -v -n Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 如果你看到其他东西那可能就是问题所在了。为了检验，停止 iptables 一下并再次运行 telnet samba.example.com 445 看看你是否能连接。如果你还是不能连接看看你的提供商或企业有没有防火墙拦截你。Error 2 - DNS 问题DNS 问题通常发生在你正使用的主机名没有解析到 IP 地址。错误如下：telnet samba.example.com 445 Server lookup failure: samba.example.com:445, Name or service not known 第一步是把主机名替换成服务器的 IP 地址。如果你可以连上那么就是主机名的问题。有很多发生的原因（以下是我见过的）：域名注册了吗？用 whois 来检验。域名过期了吗？用 whois 来检验。是否使用正确的主机名？用 dig 或 host 来确保你使用的主机名解析到正确的 IP。你的 A 记录正确吗？确保你没有偶然创建类似 smaba.example.com 的 A 记录。一定要多检查几次拼写和主机名是否正确（是 samba.example.com 还是 samba1.example.com）？这些经常会困扰你，特别是比较长、难记或其它国家的主机名。Error 3 - 服务器没有侦听端口这种错误发生在 telnet 可达服务器但是指定端口没有监听。就像这样：telnet samba.example.com 445 Trying 172.31.25.31... telnet: Unable to connect to remote host: Connection refused 有这些原因：你 确定 连接的是正确的服务器？你的应用服务器没有侦听预期的端口。在服务器上运行 netstat -plunt 来查看它究竟在干什么并看哪个端口才是对的，实际正在监听中的。应用服务器没有运行。这可能突然而又悄悄地发生在你启动应用服务器之后。启动服务器运行 ps auxf 或 systemctl status application.service 查看运行。Error 4 - 连接被服务器关闭这种错误发生在连接成功建立但是应用服务器建立的安全措施一连上就将其结束。错误如下：telnet samba.example.com 445 Trying 172.31.25.31... Connected to samba.example.com. Escape character is '^]'. Connection closed by foreign host. 最后一行 Connection closed by foreign host. 意味着连接被服务器主动终止。为了修复这个问题，需要看看应用服务器的安全设置确保你的 IP 或用户允许连接。成功连接成功的 telnet 连接如下：telnet samba.example.com 445 Trying 172.31.25.31... Connected to samba.example.com. Escape character is '^]'. 连接会保持一段时间只要你连接的应用服务器时限没到。输入 CTRL+] 中止连接，然后当你看到 telnet> 提示，输入 quit 并按回车：telnet samba.example.com 445 Trying 172.31.25.31... Connected to samba.example.com. Escape character is '^]'. ^] telnet> quit Connection closed. 总结客户程序连不上服务器的原因有很多。确切原因很难确定，特别是当客户是图形用户界面提供很少或没有错误信息。用 telnet 并观察输出可以让你很快确定问题所在节约很多时间。via: https://bash-prompt.net/guides/telnet/作者：Elliot Cooper 译者：XYenChi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
用 Apache 服务器模块保护您的网站免受应用层 DOS 攻击
有多种可以导致网站下线的攻击方法，比较复杂的方法要涉及数据库和编程方面的技术知识。一个更简单的方法被称为“ 拒绝服务 Denial Of Service ”（DOS）攻击。这个攻击方法的名字来源于它的意图：使普通客户或网站访问者的正常服务请求被拒绝。一般来说，有两种形式的 DOS 攻击：OSI 模型的三、四层，即网络层攻击OSI 模型的七层，即应用层攻击第一种类型的 DOS 攻击——网络层，发生于当大量的垃圾流量流向网页服务器时。当垃圾流量超过网络的处理能力时，网站就会宕机。第二种类型的 DOS 攻击是在应用层，是利用合法的服务请求，而不是垃圾流量。当页面请求数量超过网页服务器能承受的容量时，即使是合法访问者也将无法使用该网站。本文将着眼于缓解应用层攻击，因为减轻网络层攻击需要大量的可用带宽和上游提供商的合作，这通常不是通过配置网络服务器就可以做到的。通过配置普通的网页服务器，可以保护网页免受应用层攻击，至少是适度的防护。防止这种形式的攻击是非常重要的，因为 Cloudflare 最近 报告称 网络层攻击的数量正在减少，而应用层攻击的数量则在增加。本文将介绍如何使用 zdziarski 开发的 Apache2 的模块 mod\_evasive。另外，mod\_evasive 会阻止攻击者通过尝试数百个用户名和密码的组合来进行猜测（即暴力攻击）的企图。mod\_evasive 会记录来自每个 IP 地址的请求的数量。当这个数字超过相应 IP 地址的几个阈值之一时，会出现一个错误页面。错误页面所需的资源要比一个能够响应合法访问的在线网站少得多。在 Ubuntu 16.04 上安装 mod\_evasiveUbuntu 16.04 默认的软件库中包含了 mod\_evasive，名称为 “libapache2-mod-evasive”。您可以使用 apt-get 来完成安装：apt-get update apt-get upgrade apt-get install libapache2-mod-evasive 现在我们需要配置 mod\_evasive。它的配置文件位于 /etc/apache2/mods-available/evasive.conf。默认情况下，所有模块的设置在安装后都会被注释掉。因此，在修改配置文件之前，模块不会干扰到网站流量。 #DOSHashTableSize 3097 #DOSPageCount 2 #DOSSiteCount 50 #DOSPageInterval 1 #DOSSiteInterval 1 #DOSBlockingPeriod 10 #DOSEmailNotify you@yourdomain.com #DOSSystemCommand "su - someuser -c '/sbin/... %s ...'" #DOSLogDir "/var/log/mod_evasive" 第一部分的参数的含义如下：DOSHashTableSize - 正在访问网站的 IP 地址列表及其请求数的当前列表。DOSPageCount - 在一定的时间间隔内，每个页面的请求次数。时间间隔由 DOSPageInterval 定义。DOSPageInterval - mod\_evasive 统计页面请求次数的时间间隔。DOSSiteCount - 与 DOSPageCount 相同，但统计的是来自相同 IP 地址对网站内任何页面的请求数量。DOSSiteInterval - mod\_evasive 统计网站请求次数的时间间隔。DOSBlockingPeriod - 某个 IP 地址被加入黑名单的时长（以秒为单位）。如果使用上面显示的默认配置，则在如下情况下，一个 IP 地址会被加入黑名单：每秒请求同一页面超过两次。每秒请求 50 个以上不同页面。如果某个 IP 地址超过了这些阈值，则被加入黑名单 10 秒钟。这看起来可能不算久，但是，mod\_evasive 将一直监视页面请求，包括在黑名单中的 IP 地址，并重置其加入黑名单的起始时间。只要一个 IP 地址一直尝试使用 DOS 攻击该网站，它将始终在黑名单中。其余的参数是：DOSEmailNotify - 用于接收 DOS 攻击信息和 IP 地址黑名单的电子邮件地址。DOSSystemCommand - 检测到 DOS 攻击时运行的命令。DOSLogDir - 用于存放 mod\_evasive 的临时文件的目录。配置 mod\_evasive默认的配置是一个很好的开始，因为它不会阻塞任何合法的用户。取消配置文件中的所有参数（DOSSystemCommand 除外）的注释，如下所示： DOSHashTableSize 3097 DOSPageCount 2 DOSSiteCount 50 DOSPageInterval 1 DOSSiteInterval 1 DOSBlockingPeriod 10 DOSEmailNotify JohnW@example.com #DOSSystemCommand "su - someuser -c '/sbin/... %s ...'" DOSLogDir "/var/log/mod_evasive" 必须要创建日志目录并且要赋予其与 apache 进程相同的所有者。这里创建的目录是 /var/log/mod_evasive ，并且在 Ubuntu 上将该目录的所有者和组设置为 www-data ，与 Apache 服务器相同：mkdir /var/log/mod_evasive chown www-data:www-data /var/log/mod_evasive 在编辑了 Apache 的配置之后，特别是在正在运行的网站上，在重新启动或重新加载之前，最好检查一下语法，因为语法错误将影响 Apache 的启动从而使网站宕机。Apache 包含一个辅助命令，是一个配置语法检查器。只需运行以下命令来检查您的语法：apachectl configtest 如果您的配置是正确的，会得到如下结果：Syntax OK 但是，如果出现问题，您会被告知在哪部分发生了什么错误，例如：AH00526: Syntax error on line 6 of /etc/apache2/mods-enabled/evasive.conf: DOSSiteInterval takes one argument, Set site interval Action 'configtest' failed. The Apache error log may have more information. 如果您的配置通过了 configtest 的测试，那么这个模块可以安全地被启用并且 Apache 可以重新加载：a2enmod evasive systemctl reload apache2.service mod\_evasive 现在已配置好并正在运行了。测试为了测试 mod\_evasive，我们只需要向服务器提出足够的网页访问请求，以使其超出阈值，并记录来自 Apache 的响应代码。一个正常并成功的页面请求将收到如下响应：HTTP/1.1 200 OK 但是，被 mod\_evasive 拒绝的将返回以下内容：HTTP/1.1 403 Forbidden 以下脚本会尽可能迅速地向本地主机（127.0.0.1，localhost）的 80 端口发送 HTTP 请求，并打印出每个请求的响应代码。你所要做的就是把下面的 bash 脚本复制到一个文件中，例如 mod_evasive_test.sh：#!/bin/bash set -e for i in {1..50}; do curl -s -I 127.0.0.1 | head -n 1 done 这个脚本的部分含义如下：curl - 这是一个发出网络请求的命令。-s - 隐藏进度表。-I - 仅显示响应头部信息。head - 打印文件的第一部分。-n 1 - 只显示第一行。然后赋予其执行权限：chmod 755 mod_evasive_test.sh 在启用 mod\_evasive 之前，脚本运行时，将会看到 50 行 “HTTP / 1.1 200 OK” 的返回值。但是，启用 mod\_evasive 后，您将看到以下内容：HTTP/1.1 200 OK HTTP/1.1 200 OK HTTP/1.1 403 Forbidden HTTP/1.1 403 Forbidden HTTP/1.1 403 Forbidden HTTP/1.1 403 Forbidden HTTP/1.1 403 Forbidden ... 前两个请求被允许，但是在同一秒内第三个请求发出时，mod\_evasive 拒绝了任何进一步的请求。您还将收到一封电子邮件（邮件地址在选项 DOSEmailNotify 中设置），通知您有 DOS 攻击被检测到。mod\_evasive 现在已经在保护您的网站啦！via: https://bash-prompt.net/guides/mod_proxy/作者：Elliot Cooper 译者：jessie-pang 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
系统管理员通常需要探索在不同负载对应用性能的影响。这意味着必须要重复地人为创造负载。当然，你可以通过专门的工具来实现，但有时你可能不想也无法安装新工具。每个 Linux 发行版中都自带有创建负载的工具。他们不如专门的工具那么灵活，但它们是现成的，而且无需专门学习。CPU下面命令会创建 CPU 负荷，方法是通过压缩随机数据并将结果发送到 /dev/null：cat /dev/urandom | gzip -9 > /dev/null 如果你想要更大的负荷，或者系统有多个核，那么只需要对数据进行压缩和解压就行了，像这样：cat /dev/urandom | gzip -9 | gzip -d | gzip -9 | gzip -d > /dev/null 按下 CTRL+C 来终止进程。内存占用下面命令会减少可用内存的总量。它是通过在内存中创建文件系统然后往里面写文件来实现的。你可以使用任意多的内存，只需哟往里面写入更多的文件就行了。首先，创建一个挂载点，然后将 ramfs 文件系统挂载上去：mkdir z mount -t ramfs ramfs z/ 第二步，使用 dd 在该目录下创建文件。这里我们创建了一个 128M 的文件：dd if=/dev/zero of=z/file bs=1M count=128 文件的大小可以通过下面这些操作符来修改：bs= 块大小。可以是任何数字后面接上 B（表示字节），K（表示 KB），M（ 表示 MB）或者 G（表示 GB）。count= 要写多少个块。磁盘 I/O创建磁盘 I/O 的方法是先创建一个文件，然后使用 for 循环来不停地拷贝它。下面使用命令 dd 创建了一个全是零的 1G 大小的文件：dd if=/dev/zero of=loadfile bs=1M count=1024 下面命令用 for 循环执行 10 次操作。每次都会拷贝 loadfile 来覆盖 loadfile1：for i in {1..10}; do cp loadfile loadfile1; done 通过修改 {1..10} 中的第二个参数来调整运行时间的长短。（LCTT 译注：你的 Linux 系统中的默认使用的 cp 命令很可能是 cp -i 的别名，这种情况下覆写会提示你输入 y 来确认，你可以使用 -f 参数的 cp 命令来覆盖此行为，或者直接用 /bin/cp 命令。）若你想要一直运行，直到按下 CTRL+C 来停止，则运行下面命令：while true; do cp loadfile loadfile1; done via: https://bash-prompt.net/guides/create-system-load/作者：Elliot Cooper 译者：lujun9972 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
bash 命令通常单线程运行。这意味着所有的处理工作只在单个 CPU 上执行。随着 CPU 规模的扩大以及核心数目的增加，这意味着只有一小部分的 CPU 资源用于处理你的工作。当我们的工作受制于 CPU 处理数据的速度时，这些未使用的 CPU 资源能产生很大的效用。这种情况在进行多媒体转换（比如图片和视频转换）以及数据压缩中经常遇到。本文中，我们将会使用 parallel 程序。parallel 会接受一个列表作为输入，然后在所有 CPU 核上并行地执行命令来处理该列表。Parallel 甚至会按顺序将结果输出到标准输出中，因此它可以用在管道中作为其他命令的标准输入。如何使用 parallelparallel 在标准输入中读取一个列表作为输入，然后创建多个指定命令的进程来处理这个列表，其格式为：list | parallel command 这里的 list 可以由任何常见的 bash 命令创建，例如：cat、grep、find。这些命令的结果通过管道从它们的标准输出传递到 parallel 的标准输入，像这样：find . -type f -name "*.log" | parallel 跟 find 中使用 -exec 类似，parallel 使用 {} 来表示输入列表中的每个元素。下面这个例子中，parallel 会使用 gzip 压缩所有 find 命令输出的文件：find . -type f -name "*.log" | parallel gzip {} 下面这些实际的使用 parallel 的例子可能会更容易理解一些。使用 parallel 来进行 JPEG 压缩在这个例子中，我收集了一些比较大的 .jpg 文件（大约 10MB 大小），要用 Mozilla 出品的 JPEG 图像压缩工具 MozJPEG 来进行处理。该工具会在尝试保持图像质量的同时减少 JPEG 图像文件的大小。这对降低网页加载时间很重要。下面是一个普通的 find 命令，用来找出当前目录中的所有 .jpg 文件，然后通过 MozJPEG 包中提供的图像压缩工具 （cjpeg） 对其进行处理：find . -type f -name "*.jpg" -exec cjpeg -outfile LoRes/{} {} ';' 总共耗时 0m44.114s。该命令运行时的 top 看起来是这样的：你可以看到，虽然有 8 个核可用，但实际只有单个线程在用单个核。下面用 parallel 来运行相同的命令：find . -type f -name "*.jpg" | parallel cjpeg -outfile LoRes/{} {} 这次压缩所有图像的时间缩减到了 0m10.814s。从 top 显示中可以很清楚地看出不同：所有 CPU 核都满负荷运行，有 8 个线程对应使用 8 个 CPU 核。parallel 与 gzip 连用如果你需要压缩多个文件而不是一个大文件，那么 parallel 就能用来提高处理速度。如果你需要压缩单个文件而同时又想要利用所有的 CPU 核的话，那么你应该 gzip 的多线程替代品 pigz。首先，我用随机数据创建了 100 个大约 1GB 的文件：for i in {1..100}; do dd if=/dev/urandom of=file-$i bs=1MB count=10; done 然而我用 find -exec 命令来进行压缩：find . -type f -name "file*" -exec gzip {} ';' 总共耗时 0m28.028s，而且也是只利用了单核。换成 parallel 版本：find . -type f -name "file*" | parallel gzip {} 耗时减少到了 0m5.774s。parallel 是一款非常好用的工具，应该加入到你的系统管理工具包中，在合适的场合它能帮你节省大量的时间。via: https://bash-prompt.net/guides/parallell-bash/作者：Elliot Cooper 译者：lujun9972 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
本指南中所谓的服务器被入侵或者说被黑了的意思，是指未经授权的人或程序为了自己的目的登录到服务器上去并使用其计算资源，通常会产生不好的影响。免责声明：若你的服务器被类似 NSA 这样的国家机关或者某个犯罪集团入侵，那么你并不会注意到有任何问题，这些技术也无法发觉他们的存在。然而，大多数被攻破的服务器都是被类似自动攻击程序这样的程序或者类似“脚本小子”这样的廉价攻击者，以及蠢蛋罪犯所入侵的。这类攻击者会在访问服务器的同时滥用服务器资源，并且不怎么会采取措施来隐藏他们正在做的事情。被入侵服务器的症状当服务器被没有经验攻击者或者自动攻击程序入侵了的话，他们往往会消耗 100% 的资源。他们可能消耗 CPU 资源来进行数字货币的采矿或者发送垃圾邮件，也可能消耗带宽来发动 DoS 攻击。因此出现问题的第一个表现就是服务器 “变慢了”。这可能表现在网站的页面打开的很慢，或者电子邮件要花很长时间才能发送出去。那么你应该查看那些东西呢?检查 1 - 当前都有谁在登录?你首先要查看当前都有谁登录在服务器上。发现攻击者登录到服务器上进行操作并不复杂。其对应的命令是 w。运行 w 会输出如下结果： 08:32:55 up 98 days, 5:43, 2 users, load average: 0.05, 0.03, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 113.174.161.1 08:26 0.00s 0.03s 0.02s ssh root@coopeaa12 root pts/1 78.31.109.1 08:26 0.00s 0.01s 0.00s w 第一个 IP 是英国 IP，而第二个 IP 是越南 IP。这个不是个好兆头。停下来做个深呼吸, 不要恐慌之下只是干掉他们的 SSH 连接。除非你能够防止他们再次进入服务器，否则他们会很快进来并踢掉你，以防你再次回去。请参阅本文最后的“被入侵之后怎么办”这一章节来看找到了被入侵的证据后应该怎么办。whois 命令可以接一个 IP 地址然后告诉你该 IP 所注册的组织的所有信息，当然就包括所在国家的信息。检查 2 - 谁曾经登录过?Linux 服务器会记录下哪些用户，从哪个 IP，在什么时候登录的以及登录了多长时间这些信息。使用 last 命令可以查看这些信息。输出类似这样：root pts/1 78.31.109.1 Thu Nov 30 08:26 still logged in root pts/0 113.174.161.1 Thu Nov 30 08:26 still logged in root pts/1 78.31.109.1 Thu Nov 30 08:24 - 08:26 (00:01) root pts/0 113.174.161.1 Wed Nov 29 12:34 - 12:52 (00:18) root pts/0 14.176.196.1 Mon Nov 27 13:32 - 13:53 (00:21) 这里可以看到英国 IP 和越南 IP 交替出现，而且最上面两个 IP 现在还处于登录状态。如果你看到任何未经授权的 IP，那么请参阅最后章节。登录后的历史记录会记录到二进制的 /var/log/wtmp 文件中（LCTT 译注：这里作者应该写错了，根据实际情况修改），因此很容易被删除。通常攻击者会直接把这个文件删掉，以掩盖他们的攻击行为。 因此, 若你运行了 last 命令却只看得见你的当前登录，那么这就是个不妙的信号。如果没有登录历史的话，请一定小心，继续留意入侵的其他线索。检查 3 - 回顾命令历史这个层次的攻击者通常不会注意掩盖命令的历史记录，因此运行 history 命令会显示出他们曾经做过的所有事情。 一定留意有没有用 wget 或 curl 命令来下载类似垃圾邮件机器人或者挖矿程序之类的非常规软件。命令历史存储在 ~/.bash_history 文件中，因此有些攻击者会删除该文件以掩盖他们的所作所为。跟登录历史一样，若你运行 history 命令却没有输出任何东西那就表示历史文件被删掉了。这也是个不妙的信号，你需要很小心地检查一下服务器了。（LCTT 译注，如果没有命令历史，也有可能是你的配置错误。）检查 4 - 哪些进程在消耗 CPU？你常遇到的这类攻击者通常不怎么会去掩盖他们做的事情。他们会运行一些特别消耗 CPU 的进程。这就很容易发现这些进程了。只需要运行 top 然后看最前的那几个进程就行了。这也能显示出那些未登录进来的攻击者。比如，可能有人在用未受保护的邮件脚本来发送垃圾邮件。如果你最上面的进程对不了解，那么你可以 Google 一下进程名称，或者通过 losf 和 strace 来看看它做的事情是什么。使用这些工具，第一步从 top 中拷贝出进程的 PID，然后运行：strace -p PID 这会显示出该进程调用的所有系统调用。它产生的内容会很多，但这些信息能告诉你这个进程在做什么。lsof -p PID 这个程序会列出该进程打开的文件。通过查看它访问的文件可以很好的理解它在做的事情。检查 5 - 检查所有的系统进程消耗 CPU 不严重的未授权进程可能不会在 top 中显露出来，不过它依然可以通过 ps 列出来。命令 ps auxf 就能显示足够清晰的信息了。你需要检查一下每个不认识的进程。经常运行 ps （这是个好习惯）能帮助你发现奇怪的进程。检查 6 - 检查进程的网络使用情况iftop 的功能类似 top，它会排列显示收发网络数据的进程以及它们的源地址和目的地址。类似 DoS 攻击或垃圾机器人这样的进程很容易显示在列表的最顶端。检查 7 - 哪些进程在监听网络连接?通常攻击者会安装一个后门程序专门监听网络端口接受指令。该进程等待期间是不会消耗 CPU 和带宽的，因此也就不容易通过 top 之类的命令发现。lsof 和 netstat 命令都会列出所有的联网进程。我通常会让它们带上下面这些参数：lsof -i netstat -plunt 你需要留意那些处于 LISTEN 和 ESTABLISHED 状态的进程，这些进程要么正在等待连接（LISTEN），要么已经连接（ESTABLISHED）。如果遇到不认识的进程，使用 strace 和 lsof 来看看它们在做什么东西。被入侵之后该怎么办呢?首先，不要紧张，尤其当攻击者正处于登录状态时更不能紧张。你需要在攻击者警觉到你已经发现他之前夺回机器的控制权。如果他发现你已经发觉到他了，那么他可能会锁死你不让你登陆服务器，然后开始毁尸灭迹。如果你技术不太好那么就直接关机吧。你可以在服务器上运行 shutdown -h now 或者 systemctl poweroff 这两条命令之一。也可以登录主机提供商的控制面板中关闭服务器。关机后，你就可以开始配置防火墙或者咨询一下供应商的意见。如果你对自己颇有自信，而你的主机提供商也有提供上游防火墙，那么你只需要以此创建并启用下面两条规则就行了：只允许从你的 IP 地址登录 SSH。封禁除此之外的任何东西，不仅仅是 SSH，还包括任何端口上的任何协议。这样会立即关闭攻击者的 SSH 会话，而只留下你可以访问服务器。如果你无法访问上游防火墙，那么你就需要在服务器本身创建并启用这些防火墙策略，然后在防火墙规则起效后使用 kill 命令关闭攻击者的 SSH 会话。（LCTT 译注：本地防火墙规则 有可能不会阻止已经建立的 SSH 会话，所以保险起见，你需要手工杀死该会话。）最后还有一种方法，如果支持的话，就是通过诸如串行控制台之类的带外连接登录服务器，然后通过 systemctl stop network.service 停止网络功能。这会关闭所有服务器上的网络连接，这样你就可以慢慢的配置那些防火墙规则了。重夺服务器的控制权后，也不要以为就万事大吉了。不要试着修复这台服务器，然后接着用。你永远不知道攻击者做过什么，因此你也永远无法保证这台服务器还是安全的。最好的方法就是拷贝出所有的数据，然后重装系统。（LCTT 译注：你的程序这时已经不可信了，但是数据一般来说没问题。）via: https://bash-prompt.net/guides/server-hacked/作者：Elliot Cooper 译者：lujun9972 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出