Skip to content

Latest commit

 

History

History
1821 lines (1280 loc) · 95 KB

File metadata and controls

1821 lines (1280 loc) · 95 KB

二、保护用户帐户

管理用户是信息技术管理中更具挑战性的方面之一。您需要确保用户可以随时访问他们的资料,并且他们可以执行完成工作所需的任务。您还需要确保用户的资料始终不会被未经授权的用户窃取,并且用户不能执行任何不符合其工作描述的任务。这是一项艰巨的任务,但我们的目标是证明这是可行的。在本章中,我们将了解如何锁定用户帐户和用户凭据,以保护他们免受攻击者和窥探者的攻击。我们还将研究如何防止用户为了执行工作而拥有更多的特权。

本章涉及的具体主题如下:

  • 以 root 用户身份登录的危险
  • 使用sudo的优点
  • 为完全管理用户和仅具有某些委派权限的用户设置sudo权限
  • 高级使用技巧和诀窍sudo
  • 锁定用户的主目录
  • 强制实施强密码标准
  • 设置和实施密码和帐户过期
  • 防止暴力密码攻击
  • 锁定用户帐户
  • 设置安全横幅
  • 检测泄露的密码
  • 了解中央用户管理系统

以 root 用户身份登录的危险

与 Windows 相比,Unix 和 Linux 操作系统的一个巨大优势是,Unix 和 Linux 在将特权管理帐户与普通用户帐户分开方面做得更好。事实上,旧版本的 Windows 如此容易受到安全问题(如免下车病毒感染)影响的一个原因是,通常的做法是设置具有管理权限的用户帐户,而没有新版本 Windows 中的用户访问控制(【UAC】)的保护。(即使在 UAC,Windows 系统仍然会被感染,只是没有那么频繁。)使用 Unix 和 Linux,感染一个配置正确的系统要困难得多。

您可能已经知道 Unix 或 Linux 系统上的全能管理员帐户是根帐户。如果您以 root 用户身份登录,您可以对该系统执行任何想要的操作。所以你可能会想,“是的,这很方便,所以这就是我要做的。”但是,始终以根用户身份登录可能会带来大量安全问题。请考虑以下内容。以 root 用户身份登录可以执行以下操作:

  • 使您更容易意外执行对系统造成损害的操作
  • 使其他人更容易执行对系统造成损害的操作

因此,如果您总是以根用户身份登录,或者即使您只是让根用户帐户易于访问,您也可以说您为攻击者和入侵者做了大量工作。同样,想象一下,如果你是一家大公司的 Linux 管理员,允许用户执行管理任务的唯一方法是给他们所有的根密码。如果其中一个用户离开公司,会发生什么?你不会希望那个人仍然能够登录系统,所以你必须更改密码,并将新密码分发给所有其他用户。如果您只想让用户只对某些任务拥有管理员权限,而不是拥有完全的根权限,该怎么办?

我们需要的是一种机制,该机制允许用户执行管理任务,而不会承担让他们始终以根用户身份登录的风险,并且还允许用户只拥有执行特定工作所需的管理员权限。在 Linux 和 Unix 中,我们以sudo实用程序的形式拥有这种机制。

使用 sudo 的优势

如果使用得当,sudo实用程序可以大大提高系统的安全性,并且可以让管理员的工作变得更加容易。使用sudo,您可以执行以下操作:

  • 为某些用户分配完全管理权限,而只为其他用户分配执行与其各自工作直接相关的任务所需的权限。
  • 允许用户通过输入他们自己的正常用户密码来执行管理任务,这样您就不必将根密码分发给每个人和他的兄弟。
  • 让入侵者更难侵入你的系统。如果您实现sudo并禁用根用户帐户,潜在的入侵者将不知道攻击哪个帐户,因为他们不知道哪个帐户具有管理员权限。
  • 创建可以在整个企业网络中部署的sudo策略,即使该网络混合了 Unix、BSD 和 Linux 机器。
  • 提高您的审计能力,因为您将能够看到用户使用他们的管理权限在做什么。

关于最后一点,请考虑我的 CentOS 7 虚拟机的安全日志中的以下片段:

Sep 29 20:44:33 localhost sudo: donnie : TTY=pts/0 ; PWD=/home/donnie ; 
USER=root ; COMMAND=/bin/su - 
Sep 29 20:44:34 localhost su: pam_unix(su-l:session): session opened for 
user root by donnie(uid=0) 
Sep 29 20:50:39 localhost su: pam_unix(su-l:session): session closed for 
user root 

您可以看到,我使用su -登录到根命令提示符,然后注销。当我登录时,我做了几件需要 root 权限的事情,但是没有一件被记录下来。不过被记录下来的是我用sudo做的事情。也就是说,因为这台机器上的根帐户被禁用,所以我使用了我的sudo特权来让su -为我工作。让我们看另一个片段来展示更多关于它如何工作的细节:

Sep 29 20:50:45 localhost sudo: donnie : TTY=pts/0 ; PWD=/home/donnie ; 
USER=root ; COMMAND=/bin/less /var/log/secure 
Sep 29 20:55:30 localhost sudo: donnie : TTY=pts/0 ; PWD=/home/donnie ; 
USER=root ; COMMAND=/sbin/fdisk -l 
Sep 29 20:55:40 localhost sudo: donnie : TTY=pts/0 ; PWD=/home/donnie ; 
USER=root ; COMMAND=/bin/yum upgrade 
Sep 29 20:59:35 localhost sudo: donnie : TTY=tty1 ; PWD=/home/donnie ;
USER=root ; COMMAND=/bin/systemctl status sshd 
Sep 29 21:01:11 localhost sudo: donnie : TTY=tty1 ; PWD=/home/donnie ; 
USER=root ; COMMAND=/bin/less /var/log/secure

这一次,我使用我的sudo权限打开一个日志文件,查看我的硬盘配置,执行系统更新,检查安全外壳守护程序的状态,并再次查看一个日志文件。所以,如果你是我公司的安全管理员,你就能看到我是否在滥用我的sudo权力。

现在,你在问,“什么能阻止一个人仅仅做一个sudo su -来阻止他或她的恶行被发现?”那很简单。就是不给人去根命令提示符的权力。

为完全管理用户设置 sudo 权限

在我们研究如何限制用户可以做什么之前,我们先来看看如何允许用户做所有的事情,包括登录到根命令提示符。有几种方法可以做到这一点。

将用户添加到预定义的管理组

第一种方法是最简单的,将用户添加到预定义的管理员组,然后,如果还没有完成,配置sudo策略以允许该组完成其工作。除了不同的 Linux 发行家族使用不同的管理组之外,这样做很简单。

在 Unix、BSD 和大多数 Linux 系统上,您可以将用户添加到轮组中。(红帽家族的成员,包括 CentOS,都属于这一类。)当我在我的任何一台 CentOS 机器上执行groups命令时,我会得到以下信息:

[donnie@localhost ~]$ groups
donnie wheel
[donnie@localhost ~]$

这说明我是车轮组的成员。通过做sudo visudo,我将打开sudo策略文件。向下滚动,我们会看到赋予车轮组强大动力的线条:

## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL

百分号表示我们在和一个团队合作。ALL的三种外观意味着该组的成员可以作为任何用户,在部署了该策略的网络中的任何机器上执行任何命令。唯一的小问题是,为了执行sudo任务,组成员将被提示输入他们自己的正常用户帐户密码。再向下滚动一点,您将看到以下内容:

## Same thing without a password
# %wheel ALL=(ALL) NOPASSWD: ALL

如果我们注释掉前一个片段中的%wheel行,并删除这个片段中%wheel行前面的注释符号,那么轮盘组的成员将能够执行他们所有的sudo任务,而无需输入任何密码。那是我真的不推荐的东西,即使是家用的。在商业环境中,允许人们拥有无密码sudo特权是绝对不允许的。

要将现有用户添加到wheel组,请使用带有-G选项的usermod。您可能还想使用-a选项,以防止将用户从他或她所属的其他组中删除。举个例子,让我们加上玛吉:

sudo usermod -a -G wheel maggie

您也可以在创建wheel组时将用户帐户添加到该组。现在让我们为弗兰克做这件事:

sudo useradd -G wheel frank

Note that, with my usage of useradd, I'm assuming that we're working with a member of the Red Hat family, which comes with predefined default settings to create user accounts. For non-Red Hat-type distributions that use the wheel group, you'd need to either reconfigure the default settings or use extra option switches in order to create the user's home directory and to assign the correct shell. Your command then would look something like this:

sudo useradd -G wheel -m -d /home/frank -s /bin/bash frank

对于 Debian 家族的成员,包括 Ubuntu,程序是一样的,除了你会使用sudo组而不是wheel组。(这种数字,考虑到 Debian 人几乎总是随着不同的鼓点行进。)

One way in which this technique would come in handy is whenever you need to create a virtual private server on a cloud service, such as Rackspace, DigitalOcean, or Vultr. When you log in to one of those services and initially create your virtual machine, the cloud service will have you log in to that virtual machine as the root user. (This even happens with Ubuntu, even though the root user account is disabled whenever you do a local installation of Ubuntu.)

The first thing that you'll want to do in this scenario is to create a normal user account for yourself and give it full sudo privileges. Then, log out of the root account and log back in with your normal user account. You'll then want to disable the root account with this command:

sudo passwd -l root

You'll also want to do some additional configuration to lock down Secure Shell access, but we'll cover that in Chapter 6, SSH Hardening.

在 sudo 策略文件中创建一个条目

好的,如果你只是在一台机器上工作,或者你正在一个只使用这两个管理组之一的网络上部署一个sudo策略,那么将用户添加到wheel组或sudo组非常有效。但是如果你想在一个由红帽和 Ubuntu 机器混合组成的网络中部署一个sudo策略呢?或者,如果您不想在每台机器上添加用户到管理组,该怎么办?然后,只需在sudo政策文件中创建一个条目。您可以为单个用户创建条目,也可以创建用户别名。如果在 CentOS 虚拟机上执行sudo visudo,您将看到一个用户别名的注释示例:

# User_Alias ADMINS = jsmith, mikem

您可以取消对这一行的注释并添加您自己的一组用户名,或者您也可以添加一行带有您自己的用户别名的用户名。要为用户别名的成员提供完整的sudo权限,请添加另一行,如下所示:

ADMINS ALL=(ALL) ALL 

也可以只为单个用户添加一个visudo条目,在非常特殊的情况下,您可能需要这样做。这里有一个例子:

frank ALL=(ALL) ALL

但是为了便于管理,最好使用用户组或用户别名。

The sudo policy file is the /etc/sudoers file. I always hesitate to tell students that because, every once in a while, I have a student try to edit it in a regular text editor. That doesn't work though, so please don't try it. Always edit sudoers with the sudo visudo command.

为仅具有某些委派权限的用户设置 sudo

信息技术安全理念的一个基本原则是给予网络用户足够的特权,以便他们能够完成工作,但除此之外没有其他特权。所以,你会希望尽可能少的人拥有完全的sudo特权。(如果您启用了根用户帐户,您会希望知道根密码的人更少。)您还需要一种方法,根据人们的具体工作将权限委派给他们。备份管理员需要能够执行备份任务,帮助台人员需要执行用户管理任务,等等。借助sudo,您可以委派这些权限,并禁止用户从事任何其他不符合其工作描述的管理工作。

最好的解释是让你在你的 CentOS 虚拟机上打开visudo。因此,继续启动 CentOS 虚拟机,并输入以下命令:

