系统保护意味着确保你的计算机资源仅由授权人员用于授权目的(only by authorized people for authorized purposes)。
既要防止系统资料被盗,也要防止系统资源被盗用。即使你系统上的数据毫无价值,你也必须保护系统的资源。
大多数实际入侵都来自政府审查的国家,流量分析表明,入侵者实际上只是想不受限制地访问新闻网站。
一般来说,操作系统不会被破坏,但其上运行的程序会。
所有能学到的关于系统安全的一切都只是工具包中的工具,而不是所有问题的答案。
提高系统的安全级别、合理的权限、文件标志、定期补丁、密码控制,以及构成良好安全策略的所有其他因素,这些相结合时,会帮助提升系统安全。
第十九章会介绍更高级的安全工具。
我们把潜在的攻击者任意分为四组:脚本小子(script kiddies)、心怀不满的用户、僵尸网络(botnets)、熟练的攻击者。这种分组不够详细、系统,但容易理解,基本上包括了你可能遇到的99%的攻击者。
script kiddies——脚本小子,这是最多的人类攻击者,他们不是系统管理员,对攻击并不熟练。他们下载以点击为基础的攻击程序,并寻找易受攻击的系统。幸运的是,脚本小子很容易防御:只需要保持软件更新并遵循良好的计算实践。
第二类是你自己的用户,他们造成了大多数安全问题。你组织的员工最有可能知道安全漏洞在哪里,觉得规则不适用于他们,并有时间破坏你的安全。如果你告诉员工公司政策禁止他访问某些计算机资源,而他觉得他应该访问这些资源,他可能会寻找绕过限制的方法。任何自以为是、想跳出规则的人都是一种安全风险。
阻止这些人的最好方法就是不要草率行事。不要让项目半途而废。当有人离开公司时,禁用他的帐户,更改所有管理密码,通知所有员工该人的离职,并提醒他们不要与该人分享机密知识。制定一个具有真正违规处罚的计算机安全政策,并让人力资源部执行。并摆脱不安全的调制解调器、在奇怪端口上运行的无证(undocumented)telnet服务器,或者任何你认为没有人会找到它的匆忙黑客攻击。
僵尸网络(botnets)比上述任何一种都多,但它们不是人类。它们是被恶意软件入侵的机器,有一个中心点控制。僵尸网络可以包括数百万台机器。恶意软件作者控制着僵尸网络,并将其用于从搜索更易受攻击的主机到发送垃圾邮件或闯入安全网站的任何事情。FreeBSD操作系统也可能被僵尸网络同化。
幸运的是,僵尸网络防御很像脚本小子防御:保持软件补丁并遵循良好的计算实践大有裨益。
熟练攻击者是最危险的群体,他们是有能力的系统管理员、安全研究人员、渗透专家和想要访问你特定资源的罪犯。
如今,计算机渗透是一个利润丰厚的犯罪领域,特别是如果受害者拥有可用于分布式拒绝服务(distributed denial-of-service——DDos)攻击或大规模垃圾邮件传输的资源。妥协一个网络农场并将其变成邪恶是有利可图的。如果你有宝贵的公司机密,你可能会成为这些入侵者的目标。
抵御任何攻击者的最佳防御是保持系统的最新状态。这意味着您必须知道何时修补系统、修补什么以及如何修补。一个过时的系统是脚本孩子最好的朋友。
FreeBSD项目包括专门审计源代码和观察基础操作系统和附加软件安全问题的志愿者。这些开发人员维护着一个非常低容量的邮件列表,FreeBSD-security-notifications@FreeBSD.org,订阅是个好主意。虽然您可以监视其他邮件列表以获取一般公告,但安全通知列表是FreeBSD特定信息的单一来源。要订阅安全通知邮件列表,请参阅以下说明http://lists.freebsd.org/.FreeBSD安全团队会在邮件列表上发布公告。
仔细阅读建议,并对影响您的建议迅速采取行动,因为您可以确定脚本小子正在搜索易受攻击的机器。正如第18章所讨论的那样,FreeBSD使应用安全补丁变得非常容易。
FreeBSD有很多种方法允许用户在不让他们自由支配系统的情况下完成工作。我们将在这里介绍最重要的工具,首先从添加用户开始。
FreeBSD使用标准的Unix用户管理程序,如passwd(1)、pw(8)、vipw(8)。FreeBSD还包括一个友好的交互式用户添加程序adduser(8)。只有root可以添加用户。
第一次运行adduser(8)时,它会提示你为所有新用户设置适当的默认值。使用以下示例会话帮助你确定系统的适当默认值:
xxxxxxxxxx
# adduser
➊ Username: xistence
➋ Full name: Bert Reger
➌ Uid (Leave empty for default):
Username➊是帐户的名称。我的系统上的用户会得到他们的首字母、中间字母和姓氏的用户名。你可以根据你想出的任何方案来分配用户名。在这里,我让用户选择自己的用户名,但这不是个好习惯。Full name➋是用户的真实姓名。FreeBSD允许您选择一个数字的用户ID(UID)➌。FreeBSD从1000开始对UID进行编号;虽然您可以更改此设置,但1000以下的所有UID都保留供系统使用。我建议只按ENTER键获取下一个可用的UID。
xxxxxxxxxx
➊ Login group [xistence]:
➋ Login group is xistence. Invite xistence into other groups? []: www
➌ Login class [default]:
➍ Shell (sh csh tcsh nologin) [sh]: tcsh
➎ Home directory [/home/xistence]:
➏ Home directory permissions (Leave empty for default):
用户的默认组——Login group➊很重要——记住,Unix权限是由所有者和组设置的。FreeBSD的默认设置是让每个用户都在自己的组中,这通常是大多数设置中最明智的方式。任何一本关于系统管理的厚书都提供了几种分组方案——可以随意使用任何符合您需求的方案。如果合适,您可以将此用户添加到除主组之外的其他组——other group➋中。
登录类——Login class➌指定用户可以访问的资源级别。我们将在本节稍后讨论登录类。
shell➍是命令行环境。虽然系统默认值是/bin/sh,但我更喜欢tcsh。如果你对另一个shell有很深的依赖,可以随时使用它。知识渊博的用户可以更改自己的shell。
Home directory➎是用户文件驻留在磁盘上的位置。用户和该用户的主要组拥有此目录。如果需要,您可以在目录上设置自定义权限Home directory permissions➏,这样其他用户就无法查看此用户的目录。
xxxxxxxxxx
➊ Use password-based authentication? [yes]:
➋ Use an empty password? (yes/no) [no]:
➌ Use a random password? (yes/no) [no]: y
➍ Lock out the account after creation? [no]: n
密码选项为您提供了一定程度的灵活性。如果您的所有用户都对基于密钥的SSH身份验证感到满意,也许您可以不使用密码。与此同时,我们其他人都被密码所困➊。
如果您希望用户通过控制台设置自己的密码,请使用空密码——empty password➋。谁先连接到该帐户,谁就可以设置密码。这使得在氢飞船(hydrogen dirigible)内吸烟时,空密码是一个好主意。
另一方面,随机密码——random password➌对于新帐户来说是个好主意。FreeBSD提供的随机密码生成器足以满足日常使用。随机密码通常很难记住,这会鼓励用户尽快更改密码。
当帐户被锁定——Lock out时➍,没有人可以使用它登录。这通常会适得其反。
输入所有这些信息后,adduser会将所有内容都吐回给您进行审核、确认或拒绝。确认后,adduser将验证帐户设置,并向您提供随机生成的密码。然后,它创建用户的主目录,从/etc/skel复制shell配置文件(此处存疑,未找到该文件),并询问您是否要设置另一个用户。
在某些Unix系统上创建新用户需要你手动编辑/etc/passwd、重建密码数据库、编辑/etc/group、创建主目录、设置该主目录的权限、安装点文件(dotfiles)等。
adduser(8)程序提供了一组合理的默认值。对于具有不同要求的站点,/etc/adduser.conf允许你将这些要求设置为默认值,同时保持高度的自动化。要创建adduser.conf文件,请运行adduser -C并回答问题:
xxxxxxxxxx
➊ Uid (Leave empty for default):
➋ Login group []:
➌ Enter additional groups []: staff
➍ Login class [default]: staff
➎ Shell (sh csh tcsh nologin) [sh]: tcsh
➏ Home directory [/home/]: /nfs/u1/home
➐ Use password-based authentication? [yes]:
➑ Use an empty password? (yes/no) [no]:
➒ Use a random password? (yes/no) [no]: yes
➓ Lock out the account after creation? [no]: no
您可能希望从1000以外的某个地方开始对UID进行编号。如果你想要更高的初始Uid,请在uid空间➊中输入。不要从1000以下开始。
Login group➋是默认用户组。空登录组意味着用户帐户默认具有自己的唯一用户组(FreeBSD默认)。 默认情况下,您可以指定新帐户所属的任何additional group➌以及Login class➍。我将这两个都设置为staff,以便所有新用户都添加到该组并分配该类。
为用户选择默认shell➎。
您的Home directory➏可能与独立的FreeBSD标准不同。在这个例子中,我指定了一种典型的NFS挂载主目录样式,当许多用户在许多机器上都有帐户时使用。
为新用户选择默认密码行为。您可以指定用户是否应该使用密码——Use password-based authentication➐以及初始密码是empty➑还是random➒。
最后,决定新帐户是否应默认Lock out➓。
您可以在adduser.conf(5)中找到更多配置设置。虽然您可以在此处设置帐户特性,但此文件的格式被认为是adduser(8)的内部格式。设置名称可以随任何FreeBSD版本而更改。要更改adduser.conf,请重新运行adduser -C。
FreeBSD用于编辑账户的工具包括passwd(1)、chpass(1)、vipw(8)、pw(8)。这些工作在紧密相关的文件/etc/master.passwd、/etc/passwd、/etc/spwd.db和/etc/pwd.db之上。我们先从文件开始,然后查看编辑这些文件的常用工具。
/etc/master.passwd、/etc/passwd、/etc/spwd.db和/etc/pwd.db这四个文件保存用户账户信息。每个文件的格式和用途略有不同。/etc/master.passwd文件是用户账户信息的权威来源,其中包含加密形式的用户密码。普通用户无权查看/etc/master.passwd的内容。然而,普通用户需要访问基本账户信息。除此之外,无特权的系统程序如何识别用户?/etc/passwd文件列出了删除了所有特权信息(如加密密码)的用户账户。任何人都可以查看/etc/passwd的内容,以获取基本账户信息。
许多程序需要账户信息,解析文本文件的速度非常慢。在笔记本电脑超级计算机的时代,“慢”这个词并不是很有意义,但在迪斯科自由漫游地球的时代,这是一个非常现实的问题。因此,BSD派生系统使用/etc/master.passwd,包含敏感的用户信息,但只能由root读取。任何人都可以读取/etc/pwd.db文件,但它包含/etc/passwd中包含的有限信息子集。
每当任何标准用户管理程序更改/etc/master.passwd中的账户信息时,FreeBSD都会运行pwd_mkdb(8)来更新其他三个文件。例如,passwd(1)、chpass(1)和vipw(8)三个程序都允许你更改主密码文件,并且所有三个程序均会触发pwd_mkdb来更新相关文件。
使用passwd(1)更改密码。用户可以更改自己的密码,root可以更改任何人的密码。要更改自己的密码,只需要在命令提示符下输入passwd:
xxxxxxxxxx
# passwd
Changing local password for mwlucas
Old Password:
New Password:
Retype New Password:
更改自己的密码时,passwd(1)首先会询问您当前的密码。这是为了确保在您不知情的情况下,其他人无法更改您的密码。当你离开终端时,注销总是好的,但当你不这样做时,这个简单的passwd(1)检查可以防止恶作剧者真正惹恼你。然后输入两次新密码,就完成了。当你是超级用户并想更改另一个用户的密码时,只需将用户名作为passwd的参数:
xxxxxxxxxx
# passwd mwlucas
Changing local password for mwlucas
New Password:
Retype New Password:
注意,root不需要知道用户的旧密码。root可以用期望的方式修改系统中任何用户的密码。
一些用户管理工具,如chpass和vipw,会弹出一个文本编辑器窗口,你可以在其中进行更改。这些工具通常会检查环境变量$EDITOR,以了解你更喜欢哪种文件编辑器。$EDITOR允许你默认使用vi、Emacs或其他任何编辑器。我推荐Vigor,一个带有动画回形针帮助系统的vi(1)克隆版,它可能会让旧版MS Office用户感觉更舒服。
账户具有比密码更多的相关信息。chpass(1)实用程序允许用户编辑他们在账户中可以访问的所有内容。例如,如果我以普通用户身份运行chpass(1),我会得到一个包含以下文本的编辑器:
xxxxxxxxxx
#Changing user information for mwlucas.
Shell: /bin/tcsh
Full Name: Michael W Lucas
Office Location:
Office Phone:
Home Phone:
Other information:
我可以编辑我帐户中的六个信息字段。第一个shell,我的shell,可以设置为/etc/shells中列出的任何shell(请参阅第178页的“shells和/etc/shells”)。我可以更改我的全名(Full Name);也许我希望列出我的完整中间名,或者也许我希望其他系统用户知道我是Scabies先生。我可以更新我的办公室位置(Office Location)和办公室电话(Office Phone),这样我的同事就可以很容易地找到我。这是另一个在BSD成长的大学校园里非常有用的功能,在那里,系统用户很少知道任何人的物理位置。现在我们有了广泛的在线目录和更多的计算机,它就没那么有用了。我通常将家里的电话号码(Home Phone)设置为911(英国为999),并在“其他”(Other information)栏中输入一点个人信息。
还要注意我作为普通用户无法更改的内容。系统管理员设置了我的主目录,即使系统有一个新的硬盘,里面有很多空的空间来存放我的MP3收藏,我也可能不会更改它。我的UID和GID号码同样由系统或系统管理员分配。
另一方面,如果我经营一家公司,它更高的特权给了我一种截然不同的看法。
xxxxxxxxxx
#Changing user information for xistence.
Login: xistence
➊ Password: $6$D9b4FFD0kHK2sPSP$bXUFTQqV/QposXw2KTlswzpvoz4HBo8...
Uid [#]: 1001
Gid [# or name]: 1001
Change [month day year]:
Expire [month day year]:
Class:
Home directory: /home/xistence
Shell: /bin/tcsh
Full Name: Bert Regeer
Office Location:
Office Phone:
Home Phone:
Other information:
作为root,你可以对用户账户做任何你想做的事情。将他的登录名更改为megaloser只是你可以造成的破坏的开始。您甚至可以访问用户的哈希密码➊。除非您对计算密码哈希感到满意,否则不要更改此字段。使用passwd(1)可以更安全可靠地更改用户的密码。您还可以更改用户的主目录,尽管chpass(1)不会移动用户的文件;你必须亲手拷贝。
您还可以设置密码更改(Change)和帐户过期(Expire)的日期。如果您刚刚更改了用户的密码,并希望他在首次登录时更改密码,则密码过期非常有用。当有人要求帐户但坚持只在有限的时间内需要时,帐户过期是有用的。您可以忘记返回删除该帐户,但FreeBSD永远不会忘记。这两个字段都采用month-day-year格式的日期,但您只需要月份的前三个字母。例如,要使用户的密码在2028年6月8日到期,我会在“Change”空间中输入Jun 8 2028。一旦用户更改了密码,密码过期字段将再次被清空,但只有系统管理员可以延长帐户过期日期。
虽然chpass(1)可以用于编辑单个帐户,但当您必须编辑多个帐户时会发生什么?假设您的系统有数百个用户,并且有一个全新的硬盘作为主分区。你真的想运行chpass(1)数百次吗?这就是vipw(8)发挥作用的地方。
使用vipw(8)直接编辑/etc/master.passwd。当你完成编辑时,vipw(8)会检查密码文件的语法,以确保你没有破坏任何东西。然后,它保存新的密码文件并运行pwd_mkdb(8)。虽然vipw(8)可以保护你的密码文件免受许多基本错误的影响,但如果你聪明,你仍然可以把事情搞砸。您必须了解密码文件的格式才能正确使用vipw(8)。
如果/etc/master.passwd中的信息与其他文件中的信息冲突,则/etc/master.psswd获胜。例如,出现在/etc/master.passwd中的主组是正确的,即使/etc/group没有将用户显示为成员。这种“master.passwd总是正确的”逻辑在整个用户管理中根深蒂固。
/etc/master.passwd中的每一行都是一个帐户记录,包含10个冒号分隔的字段。这些字段如下:
虽然chpass(1)可以搞乱单个用户账户,但vipw(8)却可能会影响整个用户群,慎用!
rmuser(8)程序删除用户账户。系统将提示你输入要删除的用户名,并询问是否要删除该用户的主目录。这就是你所需要做的,毕竟,毁灭(destruction)比创造容易得多。
pw(8)命令为用户帐户提供了一个强大的命令行界面。useradd(8)以友好的方式引导您设置帐户,而pw(8)允许您在单个命令行上指定所有内容。我发现pw(8)在日常使用中很麻烦,但如果你管理许多用户帐户,它是无价的。
我确实使用pw(8)来锁定帐户。当一个锁定的帐户处于活动状态时,没有人可以登录。当客户拖欠账单时,我使用了这个方法,效果很好;当用户无法登录时,他们会很快打电话,但他们的网站仍在继续,电子邮件也在不断积累。
xxxxxxxxxx
# pw lock xistence
当伯特道歉时,我会解锁他的账户:
xxxxxxxxxx
# pw unlock xistence
如果你需要脚本来管理你的用户,一定要阅读pw(8)手册页。
shell 是提供用户命令提示符的程序。不同的shell行为不同,提供不同的快捷方式和功能。许多人非常依恋特定的shell,如果他们常用的shell在系统上不可用,他们会抱怨。packages集合包含许多shell。
/etc/shells 文件包含所有合法的用户shell列表。当你从port或package安装了一个shell,它就会被添加到 /etc/shells 文件中。如果你从源代码编译了一个shell,你必须手动将它的完整路径添加到 /etc/shells 文件里面。
如果用户的shell未在 /etc/shells 文件中列出,FTP守护进程将不允许用户通过FTP登录。如果将 /sbin/nologin 用作FTP-only用户shell,则必须将其添加到此文件,尽管处理此类用户的更好方法是使用登录类,本章稍后会介绍。
Unix安全性一直被认为有点粗糙,因为一个超级用户 root 可以做任何事情。其他用户是卑微的人,他们忍受着root施加的枷锁。问题是,root手上没有各种各样的枷锁,也不能很好地个性化。虽然这有一些道理,但一个体面(decent)的管理员可以将组和权限结合起来,安全地处理几乎任何问题。
某些操作需要对系统进行绝对控制,包括操纵核心系统文件,如内核、设备驱动程序和身份验证系统。这些活动被设计为由root执行。
要使用root密码,你可以在控制台登录提示下以root身份登录,或者,如果你是wheel组的成员,你可以用自己的身份登录,并使用切换用户(switch user)命令su(1)
。(稍后我们将讨论组)。我推荐用su;它记录谁使用了它并可以在远程系统上使用。该命令看起来很简单:
xxxxxxxxxx
# su
Password:
#
然后使用 id(1)
命令检查当前的用户ID:
xxxxxxxxxx
# id
uid=0(root) gid=0(wheel) groups=0(wheel), 5(operator)
#
现在,你拥有了整个系统。考虑每一个按键;粗心大意会使你的硬盘恢复到原始状态,即未格式化的空旷荒地。如果有的话,也要谨慎共享root密码,因为任何拥有root密码的人都可以对系统造成无限的损害。
记住,只有whell组中的用户才能使用root密码通过 su(1)
成为root。任何人都可以在系统控制台上使用root密码,这就是为什么对系统的物理保护至关重要。如果你把root密码给一个没有物理访问权限的普通用户,他们可以根据需要多次键入su和输入root密码,但仍然无法使用。
这自然会引发一个问题,“谁需要root访问权限?”本书中讨论的大部分配置都需要使用root密码。一旦系统正常运行,你可以大大减少或停止使用root密码。对于那些绝对需要root权限的剩余任务,我建议使用sudo包,可能还有我的书 Sudo Master 。减少对root访问需求的最简单方法之一是正确使用组。
类Unix操作系统将用户分为不同的 groups ,每组由执行类似管理功能的人组成。系统管理员可以定义一个名为 webmasters 的组,将编辑网页的人员的账户添加到该组,并设置与web相关的文件的权限,以便该组的成员可以编辑这些文件。她还可以创建一个名为 email 的组,将电子邮件管理员添加到该组,并相应地设置邮件相关文件的权限。以这种方式使用组是系统管理中一种强大而经常被忽视的工具。
任何用户都可以用 id(1)
标识她所属的组。前面的示例显示,用户root位于wheel组和operator组中。然而,root是一个特殊的用户,她可以做任何她想做的事情。下面是我的账户,对普通用户来说更现实一些:
xxxxxxxxxx
# id
uid=1001(mwlucas) gid=1001(mwlucas) groups=1001(mwlucas),0(wheel),68(dialer),10001(webmaster)
我的UID是1001,我的用户名是 mwlucas。我的GID(主要组ID)是1001,我的主要组也被命名未 mwlucas。对于系统上的第一用户来说,这一切都是相当标准的,即使在后来的用户中,唯一改变的是分配给账户和主要组的编号。更有趣的是我被分配到了哪些其他组:除了我的主要组外,我还在组wheel、dialer、webmaster中。wheel成员可以使用root密码成为root,dialer成员可以使用 tip(1)
而不成为root,webmaster成员可以在本地系统上编辑web文件。这些组中的每一个在我的系统上都有特权,作为这些组的成员,我继承了这些特权。
组信息在 /etc/group 中定义。
文件 /etc/group 包含除用户的主组(使用 /etc/master.passwd 中的用户账户定义)之外的所有组信息。 /etc/group 中的每一行都包含四个冒号分隔的字段:组名、组密码、组ID、组成员列表。
下面是一个简单的条目:
xxxxxxxxxx
wheel:*:0:root,mwlucas,xistence
组名是组的人性化(human-friendly)名称。这个组被命名为 wheel 。组名是任意的;如果你愿意,你可以称一群用户为 lackeys(走狗)。选择能够让你了解这些组的用途的组名;虽然你可能还记得 lackeys 可能会编辑公司的网页,但你的同事会理解吗?
第二个字段是组密码。这是个好主意,但结果却是一场安全噩梦。现代类Unix系统不使用组密码,但该字段仍然存在,因为旧程序希望在这个空间中找到一些东西。星号是用来安抚此类软件的占位符(placeholder)。
第三个字段给出组的唯一数字组ID(GID)。许多程序使用GID而不是名称来标识组。wheel组的GID为0,最大GID为65535。
最后一个字段是组中所有用户的逗号分隔列表。用户 root、mwlucas 和 xistence 都是wheel组的成员。
如果要将用户添加到组中,请将他的用户名添加到改组的行末尾。例如,wheel组是可以使用root密码的用户列表。在这里,我将rwatson添加到wheel组中:
xxxxxxxxxx
wheel:*:0:root,mwlucas,xistence,rwatson
请注意,我说服rwatson(领先的安全研究员和前FreeBSD基金会主席)在我的任何系统上承担系统管理员职责的可能性从微不足道到不存在,但值得一试。
要创建新组,你只需要组的名称和组ID号。从技术上讲,组里不需要成员;有些程序作为组成员运行,FreeBSD使用组权限来控制这些程序,就像控制用户一样。
传统上,GID被分配到列表上的下一个数字。GID是介于0到65535之间的任意数字。一般来说,1000以下的GID保留给操作系统使用。需要专用组ID的程序通常使用此范围内的组ID。用户账户的GID编号从1001开始,然后递增。一些特殊群体的编号可能熊65535开始,然后递减。
除了安全问题外,root密码分发策略还可能在任何组织中引起分歧。许多系统管理员拒绝与负责维护部分系统但不提供替代方案的人共享root密码,从而阻止人们完成工作。其他系统管理员讲root发给任何想要它的人,然后再系统变得不稳定时抱怨。从长远来看,这两种态度都是不可取的。就我个人而言,我不想再你的系统上root。虽然拥有root权限可能很方便,但在系统崩溃时无需担责更有利。
一种常见的情况是,初级系统管理员负责系统的特定部分。我手下有很多DNS管理员;这些人从不安装软件、重新编译内核或执行其他系统管理员任务。他们只回复电子邮件、更新区域文件和更新加载指定的守护进程。新系统管理员通常认为他们需要root权限来做这些工作。你可以使用组。
建立自己的组,由执行类似管理功能的人员组成,可以避免分发root密码,同时仍然允许人员完成工作。在本节中,我们将对名称服务器文件实施组级访问控制。同样的原则适用于你选择保护的任何文件。邮件和web配置文件是基于组的管理的其他流行选择。
FreeBSD为集成程序保留了一些用户账户名。我们将在第十九章讨论这些无特权账户。例如,名称服务器在用户账户绑定和组绑定下运行。如果入侵者破坏了名称服务器,她只能以用户绑定的权限访问系统。
不要让用户以这些账户的身份登录。它们不是设计为交互式账户的。此外,不允许系统账户用户组拥有为该功能创建的文件。创建一个单独的用户和组来拥有程序文件。这样,我们假设的入侵者甚至无法编辑DNS服务器使用的文件,从而进一步最大限度地减少了潜在的损害。如果程序定期更新文件(例如数据库的后端存储),则必须授予程序访问权限,但很可能人类永远不需要编辑该文件。同样,数据库也没有理由能够编辑自己的配置文件。
创建拥有文件的组的最简单方法是使用 adduser(8)
创建拥有这些文件的用户,然后将该用户的主组作为文件的组。因为我们已经有一个名为 bind 的用户,所以我们将创建一个管理用户 dns 。用户名并不重要,但你应该选择一个大家都能认出的名字。
给你的管理用户一个 nologin shell,它将设置一个 /sbin/nologin shell。这会阻止任何人以管理用户身份实际登录。
如果你愿意,你可以为这类用户指定一个特定的UID和GID。众所周知,我选择的UID和GID号码与他们的相关服务账户使用的号码类似。例如,用户绑定的UID和GID为53。我可以给用户 dns 一个UID 10053,使其易于识别。在其他时候,我开始将我的管理组编号为65535,然后逐步向下。只要我在一个组织内保持完全一致,这并不重要。
不要将此管理用户添加到任何其他组。在任何情况下,都不要将此用户添加到特权组,如 wheel 。
每个用户都需要一个主目录。对于管理用户来说,/nonexistent 的主目录工作得很好。毕竟,此用户得文件在系统的其他地方。
最后,让 adduser(8)
禁用该用户。虽然shell阻止登录,但额外的防御层不会造成伤害。
现在你有了一个管理用户和一个组,你可以将文件的所有权分配给该用户。一个用户和一个组拥有每个文件。你可以使用 ls -l
查看现有的文件所有权(ownership)和权限(permissions)。许多系统管理员密切关注文件所有者,对全球权限关注较少,只关注组权限。
xxxxxxxxxx
# ls -l
total 3166
-rw-r----- 1 mwlucas mwlucas 79552 Nov 11 17:58 rndc.key
-rw-rw-r-- 1 mwlucas mwlucas 3131606 Nov 11 17:58 mwl.io.db
此处,我们创建了两个文件。第一个文件 rndc.key 可以由用户 mwlucas 读取和写入。 mwlucas 组中的任何人都可以读取该文件,但其他人无法对其进行任何操作。mwl.io.db 文件可以由用户 mwlucas 或组 mwlucas 中的任何人读取和写入,但其他用户只能读取该文件。如果你属于 mwlucas 组,则可以在不成为root的情况下编辑文件 mwl.io.db 。
使用 chown(1)
更改文件的所有者和组。你必须知道更改其所有权的用户和组的名称。在这种情况下,我们希望将这两个文件都更改为由用户 dns 和 组 dns 拥有。
xxxxxxxxxx
# chown dns:dns rndc.key
# chown dns:dns mwl.io.db
# ls -l
total 3166
-rw-r----- 1 dns dns 79552 Nov 11 17:58 rndc.key
-rw-rw-r-- 1 dns dns 3131606 Nov 11 17:58 mwl.io.db
这些文件现在由用户 dns 和组 dns 拥有。dns组里面的任何人都可以编辑 mwl.io.db ,而无需使用root密码。最后,运行名称服务器的用户bind可以读取此文件。将你的DNS管理员添加到 /etc/group 中的dns组中,他们就可以完成工作了。
DNS管理员可能认为他们需要root密码来重新启动名称服务器程序本身。然而,这很容易用 rndc(8)
来管理。其他任务可以使用cron作业或附加程序 sudo(8)
进行管理。
如果你不需要管理用户,而只需要一个组,请使用 vigr(8)
编辑 /etc/group 。
FreeBSD附带了几个默认组。大多数都是由系统使用的,对于系统管理员来说并不是什么大问题——你应该知道它们就在那里,但这与日常使用它们不同。在下表中,我为您介绍了默认组中最有用、最有趣、最好奇的组,供您娱乐和启迪。添加自己的组简化了系统管理,但这里列出的组在每个FreeBSD系统上都可用。
组名 | 目的 |
---|---|
audit | 可以访问 audit(8) 信息的用户 |
authpf | 可以向PF数据包过滤器进行身份验证的用户 |
bin | 通用系统程序的组所有者 |
bind | BIND DNS服务器软件组 |
daemon | 用于各种系统服务,如打印系统 |
_dhcp | DHCP 客户端操作 |
dialer | 可以访问串行端口的用户;适用于调制解调器和 tip(1) |
games | 游戏文件所有者 |
guest | 系统访客(几乎从未使用过) |
hast | hastd(8) 使用的文件 |
kmem | 可以访问内核内存的程序如 fstat(1) , netstat(1) 等 |
邮件系统的所有者 | |
mailnull | sendmail(8) 或其他邮件服务器的默认组 |
man | 未压缩手册页的所有者 |
network | 网络程序的所有者,如 ppp(8) |
news | Usenet新闻软件的所有者(可能未安装) |
nobody | 非特权用户nobody的主要组,供NFS使用 |
nogroup | 没有权限的组,供NFS使用 |
operator | 可以访问驱动器的用户,通常用于备份目的 |
_pflogd | PF日志组 |
proxy | PF数据包过滤器中FTP代理的组 |
smmsp | Sendmail提交组 |
sshd | SSH服务器的所有者 (see Chapter 20) |
staff | 系统管理员(来自BSD的大学 roots,当时用户是staff、faculty或students) |
sys | 另一个系统组 |
tty | 可以写入终端的程序,如 wall(1) |
unbound | 与 unbound(8) DNS 服务器相关的文件和程序 |
uucp | 与Unix-to-Unix Copy Protocol 相关的程序组 |
video | 可以访问DRM和DRI视频设备的组 |
wheel | 可以使用root密码的用户 |
www | Web服务器程序(非文件) |
_ypldap | LDAP-backed YP 服务器 ypldap(8) 所需的文件 |
我知道很少有人使用互联网新闻组或UUCP,你可能会认为你可以将这些组用于其他目的。然而,你最好创建一个新的组,而不是以后冒着混淆的风险。组ID号并不短缺。
通过对帐户设置限制,可以防止任何单个用户使用过多的内存、处理器时间或其他系统资源。现在,即使是小型计算机也有非常快的处理器和大量的内存,这些限制并不那么重要,但在拥有数十或数百名用户的系统中仍然非常有用。您还可以控制用户可以从哪里登录。
FreeBSD每次用户尝试登录时都会检查 /etc/login.access 。如果 login.access包含禁止该用户登录的规则,则登录尝试会立即失败。默认情况下,此文件没有规则,这意味着任何提供了有效用户名和密码的人都可以登录。
/etc/login.access 文件有三个冒号分隔的字段。第一个授予(+)或拒绝(-)登录权;第二个是用户或组的列表;第三个是连接资源列表。你可以使用 ALL
或 ALL EXCEPT
语法,这允许你制定简单但富有表现力的规则。规则在首次匹配的基础上进行检查。当 login(1)
发现用户和连接源匹配的规则时,连接会立即被接受或拒绝,这使得规则顺序变得至关重要。默认设置是允许登录。
例如,要只允许wheel组的成员从系统控制台登录,你可以尝试以下规则:
xxxxxxxxxx
+:wheel:console
然而,此规则的问题在于,它实际上并没有拒绝用户的登录权限。由于默认设置是接受登录,并且由于此规则所做的一切都是明确地向wheel组中的用户授予登录权限,因此没有任何变化。Bert不在wheel组中,但如果他试图登录,没有任何规则拒绝他访问。
你可以试试以下两条规则:
xxxxxxxxxx
+:wheel: console
-:ALL:console
这套规则可以达到预期的效果,但比你需要的要长。使用 ALL EXCEPT
替代:
xxxxxxxxxx
-:ALL EXCEPT wheel: console
此规则最快地拒绝不需要的登录,并且管理员出错的风险较小。通常,最好通过拒绝登录而不是允许登录来构建 login.access 列表。FreeBSD在满足此规则后立即在控制台拒绝非wheel用户。
通过添加最终规则,将默认值从 allow access
更改为 deny access
:
xxxxxxxxxx
-:ALL:ALL
任何不符合早期许可规则的登录请求都会被拒绝。
连接源 login.access 中的最后一个字段可以使用主机名、主机地址、网络号、域名或特殊值 LOCAL
和 ALL
。让我们看看它们是如何工作的。
主机名依赖于DNS或hosts文件。如果你怀疑你的名称服务器可能遭受入侵或攻击,请避免使用主机名;入侵者可以给主机名任何他们喜欢的IP地址,并欺骗你的系统接受连接,名称服务器故障可能会将你完全锁定。不过,也可以使用这样的规则:
xxxxxxxxxx
-:ALL EXCEPT wheel:fileserver.mycompany.com
wheel组中的用户可以从文件服务器登录,但其他人不能。
主机地址的工作方式类似于主机名,但它们不受DNS故障或欺骗的影响。
xxxxxxxxxx
-:ALL EXCEPT wheel:203.0.113.5
网络号是一个截断的IP地址,如下所示:
xxxxxxxxxx
-:ALL EXCEPT wheel:203.0.113.
此网络号允许wheel组中的任何人从IP地址以203.0.113开头的计算机登录,并拒绝其他人从这些IP地址访问。
最复杂的位置是 LOCAL
,它匹配任何没有点的主机名(通常,只有本地域中的主机)。例如,www.mwl.io 认为域 mwl.io 中的任何计算机都与 LOCAL
匹配。DNS欺骗可以很容易地避开此过滤器。虽然我的桌面声称它有一个主机名 storm.mwl.io,但它的IP地址有反向DNS,声称它在我的有线调制解调器提供商的网络中。主机 www.mwl.io 认为我的桌面不在同一个域中,因此不是本地的。因此,我不能使用LOCAL
验证方法。
同样,任何拥有一组IP地址的人都可以为他们的地址提供任何所需的反向DNS。最好避免 LOCAL
限制。
ALL
匹配所有内容,ALL EXCEPT
匹配除指定内容之外的所有内容。在我看来,这些是最有用的连接来源。例如,如果你有一台只能从几个管理工作站访问的高度安全的机器,你可以制定这样的规则:
xxxxxxxxxx
-:ALL EXCEPT wheel:ALL EXCEPT 203.0.113.128 203.0.113.44
这些规则的目的是构建一个与您的实际策略相匹配的登录策略。如果您提供通用服务,但只允许您的系统管理员远程登录,那么一行 login.access 将阻止任何其他用户登录:
xxxxxxxxxx
-:ALL EXCEPT wheel:ALL
如果你能忍受如此严格的限制,那就太好了。另一方面,我曾在几家使用FreeBSD提供客户端服务的互联网服务提供商工作过。除非拥有shell帐户,否则低级客户不允许登录服务器。系统管理员可以远程登录,DNS和web团队(DNS和网站管理员组的成员)也可以。但是,只有系统管理员可以登录到控制台。
xxxxxxxxxx
-:ALL EXCEPT wheel:console
-:ALL EXCEPT wheel dns webmasters:ALL
在 login.access 中设置一次,然后让组成员永远控制您的所有远程登录。
您可以通过登录类提供更具体的控件。通过 /etc/login.conf 管理的登录类定义了为用户提供的资源和信息。每个用户都被分配了一个类,每个类对可用的系统资源都有限制。当您更改类的限制时,所有用户在下次登录时都会获得新的限制。在创建用户帐户时设置用户的类,或稍后使用 chpass(1)
进行更改。
默认的 login.conf 以 default
类开头,该类由帐户使用,没有任何其他类。此类允许用户基本上无限制地访问系统资源,适用于用户数量有限的应用服务器。如果这符合您的需求,则根本不要调整文件。
每个类定义都由一系列变量赋值组成,这些赋值定义了用户的资源限制、会计和环境。类定义中的每个变量赋值都以冒号开始和结束。反斜杠字符是一个连续字符,表示类在下一行继续,这使文件更具可读性。以下是一个类的开始示例:
xxxxxxxxxx
➊default:\
➋:passwd_format=➌sha512:\
:copyright=/etc/COPYRIGHT:\
:welcome=/etc/motd:\
--snip--
这个类叫做 default
➊。我已经展示了这个类中几十个变量中的三个。例如,变量passwd_format
➋设置为 sha512
➌。这些变量赋值和类名描述了类,您可以通过将用户分配给另一个类来更改用户在系统上的体验。
login.conf 的一些变量没有值,而是通过存在来改变帐户行为。例如,requirehome
变量只需包含在类中即可生效。如果存在此值,则用户必须具有有效的主目录。
xxxxxxxxxx
:requirehome:\
编辑 login.conf 后,您必须更新登录数据库以使更改生效。
xxxxxxxxxx
# cap_mkdb /etc/login.conf
这将重建用于快速查找的数据库文件 /etc/login.conf.db,与 /etc/spwd.db 非常相似。
默认的 /etc/login.conf 包含几个用户示例类。如果你想知道在各种情况下对用户施加什么样的限制,请查看这些示例。以下部分提供了关于在登录类中可以设置什么的想法。有关FreeBSD版本中支持的设置的完整列表,请阅读手册 login.conf(5)。
资源限制允许您控制任何一个用户在任何时候可以独占系统的多少。如果你有几百个用户登录到一台机器上,其中一个用户决定编译LibreOffice,那么这个人将消耗远远超过他在处理器时间、内存和I/O方面的公平份额。通过限制一个用户可以垄断的资源,你可以使系统对所有用户的响应更灵敏。
下表定义资源限制login.conf变量:
变量 | 描述 |
---|---|
cputime | 任何一个进程可能使用的最大CPU时间 |
filesize | 任何一个文件的最大大小 |
datasize | 一个进程可以消耗的最大数据内存大小 |
stacksize | 进程可用的最大堆栈内存量 |
coredumpsize | core dump的最大尺寸 |
memoryuse | 进程可以锁定的最大内存量 |
maxproc | 用户可以运行的最大进程数 |
openfiles | 每个进程打开的最大文件数 |
Sbsize | 用户应用程序可以设置的最大套接字缓冲区大小 |
请注意,每个进程通常都会设置资源限制。如果你允许每个进程200MB的RAM,并允许每个用户40个进程,那么你只允许每个用户大约8GB的内存。也许你的系统有很多内存,但它真的有那么多吗?
除了前面列出的限制外,您还可以指定当前和最大资源限制。当前限制是建议性的,用户可以随意覆盖它们。这在协作系统上效果很好,在这种系统中,多个用户愿意共享资源,但你想通知那些超过标准资源分配的用户。许多用户都想成为好公民,当他们被告知自己正在挑战极限时,他们很乐意合作。用户不能超过最大限制。
如果你没有将限制指定为当前或最大值,FreeBSD会将其视为最大限制。
要指定当前限制,请在变量名中添加 -cur
。要设置最大限制,请添加 -max
。例如,要设置用户可以拥有的进程数量的当前和最大限制,使用以下输入:
xxxxxxxxxx
--snip--
:maxproc-cur: 30:\
:maxproc-max: 60:\
--snip--
与资源限制相对应的是资源会计。如今,会计并不像今天廉价的电脑要花费数百万美元时那么重要,所以我们不会在本书中讨论它。限制单个用户使用您的系统比为每个用户使用的CPU周期计费更重要。然而,你应该知道这种能力是存在的。
如果你需要更复杂的资源限制,请调查 rctl(8)
。
您还可以在 /etc/login.conf 中定义环境设置。这比在默认的 .cshrc 或 .profile 中设置环境设置效果更好,因为 login.conf 设置会在所有用户下次登录时立即影响他们。一些shell,如 zsh(1)
,不读取这些配置文件中的任何一个,因此使用类环境为这些用户设置适当的环境变量。
所有环境字段都识别两个特殊字符。波浪号(~)表示用户的主目录,而现金符号($)表示用户名。以下是默认类中的一些示例来说明这一点:
xxxxxxxxxx
:setenv=MAIL=➊/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES:\
:path=/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/
local/bin /usr/X11R6/bin ➋~/bin:\
通过使用$字符,环境变量MAIL被设置为 /var/MAIL/<username>➊。同样,PATH变量中的最后一个目录是用户主目录➋中的 bin 子目录。
下表列出了一些常见的 login.conf 环境设置:
变量 | 说明 |
---|---|
hushlogin | 如果存在,登录时不会给出系统信息。 |
ignorenologin | 如果存在,即使 /var/run/nologin 存在,这些用户也可以登录。 |
manpath | $MANPATH 环境变量的目录列表。 |
nologin | 如果存在,则用户无法登录。 |
path | $PATH 环境变量的目录列表。 |
priority | 用户进程的优先级(nice)(see Chapter 21). |
requirehome | 用户必须拥有有效的主目录才能登录。 |
setenv | 以逗号分隔的环境变量及其值列表。 |
shell | 登录时要执行的shell的完整路径。这将覆盖/etc/master.passwd中的shell。然而,用户的 $SHELL 包含密码文件中的shell,导致环境不一致。玩这个游戏是惹恼用户的好方法。 |
term | 默认终端类型。几乎任何试图设置终端类型的东西都会覆盖这一点。 |
timezone | $TZ 环境变量的默认值。 |
umask | 初始umask设置;应始终以0开头,请参阅builtin(1) 。 |
welcome | 登录欢迎消息的路径,通常为 /etc/motd。 |
记住,对类的更改会影响该类中的所有用户。如果用户需要更改类设置,则需要更改他们的类。
与环境设置不同,其中许多可以在登录类以外的地方设置,大多数登录和身份验证选项只能从登录类进行控制。以下是一些常见的身份验证选项:
此选项设置用于在 /etc/master.passwd 中存储密码的加密哈希。默认值为 sha512
,用于sha512哈希。其他允许的选项包括 des
(DES)、blf
(Blowfish)、md5
和sha256
(SHA256)。当你想在不同的类Unix操作系统之间共享密码文件时,DES和Blowfish最有用,但它们非常弱。SHA256是为了与SHA512默认之前的旧密码文件兼容。
如果存在,FreeBSD会抱怨用户将密码更改为全小写单词。尽管名称如此,所有大写密码都满足此选项。
这些值允许此类中的用户使用 rlogin
和 rsh
。避免使用它们,就像你那令人毛骨悚然的室友有一次试图喂你的毛茸茸的绿色肉一样。
此选项允许您安排用户何时可以使用逗号分隔的日期和时间列表登录。日期(星期)以日期名称的前两个字母表示(Su、Mo、Tu、We、Th、Fr和Sa)。时间采用标准的24小时制。例如,如果用户只能在周三上午8点到下午5点之间登录,则可以使用此条目:
xxxxxxxxxx
:times.allow=We8-17:\
此选项允许您指定用户无法登录的时间窗口。请注意,这不会启动已登录的用户。格式与times.allow相同。如果 times.allow
和 times.deny
重叠,则 times.deny
优先。
你不能让那个工作过度的开发人员回家,但你可以阻止他打开另一个终端窗口。
所有类Unix操作系统都具有相同的文件系统权限,将文件的读取、写入和执行权限分配给文件的所有者、组和所有其他人。FreeBSD通过文件标志(file flags)扩展了权限方案,这些标志与权限一起工作,以增强系统的安全性。
许多标志根据系统安全级别具有不同的效果,我们将在下一节中介绍。理解安全级别需要理解文件标志,而文件标志依赖于安全级别。
一些文件标志仅在特殊情况下有用。我们将只看最常见的标志。完整列表可参阅 chflags(1)
。
许多标志有多个名字;虽然 ls(1)
输出中只显示一个名称,但你可以在命令行中使用任何名称。这些替代名称的存在是因为人们厌倦了在键入 sappend
而不是 sappnd
时出错。在此,我们首先显示标志的主要名称,然后显示用户友好的别名。
此系统级别的“仅追加”(append-only)标志只能由root设置。带有此标志的文件可以添加到,但不能删除或以其他方式编辑。此标志对于日志文件特别有用。如果帐户被泄露,在用户的 .history 文件上设置 sappnd
可能会很有趣。由于一种常见的入侵者策略是删除 .history 或将其符号链接到 /dev/null,这样管理员就看不到发生了什么,因此 sappnd
确保脚本小子不能以这种方式掩盖他们的踪迹。查看某人试图删除 sappnd
文件的记录几乎很有趣;您几乎可以看到攻击者在尝试各种方法时越来越沮丧。当系统以安全级别1或更高级别运行时,此标志无法删除。
只有root可以设置系统级不可变标志。设置了此标志的文件不能以任何方式更改。它们不能被编辑、移动、替换或覆盖。基本上,文件系统本身阻止了所有更改此文件的尝试。当系统以安全级别1或更高级别运行时,无法删除该标志。
只有root可以在文件上设置系统级不可删除标志。文件可以编辑或更改,但不能删除。这不如前两个标志安全,因为如果一个文件可以编辑,它就可以被清空。然而,它在某些情况下仍然有用。当程序在崩溃时坚持删除自己的日志文件时,我使用了它。然而,设置任何标准系统文件通常都没有用。当系统以安全级别1或更高级别运行时,无法删除此标志。
此用户级别、仅追加标志只能由文件所有者或root设置。与系统级仅附加标志 sappnd
一样,可以添加具有此标志集的文件,但不能以其他方式编辑或删除。此标志对于来自个人程序等的日志最有用;它主要是一种让用户防止意外删除自己文件的方法。所有者或root可以删除此标志。
这个用户级别的不可变标志只能由所有者或root设置。与 schg
标志一样,这个不可变的标志可以防止任何人更改文件。同样,root可以覆盖此设置,并且用户可以在任何安全级别禁用它。此标志有助于防止错误,但它不是保护系统的方法。
此用户级别的不可删除标志只能由所有者或root设置。所有者无法删除设置了此标志的文件。Root可以覆盖该标记,用户可以随时关闭此标记,使其基本无用。
使用 chflags(1)
设置标志。例如,为了确保没有任何东西可以替换服务器的内核,您可以这样做:
xxxxxxxxxx
# chflags schg /boot/kernel/kernel
您需要删除此标志才能执行系统更新。
您可以使用 -R
标志递归更改整个目录树上的标志。例如,要使所有 /bin 目录不可变,请运行以下命令:
xxxxxxxxxx
# chflags -R schg /bin
砰!您的基本系统二进制文件不能更改。
要查看文件上设置了哪些标志,请使用 ls -lo
。
xxxxxxxxxx
# ls -lo log
-rw-r--r-- 1 mwlucas mwlucas sappnd 0 Nov 12 12:37 log
sappnd
条目告诉我们系统附加标志已在此日志上设置。为了进行比较,如果一个文件没有设置标志,它看起来像这样:
xxxxxxxxxx
# ls -lo log
-rw-r--r-- 1 mwlucas mwlucas - 0 Nov 12 12:37 log
用连字符代替标志名称告诉我们没有设置任何标志。
开箱即用的FreeBSD安装没有很多标记有标志的文件,但你可以标记任何你想要的东西。在一个我完全预料到会被黑客攻击的系统上,我在各种系统目录中疯狂地使用 chflags -R schg
,以防止任何人用木马版本替换系统二进制文件。这可能无法阻止攻击者进入,但想象他们的沮丧改善了我的心情。
要删除文件标志,请在标志名称前使用 chflags
和 no
。例如,要取消设置内核上的 schg
标志,请输入以下命令:
xxxxxxxxxx
# chflags noschg /boot/kernel/kernel
也就是说,你必须以安全级别 -1
运行才能取消许多标志。所以,闲话少说,让我们讨论一下安全级别以及它们对你意味着什么。
安全级别是更改基本系统行为以禁止某些操作的内核设置。当您提高安全级别时,内核的行为略有不同。例如,在低安全级别下,可以删除文件标志。文件可能被标记为不可变,但您可以删除该标记、编辑文件并重新标记它。当您增加安全级别时,文件标记无法删除。系统的其他部分也发生了类似的变化。总体而言,由于安全级别的提高而导致的行为变化要么挫败要么阻止入侵者。使用 rc.conf 选项 kern_securevel_Enable=“YES”
在启动时启用安全级别。
安全级别通过对您的行为施加限制使系统维护复杂化。毕竟,许多系统管理任务也是入侵者可能用来掩盖踪迹的事情。例如,在某些安全级别下,您无法在系统运行时格式化或装载新的硬盘驱动器。另一方面,安全级别对入侵者的阻碍甚至超过了对你的阻碍。
安全级别分为5个等级:-1、0、1、2和3,其中-1为最低,3为最高。使用rc.conf 选项kern_securevel_enable
启用安全级别后,可以在启动时使用 rc.conf 选项kern_securelevel
变量设置安全级别。您可以随时提高安全级别,而不仅仅是在启动时,但如果不重新启动到单用户模式,则无法降低安全级别。毕竟,如果你能随时降低安全级别,你的入侵者也可以!
每种安全级别的效果因FreeBSD版本而异。要获取最新信息,请阅读 security(7)
。
默认设置不提供任何额外的内核安全性。如果你正在学习FreeBSD并且经常更改配置,请保持在securelevel -1,并使用内置的文件权限和其他Unix安全保护措施。像 sappnd
和schg
这样的标志可以工作,但 chflags(1)
可以很容易地删除这些标志。
securelevel 0仅在启动过程中使用,与securelevel -1相比没有特殊功能。然而,当系统达到多用户模式时,安全级别会自动提高到1。在 /etc/rc.conf 中设置 kern_securelevel=0
实际上与设置 kern_securelevel=1
相同。如果您有执行安全级别1禁止的操作的启动脚本,则安全级别0会很有帮助。
在安全级别1,即基本安全模式下,事情变得有趣起来:
debug.kdb.enter
sysctl进入内核调试器。debug.kdb.parist
sysctl使系统死机。对于普通用户来说,securevel 1最明显的效果是BSD特定的文件系统标志不能更改。如果一个文件被标记为系统级不可变,而你想替换它,那就太糟糕了。
安全级别2具有安全级别1的所有行为,但增加了两项:
这两者似乎与新系统管理员无关,但它们提供了重要的安全保护。虽然Unix提供了方便的工具,如文本编辑器来编写文件,但也可以绕过这些工具和实际的文件系统来访问硬盘上的底层1和0。轻触硬盘可以更改任何文件,而不管文件权限如何。这种情况通常只发生在您安装新硬盘并必须在其上创建文件系统时。通常,只有root用户可以以这种方式直接写入磁盘。在安全级别2,即使是root也不能使用 newfs(8)
、zpool(8)
等。
同样,另一个古老的黑客技巧是更改系统时间,编辑文件,然后将时间改回来。这样,当管理员查找可能造成麻烦的文件时,被篡改的文件似乎已经几个月或几年没有被触及,因此似乎不是一个明显的问题。
安全级别3是网络安全模式。除了安全级别1和2的设置外,您无法调整数据包过滤规则。主机上的防火墙是不可变的。如果你有一个启用了数据包过滤或带宽管理的系统,并且这些规则经过了很好的调整,不太可能改变,你可以使用安全级别3。
适合您环境的安全级别完全取决于您的情况。如果您刚刚将FreeBSD机器投入生产,并且仍在对其进行微调,请将安全级别保持在-1。但是,一旦调整了系统,就可以提高安全级别。大多数生产系统在安全级别2下运行良好。
如果你使用FreeBSD的数据包过滤或防火墙软件包,securevel 3可能看起来很诱人。但是,在启用此功能之前,请务必确定您的防火墙规则!安全级别3使您无法在不中断连接的情况下更改防火墙。你百分之百确定你的客户不会打电话来说,“这是支票。现在给我更多的服务器!”吗?
考虑一种情况,有人破坏了您的web服务器上的CGI脚本,使用该脚本引导到shell中,然后使用shell引导自己进入root访问。
如果你相应地设置了安全级别,也许这个攻击者会感到沮丧,因为她不仅不能用她专门编译的内核替换你的内核,甚至不能加载内核模块。没问题,她仍然可以用木马版本替换各种系统程序,这样下次登录时,您的新版本 login(1)
会将您的密码发送到匿名的网络邮箱或互联网新闻组。
因此,为了保护您的密钥文件,您可以四处执行 chflags schg -R /bin/*
、chflags chg -R /usr/lib
等操作。好的。如果你忘记了一个文件,比如 /etc/rc.bsdextended 之类的模糊文件,入侵者可以编辑该文件以包含 chflags -R noschg /
。然后,她可以在你可能没有注意到的深夜重新启动你的系统。你多久坐下来彻底审核一次你的 /etc/rc 文件?
你认为你的系统是安全的,每个文件都得到了完全的保护。但是本地程序启动目录 /usr/local/etc/rc.d 呢?系统引导过程会尝试执行此目录中包含以 #PROVIDE:
开头的行的任何可执行文件(请参阅第17章了解原因)。因此,您的入侵者可以通过在那里放置一个简单的shell脚本来造成很大的破坏。毕竟,/etc/rc 在引导过程结束时提高了安全级别。如果她创建了一个shell脚本,在 /etc/rc 可以提升安全级别之前杀死正在运行的 /etc/rc,然后她转身运行自己的 /var/.hidden/rc.rootkit 来完成系统的启动,该怎么办?
当然,这只是几种可能性。还有其他一些,只受入侵者创造力的限制。请记住,系统安全是一个棘手的问题,没有简单的解决方案。一旦入侵者有了命令提示符,你就可以对抗他们了。如果它们是好的,你甚至不会注意到渗透,直到为时已晚。通过遵循良好的计算实践并保持系统最新,您可以从一开始就阻止它们入侵。不要让安全感让你懒惰!
如果你一直对 schg
标志持开放态度,你很快就会发现你无法方便地升级或修补你的系统。事实上,如果你不知道如何与入侵者合作,那么让入侵者生活困难的同样条件也会让你的生活变成人间地狱。
如果已使用 schg
冻结 /etc/rc.conf ,则必须降低安全级别才能更改系统上运行的程序。当然,securelevel设置在该文件中,因此为了编辑它,您必须在 /etc/rc 运行之前控制系统。这意味着您必须引导到单用户模式(如第4章所述),挂载文件系统,对有问题的文件运行chflags noschg
,然后继续引导。您甚至可以在 /etc/rc.conf 中完全禁用securelevels,并在系统运行时正常工作,或者在/etc/rc.local中添加命令,使其在设置securelevel之前生效。这样,您将更快地恢复服务,但会失去文件标志的保护。
完成维护后,您可以通过将kern.securevel
sysctl更改为所需的securelevel来提高(但不能降低)securelevel。
xxxxxxxxxx
# sysctl kern.securelevel=3
现在您可以控制文件更改,让我们考虑控制从网络对系统的访问。
入侵者通常会闯入监听网络的应用程序,而不是操作系统本身。操作系统可能会也可能不会帮助保护软件免受网络攻击,但入侵本身始于应用程序。减少对服务器的攻击次数的一种方法是识别所有正在监听网络的程序,并禁用任何非严格必要的程序。FreeBSD提供 sockstat(1)
作为识别正在监听网络的程序的简单方法。
我们在第8章中详细介绍了 sockstat
;运行 sockstat -4
会显示所有打开的IPv4 TCP/IP端口。您打开的每个网络端口都是一个潜在的弱点和潜在的目标。关闭不必要的网络服务,并保护您必须提供的网络服务。
定期检查系统上哪些端口是打开的是个好主意,因为你可能会学到一些让你惊讶的东西。你可能会发现,你安装的某个软件有一个你不知道的网络组件,它一直在悄悄地监听网络。
一旦你知道什么在运行,你如何关闭你不需要的东西?关闭这些端口的最佳方法是不要启动运行它们的程序。网络守护进程通常从以下两个位置之一启动:/etc/rc.conf 或 /etc/rc.d 中的启动脚本。与主FreeBSD系统集成的程序,如sendmail(8)
、sshd(8)
和rpcbind(8)
,在 rc.conf 中有标志来启用或禁用它们,许多附加程序也是如此。有关启动时启用和禁用程序的详细信息,请参阅第4章。
我见过的许多公司都有严密保护的服务器,但很少关注工作站安全。然而,潜在的入侵者并不关心系统是服务器还是工作站。许多服务器和防火墙对系统管理员的工作站都有特殊的规则。入侵者会很乐意渗透工作站,并试图利用它来访问服务器。虽然服务器安全是关键,但不要忽视工作站,尤其是你的工作站!
网络探测器很奇怪,因为你真的不知道什么时候有人会戳你的主机。要查看这种情况有多严重,请在公共服务器上的/etc/rc.conf中将 log_in_vain
设置为1
。这告诉内核记录到关闭端口的所有连接尝试。当有人检查您的主机是否存在不存在的telnet、Squid或数据库侦听器时,内核会将尝试记录到 /var/log/messages
。只看日志足够长的时间,让你清楚地意识到整个互联网都在找你——然后禁用 log_in_vain
。
一旦你只打开了必要的网络端口,并且知道哪些程序正在使用这些端口,你就知道哪些程序必须最关心安全。如果FreeBSD安全团队发出通知,指出你没有运行的服务有问题,你可以安全地推迟实施修复,直到下一个维护窗口。但是,如果安全团队宣布您正在使用的程序存在漏洞,您就知道必须尽快实施修复。如果他们宣布你正在使用的网络软件存在严重的安全问题,你知道你必须迅速采取行动。仅仅能够智能快速地应对实际风险,就有助于保护您免受大多数入侵者的攻击。文件标志和安全级别等工具可以最大限度地减少成功入侵者可能造成的损害。最后,使用组将您自己的系统管理员限制在系统的特定部分可以保护您的计算机免受意外和故意的损害。
现在让我们换个话题,谈谈存储。