Phil Zona 发布的文章

Hidden features of Linux

使用 Linux 最酷的事情之一就是随着时间的推移,你可以不断获得新的知识。每天,你都可能会遇到一个新的实用工具,或者只是一个不太熟悉的奇技淫巧,但是却非常有用。这些零碎的东西并不总是能够改变生活,但是却是专业知识的基础。

即使是专家,也不可能事事皆知。无论你有多少经验,可能总会有更多的东西需要你去学习。所以,在这儿我列出了七件关于 Linux 你可能不知道的事情。

一个查找命令历史的交互模式

你可能对 history 命令非常熟悉,它会读取 bash 历史,然后以编号列表的方式输出到标准输出(stdout)。然而,如果你在 curl 命令的海洋里寻找一个特定的链接(URL),那么这个列表并不总是那么容易阅读的。

你还可以有另一个选择,Linux 有一个交互式的反向搜索可以帮助你解决这个问题。你可以通过快捷键 ctrl+r启动交互模式,然后进入一个交互提示中,它将会根据你提供的字符串来向后搜索 bash 历史,你可以通过再次按下 ctrl+r 向后搜索更老的命令,或者按下 ctrl+s 向前搜索。

注意,ctrl+s 有时会与 XON/XOFF 流控制冲突,即 XON/XOFF 流控制也会使用该快捷键。你可以通过运行 stty -ixon 命令来禁用该快捷键。在你的个人电脑上,这通常是有用的,但是在禁用前,确保你不需要 XON/XOFF 。

Cron 不是安排任务的唯一方式

Cron 任务对于任何水平的系统管理员,无论是毫无经验的初学者,还是经验丰富的专家来说,都是非常有用的。但是,如果你需要安排一个一次性的任务,那么 at 命令为你提供了一个快捷的方式来创建任务,从而你不需要接触 crontab 。

at 命令的运行方式是在后面紧跟着你想要运行任务的运行时间。时间是灵活的,因为它支持许多时间格式。包括下面这些例子:

at 12:00 PM September 30 2017
at now + 1 hour
at 9:00 AM tomorrow

当你以带参数的方式输入 at 命令以后,将会提示你该命令将在你的 Linux 系统上运行。这可能是一个备份脚本,一套维护任务,或者甚至是一个普通的 bash 命令。如果要结束任务,可以按 ctrl+d

另外,你可以使用 atq 命令查看当前用户的所有任务,或者使用 sudo atq 查看所有用户的任务。它将会展示出所有排定好的任务,并且每个任务都伴有一个 ID 。如果你想取消一个排定好的任务,可以使用 atrm 命令,并且以任务 ID 作为参数。

你可以按照功能搜索命令,而不仅仅是通过名字

记住命令的名字非常困难,特别是对于初学者来说。幸运的是,Linux 附带了一个通过名字和描述来搜索 man 页面的工具。

下次,如果你没有记住你想要使用的工具的名称,你可以尝试使用 apropos 命令加上你想要干的事情的描述。比如,apropos build filesystem 将会返回一系列名字和描述包括了 “build” 和 “filesystem” 单词的工具。

apropos 命令接受一个或多个字符串作为参数,但同时它也有其他参数,比如你可以使用 -r 参数,从而通过正则表达式来搜索。

一个允许你来管理系统版本的替代系统

如果你曾进行过软件开发,你就会明白跨项目管理不同版本的语言的支持的重要性。许多 Linux 发行版都有工具可以来处理不同的内建版本。

可执行文件比如 java 往往符号链接到目录 /etc/alternatives 下。反过来,该目录会将符号链接存储为二进制文件并提供一个管理这些链接的接口。Java 可能是替代系统最常管理的语言,但是,经过一些配置,它也可以作为其他应用程序替代品,比如 NVM 和 RVM (NVM 和 RVM 分别是 NodeJS 和 Ruby 的版本管理器)。

在基于 Debian 的系统中,你可以使用 update-alternatives 命令创建和管理这些链接。在 CentOS 中,这个工具就叫做 alternatives 。通过更改你的 alternatives 文件中的链接,你便可以安装一个语言的多个版本,并且在不同的情况下使用不同的二进制。这个替代系统也提供了对任何你可能在命令行运行的程序的支持。

shred 命令是更加安全的删除文件方式