sudo visudo

与 Ubuntu 不同,CentOS 有一个完整的注释和文档化的sudoers文件。我已经向您展示了创建ADMIN用户别名的行,您可以为其他目的创建其他用户别名。例如,您可以为备份管理员创建一个BACKUPADMINS用户别名,为 web 服务器管理员创建一个WEBADMINS用户别名,或者您想要的任何其他别名。因此,您可以添加一行,如下所示:

User_Alias SOFTWAREADMINS = vicky, cleopatra

这很好,除了维基和克利奥帕特拉仍然无能为力。您需要为用户别名分配一些职责。

如果您查看后面提到的示例用户别名,您将看到一个示例命令别名列表。其中一个例子恰好是SOFTWARE,它包含管理员安装或删除软件或更新系统所需的命令。它被注释掉了,所有其他示例命令别名也被注释掉了,因此您需要从行首删除哈希符号,然后才能使用它:

Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum

现在,只需将SOFTWARE命令别名分配给SOFTWAREADMINS用户别名即可:

SOFTWAREADMINS ALL=(ALL) SOFTWARE

维基和克利奥帕特拉都是SOFTWAREADMINS用户别名的成员,现在可以在安装了此策略的所有服务器上以 root 权限运行rpmup2dateyum命令。

在您取消对这些预定义命令别名的注释并将它们分配给用户、组或用户别名后,除了一个之外,所有这些预定义命令别名都可以使用。唯一的例外是SERVICES命令别名:

Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start, /usr/bin/systemctl stop, /usr/bin/systemctl reload, /usr/bin/systemctl restart, /usr/bin/systemctl status, /usr/bin/systemctl enable, /usr/bin/systemctl disable

这个SERVICES别名的问题在于,它还列出了systemctl命令的不同子命令。sudo的工作方式是,如果一个命令被单独列出,那么被分配的用户可以将该命令与任何子命令、选项或参数一起使用。因此,在SOFTWARE示例中,SOFTWARE用户别名的成员可以运行如下命令:

sudo yum upgrade

但是,当命令别名中列出一个带有子命令、选项或参数的命令时,所有被分配了该命令别名的人都可以运行。当SERVICES命令别名处于当前配置时,systemctl命令不起作用。为了了解原因,让我们在SERVICESADMINS用户别名中设置查理和莱昂内尔,然后取消SERVICES命令别名的注释,就像我们之前做的那样:

User_Alias SERVICESADMINS = charlie, lionel
SERVICESADMINS ALL=(ALL) SERVICES

现在,看看当莱昂内尔试图检查安全外壳服务的状态时会发生什么:

[lionel@centos-7 ~]$ sudo systemctl status sshd
 [sudo] password for lionel:
 Sorry, user lionel is not allowed to execute '/bin/systemctl status sshd' as root on centos-7.xyzwidgets.com.
 [lionel@centos-7 ~]$

好吧,那么莱昂内尔可以运行sudo systemctl status,这几乎没有用,但是他不能做任何有意义的事情,比如指定他想要检查的服务。这有点问题。有两种方法可以解决这个问题,但只有一种方法是你想用的。您可以删除所有的systemctl子命令,并使SERVICES别名如下所示:

Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl

但是如果你这样做了,莱昂内尔和查理也将能够关闭或重新启动系统,编辑服务文件,或将机器从一个系统目标更改为另一个。那可能不是你想要的。因为systemctl命令涵盖了许多不同的功能,所以您必须小心不要允许委派用户访问太多这些功能。更好的解决方案是在每个systemctl子命令中添加一个通配符:

Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start *, /usr/bin/systemctl stop *, /usr/bin/systemctl reload *, /usr/bin/systemctl restart *, /usr/bin/systemctl status *, /usr/bin/systemctl enable *, /usr/bin/systemctl disable * 

现在,莱昂内尔和查理可以为任何服务执行本命令别名中列出的任何systemctl功能:

 [lionel@centos-7 ~]$ sudo systemctl status sshd
 [sudo] password for lionel:
 ● sshd.service - OpenSSH server daemon
 Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
 Active: active (running) since Sat 2017-09-30 18:11:22 EDT; 23min ago
 Docs: man:sshd(8)
 man:sshd_config(5)
 Main PID: 13567 (sshd)
 CGroup: /system.slice/sshd.service
 └─13567 /usr/sbin/sshd -D
 Sep 30 18:11:22 centos-7.xyzwidgets.com systemd[1]: Starting OpenSSH server daemon...
 Sep 30 18:11:22 centos-7.xyzwidgets.com sshd[13567]: Server listening on 0.0.0.0 port 22.
 Sep 30 18:11:22 centos-7.xyzwidgets.com sshd[13567]: Server listening on :: port 22.
 Sep 30 18:11:22 centos-7.xyzwidgets.com systemd[1]: Started OpenSSH server daemon.
 [lionel@centos-7 ~]$

请记住,您不仅限于使用用户别名和命令别名。您还可以为 Linux 组或单个用户分配权限。您还可以将单个命令分配给用户别名、Linux 组或单个用户。这里有一个例子:

katelyn ALL=(ALL) STORAGE
gunther ALL=(ALL) /sbin/fdisk -l
%backup_admins ALL=(ALL) BACKUP

Katelyn 现在可以执行STORAGE命令别名中的所有命令,而 Gunther 只能使用fdisk查看分区表。backup_admins Linux 组的成员可以在BACKUP命令别名中执行命令。

在本主题中,我们将看到的最后一件事是您在用户别名示例之前看到的主机别名示例:

# Host_Alias FILESERVERS = fs1, fs2
# Host_Alias MAILSERVERS = smtp, smtp2

每个主机别名由服务器主机名列表组成。这允许您在一台机器上创建一个sudoers文件,并在网络上部署它。例如,您可以使用适当的命令创建一个WEBSERVERS主机别名、WEBADMINS用户别名和一个WEBCOMMANDS命令别名。您的配置如下所示:

Host_Alias WEBSERVERS = webserver1, webserver2
User_Alias WEBADMINS = junior, kayla
Cmnd_Alias WEBCOMMANDS = /usr/bin/systemctl status httpd, /usr/bin/systemctl start httpd, /usr/bin/systemctl stop httpd, /usr/bin/systemctl restart httpd

WEBADMINS WEBSERVERS=(ALL) WEBCOMMANDS 

现在,当用户向网络上的服务器键入命令时,sudo将首先查看该服务器的主机名。如果用户被授权在该服务器上执行该命令,则sudo允许。否则,sudo予以否认。在中小型企业中,手动将主sudoers文件复制到网络上的所有服务器上可能效果不错。但是在大型企业中,您会希望简化和自动化流程。为此,您可以使用类似木偶、厨师或 Ansible 的东西。(这三项技术超出了本书的范围,但在 Packt 网站上,你会找到大量关于这三项技术的书籍和视频课程。)

所有这些技术都可以在你的 Ubuntu 虚拟机和 CentOS 虚拟机上运行。唯一的问题是 Ubuntu 没有任何预定义的命令别名,所以您必须自己键入。

不管怎样,我知道你厌倦了阅读,所以让我们做一些工作。

分配有限 sudo 权限的实践实验

在本实验中,您将创建一些用户,并为他们分配不同级别的权限。为了简化事情,我们将使用 CentOS 虚拟机。

  1. 登录 CentOS 7 虚拟机或 CentOS 8 虚拟机,并为 Lionel、Katelyn 和 Maggie 创建用户帐户:
 sudo useradd lionel
 sudo useradd katelyn
 sudo useradd maggie
 sudo passwd lionel
 sudo passwd katelyn
 sudo passwd maggie
  1. 打开visudo:
sudo visudo

找到STORAGE命令别名,并删除其前面的注释符号。

  1. 使用制表符分隔列,在文件末尾添加以下行:
lionel ALL=(ALL) ALL
katelyn ALL=(ALL) /usr/bin/systemctl status sshd
maggie ALL=(ALL) STORAGE 

保存文件并退出visudo

  1. 为了节省时间,我们将使用su登录不同的用户帐户。这样,您就不需要注销自己的帐户来执行这些步骤。首先,登录莱昂内尔的帐户,并通过运行几个根级命令来验证他是否拥有完全sudo权限:
 su - lionel
 sudo su -
 exit
 sudo systemctl status sshd
 sudo fdisk -l
 exit
  1. 这一次,以 Katelyn 的身份登录,并尝试运行一些根级命令。不过,如果它们都不起作用,不要太失望:
 su - katelyn
 sudo su -
 sudo systemctl status sshd
 sudo systemctl restart sshd
 sudo fdisk -l
 exit
  1. 最后,以 Maggie 的身份登录,运行您为 Katelyn 运行的同一组命令。
  2. 请记住,虽然本实验只有三个单独的用户,但是通过在用户别名或 Linux 组中设置他们,您可以轻松地处理更多的用户。

Since sudo is such a great security tool, you would think that everyone would use it, right? Sadly, that's not the case. Pretty much any time you look at either a Linux tutorial website or a Linux tutorial YouTube channel, you'll see the person who's doing the demo logged in at the root user command prompt. In some cases, I've seen the person remotely logged in as the root user on a cloud-based virtual machine. Now, if logging in as the root user is already a bad idea, then logging in across the internet as the root user is an even worse idea. In any case, seeing everybody do these tutorial demos from the root user's shell drives me absolutely crazy.

Having said all this, there are some things that don't work with sudo. Bash shell internal commands such as cd don't work with it, and using echo to inject kernel values into the /proc filesystem also doesn't work with it. For tasks such as these, a person would have to go to the root command prompt. Still, though, make sure that only users who absolutely have to use the root user command prompt have access to it.

使用 sudo 的高级提示和技巧

既然我们已经了解了设置好的sudo配置的基础知识,我们就遇到了一点矛盾。也就是说,即使sudo是一个安全工具,你可以用它做的某些事情会让你的系统比以前更加不安全。让我们看看如何避免这种情况。

sudo 计时器

默认情况下,sudo计时器设置为五分钟。这意味着,一旦用户执行一个sudo命令并输入密码,他或她就可以在五分钟内执行另一个sudo命令,而无需再次输入密码。虽然这显然很方便,但如果用户离开办公桌时,命令终端仍处于打开状态,这也会有问题。

如果五分钟计时器还没有到期,其他人可以过来执行一些根级别的任务。如果您的安全需要,您可以通过在sudoers文件的Defaults部分添加一行来轻松禁用该计时器。这样,用户每次运行sudo命令时都必须输入密码。您可以将其设置为所有用户的全局设置,也可以只为特定的单个用户设置。

假设你正坐在舒适的小隔间里,登录到一台远程 Linux 服务器上,该服务器仍然启用了五分钟计时器。如果你需要离开你的办公桌一会儿,你最好的办法是先注销服务器。除此之外,您可以通过运行以下命令重置sudo计时器:

sudo -k

这是为数不多的不输入密码就能完成的sudo动作之一。但是下次你执行sudo命令时,你必须输入你的密码,即使你之前输入密码已经不到五分钟了。

查看您的 sudo 权限

你不确定你拥有什么特权吗?别担心,你有办法找到的。只需运行以下命令:

sudo -l

当我为自己这样做时,我首先看到我的帐户的一些环境变量,然后我看到我有完全的sudo特权:

donnie@packtpub1:~$ sudo -l
 [sudo] password for donnie:
 Matching Defaults entries for donnie on packtpub1:
 env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

 User donnie may run the following commands on packtpub1:
 (ALL : ALL) ALL
 donnie@packtpub1:~$

