基础知识 - shadow密码
shadow密码
2004-04-23 15:18 pm来自:Linux文档
现载:Www.8s8s.coM
地址:无名
v1.3, 3 April 1996 翻译日期: 15 MAY 2000
这份文件主要描述如何取得,安装和设定 Shadow Suite 密码。它也描述取得和安装需要存取使用者密码之其他软体和网路监控程式(network daemons)。这些其他软体不是 Shadow Suit 的真实部分,但是这些程式将需要被重新编译用以支援Shadow Suite 。这份文件亦包括一个程式□例:对程式加入 shadow 支援。本文结尾部分为常问问题及答案。
CLDP -- linux 中文文件计划
BOTTOM
首 页
最新消息
中译文件
HOWTOs
1. 简介
这篇文章为 linux Shadow-Password-HOWTO。 主要是在描述为何及如何於 Linux 系统加入 shadow 密码支援。 其亦包括如何使用 Shadow Suite's 某些□例。
当进行 Shadow Suite 安装及使用许多的 utility 程式时.你必须以 root 权限签入。 且进行 Shadow Suite 安装时,系统软体将被改变,因此强烈的建议您照说明档备分程式。在此强调在您开始作业前需先阅读及了解所有的说明书。
1.1 更改上一版本部分
新增:
新增一个子节:为何您不要安装 shadow
新增一个子节:修改 xdm 程式
新增一节:为何您不要安装 shadow
新增一节:如何於未来运作 Shadow Suite
新增一节:常问问题及答案
更正/修改:
更正在 Sunsite 的 html 参考资料
更正在 wu-ftp 节在 Makefile 新增 -lshadow
更正较不严重拼音和措词错误
更改 wu-ftp 节用以支援 ELF
修改在不同签入(login)程式安全问题
修改 linux Shadow Suite 建议为 Marek Michalkiewicz
1.2 新版文件
您可利用匿名档进入该 FTP 站下载最新版文件: sunsite.unc.edu
/pub/linux/docs/HOWTO/Shadow-Password-HOWTO
or:
/pub/linux/docs/HOWTO/other-formats/Shadow-Password-HOWTO{-html.tar,ps,dvi}.gz
或透过网站: linux Documentation Project Web Server,网页: Shadow-Password-HOWTO 或与我联络: . 亦可透过新闻群组张贴: comp.os.linux.answers
这些文件现在已经包於 Shadow-YYDDMM 套件中。
1.3 回覆
请将任何评语、修改或建议寄至: Michael H. Jackson 我会尽快回覆并更正该文件。如果你发现任何问题,请直接 email 给我,我会将此最新技术张贴於新闻群组。
2、为何shadow你的passwd档?
大部分目前 linux 发行版本预设值并未包含Shadow Suite 安装。这些版本包括 Slackware 2.3, Slackware 3.0 和其他受欢迎的发行版本。主要原因之一是在原始Shadow Suite版权声明中并未很清楚的描述该软体是否需使用者付费。 Linux 使用 GNU 版权通常允续使用者可免费且任意使用相关套件。
Shadow Suite现在维护人员 Marek Michalkiewicz 已经可以从在 BSD 样式允需再使用版权之原始作者那接收原始码。 目前版权发行已解决,因此可以预期在未来版本之预设值将包括 password shadowing。 即使如此,你仍需要自行安装。
如果你的版本是从 CD-ROM 安装。你可能发现即使目前版本并未有Shadow Suite 安装,但你仍然可以在该片 CD-ROM 找到你需要安装的Shadow Suite。
然而,所有Shadow Suite 3.3.1, 3.3.1-2 版本和 shadow-mk 伴随签入(login)程式和其他suid root程式均有安全上问题,因此不应该使用太久。
所有必要档案均可以透过匿名 FTP 站或网站找到。
在没有安装Shadow Suite的 linux 系统,包括密码的帐号使用者资讯通常储存在 /etc/passwd 档。储存的密码为 加密(encrypted)格式。 然而,如果你问一个密码专家,他/她将告诉你真正的密码档只是编码(encoded)而不是加密格式,因为当使用 crypt(3) 时,文字档倍设为 null 且密码是键值(key)。 因此,接下来我将在这篇文件中使用 编码。
使用在密码栏位编码的演算法於技术上是使用one way hash function。这是一个在单一方向计算简单但逆向计算非常困难的演算法。关於这正确的演算法可以在 2.4 节或於 crypt(3) 操作手册找到。
当使用者挑选或指定一个密码,系统将随机产生一个值,叫做salt,将密码进行编码。 这表示任何特定的密码可以 4096 中不同方法储存。 salt 值将储存被编码的密码 。
当使用者签入或提供一个密码, salt 首先接收欲储存编码密码。然後这提供密码会和 salt 值一起编码,且比较已经编码密码。如果有 match ,该使用者通过权限检查。
随机编码和复原原始密码是有计算复杂度的(但不是不可能的)。然而,在某些系统很多使用者的密码都设为一般文字(或是一般文字的简单变化)
系统骇客知道这件事,且将简单的加密文字和一般使用4096 salt 值密码之目录。然後他们将比较在资料库之 /etc/passwd 档之编码密码,只要他们找到一个比对,他们可以找到一个帐号之密码。这和dictionary attack有关,且用於未经许可存取系统取得和展开常用的方法之一。
如果你想过一个 8 码的密码编码成 4096 * 13 码的字串,那麽一个用在描述 400,000 一般文字、名字、密码和简单变化的字典将需要 4GB 硬碟存取空间。 骇客需要做的只是分类字串跟检查比对结果。 自从 4GB 硬碟可以以美金 1000.00 以下买到後,对大多数系统骇客的意义可想而知 。
如果骇客首先发现你的 /etc/passwd 档,他们只需要将真正包含在 /etc/passwd 档 salt 值的字典编码,这方法可由拥有486级电脑或几个有几百 MB 硬碟空间的十来岁的小孩适用。
即使没有很大的磁碟空间,像 crack(1) 的工具程式通常可以在足够使用者系统中至少破解一对密码(假设系统使用者倍允许挑选他们想要的密码)。
/etc/passwd 档也包括一些相关资讯,像使用者 ID 和群组 ID所使用的系统程式;因此 /etc/passwd 档 必须 保持全世界可读性. 如果你改变 /etc/passwd 档以致於没有人可以读取,你将发现的第一件事是 ls -l 命令将取代名称而显示使用者 ID 。
Shadow Suite 透过将密码存至另一个档(通常是 /etc/shadow 档)来解决该问题。 /etc/shadow 档对任何人设定可读档,只有 root 权限可以读写 /etc/shadow 档。某些程式(像 xlock)不需要改变密码,只需要确认密码即可。这些程式可以以 suid root 执行或者你可以设定一个群组 shadow 用来唯读 /etc/shadow 档,然後这些程式可以执行 sgid shadow。
透过移动密码至 /etc/shadow 档,我们可以有力的备有骇客从存取编码密码到执行 dictionary attack 的证据。
除此之外, Shadow Suite 新增许多特色:
设定档於设定为签入时预设(/etc/login.defs)
新增、修改和删除使用者帐号群组之工具程式
密码寿命计算及到期日
帐号到期日跟锁死
隐藏群组密码 (可选择的)
两倍长度密码 (16 字元密码) [不建议使用]
针对使用者密码选择有较好的控制
可拨接密码
备用有效权限程式 [不建议使用]
安装 Shadow Suite 贡献为有更安全系统,但是还有其他方法可以改善 linux 系统的安全,且最终将有一系列的 Linux 安全 HOWTO's 将讨论其他安全基准和相关文件版本.
针对目前其他 linux 安全文件资讯,请参照网址: Linux Security home page.
2.1 为何您不要 shadow 你的 passwd 档
有一些状况跟设定运用在安装 Shadow Suite 将 不是 好主意: There are a few circumstances and configurations in which installing the Shadow Suite would NOT be a good idea:
主机没有包含使用者帐号。
主机是在 LAN 上跑且使用网路资讯服务(Network Information Services, NIS)得到或供应使用者名称和密给网路上的其他机器使用(事实上这还是可以执行,但是实际上并不能增加任何安全)。
机器是使用终端主机来验证使用者经由 NFS(Network File System), NIS 或某些其他方法。
机器跑其他软体验证使用者且没有任何 shadow 版本或原始码可获得。
2.2 格式化 /etc/passwd 档
一个 non-shadowed /etc/passwd 档格式如下所示:
username:passwd:UID:GID:full_name:directory:shell
其中
username
使用者(签入)名称
passwd
编码密码
UID
使用者编号
GID
预设存组编号
full_name
使用者全名 - 事实上这个栏位称作 GECOS (General Electric Comprehensive Operating System) 栏位且可以储存全名外的资讯。Shadow commands and manual pages refer to this field as the comment field.
directory
使用者根目录 (绝对路径)
shell
使用者签入的环境 (绝对路径)
举例说明:
username:Npge08pfz4wuk:503:100:Full Name:/home/username:/bin/sh
中,Np 是 salt 且 ge08pfz4wuk 是编码密码。 已编码的 salt/password 就像 kbeMVnZM0oL7I 且这两个字串是一样的密码。对相同密码可能有 4096 种可能的编码。(本□例的密码是 "passwaor",这是比较 不好 的密码)。
只要 shadow suite 已经安装, /etc/passwd 档将被替代成:
username:x:503:100:Full Name:/home/username:/bin/sh
本□例之第二栏位 x 现在只是一个 place holder。 /etc/passwd档的格式并未真的改变,只是不再包含 编码密码。这表示任何程式可以读取 /etc/passwd 档,但并不真的需要确认密码是不是正确地运作。
这些密码现在被重新放在 shadow 档(通常是在 /etc/shadow 档)。
2.3 格式化 shadow 档
/etc/shadow 档包括下列资讯:
username:passwd:last:may:must:warn:expire:disable:reserved
其中
username
使用者名称
passwd
编码密码
last
密码上次更动日期,以从1970年1月1日算起的天数代表
may
密码改变前天数
must
密码最常使用天数
warn
代表期限前几天就事先警告使用者
expire
超过密码过期天数後,就关闭该帐号
disable
帐号关闭,以从1970年1月1日算起的天数代表
reserved
预备栏位
依照之前□例将变成:
username:Npge08pfz4wuk:9479:0:10000::::
2.4 回顾 crypt(3).
从 crypt(3) 使用者文件得到:
"crypt 是密码加密方程式。 It is based on the Data Encryption Standard algorithm with variations intended (among other things) to discourage use of hardware implementations of a key search.
[The] key 是使用者输入的密码。 [编码字串全是 NULLs]
[The] salt 是从 [a-zA-Z0-9./] 集合中选出的两个位元字串。该字串是用於扰乱在 4096 种不同方法之一个演算法。
透过得到 key 的每个位元的最低 7 bit[s],可以建立 56-bit key 。 这56-bit key 是用在重复加密一个常数字串(通常是包含所有灵的字串)。 传回值指到加密密码是一连串可印出之13个 ASCII 字元(最前面的一两个字元表示 salt 本身)。 透过每次的呼叫可将传回直指到静态资料。
警告讯息: Key space 包括 2**56 即等於 7.2e16 可能的值。与用重大的平行电脑将 Key space 极尽的搜寻是可能。像 crack(1) 软体用来搜寻部分的由人产生之密码的 key space 是可获得的。因此,密码的选择至少应该避免使用一般字及名字。一个用来检查解开密码选择的 passwd(1) 程式使用是值得推荐的。
DES 演算法本身有一些使 crypt(3) 在任何其他密码权限区隔介面很差选择的使用方面剧变。如果你计画使用 crypt(3) 介面来加密计画,以下描述千万别这麽作:得要一本加密好书和广泛获得 DES 程式库 ." 一起使用。
大多 Shadow Suites 包括 16 位元的密码长度两倍之原始码。 在 des 专家建议避免使用当开始对较常密码先简单的编码左半然後右半。由於 crypt 运作方法,这将造成 较差的 安全编码密码。除此之外,使用者有可能记住 16 位元密码是一件比较差的事情。
目前有允许权限理论用以取代某些更安全和支援较长密码(例如 MD5 演算法)且保有和 crypt 方法相容的发展工作正在进行。
如果你正在寻找一本加密的好书,建议如下:
"Applied Cryptography: Protocols, Algorithms, and Source Code in C"
by Bruce Schneier
ISBN: 0-471-59756-2
3、取得 Shadow Suite
3.1 Shadow Suite for linux 的历史(暂不翻译)
3.2 History of the Shadow Suite for linux
DO NOT USE THE PACKAGES IN THIS SECTION, THEY HAVE SECURITY PROBLEMS
The original Shadow Suite was written by John F. Haugh II.
There are several versions that have been used on linux systems:
shadow-3.3.1 is the original.
shadow-3.3.1-2 is linux specific patch made by Florian La Roche and contains some further enhancements.
shadow-mk was specifically packaged for linux.
The shadow-mk package contains the shadow-3.3.1 package distributed by John F. Haugh II with the shadow-3.3.1-2 patch installed, a few fixes made by Mohan Kokal that make installation a lot easier, a patch by Joseph R.M. Zbiciak for login1.c (login.secure) that eliminates the -f, -h security holes in /bin/login, and some other miscellaneous patches.
The shadow.mk package was the previously recommended package, but should be replaced due to a security problem with the login program.
There are security problems with Shadow versions 3.3.1, 3.3.1-2, and shadow-mk involving the login program. This login bug involves not checking the length of a login name. This causes the buffer to overflow causing crashes or worse. It has been rumored that this buffer overflow can allow someone with an account on the system to use this bug and the shared libraries to gain root access. I won't discuss exactly how this is possible because there are a lot of linux systems that are affected, but systems with these Shadow Suites installed, and most pre-ELF distributions without the Shadow Suite are vulnerable!
For more information on this and other linux security issues, see the Linux Security home page (Shared Libraries and login Program Vulnerability)
3.3 如何取得 Shadow Suite?
目前建议 Shadow Suite 版本目前还是 BETA 测试版,然後,最近版本在生产环境是安全的且没有包含易受攻击的 签入(login) 程式。
该套件(package)使用惯例命名为:
shadow-YYMMDD.tar.gz
其中 YYMMDD 是Suite 的发行日期。
目前 BETA 测试版本是 Version 3.3.3 ,且由 Marek Michalkiewicz 维护。
还可以从该处得到: shadow-current.tar.gz.
下列网站也可以找到相关资讯:
ftp://ftp.icm.edu.pl/pub/linux/shadow/shadow-current.tar.gz
ftp://iguana.hut.fi/pub/linux/shadow/shadow-current.tar.gz
ftp://ftp.cin.net/usr/ggallag/shadow/shadow-current.tar.gz
ftp://ftp.netural.com/pub/linux/shadow/shadow-current.tar.gz
你应该可以获得目前最新的版本。
你应该不要是用比 shadow-960129 更旧版本,因为它们有 签入 的安全问题。
於参考资料方面,我用 shadow-960129 档进行安装介绍。
如果你之前使用 shadow-mk ,你应该更信这个版本且重建编译。
3.4 Shadow Suite包含什麽?
Shadow Suite 包括对下列功能之替代程式:
su, login, passwd, newgrp, chfn, chsh, and id
该套件还包括新程式:
chage, newusers, dpasswd, gpasswd, useradd, userdel, usermod, groupadd, groupdel, groupmod, groups, pwck, grpck, lastlog, pwconv, and pwunconv
除此之外,函式库: libshadow.a 也包括需要存取使用者密码之写和编译程式。
程式之操作手册也包含在其中。
也有对签入程式的 configuration file ,它将被安装在 /etc/login.defs 档。
4. 编译程式
4.1 解压缩
在接收套件後第一个步骤就是 unpacking。该套件是 tar 档案格式使用 gzip 压缩,所以首先将该档案移到 /usr/src ,然後输入:
tar -xzvf shadow-current.tar.gz
这将会 unpack 到一个目录:/usr/src/shadow-YYMMDD
4.2 设定 config.h 档
第一件事是你需要复制 Makefile 和 config.h 档:
cd /usr/src/shadow-YYMMDD
cp Makefile.linux Makefile
cp config.h.linux config.h
然後你应该留意 config.h 档。 该档案包括某些设定选项的定义。如果你使用 建议 套件,我建议你在第一次设定关掉 group shadow support。
shadowed group passwords 预设值是开启的。 在 config.h 档关到这个设定,且改变 #define SHADOWGRP 变成 #undef SHADOWGRP。我建议您一开始关掉它们,然後如果你真的需要 group passwords 和 group administrators 时你在开启它们和重新编译。 如果你开启它, 你 必须 建立 /etc/gshadow 档。
开启长密码的选项也不建议使用。
不要 改变 #undef AUTOSHADOW 的设定。
AUTOSHADOW 选项初始设计是用以让 shadow 可以像 function 一样执行。理论上听起来不错,但是没办法正确的运作。 如果你开启这个选项,且这个程式以 root 权限在执行, 它会像 root 权限执行一项呼叫 getpwnam() ,然後变更 /etc/passwd 档 (有no-longer-shadowed 密码)。 这类程式包括 chfn 和 chsh。(如果 root 在呼叫 getpwnam() 之前使用 chfn 和 chsh,使用者帐号将没有办法真实且有效交易。)
如果你要建立 libc,同样的警告也有效,它有个 SHADOW_COMPAT 作相同的事。 它 不应该被使用!如果你开始从你的 /etc/passwd 档撷取编码密码,这会是个问题。
如果你正使用比 4.6.27 还高的 libc 版本,你将需要在 config.h 和 Makefile两个档做很多改变。在 config.h 档的编辑和改变:从:
#define HAVE_BASENAME
到:
#undef HAVE_BASENAME
然後在 Makefile 档的改变:
SOBJS = smain.o env.o entry.o susetup.o shell.o
sub.o mail.o motd.o sulog.o age.o tz.o hushed.o
SSRCS = smain.c env.c entry.c setup.c shell.c
pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c pwpack.c rad64.c
tz.c hushed.c
SOBJS = smain.o env.o entry.o susetup.o shell.o
sub.o mail.o motd.o sulog.o age.o tz.o hushed.o basename.o
SSRCS = smain.c env.c entry.c setup.c shell.c
pwent.c sub.c mail.c motd.c sulog.c shadow.c age.c pwpack.c rad64.c
tz.c hushed.c basename.c
这些包含在 basename.c 程式码的改变均需倍包括在 libc 4.6.27 内。
4.3 备份原始程式
在 shadow suite 要更新时,制作程式备份将是一个很好的点子。在 Slackware 3.0 系统中,这些档案是:
/bin/su
/bin/login
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/id
这 BETA 套件已经有个 储存 在 Makefile 的目的档,但是因为不同的版本通常将程式放在不同的地方,因此常被人评论。
你应该备份你的 /etc/passwd 档,但是你要很小心地命名,不然如我你将它放在相同目录,你将无法重写 passwd 命令。
4.4 执行 make
你需要以 root 权限签入以执行安装程序.
执行 make 来编译套件中的执行档:
make all
你可能会看到警告语: rcsid defined but not used. 这没关系,因为作者使用版本控制套件才会发生。
5. 安装
5.1 手边准备一个开机片
如果真的发生严重错误,有个开机磁片之有用的。如果你要 boot/root 合并的安装,你可以参考 Bootdisk-HOWTO 以制作 root 开机之开机片。
5.2 移除复制的 man pages
你也应该将操作手册更新,即使你很厉害到足以不用备份安装 Shadow Suite,你仍然要将将旧的操作手册移除,因为新版的操作手册无法正常的覆盖旧版本。
你可以使用一个组合: man -aW 命令 和 locate 命令 寻找需备移除的操作手册。在你执行 make install 前找出较旧版本比较容易。
如果你使用 Slackware 3.0 版本,然後你要移除的操作手册是:
/usr/man/man1/chfn.1.gz
/usr/man/man1/chsh.1.gz
/usr/man/man1/id.1.gz
/usr/man/man1/login.1.gz
/usr/man/man1/passwd.1.gz
/usr/man/man1/su.1.gz
/usr/man/man5/passwd.5.gz
在 /var/man/cat[1-9] 次目录也有相同的名字需要被删除。
5.3 执行 make install
现在你已经准备要输入: (以 root 权限执行)
make install
这将安装最新和更新程式且修复档案许可权。它也会安装操作手册。
这也将在安装时考虑将 Shadow Suite 包含档案放在正确的位置 /usr/include/shadow 。
使用 BETA 套件,你需要手动复制 login.defs 这个档到 /etc 这个目录下,而且要确认只有 root 权限可以改变它。
cp login.defs /etc
chmod 700 /etc/login.defs
这个档案是 签入 程式的 configuration file。 你应该检查跟确定这个档的改变状况。这是你决定哪个 tty 的 root 可以从哪里签入和设定其他安全方针的地方(像预设密码的到期日)。
5.4 执行 pwconv
接下来的步骤是执行 pwconv。 这也需以 root执行且最好在 /etc 目录下执行:
cd /etc
/usr/sbin/pwconv
pwconv 撷取你的 /etc/passwd 档且删除某些栏位为了建立两个档案: /etc/npasswd 和 /etc/nshadow.
一个 pwunconv 也提供你建立一个 /etc/passwd 和 /etc/shadow 组合的正常 /etc/passwd 档案。
5.5 重新命名 npasswd 和 nshadow
现在你已经执行 pwconv ,而且你已经建立 /etc/npasswd 和 /etc/nshadow 档案。这需要复制到 /etc/passwd 和 /etc/shadow 档。 我们也需要复制原始 /etc/passwd 档,而且确定只有 root 可以读它。我们将该档案放在 root 得根目录:
cd /etc
cp passwd ~passwd
chmod 600 ~passwd
mv npasswd passwd
mv nshadow shadow
你也应该确定档案的拥有者跟存取权限是正确的。 如果你将要使用 X-Windows , xlock 和 xdm 可能需要读取 shadow 档(但需不要写入该档)。
有两个方法可以做。 你可以设定 xlock 的 suid 是 root (xdm 通常以 root 权限执行)。 或者你可以使 root 成为 shadow 的群组可以拥有 shadow 档,但是在作这之前,要确定你已经有个 shadow group (可以在 /etc/group 档看到)。不应改有任何使用者真的在 shadow group 。
chown root.root passwd
chown root.shadow shadow
chmod 0644 passwd
chmod 0640 shadow
你的系统现在有 shadow 的密码档罗。 你现在 应该 重开一个终端机视窗和确认你可以签入(login)。
请马上确实的作这件事!
如过你不能,可能某些事情有错误罗! 为了要回到 to a non-shadowed 状态,请作下列步骤:
cd /etc
cp ~passwd passwd
chmod 644 passwd
你将重新储存这些档案到先前你储存它们的正确位置。
6. upgrade或patch程式
6. 其他你需要升级(upgrade)或补强(patch)程式
即使 shadow suite 对大部分需要存取密码档的程式可以包含更新程式,但是仍有一些需要存取密码档的额外程式在系统中。
如果你正执行 Debian 版本 (或者即使你不是),你可以找到 Debian 需要 rebuild 的原始码: ftp://ftp.debian.org/debian/stable/source/
这节剩馀的部分在讨论更新 adduser, wu_ftpd, ftpd, pop3d, xlock,xdm 和 sudo 程式以便於让这些程式支援 shadow suite。
请看 Adding Shadow Support to a C program 这节,主要是在讨论如何将 shadow 支援放到其他需要程式(虽然这些程式需要以 SUID root 执行或 SGID shadow 需正确存取 shadow 档)。
6.1 Slackware adduser 程式
Slackware 版本包含一个新增使用者的交互程式叫做 /sbin/adduser。该程式的 shadow 版本可以在 ftp://sunsite.unc.edu/pub/linux/system/ Admin/accounts/adduser.shadow-1.4.tar.gz找到。
我很鼓励你使用 Shadow Suite 供应的程式(例如useradd, usermod, 和 userdel) 来取代 slackware 的adduser 程式。 它们只需花一点时间学习,但是它将值得的,因为你可以看到更多控制和在正确展现锁住 /etc/passwd 和 /etc/shadow 的档案(adduser 就没有办法罗)。
参考 Putting the Shadow Suite to use 该节得到更多相关资讯。
但是如果你已经拥有罗,接下来是你要做的部分:
tar -xzvf adduser.shadow-1.4.tar.gz
cd adduser
make clean
make adduser
chmod 700 adduser
cp adduser /sbin
6.2 wu_ftpd Server
大部分的 linux 系统都有 wu_ftpd server。 如果你的版本没有附带 shadow 安装,那麽你的 wu_ftpd 就没有办法对 shadow 编译。 wu_ftpd 是从 inetd/tcpd 开始且以 root 权限执行的程式。 如果你正在跑一个旧版的 wu_ftpd daemon, 无论如何你将要更新它因为较旧版本有 bug 将危及 root 权限。(参考 Linux security home page 得到更多相关资讯)。
幸运的是你只需要取的有嵌入 shaow 的原始码和重新编译就可以罗!
如果你不是正在执行 ELF 系统, wu_ftp server 可以从 Sunsite 网址 wu-ftp-2.4-fixed.tar.gz 找到。
当你获得这个 server,把它放在 /usr/src目录,然後输入:
cd /usr/src
tar -xzvf wu-ftpd-2.4-fixed.tar.gz
cd wu-ftpd-2.4-fixed
cp ./src/config/config.lnx.shadow ./src/config/config.lnx
然後编辑 ./src/makefiles/Makefile.lnx,和改变
LIBES = -lbsd -support
这一行到:
LIBES = -lbsd -support -lshadow
现在你已经准备好执行 script 建立跟安装:
cd /usr/src/wu-ftpd-2.4-fixed
/usr/src/wu-ftp-2.4.fixed/build lnx
cp /usr/sbin/wu.ftpd /usr/sbin/wu.ftpd.old
cp ./bin/ftpd /usr/sbin/wu.ftpd
这是用在 linux shadow configuration file、编译和安装 server。
在我的 Slackware 2.3 系统,我也需要在执行前作下列步骤:
build:
cd /usr/include/netinet
ln -s in_systm.h in_system.h
cd -
在 ELF 系统下会有编译问题的报告,但是下一版的 Beta 版则可以正确的执行。可以从 wu-ftp-2.4.2-beta-10.tar.gz 找到。
当你获得这个 server,把它放在 /usr/src目录,然後输入:
cd /usr/src
tar -xzvf wu-ftpd-2.4.2-beta-9.tar.gz
cd wu-ftpd-beta-9
cd ./src/config
然後编辑 config.lnx,和改变:
#undef SHADOW.PASSWORD
这一行到:
#define SHADOW.PASSWORD
然後,
cd ../Makefiles
且编辑 Makefile.lnx 档和改变
LIBES = -lsupport -lbsd # -lshadow
这一行到:
LIBES = -lsupport -lbsd -lshadow
然後建立(build)和安装(install):
cd ..
build lnx
cp /usr/sbin/wu.ftpd /usr/sbin/wu.ftpd.old
cp ./bin/ftpd /usr/sbin/wu.ftpd
注:你应该检查你的 /etc/inetd.conf 档来确认你的 wu.ftpd server 是不是真的活著。有些版本可能将 server daemons 放在不同的地方或用不同的名字表示。
6.3 标准 ftpd
如果你正在执行标准的 ftpd server,我将建议你更新 wu_ftpd server。离开上述的 bug ,系统会比较安全。
如果你坚持在标准模式,或者你需要 NIS 支援,在 Sunsite ftpd-shadow-nis.tgz 有参考资料。
6.4 pop3d (Post Office Protocol 3)
如果你需要支援第三版 Post Office Protocol (POP3),你将需要重新编译 pop3d 程式。 pop3d 可以透过 inetd/tcpd 以 root 权限正常的执行。
从 Sunsite 有两个版本可以获得: pop3d-1.00.4.linux.shadow.tar.gz 和 pop3d+shadow+elf.tar.gz
这两个都很简单可以安装。
6.5 xlock
如果你安装 shadow suite,然後执行 X Windows System 和 lock 萤幕没以更新你的 xlock 档, 你将必须使用 CNTL-ALT-Fx 去切换另一个 tty,签入(login)和杀掉(kill) xlock process (或使用 CNTL-ALT-BS 杀掉 X server)。很幸运的这也很容易可以更新你的 xlock 程式。
如果你正执行 XFree86 Versions 3.x.x,且正正确使用 xlockmore (是一个很棒的萤幕保护程式). 这个套件支援 shadow,只要重新编译即可。如果你有任何较老的 xlock 版本,我建议你更新下列版本:
xlockmore-3.5.tgz 可以从 ftp://sunsite.unc.edu/pub/linux/X11/xutils/screensavers/xlockmore-3.7.tgz 网站获得。
基本上这是你所要的。
撷取 xlockmore-3.7.tgz ,并将它放在 /usr/src 目录并解压缩:
tar -xzvf xlockmore-3.7.tgz
编辑这个档: /usr/X11R6/lib/X11/config/linux.cf, 和改变
#define HasShadowPasswd NO
这一行到:
#define HasShadowPasswd YES
然後建立可执行档:
cd /usr/src/xlockmore
xmkmf
make depend
make
然後搬移所以档案到正确目录且更新档案拥有者及执行权限:
cp xlock /usr/X11R6/bin/
cp XLock /var/X11R6/lib/app-defaults/
chown root.shadow /usr/X11R6/bin/xlock
chmod 2755 /usr/X11R6/bin/xlock
chown root.shadow /etc/shadow
chmod 640 /etc/shadow
你的 xlock 将可以正确的运作罗!
6.6 xdm
xdm 是一个可以表示在 X-Windows 签入画面的程式。某些系统开始 xdm 当系统被告知道一个特定的执行水准(参考 /etc/inittab)。
伴随著 Shadow Suite 安装, xdm 需要被更新。很幸运的这也很容易可以更新你的 xdm 程式。
xdm.tar.gz 可以从下列网址获得: ftp://sunsite.unc.edu/pub/linux/X11/xutils/xdm.tar.gz
撷取 xdm.tar.gz 档并将它放在 /usr/src目录然後解压缩:
tar -xzvf xdm.tar.gz
编辑这个档: /usr/X11R6/lib/X11/config/linux.cf,且改变
#define HasShadowPasswd NO
这一行到:
#define HasShadowPasswd YES
然後建立可执行档:
cd /usr/src/xdm
xmkmf
make depend
make
然後搬移所有档案正确目录:
cp xdm /usr/X11R6/bin/
xdm 以 root 权限在执行,所以你不需要改变档案存取权限。
6.7 sudo
sudo 程式允许系统管理员让使用者可以以 root 权限正常的执行程式。这是非常方便的因为它可以限制管理者执行 root 帐号本身权限,还可以允许使用者作像 mounte drives 的事情。
sudo 需要读取密码因为在执行时需确认使用者密码。 sudo 已经执行 SUID root,所以存取 /etc/shadow 党不是问题。
sudo 支援 shadow suite 可在下列网址取得: ftp://sunsite.unc.edu/pub/linux/system/Admin/sudo-1.2-shadow.tgz
警告:当你安装 sudo 你的 /etc/sudoers 档将取代预设值,所以你需要备份原始程式。如果你有家任何设定在预设程式,你可能要编辑 Makefile 且移除复制该档到 /etc 的这行。
该套件已经对 shadow 进行设定,所以只要重新编译该套件即可 (把它放在 /usr/src 目录):
cd /usr/src
tar -xzvf sudo-1.2-shadow.tgz
cd sudo-1.2-shadow
make all
make install
6.8 imapd (E-Mail [pine package])
imapd 是一个像 pop3d 的 email server。 imapd 随著 Pine E-mail 套件发生。 其操作手册在介绍该套件时即包含 shadow 支援。然而,我发现这不全然正确。 再加上在编译时加上 libshadow.a 函式库和该套件结合 build script / Makefile 是非常不容易的。所以对 imapd 加入 shadow 支援是不太可能的。
如果有任何答案,可以 Email 给我,我会将该解答放到这里。
6.9 pppd (Point-to-Point Protocol Server)
pppd server 可以使用几种权限设定: Password Authentication Protocol (PAP) 和 Cryptographic Handshake Authentication Protocol (CHAP)。 pppd server 从 /etc/ppp/chap-secrets 和/或 /etc/ppp/pap-secrets 档读取密码字串。如果你正使用预设 pppd 的执行,就没有必要再重新安装 pppd 。
pppd 以允许你使用 login 参数。 如果 login 选项被选取, pppd 将使用 /etc/passwd 档的帐号密码给 PAP. 当然在不久密码档会是 shadowedm。pppd-1.2.1d 档已经加入对 shadow 的支援。
下一节加入支援 shadow 的□例是针对 pppd-1.2.1d (一个较老版本的 pppd).
pppd-2.2.0 版就已经包括 shadow 支援罗。
7. 将 Shadow Suite 放进来使用
这节描述你需要知道有些程式在安装时就已经有 Shadow Suite。大部分的资讯在操作手册可以找到。
7.1 新增、修改和删除使用者
Shadow Suite 新增下列指令用来新增、修改和删除使用者。 这也是可以安装 adduser 程式。
useradd
useradd 使令可用在系统中新增使用者。 你也可以采用此指令来改变预设字串。
你应该做的第一件事是检查预设值设定和针对你的系统进行改变:
useradd -D
GROUP=1
HOME=/home
INACTIVE=0
EXPIRE=0
SHELL=
SKEL=/etc/skel
预设值不全是你要的,所以如果你开始新增使用者,你必须详阅每个使用者资讯。而且,我们可能和应该改变设定值。
在我的系统上:
我要预设群组是 100
我要密码每到 60 天就到期
我不要锁住帐号因为密码会到期
我要预设 shell 是 /bin/bash
为了这些改变,我要使用:
useradd -D -g100 -e60 -f0 -s/bin/bash
现在执行 useradd -D 将得到:
GROUP=100
HOME=/home
INACTIVE=0
EXPIRE=60
SHELL=/bin/bash
SKEL=/etc/skel
尽管依照你需要修改,预设值将存在 /etc/default/useradd.
先在你可以使用 useradd 来新增系统使用者。举例说明,新增一使用者 fred 使用预设值方式如下:
useradd -m -c "Fred Flintstone" fred
这将在 /etc/passwd 档中的一行建立如下:
fred:*:505:100:Fred Flintstone:/home/fred:/bin/bash
且在 /etc/shadow 档中的一行建立如下;
fred:!:0:0:60:0:0:0:0
fred的根目录将被建立且 /etc/skel 的内容将被复制因为指令句中有 -m 设定。
因为我们并未详述 UID,系统会直接寻找下一个可获得的编号。
fred的帐号被建立罗,但是 fred 仍然不能签入直到我们不再锁住(unlock)这个帐号。透过更改密码完成 unlock 帐号,方法如下:
passwd fred
Changing password for fred□Enter the new password (minimum of 5 characters)
Please use a combination of upper and lower case letters and numbers.
New Password: *******
Re-enter new password: *******
现在 /etc/shadow 档将包含:
fred:J0C.WDR1amIt6:9559:0:60:0:0:0:0
且 fred 将可以签入和使用该系统。 useradd 和其他附带 Shadow Suite 比较好的地方是可以自动改变 /etc/passwd 和 /etc/shadow 。 所以如果你正在新增一个使用者,且另一个使用者正在更改密码,这两个操作都可以正确的执行。
你使用提供的指令比直接存取 /etc/passwd 和 /etc/shadow 档还好。 如果你正编辑 /etc/shadow 档,且有个使用者在你编辑时要改变他的密码,然後你储存编辑结果,这个使用者的密码将会遗失掉。
这里是使用 useradd 和 passwd 新增使用者的一些 interactive script :
#!/bin/bash
#
# /sbin/newuser - A script to add users to the system using the Shadow
# Suite's useradd and passwd commands.
#
# Written my Mike Jackson as an example for the linux
# Shadow Password Howto. Permission to use and modify is expressly granted.
#
# This could be modified to show the defaults and allow modification similar
# to the Slackware Adduser program. It could also be modified to disallow
# stupid entries. (i.e. better error checking).
#
##
# Defaults for the useradd command
##
GROUP=100 # Default Group
HOME=/home # Home directory location (/home/username)
SKEL=/etc/skel # Skeleton Directory
INACTIVE=0 # Days after password expires to disable account (0=never)
EXPIRE=60 # Days that a passwords lasts
SHELL=/bin/bash # Default Shell (full path)
##
# Defaults for the passwd command
##
PASSMIN=0 # Days between password changes
PASSWARN=14 # Days before password expires that a warning is given
##
# Ensure that root is running the script.
##
WHOAMI=`/usr/bin/whoami`
if [ $WHOAMI != "root" ]; then
echo "You must be root to add news users!"
exit 1
fi
##
# Ask for username and fullname.
##
echo ""
echo -n "Username: "
read USERNAME
echo -n "Full name: "
read FULLNAME
#
echo "Adding user: $USERNAME."
#
# Note that the "" around $FULLNAME is required because this field is
# almost always going to contain at least on space, and without the "'s
# the useradd command would think that you we moving on to the next
# parameter when it reached the SPACE character.
#
/usr/sbin/useradd -c"$FULLNAME" -d$HOME/$USERNAME -e$EXPIRE
-f$INACTIVE -g$GROUP -m -k$SKEL -s$SHELL $USERNAME
##
# Set password defaults
##
/bin/passwd -n $PASSMIN -w $PASSWARN $USERNAME >/dev/null 2>&1
##
# Let the passwd command actually ask for password (twice)
##
/bin/passwd $USERNAME
##
# Show what was done.
##
echo ""
echo "Entry from /etc/passwd:"
echo -n " "
grep "$USERNAME:" /etc/passwd
echo "Entry from /etc/shadow:"
echo -n " "
grep "$USERNAME:" /etc/shadow
echo "Summary output of the passwd command:"
echo -n " "
passwd -S $USERNAME
echo ""
新增使用者是用 script 比直接编辑 /etc/passwd / /etc/shadow 档或使用像 Slackware 的 adduser 程式还要好。
需要更多 useradd 资讯请参照线上操作手册。
usermod
usermod 程式是用在修改使用者资讯。它的参数使用和 useradd 程式类似。
如果你要更新 fred 的 shell,你要作下列步骤:
usermod -s /bin/tcsh fred
现在 fred 的 /etc/passwd 档将变成:
fred:*:505:100:Fred Flintstone:/home/fred:/bin/tcsh
如果要使 fred 的帐号到期日为 09/15/97:
usermod -e 09/15/97 fred
现在 fred 在 /etc/shadow 的栏位变成:
fred:J0C.WDR1amIt6:9559:0:60:0:0:10119:0
需要更多 usermod 资讯请参照线上操作手册。
userdel
userdel 用在删除使用者,使用方法为:
userdel -r username
-r 参数可以将该使用者根目录全部移除。位在期待目录的档案则需手动移除。
如果你只是要简单的锁住帐号而没有要删除它,建议你使用 passwd 指令。
7.2 passwd 指令和 passwd 老化
passwd 指令很明显使用在改变密码,除此之外,可由 root 使用在:
Lock 和 unlock 帐号 (-l and -u)
设定密码合法的最大天数 (-x)
设定密码改变间的最小天数 (-n)
设定密码到期的警告天数 (-w)
设定在帐号未被锁死密码到期後的警告天数 (-i)
允许查询帐号资讯 (-S)
举例说明,如果要锁死 fred 帐号:
passwd -S fred
fred P 03/04/96 0 60 0 0
这表示 fred 的密码是有效的,它在 03/04/96 被修改且任何时间都可被修改, fred 将不会收到警告且帐号将不会因密码到期而关闭。
这表示如果 fred 在密码到期後签入,它将被要求用一个新密码签入。
如果我们决定要警告 fred 在密码过期前 14 天,且让它的帐号在到期後14天警告,我们需要作下列步骤:
passwd -w14 -i14 fred
现在 fred 改变为:
fred P 03/04/96 0 60 14 14
需要更多 passwd 资讯请参照线上操作手册。
7.3 login.defs 档
/etc/login 档是对 login 程式的 configuration file 且 对 Shadow Suite。
/etc/login 包含从预设值密码改变的驱动设定。
/etc/login.defs 档是一个很好的文件档,然而仍有些事情要注意:
It contains flags that can be turned on or off that determine the amount of logging that takes place.
It contains pointers to other configuration files.
It contains defaults assignments for things like password aging.
跟去上述你可以发现这是一个重要档,且你应该确认目前设定及你将对你系统的设定内容。
7.4 群组密码
/etc/groups 档包括允许是用者存取群组之密码。 如果你定义 SHADOWGRP 在 /usr/src/shadow-YYMMDD/config.h 档将开启该功能。
如果你定义该常数且编译它,你需建立一个 /etc/gshadow 档来保存群组密码和群组管理者资讯。
当你建立 /etc/shadow。你使用一个呼叫程式叫做 pwconv,该程式不会建立 /etc/gshadow 档,但是这没关系,只要你自行建立即可。
为了建立起始 /etc/gshadow 档要执行下列步骤:
touch /etc/gshadow
chown root.root /etc/gshadow
chmod 700 /etc/gshadow
每次你建立一个新群组,它们会被加到 /etc/group 和 /etc/gshadow 档。如果你透过新增或移除使用者来修改群组或改变群组密码,/etc/gshadow 档都将被改变。
groups, groupadd, groupmod, 和 groupdel 程式是用来供应 Shadow Suite 部分可以变更群组。
/etc/group 档格式如下:
groupname:!:GID:member,member,...
其中:
groupname
The name of the group
!
The field that normally holds the password, but that is now relocated to the /etc/gshadow file. GID
The numerical group ID number
member
List of group members
/etc/gshadow 档格式如下:
groupname:password:admin,admin,...:member,member,...
其中:
groupname
The name of the group
password
The encoded group password.
admin
List of group administrators
member
List of group members
gpasswd 指令是用在新增或移除管理者和群组成员。 root 或其他在群组管理者人员可新增或移除群组成员。
群组密码可以透过 passwd 指令改变,需透过 root 或在该群组管理者有权限的帐号方可修改。
Despite the fact that there is not currently a manual page for gpasswd, typing gpasswd without any parameters gives a listing of options. It's fairly easy to grasp how it all works once you understand the file formats and the concepts.
7.5 检查程式一致性
pwck
pwck 程式提供在 /etc/passwd 和 /etc/shadow 档的一致性检查。它将检查每个使用者名称且依照下列步骤确认:
the correct number of fields
unique user name
valid user and group identifier
valid primary group
valid home directory
valid login shell 它也会警告没有密码的帐号。
在安装 Shadow Suite 後执行 pwck 是一个很好的点子。它也可以每周或每月周期性的执行。 如果你使用 -r 参数,你可以用 cron 来执行且收到电子邮件报告
grpck
grpck 检查 /etc/group 和 /etc/gshadow 档一致性的程式。它作下列检查:
the correct number of fields
unique group name
valid list of members and administrators
它也有 -r 参数自动产生报表。
7.6 Dial-up 密码
Dial-up 密码是另一个对系统防御的选项列,该系统允许拨接存取。 如果你有一个系统允许许多人区域网路连结,但是你想限制拨接的权限,那你需使用 dial-up 密码。 为了要开启 dial-up 密码,你必须编辑 /etc/login.defs 档且确定将 DIALUPS_CHECK_ENAB 设定为 yes.
有两个档案包括 dial-up 资讯, /etc/dialups 包括 ttys (one per line, with the leading "/dev/" removed)。如果 tty 有被列出, dial-up 表示已经被检查。
第二个档是 /etc/d_passwd 。 这个档包括 shell 全部合法路径名称。
如果以个使用者签入一条列在 /etc/dialups 的线(line),且他的 shell 被列在 /etc/d_passwd 档,他将被允许存取透过提供正确的密码。
另一个使用 dial-up 密码的目的是设定指允许某些形式连结的线(可能是PPP 或 UUCP 连结)。如果一个使用者试著得到另一种形式连结 (i.e. a list of shells),他必须知道使用这条线的密码。 在你可以在未来使用 dial-up 前,你密需建立一些档案。
dpasswd 指令提供对在 /etc/d_passwd 档的 shells 指派密码。可以看操作手册的到更多资讯。
8. 加入 shadow 支援 C 语言
新增支援 shadow 程式事实上是很直接的。 唯一的问题是程式需要以 root (或 SUID root) 权限执行,这样才可以存取 /etc/shadow 档。
这显示一个大问题: 当建立 SUID 程式时需要很小心依照程式运作。举例说明: 如果以个程式有 shell escape,如果程式本身是 SUID root 将不需要以 root 方式呈现。
对程式新增支援 shadow 而言,它可以检查密码,但不需以 root 权限执行,而是以 SUID shadow 取代执行比较安全。 xlock 程式就是一个例子。
接下来□例介绍, pppd-1.2.1d 已经以 SUID as root 方式执行,所以新增 shadow 支援应该不会使程式产生任何影响。
8.1 标头档(Header files)
标头档应存在 /usr/include/shadow。 应该有一个 /usr/include/shadow.h档,但是它将 symbolic link 到 /usr/include/shadow/shadow.h。
为了新增支援 shadow 程式,你需要 include 标头档:
#include
#include
8.2 libshadow.a 函式库(library)
当你安装 Shadow Suite, libshadow.a 档被建立和安装在 /usr/lib 目录。
当编译一个 shadow support 程式,linker 需要包括 libshadow.a 函式库进入链结。
执行如下:
gcc program.c -o program -lshadow
然而,就像我们接下来要看的例子,大部分大程式使用 Makefile 且通常有变数呼叫 LIBS=... 需要被修改。
8.3 Shadow 结构(Structure)
libshadow.a 函式库对它从 /etc/shadow 档接收资讯使用结构化呼叫。这是从 /usr/include/shadow/shadow.h 标头档的 spwd 结构定义:
struct spwd
{
char *sp_namp; /* login name */
char *sp_pwdp; /* encrypted password */
sptime sp_lstchg; /* date of last change */
sptime sp_min; /* minimum number of days between changes */
sptime sp_max; /* maximum number of days between changes */
sptime sp_warn; /* number of days of warning before password
expires */
sptime sp_inact; /* number of days after password expires
until the account becomes unusable. */
sptime sp_expire; /* days since 1/1/70 until account expires
*/
unsigned long sp_flag; /* reserved for future use */
};
Shadow Suite 可以放除了编码密码之外的资料到 sp_pwdp 栏位。密码栏位可包括:
username:Npge08pfz4wuk;@/sbin/extra:9479:0:10000::::
这表示一个额外的密码, /sbin/extra 程式应该被更多的权限呼叫。 程式的呼叫需取得使用者名称和指出为何需被呼叫的 switch才可通过。 查看 /usr/include/shadow/pwauth.h 和原始码 pwauth.c 获得更多资讯。
为何我们应使用 pwauth 去表示真正的权限,这是什麽意思,它将使第二组权限也跑得很好。
Shadow Suite 作者指出因为大部分存在的程式都不这麽作罗,所以 Shadow Suite未来的版本将移除。
8.4 Shadow 函式(Functions)
shadow.h 包含 libshadow.a 函式库:
extern void setspent __P ((void));
extern void endspent __P ((void));
extern struct spwd *sgetspent __P ((__const char *__string));
extern struct spwd *fgetspent __P ((FILE *__fp));
extern struct spwd *getspent __P ((void));
extern struct spwd *getspnam __P ((__const char *__name));
extern int putspent __P ((__const struct spwd *__sp, FILE *__fp));
我们将使用的□例程式是: getspnam 将对供应名称恢复对我们 spwd 结构。
8.5 □例
这是一个□例描述新增 shadow 支援程式,但预设值并没有。
本□例使用 Point-to-Point Protocol Server (pppd-1.2.1d),它有个模式是表示 从 /etc/passwd 档取代 PAP 或 CHAP 档使用帐号密码的 PAP 权限,你将不需要在 pppd-2.2.0 加这些程式码,因为它已经存在罗。
pppd 的未来大致上不会被使用很多,但是如果你安装 Shadow Suite,储存在 /etc/passwd 档的密码将无法运作。
在 pppd-1.2.1d 权限使用的程式码是位在 /usr/src/pppd-1.2.1d/pppd/auth.c 档。
接下来程式码需要被加在所有其他 #include 指令档案的最上头,我们将注意有环境指令的 #includes。
#ifdef HAS_SHADOW
#include
#include
#endif
接下来要做的事情是变更实际码, 我们将变更 auth.c 档。
变更前 auth.c 档 function 为:
/*
* login - Check the user name and password against the system
* password database, and login the user if OK.
*
* returns:
* UPAP_AUTHNAK: Login failed.
* UPAP_AUTHACK: Login succeeded.
* In either case, msg points to an appropriate message.
*/
static int
login(user, passwd, msg, msglen)
char *user;
char *passwd;
char **msg;
int *msglen;
{
struct passwd *pw;
char *epasswd;
char *tty;
if ((pw = getpwnam(user)) == NULL) {
return (UPAP_AUTHNAK);
}
/*
* XXX If no passwd, let them login without one.
*/
if (pw->pw_passwd == '