我们大多数时候总是使用 rm 命令来删除文件。但是文件去哪儿了呢?真相是 rm 命令所做的事情并不是像你所想像的那样,它仅仅删除了文件系统和硬盘上的数据的硬链接。硬盘上的数据依旧存在,直到被另一个应用重写覆盖。对于非常敏感的数据来说,这会带来一个很大的安全隐患。

shred 命令是 rm 命令的升级版。当你使用 shred 命令删除一个文件之后,文件中的数据会被多次随机覆写。甚至有一个选项可以在随机覆写之后对所有的数据进行清零。

如果你想安全的删除一个文件并且以零覆盖,那么可以使用下面的命令:

shred -u -z [file name]

同时,你也可以使用 -n 选项和一个数字作为参数,从而指定在随机覆盖数据的时候迭代多少次。

通过自动更正来避免输入很长的无效文件路径

有多少次,你输入一个文件的绝对路径,然而却看到“没有该文件或目录”的消息。任何人都会明白输入一个很长的字符串的痛苦。幸运的是,有一个很简单的解决办法。

内建的 shopt 命令允许你设置不同的选项来改变 shell 的行为。设置 cdspell 选项是避免输入文件路径时一个字母出错的头痛的一个简单方式。你可以通过运行 shopt -s cdspell 命令来启用该选项。启用该选项后,当你想要切换目录时,会自动更正为最匹配的目录。

Shell 选项是节省时间的一个好方法(更不用说减少麻烦),此外还有许许多多的其他选项。如果想查看你的系统中所有选项的完整列表,可以运行不带参数的 shopt 命令。需要注意的是,这是 bash 的特性,如果你运行 zsh 或者其他可供选择的 shell,可能无法使用。

通过子 shell 返回到当前目录

如果你曾经配置过一个比较复杂的系统,那么你可能会发现你需要频繁的更换目录,从而很难跟踪你所在的位置。如果在运行完一个命令后自动返回到当前位置,不是很好吗?

Linux 系统实际上提供了一个解决该问题的方法,并且非常简单。如果你想通过 cd 命令进入另一个目录完成一些任务,然后再返回当前工作目录,那么你可以将命令置于括号中。你可以在你的 Linux 系统上尝试下面这个命令。记住你当前的工作目录,然后运行:

(cd /etc && ls -a)

该命令会输出 /etc 目录的内容。现在,检查你的当前工作目录。它和执行该命令前的目录一样,而不是 /etc 目录。

它是如何工作的呢?运行一个括号中的命令会创建一个子 shell 或一个当前 shell 进程的复刻副本。该子 shell 可以访问所有的父变量,反之则不行。所以请记住,你是在运行一个非常复杂的单行命令。

在并行处理中经常使用子 shell ,但是在命令行中,它也能为你带来同样的力量,从而使你在浏览文件系统时更加容易。


作者简介:

Phil Zona 是 Linux Academy 的技术作家。他编写了 AWS、Microsoft Azure 和 Linux 系统管理的指南和教程。他同时也管理着 Cloud Assessments 博客,该博客旨在帮助个人通过技术实现他们的事业目标。


via: http://opensourceforu.com/2017/09/top-7-things-linux-may-not-known-far/

作者:PHIL ZONA 译者:ucasFL 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

现在让我们强化你的服务器以防止未授权访问。

经常升级系统

保持最新的软件是你可以在任何操作系统上采取的最大的安全预防措施。软件更新的范围从关键漏洞补丁到小 bug 的修复,许多软件漏洞实际上是在它们被公开的时候得到修补的。

自动安全更新

有一些用于服务器上自动更新的参数。Fedora 的 Wiki 上有一篇很棒的剖析自动更新的利弊的文章,但是如果你把它限制到安全更新上,自动更新的风险将是最小的。

自动更新的可行性必须你自己判断,因为它归结为在你的服务器上做什么。请记住,自动更新仅适用于来自仓库的包,而不是自行编译的程序。你可能会发现一个复制了生产服务器的测试环境是很有必要的。可以在部署到生产环境之前,在测试环境里面更新来检查问题。

添加一个受限用户账户

到目前为止,你已经作为 root 用户访问了你的服务器,它有无限制的权限,可以执行任何命令 - 甚至可能意外中断你的服务器。 我们建议创建一个受限用户帐户,并始终使用它。 管理任务应该使用 sudo 来完成,它可以临时提升受限用户的权限,以便管理你的服务器。

不是所有的 Linux 发行版都在系统上默认包含 sudo,但大多数都在其软件包仓库中有 sudo。 如果得到这样的输出 sudo:command not found,请在继续之前安装 sudo