当弗兰克,我以前的野生火焰点暹罗猫,为他的帐户这样做时,他看到他只能做fdisk -l命令:

frank@packtpub1:~$ sudo -l
 [sudo] password for frank:
 Matching Defaults entries for frank on packtpub1:
 env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

 User frank may run the following commands on packtpub1:
 (ALL) /sbin fdisk -l
 frank@packtpub1:~$

但既然他是猫,他就不会抱怨。相反,他会尝试做一些偷偷摸摸的事情,我们稍后会看到。

禁用 sudo 定时器的动手实验

在本实验中,您将禁用 CentOS 虚拟机上的sudo计时器:

  1. 登录到您在上一实验中使用的同一个 CentOS 虚拟机。我们将使用您已经创建的用户帐户。
  2. 在您自己的用户帐户命令提示符下,输入以下命令:
 sudo fdisk -l
 sudo systemctl status sshd
 sudo iptables -L

您将会看到,您只需要输入一次密码就可以执行所有三个命令。

  1. 在您自己的用户帐户命令提示符下,运行以下命令:
 sudo fdisk -l
 sudo -k
 sudo fdisk -l

注意sudo -k命令如何重置你的计时器,所以你必须再次输入你的密码。使用以下命令打开visudo:

sudo visudo

在文件的Defaults specification部分,添加以下一行:

Defaults timestamp_timeout = 0 

保存文件并退出visudo

  1. 执行您在步骤 2 中执行的命令。这一次,你应该看到每次都要输入密码。
  2. 打开visudo并修改您添加的线条,使其看起来像这样:
Defaults:lionel timestamp_timeout = 0 

保存文件并退出visudo

  1. 从您自己的帐户外壳中,重复您在步骤 2 中执行的命令。然后,以莱昂内尔的身份登录,再次执行命令。
  2. 通过运行以下命令查看您自己的sudo权限:
sudo -l

Note that this procedure also works for Ubuntu.

阻止用户拥有根外壳访问权限

假设您想要设置一个具有有限sudo权限的用户,但是您通过添加一行这样的内容做到了:

maggie ALL=(ALL) /bin/bash, /bin/zsh

我很抱歉地说,你一点也没有限制玛吉的进入。你已经有效地给了她巴什外壳和 ZSH 外壳的全部特权。所以,不要给你的sudoers加上这样的台词,因为会给你带来麻烦。

防止用户使用 shell 转义

某些程序,尤其是文本编辑器和寻呼机,有一个方便的 shell 转义功能。这允许用户运行 shell 命令,而不必先退出程序。例如,从 Vi 和 Vim 编辑器的命令模式中,有人可以通过运行:!ls来运行ls命令。执行该命令如下所示:

# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
~
~
:!ls

输出如下所示:

[donnie@localhost default]$ sudo vim useradd
 [sudo] password for donnie:
 grub nss useradd
 Press ENTER or type command to continue
 grub nss useradd
 Press ENTER or type command to continue

现在,假设您希望弗兰克能够编辑sshd_config文件,并且只能编辑该文件。您可能想在您的sudo配置中添加一行,如下所示:

frank ALL=(ALL) /bin/vim /etc/ssh/sshd_config

这看起来可行,对吧?嗯,它没有,因为一旦弗兰克用他的sudo权限打开了sshd_config文件,他就可以使用 Vim 的 shell 转义功能来执行其他根级命令,包括能够编辑其他配置文件。你可以让弗兰克用sudoedit代替vim来解决这个问题:

frank ALL=(ALL) sudoedit /etc/ssh/sshd_config

sudoedit没有脱壳功能,可以放心的让 Frank 使用。其他具有 shell 转义功能的程序包括:

  • 编辑器
  • 较少的
  • 视角
  • 更多

防止用户使用其他危险程序

如果你给用户无限制的使用权限,一些没有 shell 转义的程序仍然是危险的。其中包括以下内容:

  • 切口
  • 使用
  • 一项 Linux 指令

如果你必须给某人sudo特权来使用这些程序中的一个,最好将它们的使用限制在特定的文件。这就引出了我们的下一个提示。

用命令限制用户的操作

假设您创建了一个sudo规则,以便西尔维斯特可以使用systemctl命令:

sylvester ALL=(ALL) /usr/bin/systemctl

这使得西尔维斯特可以充分利用systemctl功能。他可以控制守护进程,编辑服务文件,关闭或重启,以及执行systemctl所做的其他功能。那可能不是你想要的。更好的办法是明确西尔维斯特被允许扮演什么样的systemctl角色。假设您希望他能够仅控制安全外壳服务。您可以让线条看起来像这样:

sylvester ALL=(ALL) /usr/bin/systemctl * sshd 

西尔维斯特现在可以使用安全外壳服务做他需要做的一切,但是他不能关闭或重新启动系统,编辑其他服务文件,或者更改系统目标。但是,如果您希望西尔维斯特只对安全外壳服务执行某些特定的操作,该怎么办呢?然后,您必须省略通配符,并指定希望 Sylvester 执行的所有操作:

sylvester ALL=(ALL) /usr/bin/systemctl status sshd, /usr/bin/systemctl restart sshd 

现在,西尔威斯特只能重新启动安全外壳服务或检查其状态。

When writing sudo policies, you'll want to be aware of the differences between the different Linux and Unix distributions on your network. For example, on Red Hat and CentOS systems, the systemctl binary file is located in the /usr/bin directory. On Debian/Ubuntu systems, it's located in the /bin directory. If you have to roll out a sudoers file to a large enterprise network with mixed operating systems, you can use host aliases to ensure that servers will only allow the execution of commands that are appropriate for their operating systems.

Also, be aware that some system services have different names on different Linux distributions. On Red Hat and CentOS systems, the Secure Shell service is sshd. On Debian/Ubuntu systems, it's just plain ssh.

让用户像其他用户一样运行

在下面一行中,(ALL)表示西尔维斯特可以以任何用户的身份运行systemctl命令:

sylvester ALL=(ALL) /usr/bin/systemctl status sshd, /usr/bin/systemctl restart sshd

这有效地为这些命令赋予了 Sylvester root 权限,因为 root 用户肯定是任何用户。如果需要,您可以将(ALL)更改为(root),以便指定 Sylvester 只能作为根用户运行这些命令:

sylvester ALL=(root) /usr/bin/systemctl status sshd, /usr/bin/systemctl restart sshd 

好吧,那可能没什么意义,因为没什么变化。西尔维斯特以前拥有这些systemctl命令的根权限,现在他仍然拥有它们。但是这个特性有更多的实际用途。假设 Vicky 是数据库管理员,您希望她以database用户的身份运行:

vicky ALL=(database) /usr/local/sbin/some_database_script.sh

Vicky 可以通过输入以下命令以数据库用户的身份运行该命令:

sudo -u database some_database_script.sh

这是您可能不会经常使用的功能之一,但无论如何都要记住。你永远不知道它什么时候会派上用场。

通过用户的外壳脚本防止滥用

那么,如果一个用户写了一个需要sudo权限的 shell 脚本呢?为了回答这个问题,让弗兰克创建如下所示的frank_script.sh shell 脚本:

#!/bin/bash

echo "This script belongs to Frank the Cat."

好吧,他不需要sudo特权,但是让我们假设他需要。在他设置了可执行权限并用sudo运行之后,输出会是这样的:

 frank@packtpub1:~$ sudo ./frank_script.sh
 [sudo] password for frank:
 Sorry, user frank is not allowed to execute './frank_script.sh' as root on packtpub1.tds.
 frank@packtpub1:~$

因此,自然感到沮丧,弗兰克要求我创建一个sudo规则,这样他就可以运行脚本。所以,我打开visudo并为弗兰克添加了这条规则:

frank ALL=(ALL) /home/frank/frank_script.sh

现在,当弗兰克用sudo运行脚本时,它起作用了:

 frank@packtpub1:~$ sudo ./frank_script.sh
 [sudo] password for frank:
 This script belongs to Frank the Cat.
 frank@packtpub1:~$

但是由于这个文件在弗兰克自己的主目录中,并且他是它的所有者,所以他可以以任何他想要的方式编辑它。因此,作为偷偷摸摸的类型,他在脚本的末尾添加了sudo -i行,现在看起来是这样的:

#!/bin/bash

echo "This script belongs to Frank the Cat."
sudo -i

当你观察接下来发生的事情时,要做好震惊的准备:

 frank@packtpub1:~$ sudo ./frank_script.sh
 This script belongs to Frank the Cat.
 root@packtpub1:~#

如您所见,Frank 现在以 root 用户身份登录。

sudo -i做的是将一个人登录到根用户的 shell 中,和sudo su -做的一样。如果弗兰克在他自己的命令提示符下执行sudo -i命令,它将会失败,因为弗兰克没有这样做的特权。但他确实有sudo特权运行自己的 shell 脚本。通过将 shell 脚本留在自己的主目录中,Frank 可以将根级命令放入其中。通过使用sudo运行脚本,脚本中的根级命令将以根级权限执行。

为了弥补这一点,我将使用我令人敬畏的sudo的力量将弗兰克的脚本移动到/usr/local/sbin目录,并将所有权更改为根用户,这样弗兰克将无法编辑它。当然,在此之前,我会确保删除其中的sudo -i一行:

 donnie@packtpub1:~$ sudo -i
 root@packtpub1:~# cd /home/frank
 root@packtpub1:/home/frank# mv frank_script.sh /usr/local/sbin
 root@packtpub1:/home/frank# chown root: /usr/local/sbin/frank_script.sh
 root@packtpub1:/home/frank# exit
 logout
 donnie@packtpub1:~$

最后,我将打开visudo并更改他的规则,以反映脚本的新位置。新规则如下所示:

frank ALL=(ALL) /usr/local/sbin/frank_script.sh

弗兰克仍然可以运行脚本,但他不能编辑它:

 frank@packtpub1:~$ sudo frank_script.sh
 This script belongs to Frank the Cat.
 frank@packtpub1:~$

检测和删除默认用户帐户

处理物联网 ( 物联网)设备的一个挑战是,您不会像设置普通服务器时那样在这些设备上进行正常的操作系统安装。相反,您可以下载预装了操作系统的映像,并将该映像刻录到 microSD 卡上。安装的操作系统是用默认的用户帐户设置的,很多时候该用户是用完整的sudo权限设置的,不需要输入sudo密码。让我们以树莓皮的 Raspex Linux 发行版为例。(Raspex 是从 Ubuntu 源代码构建的。)在 Raspex 下载网站的文档页面,我们看到默认用户是raspex,该用户的默认密码也是raspex。我们还看到root用户的默认密码是root:

因此,默认凭据是公开的,全世界都可以看到。显然,设置物联网设备首先要做的就是设置自己的用户账号,给它一个好的密码,给它sudo特权。那就去掉那个默认账号,因为留在原地,尤其是留了默认密码,简直是自找麻烦。

但是让我们深入挖掘一下。查看 Raspex 上的/etc/password文件,您会在那里看到默认用户:

raspex:x:1000:1000:,,,:/home/raspex:/bin/bash

然后,查看/etc/sudoers文件,您会看到这一行,它允许raspex用户执行所有sudo命令,而无需输入密码:

raspex ALL=(ALL) NOPASSWD: ALL