要添加新用户,首先通过 SSH 登录到你的服务器。

CentOS / Fedora

1、 创建用户,用你想要的名字替换 example_user,并分配一个密码:

useradd example_user && passwd example_user

2、 将用户添加到具有 sudo 权限的 wheel 组:

usermod -aG wheel example_user

Ubuntu

1、 创建用户,用你想要的名字替换 example_user。你将被要求输入用户密码:

adduser example_user

2、 添加用户到 sudo 组,这样你就有管理员权限了:

adduser example_user sudo

Debian

1、 Debian 默认的包中没有 sudo, 使用 apt-get 来安装:

apt-get install sudo

2、 创建用户,用你想要的名字替换 example_user。你将被要求输入用户密码:

adduser example_user

3、 添加用户到 sudo 组,这样你就有管理员权限了:

adduser example_user sudo

创建完有限权限的用户后,断开你的服务器连接:

exit

重新用你的新用户登录。用你的用户名代替 example_user,用你的服务器 IP 地址代替例子中的 IP 地址:

ssh [email protected]

现在你可以用你的新用户帐户管理你的服务器,而不是 root。 几乎所有超级用户命令都可以用 sudo(例如:sudo iptables -L -nv)来执行,这些命令将被记录到 /var/log/auth.log 中。

加固 SSH 访问

默认情况下,密码认证用于通过 SSH 连接到您的服务器。加密密钥对更加安全,因为它用私钥代替了密码,这通常更难以暴力破解。在本节中,我们将创建一个密钥对,并将服务器配置为不接受 SSH 密码登录。

创建验证密钥对

1、这是在你本机上完成的,不是在你的服务器上,这里将创建一个 4096 位的 RSA 密钥对。在创建过程中,您可以选择使用密码加密私钥。这意味着它不能在没有输入密码的情况下使用,除非将密码保存到本机桌面的密钥管理器中。我们建议您使用带有密码的密钥对,但如果你不想使用密码,则可以将此字段留空。

Linux / OS X

如果你已经创建了 RSA 密钥对,则这个命令将会覆盖它,这可能会导致你不能访问其它的操作系统。如果你已创建过密钥对,请跳过此步骤。要检查现有的密钥,请运行 ls〜/ .ssh / id_rsa *
ssh-keygen -b 4096

在输入密码之前,按下 回车使用 /home/your_username/.ssh 中的默认名称 id_rsaid_rsa.pub

Windows

这可以使用 PuTTY 完成,在我们指南中已有描述:使用 SSH 公钥验证

2、将公钥上传到您的服务器上。 将 example_user 替换为你用来管理服务器的用户名称,将 203.0.113.10 替换为你的服务器的 IP 地址。

Linux

在本机上:

ssh-copy-id [email protected]

OS X

在你的服务器上(用你的权限受限用户登录):

mkdir -p ~/.ssh && sudo chmod -R 700 ~/.ssh/

在本机上:

scp ~/.ssh/id_rsa.pub [email protected]:~/.ssh/authorized_keys
如果相对于 scp 你更喜欢 ssh-copy-id 的话,那么它也可以在 Homebrew 中找到。使用 brew install ssh-copy-id 安装。

Windows

  • 选择 1:使用 WinSCP 来完成。 在登录窗口中,输入你的服务器的 IP 地址作为主机名,以及非 root 的用户名和密码。单击“登录”连接。

一旦 WinSCP 连接后,你会看到两个主要部分。 左边显示本机上的文件,右边显示服务区上的文件。 使用左侧的文件浏览器,导航到你已保存公钥的文件,选择公钥文件,然后点击上面工具栏中的“上传”。

系统会提示你输入要将文件放在服务器上的路径。 将文件上传到 /home/example_user/.ssh /authorized_keys,用你的用户名替换 example_user

  • 选择 2:将公钥直接从 PuTTY 键生成器复制到连接到你的服务器中(作为非 root 用户):
mkdir ~/.ssh; nano ~/.ssh/authorized_keys

上面命令将在文本编辑器中打开一个名为 authorized_keys 的空文件。 将公钥复制到文本文件中,确保复制为一行,与 PuTTY 所生成的完全一样。 按下 CTRL + X,然后按下 Y,然后回车保存文件。

最后,你需要为公钥目录和密钥文件本身设置权限:

sudo chmod 700 -R ~/.ssh && chmod 600 ~/.ssh/authorized_keys

这些命令通过阻止其他用户访问公钥目录以及文件本身来提供额外的安全性。有关它如何工作的更多信息,请参阅我们的指南如何修改文件权限

3、 现在退出并重新登录你的服务器。如果你为私钥指定了密码,则需要输入密码。

SSH 守护进程选项

1、 不允许 root 用户通过 SSH 登录。 这要求所有的 SSH 连接都是通过非 root 用户进行。当以受限用户帐户连接后,可以通过使用 sudo 或使用 su - 切换为 root shell 来使用管理员权限。

# Authentication:
...
PermitRootLogin no

2、 禁用 SSH 密码认证。 这要求所有通过 SSH 连接的用户使用密钥认证。根据 Linux 发行版的不同,它可能需要添加 PasswordAuthentication 这行,或者删除前面的 # 来取消注释。

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no
如果你从许多不同的计算机连接到服务器,你可能想要继续启用密码验证。这将允许你使用密码进行身份验证,而不是为每个设备生成和上传密钥对。

3、 只监听一个互联网协议。 在默认情况下,SSH 守护进程同时监听 IPv4 和 IPv6 上的传入连接。除非你需要使用这两种协议进入你的服务器,否则就禁用你不需要的。 这不会禁用系统范围的协议,它只用于 SSH 守护进程。

使用选项:

  • AddressFamily inet 只监听 IPv4。
  • AddressFamily inet6 只监听 IPv6。

默认情况下,AddressFamily 选项通常不在 sshd_config 文件中。将它添加到文件的末尾:

echo 'AddressFamily inet' | sudo tee -a /etc/ssh/sshd_config

4、 重新启动 SSH 服务以加载新配置。

如果你使用的 Linux 发行版使用 systemd(CentOS 7、Debian 8、Fedora、Ubuntu 15.10+)

sudo systemctl restart sshd

如果您的 init 系统是 SystemV 或 Upstart(CentOS 6、Debian 7、Ubuntu 14.04):

sudo service ssh restart

使用 Fail2Ban 保护 SSH 登录

Fail2Ban 是一个应用程序,它会在太多的失败登录尝试后禁止 IP 地址登录到你的服务器。由于合法登录通常不会超过三次尝试(如果使用 SSH 密钥,那不会超过一个),因此如果服务器充满了登录失败的请求那就表示有恶意访问。

Fail2Ban 可以监视各种协议,包括 SSH、HTTP 和 SMTP。默认情况下,Fail2Ban 仅监视 SSH,并且因为 SSH 守护程序通常配置为持续运行并监听来自任何远程 IP 地址的连接,所以对于任何服务器都是一种安全威慑。

有关安装和配置 Fail2Ban 的完整说明,请参阅我们的指南:使用 Fail2ban 保护服务器

删除未使用的面向网络的服务

大多数 Linux 发行版都安装并运行了网络服务,监听来自互联网、回环接口或两者兼有的传入连接。 将不需要的面向网络的服务从系统中删除,以减少对运行进程和对已安装软件包攻击的概率。

查明运行的服务

要查看服务器中运行的服务:

sudo netstat -tulpn
如果默认情况下 netstat 没有包含在你的 Linux 发行版中,请安装软件包 net-tools 或使用 ss -tulpn 命令。

以下是 netstat 的输出示例。 请注意,因为默认情况下不同发行版会运行不同的服务,你的输出将有所不同:

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      7315/rpcbind
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3277/sshd
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      3179/exim4
tcp        0      0 0.0.0.0:42526           0.0.0.0:*               LISTEN      2845/rpc.statd
tcp6       0      0 :::48745                :::*                    LISTEN      2845/rpc.statd
tcp6       0      0 :::111                  :::*                    LISTEN      7315/rpcbind
tcp6       0      0 :::22                   :::*                    LISTEN      3277/sshd
tcp6       0      0 ::1:25                  :::*                    LISTEN      3179/exim4
udp        0      0 127.0.0.1:901           0.0.0.0:*                           2845/rpc.statd
udp        0      0 0.0.0.0:47663           0.0.0.0:*                           2845/rpc.statd
udp        0      0 0.0.0.0:111             0.0.0.0:*                           7315/rpcbind
udp        0      0 192.0.2.1:123           0.0.0.0:*                           3327/ntpd
udp        0      0 127.0.0.1:123           0.0.0.0:*                           3327/ntpd
udp        0      0 0.0.0.0:123             0.0.0.0:*                           3327/ntpd
udp        0      0 0.0.0.0:705             0.0.0.0:*                           7315/rpcbind
udp6       0      0 :::111                  :::*                                7315/rpcbind
udp6       0      0 fe80::f03c:91ff:fec:123 :::*                                3327/ntpd
udp6       0      0 2001:DB8::123           :::*                                3327/ntpd
udp6       0      0 ::1:123                 :::*                                3327/ntpd
udp6       0      0 :::123                  :::*                                3327/ntpd
udp6       0      0 :::705                  :::*                                7315/rpcbind
udp6       0      0 :::60671                :::*                                2845/rpc.statd