另一个需要注意的是,一些面向物联网设备的 Linux 发行版在/etc/sudoers.d目录下的单独文件中有这个规则,而不是在主sudoers文件中。无论哪种方式,您都希望在设置物联网设备时删除此规则以及默认用户帐户。当然,您还需要更改root用户密码,然后锁定root用户帐户。

好吧,我想这个话题到此为止了。让我们继续下一个话题。

以红帽或 CentOS 的方式锁定用户的主目录

这是另一个不同的 Linux 发行家族在业务上互不相同的领域。正如我们将看到的,每个发行系列都有不同的默认安全设置。监管不同 Linux 发行版混合环境的安全管理员需要考虑这一点。

红帽企业版 Linux 及其所有后代(如 CentOS)的一个优点是,它们比任何其他 Linux 发行版都具有更好的开箱即用安全性。这使得加固红帽型系统变得更快更容易,因为大部分工作已经完成。我们已经做的一件事是锁定用户的主目录:

 [donnie@localhost home]$ sudo useradd charlie
 [sudo] password for donnie:
 [donnie@localhost home]$
 [donnie@localhost home]$ ls -l
 total 0
 drwx------. 2 charlie charlie 59 Oct 1 15:25 charlie
 drwx------. 2 donnie donnie 79 Sep 27 00:24 donnie
 drwx------. 2 frank frank 59 Oct 1 15:25 frank
 [donnie@localhost home]$

默认情况下,红帽类型系统上的useradd实用程序创建用户主目录,权限设置为700。这意味着只有拥有主目录的用户才能访问它。所有其他普通用户都被锁定。我们可以通过查看/etc/login.defs文件来了解原因。向下滚动到文件的底部,您会看到:

CREATE_HOME yes
UMASK 077

login.defs文件是配置了useradd默认设置的两个文件之一。这条UMASK线决定了主目录创建时的权限值。红帽型发行版将其配置为077值,这将从组和其他版本中删除所有权限。这个UMASK行在所有 Linux 发行版的login.defs文件中,但是红帽类型的发行版是唯一一个默认将UMASK设置为这样一个限制值的发行版。非红帽发行版的UMASK值通常为022,这将创建权限值为755的主目录。这允许每个人进入其他人的主目录并访问其他人的文件。

用 Debian/Ubuntu 的方式锁定用户的主目录

Debian 及其后代,如 Ubuntu,有两个用户创建实用程序:

  • useradd
  • adduser

让我们看看他们两个。

Debian/Ubuntu 上的 useradd

useradd实用程序在那里,但是 Debian 和 Ubuntu 没有像 Red Hat 和 CentOS 那样提供方便的预配置默认值。如果你只是在默认的 Debian/Ubuntu 机器上做sudo useradd frank,Frank 将没有主目录,并且会被分配错误的默认 shell。因此,要在 Debian 或 Ubuntu 系统上创建一个带有useradd的用户帐户,命令应该如下所示:

sudo useradd -m -d /home/frank -s /bin/bash frank

在这个命令中,我们有以下内容:

  • -m创建主目录。
  • -d指定主目录。
  • -s指定 Frank 的默认 shell。(没有了-s,Debian/Ubuntu 会给 Frank 分配/bin/sh shell。)

当您查看主目录时,您会发现它们是完全开放的,每个人都有执行和读取权限:

 donnie@packt:/home$ ls -l
 total 8
 drwxr-xr-x 3 donnie donnie 4096 Oct 2 00:23 donnie
 drwxr-xr-x 2 frank frank 4096 Oct 1 23:58 frank
 donnie@packt:/home$

如你所见,弗兰克和我可以进入对方的东西。(不,我不希望弗兰克进入我的东西。)每个用户都可以更改自己目录上的权限,但是有多少用户知道该怎么做呢?所以,让我们自己解决这个问题:

 cd /home
 sudo chmod 700 *

让我们看看我们现在有什么:

 donnie@packt:/home$ ls -l
 total 8
 drwx------ 3 donnie donnie 4096 Oct 2 00:23 donnie
 drwx------ 2 frank frank 4096 Oct 1 23:58 frank
 donnie@packt:/home$

看起来好多了。

要更改主目录的默认权限设置,请打开/etc/login.defs进行编辑。查找以下行:

UMASK 022

将其更改为:

UMASK 077

现在,新用户的主目录将在创建时被锁定,就像他们使用红帽一样。

adduser on Debian/Ubuntu

adduser实用程序是一种用单个命令创建用户帐户和密码的交互方式,这是 Debian 系列 Linux 发行版独有的。useradd的 Debian 实现中缺少的大多数默认设置已经为adduser设置好了。默认设置唯一的错误是它创建了具有大开755权限值的用户主目录。幸运的是,这很容易改变。(我们一会儿就知道了。)

虽然adduser对于用户账户的随意创建很方便,但是它没有useradd的灵活性,也不适合在 shell 脚本中使用。adduser会做useradd不会做的一件事是在创建帐户时自动加密用户的主目录。要让它工作,你首先必须安装ecryptfs-utils软件包。因此,要为埃及艳后创建一个带有加密主目录的帐户,请执行以下操作:

sudo apt install ecryptfs-utils

 donnie@ubuntu-steemnode:~$ sudo adduser --encrypt-home cleopatra
 [sudo] password for donnie:
 Adding user `cleopatra' ...
 Adding new group `cleopatra' (1004) ...
 Adding new user `cleopatra' (1004) with group `cleopatra' ...
 Creating home directory `/home/cleopatra' ...
 Setting up encryption ...
 ************************************************************************
 YOU SHOULD RECORD YOUR MOUNT PASSPHRASE AND STORE IT IN A SAFE LOCATION.
 ecryptfs-unwrap-passphrase ~/.ecryptfs/wrapped-passphrase
 THIS WILL BE REQUIRED IF YOU NEED TO RECOVER YOUR DATA AT A LATER TIME.
 ********************************************************************
Done configuring.
 Copying files from `/etc/skel' ...
 Enter new UNIX password:
 Retype new UNIX password:
 passwd: password updated successfully
 Changing the user information for cleopatra
 Enter the new value, or press ENTER for the default
 Full Name []: Cleopatra Tabby Cat
 Room Number []: 1
 Work Phone []: 555-5556
 Home Phone []: 555-5555
 Other []:
 Is the information correct? [Y/n] Y
 donnie@ubuntu-steemnode:~$

埃及艳后第一次登录时,她需要运行前面输出中提到的ecryptfs-unwrap-passphrase命令。然后,她会想要写下她的密码,并将其存储在安全的地方:

 cleopatra@ubuntu-steemnode:~$ ecryptfs-unwrap-passphrase
 Passphrase:
 d2a6cf0c3e7e46fd856286c74ab7a412
 cleopatra@ubuntu-steemnode:~$

当我们进入加密章节时,我们将更详细地了解整个加密过程。

配置 adduser 的实践实验

在本实验中,我们将使用 Debian/Ubuntu 系统特有的adduser实用程序:

  1. 在你的 Ubuntu 虚拟机上,打开/etc/adduser.conf文件进行编辑。找到写着DIR_MODE=0755的那行,改成 DIR_MODE=0700。保存文件并退出文本编辑器。
  2. 安装ecryptfs-utils包:
sudo apt install ecryptfs-utils
  1. 为克利奥帕特拉创建一个带有加密主目录的用户帐户,然后查看结果:
 sudo adduser --encrypt-home cleopatra
 ls -l /home
  1. 以埃及艳后身份登录并运行ecryptfs-unwrap-passphrase命令:
su - cleopatra
ecryptfs-unwrap-passphrase
exit

注意adduser要求的一些信息是可选的,你只需要点击进入键就可以了。

强制实施强密码标准

你不会认为一个听起来温和的话题,比如强密码标准,会引起如此大的争议,但事实确实如此。毫无疑问,你在整个计算机生涯中听到的传统观点是这样的:

  • 制作一定长度的密码。
  • 创建由大写字母、小写字母、数字和特殊字符组成的密码。
  • 确保密码不包含字典中的任何单词或基于用户个人数据的单词。
  • 强制用户定期更改密码。

但是,使用你最喜欢的搜索引擎,你会发现不同的专家对这些标准的细节意见不一。例如,您会看到关于密码是否应该每 30 天、60 天或 90 天更改一次的分歧,关于四种类型的字符是否都需要包含在密码中的分歧,甚至关于密码的最小长度应该是多少的分歧。

最有趣的争议来自于——在所有的地方——首先发明了上述标准的人。他现在说这都是胡说八道,后悔自己想出来的。他现在说我们应该使用长而易记的密码短语。他还说,只有当它们被攻破时,才应该改变。

Bill Burr, the former National Institutes of Standards and Technology (NIST) engineer who created the strong password criteria that I outlined earlier, shares his thoughts about why he now disavows his own work. Refer to https://www.pcmag.com/news/355496/you-might-not-need-complex-alphanumeric-passwords-after-all.

And, since the original edition of this book was published, NIST has come to agree with Bill Burr. They have now changed their password implementation criteria to match Mr. Burr's recommendations. You can read about that at https://www.riskcontrolstrategies.com/2018/01/08/new-nist-guidelines-wrong/.

然而,话虽如此,现实是许多组织仍然坚持使用定期过期的复杂密码,如果你不能说服他们,你将不得不遵守他们的规则。此外,如果您使用传统密码,您确实希望它们足够强大,能够抵御任何类型的密码攻击。现在,我们来看看在 Linux 系统上强制执行强密码标准的机制。

I have to confess that I had never before thought to try creating a passphrase to use in place of a password on a Linux system. So, I just now tried it on my CentOS virtual machine to see if it would work. 

I created an account for Maggie, my black-and-white tuxedo kitty. For her password, I entered the passphrase I like other kitty cats. You may think, "Oh, that's terrible. This doesn't meet any complexity criteria*,* and it uses dictionary words. How is that secure?" But the fact that it's a phrase with distinct words separated by blank spaces does make it secure and very difficult to brute-force.

Now, in real life, I would never create a passphrase that expresses my love for cats because it's not hard to find out that I really do love cats. Rather, I would choose a passphrase about some more obscure part of my life that nobody but me knows about. In any case, there are two advantages of passphrases over passwords. They're more difficult to crack than traditional passwords, yet they're easier for users to remember. For extra security, though, just don't create passphrases about a fact of your life that everybody knows about.

安装和配置 pwquality

我们将使用pwquality模块作为可插拔认证模块 ( PAM )。这是一项更新的技术,取代了旧的cracklib模块。在红帽 7/8 或 CentOS 7/8 系统上,默认情况下会安装pwquality,即使您只进行了最低限度的安装。如果你进入/etc/pam.d目录,你可以做一个grep操作,看看 PAM 配置文件已经设置好了。retry=3表示用户在登录系统时,只有三次尝试获取正确密码的机会:

[donnie@localhost pam.d]$ grep 'pwquality' *
 password-auth:password requisite pam_pwquality.so try_first_pass
 local_users_only retry=3 authtok_type=
 password-auth-ac:password requisite pam_pwquality.so try_first_pass
 local_users_only retry=3 authtok_type=
 system-auth:password requisite pam_pwquality.so try_first_pass
 local_users_only retry=3 authtok_type=
 system-auth-ac:password requisite pam_pwquality.so try_first_pass
 local_users_only retry=3 authtok_type=
 [donnie@localhost pam.d]$

剩下的过程对于两个操作系统都是一样的,只包括编辑/etc/security/pwquality.conf文件。当您在文本编辑器中打开此文件时,您会看到所有内容都被注释掉了,这意味着没有有效的密码复杂性标准。您还会看到它被很好地记录下来,因为每个设置都有自己的解释性注释。

您可以通过取消相应行的注释并设置相应的值来设置密码复杂性标准。让我们只看一个设置:

# Minimum acceptable size for the new password (plus one if 
# credits are not disabled which is the default). (See pam_cracklib manual.) 
# Cannot be set to lower value than 6\. 
# minlen = 8 

最小长度设置适用于信用体系。这意味着,对于密码中的每种不同类型的字符类,所需的最小密码长度将减少一个字符。例如,让我们将minlen设置为值19,并尝试为凯特琳分配密码turkeylips:

minlen = 19

[donnie@localhost ~]$ sudo passwd katelyn
 Changing password for user katelyn.
 New password:
 BAD PASSWORD: The password is shorter than 18 characters
 Retype new password:
 [donnie@localhost ~]$

因为turkeylips中的小写字符算作一种字符类的信用,所以我们只需要有 18 个字符,而不是 19 个。如果我们用TurkeyLips再次尝试,我们会得到:

[donnie@localhost ~]$ sudo passwd katelyn
 Changing password for user katelyn.
 New password:
 BAD PASSWORD: The password is shorter than 17 characters
 Retype new password:
 [donnie@localhost ~]$

这次大写的T和大写的L算作第二个字符类,所以密码中我们只需要有 17 个字符。

就在minlen线下方,你会看到信用额度。假设你不想让小写字母计入你的学分。你会发现这条线:

# lcredit = 1 

取消注释,并将1改为0:

lcredit = 0

然后,尝试将凯特琳turkeylips指定为密码:

[donnie@localhost ~]$ sudo passwd katelyn
 Changing password for user katelyn.
 New password:
 BAD PASSWORD: The password is shorter than 19 characters
 Retype new password:
 [donnie@localhost ~]$

这次pwquality真的要 19 个字符。如果我们将一个信用值设置为高于1的值,我们将获得相同类别类型的多个字符的信用值。

我们还可以将信用值设置为负数,以便在密码中要求一定数量的字符类型。例如,我们可以这样做:

dcredit = -3

这需要密码中至少有三位数字。然而,使用这一功能确实是一个坏主意,因为进行密码攻击的人很快就会找到您需要的模式,这将有助于攻击者更准确地指挥攻击。如果需要要求密码有多种字符类型,最好使用minclass参数:

# minclass = 3

它已经被设置为3值,这将需要来自三个不同类的字符。要使用该值,您所要做的就是删除注释符号。

pwquality.conf中的其余参数的工作方式基本相同,每个参数都有一个写得很好的注释来解释它的功能。

If you use your sudo privilege to set someone else's password, the system will complain if you create a password that doesn't meet complexity criteria, but it will let you do it. If a normal user were to try to change his or her own password without sudo privileges, the system would not allow a password that doesn't meet complexity criteria.

设置密码复杂性标准的实践实验室

对于本实验,您可以根据需要使用 CentOS 或 Ubuntu 虚拟机。唯一的区别是您不会为 CentOS 执行步骤 1:

  1. 仅适用于 Ubuntu,安装libpam-pwquality包:
sudo apt install libpam-pwquality
  1. 在首选文本编辑器中打开/etc/security/pwquality.conf文件。删除minlen行前面的注释符号,并将值更改为19。现在应该是这样的:
 minlen = 19

保存文件并退出编辑器。

  1. 为歌迪创建一个用户帐户,并尝试为她分配密码turkeylipsTurkeyLipsTurkey93Lips。注意每个警告消息的变化。
  2. pwquality.conf文件中,注释掉minlen行。取消对minclass线和maxclassrepeat线的注释。将maxclassrepeat值更改为5。这些行现在应该如下所示:
minclass = 3 
maxclassrepeat = 5 

保存文件并退出文本编辑器。

  1. 尝试为歌迪的帐户分配各种不符合复杂性标准的密码,并查看结果。

In the /etc/login.defs file on your CentOS machine, you'll see the line PASS_MIN_LEN 5.

Supposedly, this is to set the minimum password length, but in reality, pwquality overrides it. So, you could set this value to anything at all, and it would have no effect.

设置和实施密码和帐户过期

你永远不想让未使用的用户帐户保持活动状态。曾发生过这样的事件:管理员为临时使用(如会议)设置用户帐户,然后在不再需要这些帐户后就把它们忘了。

另一个例子是,如果你的公司雇佣合同在某个特定日期到期的合同工。允许这些账户在临时员工离开公司后保持活跃和可访问将是一个巨大的安全问题。在这种情况下,您需要一种方法来确保临时用户帐户在不再需要时不会被遗忘。如果你的雇主认同用户应该定期更改密码的传统观点,那么你也要确保做到这一点。

密码到期数据和账户到期数据是两回事。它们可以单独设置,也可以一起设置。当某人的密码过期时,他或她可以更改它,一切都会好的。如果某人的帐户过期,只有拥有适当管理员权限的人才能解锁。

首先,看一下你自己账户的到期数据。请注意,您不需要sudo权限来查看自己的数据,但您仍然需要指定自己的用户名:

donnie@packt:~$ chage -l donnie
 [sudo] password for donnie:
 Last password change : Oct 03, 2017
 Password expires : never
 Password inactive : never
 Account expires : never
 Minimum number of days between password change : 0
 Maximum number of days between password change : 99999
 Number of days of warning before password expires : 7
 donnie@packt:~$

您可以在这里看到没有设置到期数据。这里的所有内容都是根据现成的系统默认值设置的。除了显而易见的项目之外,以下是你所看到的细分:

  • Password inactive:如果这个设置为正数,那么在系统锁定我的账户之前,我有那么多天的时间来更改过期的密码。
  • Minimum number of days between password change:因为这个设置为0,所以我可以随时更改密码。如果设置为正数,我必须在更改密码后等待该天数,然后才能再次更改密码。
  • Maximum number of days between password change:这个设置为99999的默认值,表示我的密码永远不会过期。
  • Number of days of warning before password expires:默认值是7,但是当密码设置为永不过期的时候,那就相当没有意义了。

With the chage utility, you can either set password and account expiration data for other users or use the -l option to view expiration data. Any unprivileged user can use chage -l without sudo to view his or her own data. To either set data or view someone else's data, you need sudo. We'll take a closer look at chage a bit later.

在了解如何更改过期数据之前,我们先来看看默认设置存储在哪里。我们先来看看/etc/login.defs文件。这三条相关的线如下:

PASS_MAX_DAYS 99999 
PASS_MIN_DAYS 0 
PASS_WARN_AGE 7

您可以编辑这些值以适应您组织的需求。例如,将PASS_MAX_DAYS更改为30值将导致从该点开始的所有新用户密码都有 30 天的过期数据。(顺便说一下,在login.defs中设置默认密码到期数据对红帽或 CentOS 以及 Debian/Ubuntu 都有效。)

仅为红帽或 CentOS 用户添加配置默认到期数据

/etc/default/useradd文件具有其余的默认设置。在本例中,我们将看一下 CentOS 机器上的一个:

Ubuntu also has the useradd configuration file, but it doesn't work. No matter how you configure it, the Ubuntu version of useradd just won't read it. So, the write-up about this file only applies to Red Hat or CentOS.

# useradd defaults file
GROUP=100
HOME=/home 
INACTIVE=-1 
EXPIRE= 
SHELL=/bin/bash 
SKEL=/etc/skel 
CREATE_MAIL_SPOOL=yes

EXPIRE=行设置新用户账户的默认到期日期。默认情况下,没有默认的到期日期。INACTIVE=-1表示用户密码过期后,用户账号不会自动锁定。如果我们将它设置为正数,那么在帐户被锁定之前,任何新用户都有那么多天的时间来更改过期的密码。要更改useradd文件中的默认值,您可以手动编辑文件,或者使用useradd -D并为您想要更改的项目选择适当的选项开关。例如,要将默认到期日期设置为 2023 年 12 月 31 日,命令如下:

sudo useradd -D -e 2023-12-31

要查看新的配置,您可以打开useradd文件或只需执行sudo useradd -D:

[donnie@localhost ~]$ sudo useradd -D
 GROUP=100
 HOME=/home
 INACTIVE=-1
 EXPIRE=2023-12-31
 SHELL=/bin/bash
 SKEL=/etc/skel
 CREATE_MAIL_SPOOL=yes
 [donnie@localhost ~]$

您现在已经对其进行了设置,以便创建的任何新用户帐户都将具有相同的到期日期。您可以使用INACTIVE设置或SHELL设置进行同样的操作:

sudo useradd -D -f 5
 sudo useradd -D -s /bin/zsh

 [donnie@localhost ~]$ sudo useradd -D
 GROUP=100
 HOME=/home
 INACTIVE=5
 EXPIRE=2019-12-31
 SHELL=/bin/zsh
 SKEL=/etc/skel
 CREATE_MAIL_SPOOL=yes
 [donnie@localhost ~]$

现在,创建的任何新用户帐户都将把 Zsh shell 设置为默认 shell,并且必须在五天内更改过期密码,以防止帐户被自动锁定。

useradd doesn't do any safety checks to ensure that the default shell that you've assigned is installed on the system. In our case, Zsh isn't installed, but useradd will still allow you to create accounts with Zsh as the default shell.

那么,这个useradd配置功能在现实生活中到底有多大用处呢?可能没那么多,除非你需要用同样的设置同时创建一大堆用户账户。即便如此,一个精明的管理员也只是用一个 shell 脚本来自动化这个过程,而不是摆弄这个配置文件。

使用 useradd 和 usermod 设置每个帐户的到期数据

您可能会发现在login.defs中设置默认密码到期数据很有用,但配置useradd配置文件可能不会太有用。真的,你想创建所有用户帐户的机会有多大?在login.defs中设置密码到期数据更有用,因为你只是说你希望新密码在特定的天数内到期,而不是让它们都在特定的日期到期。

最有可能的是,你会想要根据每个账户设置账户到期数据,这取决于你是否知道在某个特定日期不再需要这些账户。有三种方法可以做到这一点:

  • 在创建帐户时,使用带有适当选项开关的useradd设置到期数据。(如果您需要用相同的到期数据一次创建一大堆帐户,您可以使用 shell 脚本自动完成这个过程。)
  • 使用usermod修改现有账户的到期数据。(关于usermod的美好之处在于它使用了与useradd相同的选项开关。)
  • 使用chage修改现有账户的到期数据。(这个使用了一组完全不同的选项开关。)

可以使用useraddusermod设置账户到期数据,但不能设置密码到期数据。影响帐户到期数据的仅有两个选项开关如下:

  • -e:用这个设置账户的到期日,格式为 YYYY-MM-DD。
  • -f:用这个设置用户密码过期后,你希望他或她的账户被锁定的天数。

假设您想为 Charlie 创建一个将于 2020 年底到期的帐户。在红帽或 CentOS 机器上,您可以输入以下内容:

sudo useradd -e 2020-12-31 charlie

在非红帽或 CentOS 机器上,您必须添加选项开关来创建主目录并分配正确的默认外壳:

sudo useradd -m -d /home/charlie -s /bin/bash -e 2020-12-31 charlie

使用chage -l验证您输入的内容:

donnie@ubuntu-steemnode:~$ sudo chage -l charlie
 Last password change : Oct 06, 2017
 Password expires : never
 Password inactive : never
 Account expires : Dec 31, 2020
 Minimum number of days between password change : 0
 Maximum number of days between password change : 99999
 Number of days of warning before password expires : 7
 donnie@ubuntu-steemnode:~$

现在,假设查理的合同已经延长,您需要将他的帐户到期日期更改为 2021 年 1 月底。您将在任何 Linux 发行版上以相同的方式使用usermod:

sudo usermod -e 2021-01-31 charlie

再次用chage -l验证一切是否正确:

donnie@ubuntu-steemnode:~$ sudo chage -l charlie
 Last password change : Oct 06, 2017
 Password expires : never
 Password inactive : never
 Account expires : Jan 31, 2021
 Minimum number of days between password change : 0
 Maximum number of days between password change : 99999
 Number of days of warning before password expires : 7
 donnie@ubuntu-steemnode:~$

或者,您可以设置密码过期的帐户被锁定的天数:

sudo usermod -f 5 charlie

但是如果你现在这样做,你将不会在chage -l输出中看到任何差异,因为我们仍然没有为查理的密码设置到期数据。

使用 chage 设置每个帐户的到期数据

您将只使用chage修改现有帐户,并使用它来设置帐户到期或密码到期。以下是相关的选项开关:

| 选项 | 解释 | | -d | 如果您在某人的帐户上使用-d 0选项,您将强制用户在下次登录时更改他或她的密码。 | | -E | 这相当于小写的-e代表useraddusermod。它设置用户帐户的到期日期。 | | -I | 这相当于useraddusermod-f。它设置密码过期的帐户被锁定的天数。 | | -m | 这将设置密码更改的最小间隔天数。换句话说,如果查理今天更改密码,-m 5选项会强制他等待五天才能再次更改密码。 | | -M | 这将设置密码过期前的最大天数。(但请注意,如果查理上次设置密码是在 89 天前,在他的帐户上使用-M 90选项将导致他的密码明天到期,而不是从现在起的 90 天。) | | -W | 这将设置密码即将过期的警告天数。 |

一次只能设置其中一个数据项,也可以一次全部设置。事实上,为了避免每个项目都有不同的演示让您感到沮丧,让我们一次性设置它们,除了-d 0,然后我们将看到我们得到了什么:

sudo chage -E 2021-02-28 -I 4 -m 3 -M 90 -W 4 charlie
 donnie@ubuntu-steemnode:~$ sudo chage -l charlie
 Last password change : Oct 06, 2019
 Password expires : Jan 04, 2020
 Password inactive : Jan 08, 2020
 Account expires : Feb 28, 2021
 Minimum number of days between password change : 3
 Maximum number of days between password change : 90
 Number of days of warning before password expires : 4
 donnie@ubuntu-steemnode:~$

现在已经设置了所有到期数据。

对于我们的最后一个示例,假设您刚刚为 Samson 创建了一个新帐户,并且您想在他第一次登录时强制他更改密码。有两种方法可以做到这一点。无论哪种方式,你都可以在最初设置好他的密码后进行。例如,让我们这样做:

sudo chage -d 0 samson
 or
 sudo passwd -e samson

 donnie@ubuntu-steemnode:~$ sudo chage -l samson
 Last password change : password must be changed
 Password expires : password must be changed
 Password inactive : password must be changed
 Account expires : never
 Minimum number of days between password change : 0
 Maximum number of days between password change : 99999
 Number of days of warning before password expires : 7
 donnie@ubuntu-steemnode:~$

接下来,我们将进行动手实验。

设置帐户和密码到期数据的实践实验室

在本实验中,您将创建几个新的用户帐户,设置到期数据,并查看结果。您可以在 CentOS 或 Ubuntu 虚拟机上进行本实验。唯一不同的是useradd命令:

  1. 为 Samson 创建一个截止日期为 2023 年 6 月 30 日的用户帐户,并查看 CentOS 的结果,运行以下命令:
sudo useradd -e 2023-06-30 samson
sudo chage -l samson

对于 Ubuntu,运行以下命令:

sudo useradd -m -d /home/samson -s /bin/bash -e 2023-06-30
sudo chage -l samson
  1. 使用usermod将 Samson 的账户到期日变更为 2023 年 7 月 31 日:
sudo usermod -e 2023-07-31
sudo chage -l samson
  1. 为 Samson 的帐户分配一个密码,然后强制他在第一次登录时更改密码。以 Samson 身份登录,更改他的密码,然后登录到您自己的帐户:
sudo passwd samson
sudo passwd -e samson
sudo chage -l samson
su - samson
exit
  1. 使用chage设置五天的密码更改等待期、90 天的密码到期期、两天的不活动期和五天的警告期:
sudo chage -m 5 -M 90 -I 2 -W 5 samson
sudo chage -l samson
  1. 保留此帐户,因为您将在下一节的实验中使用它。

接下来,让我们看看如何防止暴力攻击。

防止暴力密码攻击

令人惊讶的是,这是另一个引起一些争议的话题。我的意思是,没有人否认自动锁定受到攻击的用户账户的智慧。有争议的部分涉及在锁定帐户之前我们应该允许的失败登录尝试的次数。

回到计算的石器时代,很久以前我还满头大汗,早期的 Unix 操作系统只允许用户创建最多八个小写字母的密码。因此,在那个年代,早期的人类有可能仅仅通过坐在键盘前输入随机密码就强行破解别人的密码。就在那时,用户帐户在三次登录失败后就被锁定的理念开始了。如今,使用强密码,或者更好的是强密码,将锁定值设置为三次失败的登录尝试将完成三件事:

  • 它会不必要地让用户感到沮丧。
  • 这会给服务台人员带来额外的工作。
  • 如果一个帐户真的受到攻击,它会在你有机会收集攻击者的信息之前锁定该帐户。

将锁定值设置为更现实的值,例如 100 次失败的登录尝试,仍将提供良好的安全性,同时仍让您有足够的时间收集关于攻击者的信息。同样重要的是,您不会给用户和帮助台人员带来不必要的挫败感。

无论如何,不管你的雇主允许你多少次失败的登录尝试,你仍然需要知道如何设置。所以,让我们开始吧。

配置 pam _ tally2 PAM

为了让这种魔力发挥作用,我们将依靠我们的好朋友帕姆。pam_tally2模块已经安装在 CentOS 和 Ubuntu 上,但是没有配置。对于我们的两个虚拟机,我们将编辑/etc/pam.d/login文件。弄清楚如何配置很容易,因为在pam_tally2手册页的底部有一个例子:

EXAMPLES
 Add the following line to /etc/pam.d/login to lock the account after
4 failed logins. Root account will be locked as well. The accounts will be
automatically unlocked after 20 minutes. The module does not have to be
called in the account phase because the login calls pam_setcred(3)
correctly.
 auth required pam_securetty.so
 auth required pam_tally2.so deny=4 even_deny_root
unlock_time=1200
 auth required pam_env.so
 auth required pam_unix.so
 auth required pam_nologin.so
 account required pam_unix.so
 password required pam_unix.so
 session required pam_limits.so
 session required pam_unix.so
 session required pam_lastlog.so nowtmp
 session optional pam_mail.so standard

在示例的第二行,我们看到pam_tally2设置如下:

  • deny=4:这意味着被攻击的用户账号只有四次登录尝试失败后才会被锁定。
  • even_deny_root:这意味着即使是根用户账号受到攻击也会被锁定。
  • unlock_time=1200:1200 秒后,或者 20 分钟后,账户会自动解锁。

现在,如果您查看任何一台虚拟机上的实际login文件,您会发现它们看起来并不完全像这两个手册页中的示例login文件。没关系,我们还是会成功的。

一旦您配置了login文件并且登录失败,您将看到在/var/log目录中创建了一个新文件。您可以使用pam_tally2实用程序查看该文件中的信息。如果不想等待超时时间,也可以使用pam_tally2手动解锁锁定的账户:

donnie@ubuntu-steemnode:~$ sudo pam_tally2
 Login Failures Latest failure From
 charlie 5 10/07/17 16:38:19
 donnie@ubuntu-steemnode:~$ sudo pam_tally2 --user=charlie --reset
 Login Failures Latest failure From
 charlie 5 10/07/17 16:38:19
 donnie@ubuntu-steemnode:~$ sudo pam_tally2
 donnie@ubuntu-steemnode:~$

请注意,在我对查理的帐户进行了重置之后,我没有从执行另一个查询中收到任何输出。

配置 pam _ tally2 的实践实验

配置pam_tally2超级简单,因为只需要在/etc/pam.d/login文件中增加一行。为了让事情变得更简单,你可以从pam_tally2手册页的例子中复制并粘贴那一行。尽管我之前说过要将失败登录的次数增加到 100 次,但我们暂时将这个数字保持在 4 次,我知道您不想为了演示这个而必须进行 100 次失败登录:

  1. 在 CentOS 或 Ubuntu 虚拟机上,打开/etc/pam.d/login文件进行编辑。寻找调用pam_securetty模块的行。(那应该是在 Ubuntu 的 32 号线附近和 CentOS 的 2 号线附近。)在该行下方,插入以下一行:
auth required pam_tally2.so deny=4 even_deny_root unlock_time=1200

保存文件并退出编辑器。

  1. 对于这一步,您需要注销自己的帐户,因为pam_tally2su不兼容。因此,请注销,并在故意使用错误密码的同时,尝试登录您在上一实验中创建的samson帐户。继续这样做,直到您看到帐户被锁定的消息。请注意,当deny值设置为4时,实际上需要五次失败的登录尝试才能锁定 Samson。
  2. 重新登录到您自己的用户帐户。运行此命令并记录输出:
sudo pam_tally2
  1. 在这一步中,您将模拟自己是服务台工作人员,而 Samson 刚刚打电话来请求您解锁他的帐户。在确认您真的与真正的 Samson 对话后,输入以下两个命令:
sudo pam_tally2 --user=samson --reset
sudo pam_tally2
  1. 现在你已经看到了这是如何工作的,打开/etc/pam.d/login文件进行编辑,将deny=参数从4更改为100并保存文件。(这将使您的配置在现代安全理念方面更加现实。)

锁定用户帐户

好了,您刚刚看到了如何让 Linux 自动锁定受到攻击的用户帐户。也有一些时候,你会希望能够手动锁定用户帐户。让我们看几个例子:

  • 当一个用户去度假,你想确保当他或她不在的时候,没有人会乱动他或她的账户
  • 当用户因可疑活动而受到调查时
  • 当用户离开公司时

关于最后一点,你可能会问自己,为什么我们不能删除不再在这里工作的人的账户?而且,你当然可以,很容易。然而,在你这样做之前,你需要检查你当地的法律,以确保你不会给自己带来很大的麻烦。例如,在美国,我们有萨班斯-奥克斯利法案,该法案限制上市公司可以从其计算机中删除哪些文件。如果您要删除一个用户帐户,以及该用户的主目录和邮件缓冲区,您可能会违反萨班斯-奥克斯利法案或您自己国家的同等法律。

无论如何,有两个实用程序可以用来临时锁定用户帐户:

  • 使用usermod锁定用户账户
  • 使用passwd锁定用户账户

In apparent contradiction to what I just said, at some point you will need to remove inactive user accounts. That's because malicious actors can use an inactive account to perform their dirty deeds, especially if that inactive account had any sort of administrative privileges. But when you do remove the accounts, make sure that you do so in accordance with local laws and with company policy. In fact, your best bet is to ensure that your organization has written guidelines for removing inactive user accounts in its change management procedures.