netstat 告诉我们服务正在运行 RPCrpc.statdrpcbind)、SSH(sshd)、NTPdatentpd)和Eximexim4)。

TCP

请参阅 netstat 输出的 Local Address 那一列。进程 rpcbind 正在侦听 0.0.0.0:111:::111,外部地址是 0.0.0.0:* 或者 :::* 。这意味着它从任何端口和任何网络接口接受来自任何外部地址(IPv4 和 IPv6)上的其它 RPC 客户端的传入 TCP 连接。 我们看到类似的 SSH,Exim 正在侦听来自回环接口的流量,如所示的 127.0.0.1 地址。

UDP

UDP 套接字是无状态的,这意味着它们只有打开或关闭,并且每个进程的连接是独立于前后发生的连接。这与 TCP 的连接状态(例如 LISTENESTABLISHEDCLOSE_WAIT)形成对比。

我们的 netstat输出说明 NTPdate :1)接受服务器的公网 IP 地址的传入连接;2)通过本地主机进行通信;3)接受来自外部的连接。这些连接是通过端口 123 进行的,同时支持 IPv4 和 IPv6。我们还看到了 RPC 打开的更多的套接字。

查明该移除哪个服务

如果你在没有启用防火墙的情况下对服务器进行基本的 TCP 和 UDP 的 nmap 扫描,那么在打开端口的结果中将出现 SSH、RPC 和 NTPdate 。通过配置防火墙,你可以过滤掉这些端口,但 SSH 除外,因为它必须允许你的传入连接。但是,理想情况下,应该禁用未使用的服务。

  • 你可能主要通过 SSH 连接管理你的服务器,所以让这个服务需要保留。如上所述,RSA 密钥和 Fail2Ban 可以帮助你保护 SSH。
  • NTP 是服务器计时所必需的,但有个替代 NTPdate 的方法。如果你喜欢不开放网络端口的时间同步方法,并且你不需要纳秒精度,那么你可能有兴趣用 OpenNTPD 来代替 NTPdate。
  • 然而,Exim 和 RPC 是不必要的,除非你有特定的用途,否则应该删除它们。
本节针对 Debian 8。默认情况下,不同的 Linux 发行版具有不同的服务。如果你不确定某项服务的功能,请尝试搜索互联网以了解该功能是什么,然后再尝试删除或禁用它。

卸载监听的服务

如何移除包取决于发行版的包管理器:

Arch

sudo pacman -Rs package_name

CentOS

sudo yum remove package_name

Debian / Ubuntu

sudo apt-get purge package_name

Fedora

sudo dnf remove package_name

再次运行 sudo netstat -tulpn,你看到监听的服务就只会有 SSH(sshd)和 NTP(ntpdate,网络时间协议)。

配置防火墙

使用防火墙阻止不需要的入站流量能为你的服务器提供一个高效的安全层。 通过指定入站流量,你可以阻止入侵和网络测绘。 最佳做法是只允许你需要的流量,并拒绝一切其他流量。请参阅我们的一些关于最常见的防火墙程序的文档:

  • iptables 是 netfilter 的控制器,它是 Linux 内核的包过滤框架。 默认情况下,iptables 包含在大多数 Linux 发行版中。
  • firewallD 是可用于 CentOS/Fedora 系列发行版的 iptables 控制器。
  • UFW 为 Debian 和 Ubuntu 提供了一个 iptables 前端。

接下来

这些是加固 Linux 服务器的最基本步骤,但是进一步的安全层将取决于其预期用途。 其他技术可以包括应用程序配置,使用入侵检测或者安装某个形式的访问控制

现在你可以按你的需求开始设置你的服务器了。


via: https://www.linode.com/docs/security/securing-your-server/

作者:Phil Zona 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出