使用 usermod 锁定用户帐户

假设凯特琳已经休了产假,将会离开几个星期。我们可以通过以下方式锁定她的帐户:

 sudo usermod -L katelyn

当您查看 Katelyn 在/etc/shadow文件中的条目时,您现在会在她的密码哈希前看到一个感叹号,如下所示:

katelyn:!$6$uA5ecH1A$MZ6q5U.cyY2SRSJezV000AudP.ckXXndBNsXUdMI1vPO8aFmlLXcbGV25K5HSSaCv4RlDilwzlXq/hKvXRkpB/:17446:0:99999:7:::

这个感叹号使系统无法读取她的密码,这实际上将她锁在了系统之外。

要解锁她的帐户,只需执行以下操作:

sudo usermod -U katelyn

您将看到感叹号已被删除,因此她现在可以登录她的帐户。

使用密码锁定用户帐户

你也可以用这个锁定凯特琳的账户:

sudo passwd -l katelyn

这与usermod -L的工作相同,但方式略有不同。首先,passwd -l会给你一些关于正在发生的事情的反馈,而usermod -L则完全不给你任何反馈。在 Ubuntu 上,反馈如下:

donnie@ubuntu-steemnode:~$ sudo passwd -l katelyn
 [sudo] password for donnie:
 passwd: password expiry information changed.
 donnie@ubuntu-steemnode:~$

在 CentOS 上,反馈如下:

[donnie@localhost ~]$ sudo passwd -l katelyn
 Locking password for user katelyn.
 passwd: Success
 [donnie@localhost ~]$

还有,在 CentOS 机器上,你会看到passwd -l在密码哈希前面放了两个感叹号,而不是只有一个。无论哪种方式,效果都是一样的。

要解锁 Katelyn 的帐户,只需执行以下操作:

sudo passwd -u katelyn

In versions of Red Hat or CentOS prior to version 7, usermod -U would remove only one of the exclamation points that passwd -l places in front of the shadow file password hash, thereby leaving the account still locked. No big deal, though, because running usermod -U again would remove the second exclamation point.

In Red Hat or CentOS 7, it has been fixed. The passwd -l command still places two exclamation points in the shadow file, but usermod -U now removes both of them. (That's a shame, really, because it ruined a perfectly good demo that I liked to do for my students.)

锁定根用户帐户

如今,云是一项大生意,现在从 Rackspace、DigitalOcean 或微软 Azure 等公司租赁虚拟专用服务器非常普遍。这些可以有多种用途:

  • 你可以运行自己的网站,在那里安装自己的服务器软件,而不是让托管服务来做。
  • 您可以设置一个基于网络的应用供其他人访问。
  • 最近,我在一个加密挖掘频道上看到了一个 YouTube 演示,展示了如何在租用的虚拟专用服务器上设置一个 Stake Proof 主节点。

这些云服务的一个共同点是,当您第一次设置帐户,提供商为您设置虚拟机时,他们会让您登录根用户帐户。(即使在本地安装的 Ubuntu 上禁用了根帐户,Ubuntu 也会出现这种情况。)

我知道有一些人只是一直登录这些基于云的服务器的根帐户,并不去想它,但这真的是一个可怕的想法。有僵尸网络,如冰雹玛丽僵尸网络,持续扫描互联网,寻找其安全外壳端口暴露在互联网上的服务器。当僵尸网络找到一个,他们将对该服务器的根用户帐户进行暴力密码攻击。是的,僵尸网络有时会成功入侵,尤其是在根帐户设置了弱密码的情况下。

所以,在设置基于云的服务器时,首先要做的是为自己创建一个普通用户帐户,并以完全sudo权限设置。然后,注销根用户帐户,登录到您的新帐户,并执行以下操作:

sudo passwd -l root

我的意思是,真的,为什么要冒险让你的根帐户受损?

设置安全横幅

你真的,真的不想要的是有一个登录横幅,上面写着欢迎来到我们的网络。我这么说是因为,相当几年前,我参加了一个关于事件处理的辅导 SANS 课程。我们的讲师给我们讲了一个故事,讲的是一家公司如何把一名疑似网络入侵者告上法庭,结果却把这个案子给扔了。原因?被指控的入侵者说:“*嗯,我看到消息说欢迎来到网络,所以我认为我在那里真的很受欢迎。”*是的,据说,这足以让这个案子被驳回。

几年后,我把这个故事告诉了我的一个 Linux 管理课上的学生。一个学生说:“这没有道理。 我们的前门都有迎宾垫,但这并不意味着欢迎窃贼进来。“我不得不承认他说得有道理,我现在不得不怀疑这个故事的真实性。

无论如何,为了安全起见,您确实希望设置登录消息,明确只有授权用户才能访问系统。

使用 motd 文件

/etc/motd文件将向通过 Secure Shell 登录系统的任何人显示一条消息横幅。在您的 CentOS 机器上,已经有一个空的motd文件。在你的 Ubuntu 机器上,没有motd文件,但是创建一个很简单。无论哪种方式,在文本编辑器中打开文件并创建您的消息。保存文件,并通过安全外壳远程登录进行测试。你应该看到这样的东西:

 [email protected]'s password:
 Last login: Sat Oct 7 20:51:09 2017
 Warning: Authorized Users Only!
 All others will be prosecuted.
 [maggie@localhost ~]$

motd stands for Message of the Day.

Ubuntu 自带一个动态 MOTD 系统,显示来自 Ubuntu 母公司的消息和关于操作系统的消息。当您在/etc目录中创建新的motd文件时,您放入其中的任何消息都会显示在动态输出的末尾,如下所示:

Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-54-generic x86_64)

 * Documentation: https://help.ubuntu.com
 * Management: https://landscape.canonical.com
 * Support: https://ubuntu.com/advantage

 System information as of Sat Jul 13 00:21:49 UTC 2019

 System load: 0.0 Processes: 89
 Usage of /: 20.9% of 20.42GB Users logged in: 1
 Memory usage: 14% IP address for enp0s3: 192.168.0.3
 Swap usage: 0%

 * MicroK8s 1.15 is out! It has already been installed on more
 than 14 different distros. Guess which ones?

 https://snapcraft.io/microk8s

 153 packages can be updated.
 25 updates are security updates.

 Warning!!! Authorized users only!
 Last login: Sat Jul 13 00:09:30 2019
 donnie@packtpub1:~$

Warning!!! Authorized users only!行是我放入/etc/motd文件的内容。

使用问题文件

也在/etc目录中找到的issue文件在本地终端上显示了一条消息,就在登录提示上方。默认的issue文件只包含显示机器信息的宏代码。这里有一个来自 Ubuntu 机器的例子:

Ubuntu 18.04 LTS \n \l

或者,在红帽/CentOS 机器上,它看起来像这样:

\S
Kernel \r on an \m

在 Ubuntu 机器上,横幅看起来像这样:

在 CentOS 机器上,它看起来像这样:

您可以在问题文件中放入一条安全消息,它将在重新启动后显示:

实际上,在问题文件中放置安全消息真的有意义吗?如果你的服务器被正确地锁在一个有控制访问的服务器房间里,那么很可能不是。对于公开的台式计算机,这将更有用。

使用 issue.net 文件

只是不要。这是为了telnet登录,任何在服务器上启用telnet的人都是在严重搞砸。然而,由于某些奇怪的原因,issue.net文件仍然挂在/etc目录中。

检测泄露的密码

是的,亲爱的心,坏人确实有广泛的密码字典,要么是常用的,要么已经被泄露。暴力破解密码最有效的方法之一是使用这些字典来执行字典攻击。这是当密码破解工具从指定的字典中读入密码,并尝试每个密码,直到列表用尽,或者直到攻击成功。那么,你怎么知道你的密码是否在其中一个名单上?别紧张。只需使用一个在线服务,将为您检查您的密码。一个受欢迎的网站是我被解雇了吗?,这里可以看到:

You can get to Have I Been Pwned? here:

https://haveibeenpwned.com

你真正要做的就是输入你的密码,服务会显示它是否在任何泄露的密码列表中。但是仔细想想。你真的想把你的生产密码发到别人的网站上吗?是的,我想没有。相反,让我们只发送密码的哈希值。更好的是,让我们发送足够多的散列值,让网站能够在其数据库中找到密码,但不要太多,以至于他们无法知道你的确切密码是什么。我们将使用【我被解雇了吗? 应用编程接口 ( API )。

为了演示基本原理,让我们使用curl和应用编程接口来查看密码散列列表,这些散列的值中有21BD1。(您可以在任何虚拟机上执行此操作。我将在 Fedora 工作站上进行,我目前正在用它来输入这个。)只需运行以下命令:

curl https://api.pwnedpasswords.com/range/21BD1

你会得到很多这样的输出,所以我只显示前几行:

 [donnie@fedora-teaching ~]$ curl https://api.pwnedpasswords.com/range/21BD1
 0018A45C4D1DEF81644B54AB7F969B88D65:1
 00D4F6E8FA6EECAD2A3AA415EEC418D38EC:2
 011053FD0102E94D6AE2F8B83D76FAF94F6:1
 012A7CA357541F0AC487871FEEC1891C49C:2
 0136E006E24E7D152139815FB0FC6A50B15:3
 01A85766CD276B17DE6DA022AA3CADAC3CE:3
 024067E46835A540D6454DF5D1764F6AA63:3
 02551CADE5DDB7F0819C22BFBAAC6705182:1
 025B243055753383B479EF34B44B562701D:2
 02A56D549B5929D7CD58EEFA97BFA3DDDB3:8
 02F1C470B30D5DDFF9E914B90D35AB7A38F:3
 03052B53A891BDEA802D11691B9748C12DC:6
. . .
. . .

让我们把这个输入wc -l,一个方便的计数工具,看看我们找到了多少匹配的结果:

 [donnie@fedora-teaching ~]$ curl https://api.pwnedpasswords.com/range/21BD1 | wc -l
 % Total % Received % Xferd Average Speed Time Time Time Current
 Dload Upload Total Spent Left Speed
 100 20592 0 20592 0 0 197k 0 --:--:-- --:--:-- --:--:-- 199k
 526
 [donnie@fedora-teaching ~]$

根据这个,我们找到了 526 个匹配。但是那不是很有用,所以让我们稍微想象一下。我们将通过创建pwnedpasswords.sh shell 脚本来实现,如下所示:

#!/bin/bash
candidate_password=$1
echo "Candidate password: $candidate_password"
full_hash=$(echo -n $candidate_password | sha1sum | awk '{print substr($1, 0, 32)}')
prefix=$(echo $full_hash | awk '{print substr($1, 0, 5)}')
suffix=$(echo $full_hash | awk '{print substr($1, 6, 26)}')
if curl https://api.pwnedpasswords.com/range/$prefix | grep -i $suffix;
 then echo "Candidate password is compromised";
 else echo "Candidate password is OK for use";
fi

好吧,我现在不能试图把你变成一个 shell 脚本专家,但是这里有一个简单的解释:

  • candidate_password=$1:这需要您输入调用脚本时要检查的密码。
  • full_hash=prefix=suffix=:这些行计算密码的 SHA1 哈希值,然后只提取我们想要发送给密码检查服务的哈希部分。
  • if curl:我们以if..then..else结构结束,该结构将密码散列的选定部分发送给检查服务,然后告诉我们密码是否被泄露。

保存文件后,为用户添加可执行权限,如下所示:

chmod u+x pwnedpasswords.sh

现在,让我们看看我最喜欢的密码TurkeyLips是否被泄露了:

 [donnie@fedora-teaching ~]$ ./pwnedpasswords.sh TurkeyLips
 Candidate password: TurkeyLips
 % Total % Received % Xferd Average Speed Time Time Time Current
 Dload Upload Total Spent Left Speed
 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 09FDEDF4CA44D6B432645D6C1D3A8D4A16BD:2
 100 21483 0 21483 0 0 107k 0 --:--:-- --:--:-- --:--:-- 107k
 Candidate password is compromised
 [donnie@fedora-teaching ~]$

是的,已经妥协了,好吧。因此,我认为我不想将它用作生产密码。

现在,让我们再试一次,除了在末尾加上一个随机的两位数:

 [donnie@fedora-teaching ~]$ ./pwnedpasswords.sh TurkeyLips98
 Candidate password: TurkeyLips98
 % Total % Received % Xferd Average Speed Time Time Time Current
 Dload Upload Total Spent Left Speed
 100 20790 0 20790 0 0 110k 0 --:--:-- --:--:-- --:--:-- 110k
 Candidate password is OK for use
 [donnie@fedora-teaching ~]$

上面说这个没问题。尽管如此,您可能不希望使用这样一个已知已被泄露的简单密码排列。

I'd like to take credit for the shell script that I've presented here, but I can't. That was a creation of my buddy, Leo Dorrendorf of the VDOO Internet of Things security company. (I've reproduced the script here with his kind permission.)

If you're interested in security solutions for your Internet of Things devices, you can check them out here:

https://www.vdoo.com/

Full disclosure: the VDOO company is one of my clients.

现在,说了所有这些,我仍然需要提醒您,密码短语仍然比密码更好。密码短语不仅更难破解,而且也不太可能出现在任何人的受损凭证列表中。

检测泄露密码的实践实验室

在本实验中,您将使用pwnedpasswords应用编程接口来检查自己的密码:

  1. 使用curl查看密码散列中有多少个带有21BD1字符串的密码:
curl https://api.pwnedpasswords.com/range/21BD1
  1. 在任何一台 Linux 虚拟机的主目录中,创建包含以下内容的pwnpassword.sh脚本:
#!/bin/bash
candidate_password=$1
echo "Candidate password: $candidate_password"

full_hash=$(echo -n $candidate_password | sha1sum | awk '{print substr($1, 0, 32)}')
prefix=$(echo $full_hash | awk '{print substr($1, 0, 5)}')
suffix=$(echo $full_hash | awk '{print substr($1, 6, 26)}')

if curl https://api.pwnedpasswords.com/range/$prefix | grep -i $suffix;
        then echo "Candidate password is compromised";
        else echo "Candidate password is OK for use";
fi
  1. 向脚本添加可执行权限:
chmod u+x pwnedpasswords.sh
  1. 运行脚本,指定TurkeyLips作为密码:
./pwnedpasswords.sh TurkeyLips
  1. 重复步骤 4 任意多次,每次使用不同的密码。

到目前为止,我们所看到的在少量计算机上运行良好。但是如果你在大企业工作呢?我们接下来看看。

了解集中式用户管理

在企业环境中,您通常需要管理成百上千的用户和计算机。因此,登录到每个网络服务器或每个用户的工作站来执行我们刚刚概述的过程是非常不可行的。(但是请记住,您仍然需要这些技能。)我们需要的是一种从一个中心位置管理计算机和用户的方法。空间不允许我给出各种方法的完整细节。所以现在,我们只能满足于一个高层次的概述。

微软活动目录

我并不是 Windows 或微软的忠实粉丝。但是当涉及到活动目录时,我不得不在它应该出现的地方给予肯定。这是一个相当巧妙的产品,极大地简化了非常大的企业网络的管理。是的,可以将 Unix/Linux 计算机及其用户添加到活动目录域中。

I've been keeping a dark secret, and I hope that you won't hate me for it. Before I got into Linux, I obtained my MCSE certification for Windows Server 2003. Mostly, my clients work with nothing but Linux computers, but I occasionally do need to use my MCSE skills. Several years ago, a former client needed me to set up a Linux-based Nagios server as part of a Windows Server 2008 domain, so that its users would be authenticated by Active Directory. It took me a while to get it figured out, but I finally did, and my client was happy.

除非你戴很多帽子,就像我有时不得不做的那样,否则你——作为一名 Linux 管理员——可能不需要学习如何使用活动目录。最有可能的是,您只需告诉 Windows Server 管理员您需要什么,并让他们来处理。

我知道,你已经迫不及待地想看看我们能用 Linux 服务器做些什么。就这样。

Linux 上的 Samba

Samba 是一个 Unix/Linux 守护程序,可以服务于三个目的:

  • 它的主要目的是与 Windows 工作站共享 Unix/Linux 服务器上的目录。这些目录显示在窗口文件资源管理器中,就好像它们是从其他窗口机器上共享的一样。
  • 它也可以设置为网络打印服务器。
  • 它也可以设置为 Windows 域控制器。

您可以在 Linux 服务器上安装 Samba 版本 3,并将其设置为作为旧式的 Windows NT 域控制器。这是一个相当复杂的过程,需要一段时间。完成后,您可以将 Linux 和 Windows 机器加入域,并使用正常的 Windows 用户管理实用程序来管理用户和组。

Linux 社区的神圣 Grails 之一是找出如何在 Linux 服务器上模拟活动目录。就在几年前,随着 Samba 版本 4 的推出,这成为了现实。但是设置它是一个非常复杂的过程,你可能不会喜欢这样做。所以,也许我们应该继续寻找更好的东西。

RHEL/中央电视台的身份管理

几年前,红帽公司推出了 FreeIPA 作为 Fedora 的一套套装。为什么是 Fedora?这是因为他们想在 Fedora 上对其进行彻底测试,然后再将其用于实际的生产网络。现在 RHEL 6 号到 RHEL 8 号以及他们的所有后代,包括 CentOS 都可以使用。这就是 IPA 的含义:

  • 身份
  • 政策
  • 审计

这在某种程度上是对微软活动目录的回答,但它仍然不是一个完整的答案。它做了一些很酷的事情,但它仍然是一项正在进行的工作。最酷的是它的安装和设置非常简单。真正需要做的就是从普通的存储库中安装软件包,打开适当的防火墙端口,然后运行安装脚本。然后,你们都准备好开始通过 FreeIPA 的网络界面向新域添加用户和计算机。在这里,我要添加克利奥帕特拉,我的灰白色斑猫:

虽然可以将 Windows 机器添加到 FreeIPA 域,但不建议这样做。但是,从 RHEL/CentOS 7.1 开始,您可以使用 FreeIPA 与 Active Directory 域创建跨域信任。

The official name of this program is FreeIPA. But, for some strange reason, the Red Hat folk refuse to mention that name in their documentation. They always just refer to it as either Identity Management or IdM.

这差不多就是用户管理的话题了。让我们总结一下,然后进入下一章。

摘要

我们在这一章中讨论了很多内容,希望你能找到一些你可以实际使用的建议。我们首先向您展示了始终以 root 用户身份登录的危险,以及您应该如何使用sudo来代替。除了向您展示sudo用法的基本知识,我们还看了一些好的sudo技巧和窍门。

我们通过研究如何锁定用户的主目录,如何实施强密码策略,以及如何实施帐户和密码过期策略,进而进入用户管理。然后,我们讨论了防止暴力密码攻击的方法、如何手动锁定用户帐户、如何设置安全横幅以及如何检查泄露的密码。我们用中央用户管理系统的简要概述来结束本文。

在下一章中,我们将了解如何使用各种防火墙实用程序。到时候见。

问题

  1. 授予用户管理权限的最佳方式是什么? 答:给每个管理用户根用户密码。 B .将每个管理用户添加到sudo组或wheel组。 C .创建sudo规则,只允许管理用户执行与其工作直接相关的任务。 D .将每个管理用户添加到sudoers文件中,并授予他们完全管理权限。

  2. 以下哪一项是正确的? A .当用户以 root 用户身份登录时,他们执行的所有操作都将记录在auth.logsecure日志文件中。 B .当用户使用sudo时,他们执行的所有动作都会记录在messagessyslog文件中。 C .当用户以 root 用户身份登录时,他们执行的所有操作都将记录在messagessyslog文件中。 D .当用户使用sudo时,他们执行的所有动作都会记录在auth.logsecure日志文件中。

  3. 您会在哪个文件中配置复杂的密码标准?

  4. 使用useradd工具时,/etc/login.defs文件中的UMASK设置应该是什么?

  5. 使用adduser实用程序时,您会如何配置/etc/adduser.conf文件,以使新用户的主目录阻止其他用户访问它们?

  6. 国家标准与技术研究所最近对他们推荐的密码政策做了什么改变?

  7. 您会使用以下哪种方法为其他用户创建sudo规则? A .在自己喜欢的文本编辑器中打开/etc/sudoers文件。 B .用visudo打开/etc/sudoers文件。向每个用户的主目录添加一个sudoers文件。 D .用visudo打开/var/spool/sudoers文件。

  8. 您可以使用以下哪三种实用程序来设置用户帐户到期数据? a .useraddT5】b .adduserT6】c .usermodT7】d .chage

  9. 为什么你想锁定前员工的用户账户,而不是删除它? A .锁定账户比删除账户容易。 B .删除一个账号需要太长时间。 C .不能删除用户账号。 D .删除一个用户账号,连同用户的文件和邮箱,可能会给你带来法律上的麻烦。

  10. 您刚刚为 Samson 创建了一个用户帐户,现在您想强制他在第一次登录时更改密码。以下哪两个命令可以做到这一点? a .sudo chage -d 0 samsonT5】b .sudo passwd -d 0 samsonT6】c .sudo chage -e samsonT7】d .sudo passwd -e samson

  11. 以下哪一项代表最佳安全实践? A .始终将根用户密码给所有需要执行管理任务的用户。 B .始终给予所有需要执行管理任务的用户完全sudo权限。 C .始终只给予需要执行管理任务的所有用户特定的、有限的sudo权限。 D .始终在普通文本编辑器中编辑sudoers文件,如 nano、vim 或 emacs。

  12. 以下哪个陈述是正确的? A. sudo只能在 Linux 上使用。 B. sudo可以在 Linux、Unix、BSD 操作系统上使用。 C .当用户使用sudo执行任务时,该任务不会记录在安全日志中。 D .使用sudo时,用户必须输入 root 用户密码。

  13. 您希望特定用户编辑特定的系统配置文件,但不希望他们使用 shell escape 来执行其他管理任务。你会做以下哪一项? A .在sudoers文件中,指定用户只能使用 vim 打开特定的配置文件。在sudoers文件中,指定用户可以使用sudoedit编辑特定的配置文件。在sudoers文件中,为这些用户指定no shell escape选项。 D .在sudoers文件中,将这些用户放入没有 shell escape 权限的组中。

  14. adduser效用相对于传统的useradd效用,以下哪一项是优势? A. adduser可以用在 shell 脚本中。 B. adduser适用于所有 Linux 发行版。 C. adduser有一个选项,允许您在创建用户帐户时加密用户的主目录。 D. adduser同样适用于 Unix 和 BSD。

  15. 在最新的 Linux 发行版中,您将用来实施强密码的 PAM 的名称是什么? A .密码 B .密码 C .安全 D .密码质量

进一步阅读