<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-每日一得-随笔分类-linux</title><link>http://www.blogjava.net/alex/category/5489.html</link><description>不求多得,只求一得
about java,hibernate,spring,design,database,Ror,ruby,快速开发&lt;br/&gt;&lt;br/&gt;
最近关心的内容关键字:RoR
</description><language>zh-cn</language><lastBuildDate>Mon, 18 Jun 2007 09:14:53 GMT</lastBuildDate><pubDate>Mon, 18 Jun 2007 09:14:53 GMT</pubDate><ttl>60</ttl><item><title>[zt]如何在Linux下增加Swap </title><link>http://www.blogjava.net/alex/archive/2007/06/18/124940.html</link><dc:creator>Alex</dc:creator><author>Alex</author><pubDate>Mon, 18 Jun 2007 06:27:00 GMT</pubDate><guid>http://www.blogjava.net/alex/archive/2007/06/18/124940.html</guid><wfw:comment>http://www.blogjava.net/alex/comments/124940.html</wfw:comment><comments>http://www.blogjava.net/alex/archive/2007/06/18/124940.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alex/comments/commentRss/124940.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alex/services/trackbacks/124940.html</trackback:ping><description><![CDATA[<p>1.查看系统Swap空间使用</p>
<p>[root@jumper usr]# free<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; used&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free&nbsp;&nbsp;&nbsp;&nbsp; shared&nbsp;&nbsp;&nbsp; buffers&nbsp;&nbsp;&nbsp;&nbsp; cached<br>Mem:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 513980&nbsp;&nbsp;&nbsp;&nbsp; 493640&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 20340&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp; 143808&nbsp;&nbsp;&nbsp;&nbsp; 271780<br>-/+ buffers/cache:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 78052&nbsp;&nbsp;&nbsp;&nbsp; 435928<br>Swap:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1052248&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 21256&nbsp;&nbsp;&nbsp; 1030992</p>
<p>2.在空间合适处创建swap文件</p>
<p>[root@jumper usr]# mkdir swap<br>[root@jumper usr]# cd swap<br>[root@jumper swap]# dd if=/dev/zero of=swapfile bs=1024 count=10000<br>10000+0 records in<br>10000+0 records out<br>[root@jumper swap]# ls -al<br>total 10024<br>drwxr-xr-x&nbsp;&nbsp;&nbsp; 2 root&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4096&nbsp; 7月 28 14:58 .<br>drwxr-xr-x&nbsp;&nbsp; 19 root&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4096&nbsp; 7月 28 14:57 ..<br>-rw-r--r--&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp; 10240000&nbsp; 7月 28 14:58 swapfile</p>
<p><br>[root@jumper swap]# mkswap swapfile<br>Setting up swapspace version 1, size = 9996 KiB</p>
<p><br>3.激活swap文件<br>[root@jumper swap]# swapon swapfile<br>[root@jumper swap]# ls -l<br>total 10016<br>-rw-r--r--&nbsp;&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp;&nbsp; root&nbsp;&nbsp;&nbsp;&nbsp; 10240000&nbsp; 7月 28 14:58 swapfile<br>[root@jumper swap]# free<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; total&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; used&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free&nbsp;&nbsp;&nbsp;&nbsp; shared&nbsp;&nbsp;&nbsp; buffers&nbsp;&nbsp;&nbsp;&nbsp; cached<br>Mem:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 513980&nbsp;&nbsp;&nbsp;&nbsp; 505052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8928&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0&nbsp;&nbsp;&nbsp;&nbsp; 143900&nbsp;&nbsp;&nbsp;&nbsp; 282288<br>-/+ buffers/cache:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 78864&nbsp;&nbsp;&nbsp;&nbsp; 435116<br>Swap:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1062240&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 21256&nbsp;&nbsp;&nbsp; 1040984<br>[root@jumper swap]# &nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Swap，即交换区，除了安装Linux的时候，有多少人关心过它呢？其实，Swap的调整对Linux服务器，特别是Web服务器的性能至关重要。通过调整Swap，有时可以越过系统性能瓶颈，节省系统升级费用。&nbsp; <br><br>本文内容包括：&nbsp; <br><br><br>Swap基本原理&nbsp; <br><br>突破128M&nbsp;Swap限制&nbsp; <br><br>Swap配置对性能的影响&nbsp; <br><br>Swap性能监视&nbsp; <br><br>有关Swap操作的系统命令&nbsp; <br>Swap基本原理&nbsp; <br><br>Swap的原理是一个较复杂的问题，需要大量的篇幅来说明。在这里只作简单的介绍，在以后的文章中将和大家详细讨论Swap实现的细节。&nbsp; <br><br>众所周知，现代操作系统都实现了"虚拟内存"这一技术，不但在功能上突破了物理内存的限制，使程序可以操纵大于实际物理内存的空间，更重要的是，"虚拟内存"是隔离每个进程的安全保护网，使每个进程都不受其它程序的干扰。&nbsp; <br><br>Swap 空间的作用可简单描述为：当系统的物理内存不够用的时候，就需要将物理内存中的一部分空间释放出来，以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序，这些被释放的空间被临时保存到Swap空间中，等到那些程序要运行时，再从Swap中恢复保存的数据到内存中。这样，系统总是在物理内存不够时，才进行Swap交换。&nbsp; <br><br>计算机用户会经常遇这种现象。例如，在使用Windows系统时，可以同时运行多个程序，当你切换到一个很长时间没有理会的程序时，会听到硬盘"哗哗"直响。这是因为这个程序的内存被那些频繁运行的程序给"偷走"了，放到了Swap区中。因此，一旦此程序被放置到前端，它就会从Swap区取回自己的数据，将其放进内存，然后接着运行。&nbsp; <br><br>需要说明一点，并不是所有从物理内存中交换出来的数据都会被放到Swap中（如果这样的话，Swap就会不堪重负），有相当一部分数据被直接交换到文件系统。例如，有的程序会打开一些文件，对文件进行读写（其实每个程序都至少要打开一个文件，那就是运行程序本身），当需要将这些程序的内存空间交换出去时，就没有必要将文件部分的数据放到 Swap空间中了，而可以直接将其放到文件里去。如果是读文件操作，那么内存数据被直接释放，不需要交换出来，因为下次需要时，可直接从文件系统恢复；如果是写文件，只需要将变化的数据保存到文件中，以便恢复。但是那些用malloc和new函数生成的对象的数据则不同，它们需要Swap空间，因为它们在文件系统中没有相应的"储备"文件，因此被称作"匿名"(Anonymous)内存数据。这类数据还包括堆栈中的一些状态和变量数据等。所以说，Swap 空间是"匿名"数据的交换空间。&nbsp; <br><br>突破128M&nbsp;Swap限制&nbsp; <br><br>经常看到有些Linux（国内汉化版）安装手册上有这样的说明：Swap空间不能超过128M。为什么会有这种说法？在说明"128M"这个数字的来历之前，先给问题一个回答：现在根本不存在128M的限制！现在的限制是2G！&nbsp; <br><br>Swap 空间是分页的，每一页的大小和内存页的大小一样，方便Swap空间和内存之间的数据交换。旧版本的Linux实现Swap空间时，用Swap空间的第一页作为所有Swap空间页的一个"位映射"（Bit&nbsp;map）。这就是说第一页的每一位，都对应着一页Swap空间。如果这一位是1，表示此页Swap可用；如果是0，表示此页是坏块，不能使用。这么说来，第一个Swap映射位应该是0，因为，第一页Swap是映射页。另外，最后10个映射位也被占用，用来表示Swap的版本（原来的版本是Swap_space&nbsp;，现在的版本是swapspace2）。那么，如果说一页的大小为s，这种Swap的实现方法共能管理"8&nbsp;*&nbsp;(&nbsp;s&nbsp;-&nbsp;10&nbsp;)&nbsp;-&nbsp;1"个Swap页。对于i386系统来说s=4096，则空间大小共为133890048，如果认为 1&nbsp;MB=2^20&nbsp;Byte的话，大小正好为128M。&nbsp; <br><br>之所以这样来实现Swap空间的管理，是要防止Swap空间中有坏块。如果系统检查到Swap中有坏块，则在相应的位映射上标记上0，表示此页不可用。这样在使用Swap时，不至于用到坏块，而使系统产生错误。&nbsp; <br><br>现在的系统设计者认为：&nbsp; <br><br>1.现在硬盘质量很好，坏块很少。&nbsp; <br><br>2.就算有，也不多，只需要将坏块罗列出来，而不需要为每一页建立映射。&nbsp; <br><br>3.如果有很多坏块，就不应该将此硬盘作为Swap空间使用。&nbsp; <br><br>于是，现在的Linux取消了位映射的方法，也就取消了128M的限制。直接用地址访问，限制为2G。&nbsp; <br><br>Swap配置对性能的影响&nbsp; <br><br>分配太多的Swap空间会浪费磁盘空间，而Swap空间太少，则系统会发生错误。&nbsp; <br><br>如果系统的物理内存用光了，系统就会跑得很慢，但仍能运行；如果Swap空间用光了，那么系统就会发生错误。例如，Web服务器能根据不同的请求数量衍生出多个服务进程（或线程），如果Swap空间用完，则服务进程无法启动，通常会出现"application&nbsp;is&nbsp;out&nbsp;of&nbsp;memory"的错误，严重时会造成服务进程的死锁。因此Swap空间的分配是很重要的。&nbsp; <br><br>通常情况下，Swap空间应大于或等于物理内存的大小，最小不应小于64M，通常Swap空间的大小应是物理内存的2-2.5倍。但根据不同的应用，应有不同的配置：如果是小的桌面系统，则只需要较小的Swap空间，而大的服务器系统则视情况不同需要不同大小的Swap空间。特别是数据库服务器和Web服务器，随着访问量的增加，对Swap空间的要求也会增加，具体配置参见各服务器产品的说明。&nbsp; <br><br>另外，Swap分区的数量对性能也有很大的影响。因为Swap交换的操作是磁盘IO的操作，如果有多个 Swap交换区，Swap空间的分配会以轮流的方式操作于所有的Swap，这样会大大均衡IO的负载，加快Swap交换的速度。如果只有一个交换区，所有的交换操作会使交换区变得很忙，使系统大多数时间处于等待状态，效率很低。用性能监视工具就会发现，此时的CPU并不很忙，而系统却慢。这说明，瓶颈在 IO上，依靠提高CPU的速度是解决不了问题的。&nbsp; <br>系统性能监视&nbsp; <br><br>Swap空间的分配固然很重要，而系统运行时的性能监控却更加有价值。通过性能监视工具，可以检查系统的各项性能指标，找到系统性能的瓶颈。本文只介绍一下在Solaris下和Swap相关的一些命令和用途。&nbsp; <br><br>最常用的是Vmstat命令（在大多数Unix平台下都有这样一些命令），此命令可以查看大多数性能指标。&nbsp; <br><br>例如：&nbsp; <br>#&nbsp;vmstat&nbsp;3&nbsp; <br>procs&nbsp;memory&nbsp;swap&nbsp;io&nbsp;system&nbsp;cpu&nbsp; <br>r&nbsp;b&nbsp;w&nbsp;swpd&nbsp;free&nbsp;buff&nbsp;cache&nbsp;si&nbsp;so&nbsp;bi&nbsp;bo&nbsp;in&nbsp;cs&nbsp;us&nbsp;sy&nbsp;id&nbsp; <br>0&nbsp;0&nbsp;0&nbsp;0&nbsp;93880&nbsp;3304&nbsp;19372&nbsp;0&nbsp;0&nbsp;10&nbsp;2&nbsp;131&nbsp;10&nbsp;0&nbsp;0&nbsp;99&nbsp; <br>0&nbsp;0&nbsp;0&nbsp;0&nbsp;93880&nbsp;3304&nbsp;19372&nbsp;0&nbsp;0&nbsp;0&nbsp;0&nbsp;109&nbsp;8&nbsp;0&nbsp;0&nbsp;100&nbsp; <br>0&nbsp;0&nbsp;0&nbsp;0&nbsp;93880&nbsp;3304&nbsp;19372&nbsp;0&nbsp;0&nbsp;0&nbsp;0&nbsp;112&nbsp;6&nbsp;0&nbsp;0&nbsp;100&nbsp; <br>............&nbsp; <br><br>命令说明：&nbsp; <br>vmstat&nbsp;后面的参数指定了性能指标捕获的时间间隔。3表示每三秒钟捕获一次。第一行数据不用看，没有价值，它仅反映开机以来的平均性能。从第二行开始，反映每三秒钟之内的系统性能指标。这些性能指标中和Swap有关的包括以下几项：&nbsp; <br><br><br>procs下的w&nbsp; <br>它表示当前（三秒钟之内）需要释放内存、交换出去的进程数量。&nbsp; <br><br>memory下的swpd&nbsp; <br>它表示使用的Swap空间的大小。&nbsp; <br><br>Swap下的si，so&nbsp; <br>si表示当前（三秒钟之内）每秒交换回内存（Swap&nbsp;in）的总量，单位为kbytes；so表示当前（三秒钟之内）每秒交换出内存（Swap&nbsp;out）的总量，单位为kbytes。&nbsp; <br>以上的指标数量越大，表示系统越忙。这些指标所表现的系统繁忙程度，与系统具体的配置有关。系统管理员应该在平时系统正常运行时，记下这些指标的数值，在系统发生问题的时候，再进行比较，就会很快发现问题，并制定本系统正常运行的标准指标值，以供性能监控使用。&nbsp; <br><br>另外，使用Swapon-s也能简单地查看当前Swap资源的使用情况。例如：&nbsp; <br>#&nbsp;swapon&nbsp;-s&nbsp; <br>Filename&nbsp;Type&nbsp;Size&nbsp;Used&nbsp;Priority&nbsp; <br>/dev/hda9&nbsp;partition&nbsp;361420&nbsp;0&nbsp;3&nbsp; <br><br>能够方便地看出Swap空间的已用和未用资源的大小。&nbsp; <br><br>应该使Swap负载保持在30%以下，这样才能保证系统的良好性能。&nbsp; <br><br>有关Swap操作的系统命令&nbsp; <br><br><br>增加Swap空间，分以下几步：&nbsp; <br>1)成为超级用户&nbsp; <br>$su&nbsp;-&nbsp;root&nbsp; <br><br>2)创建Swap文件&nbsp; <br>#&nbsp;dd&nbsp;if=/dev/zero&nbsp;of=swapfile&nbsp;bs=1024&nbsp;count=65536&nbsp; <br><br>创建一个有连续空间的交换文件。&nbsp; <br><br>3)激活Swap文件&nbsp; <br>#/usr/sbin/swapon&nbsp;swapfile&nbsp; <br><br>swapfile指的是上一步创建的交换文件。&nbsp;4)现在新加的Swap文件已经起作用了，但系统重新启动以后，并不会记住前几步的操作。因此要在/etc/fstab文件中记录文件的名字，和Swap类型，如：&nbsp; <br>/path/swapfile&nbsp;none&nbsp;Swap&nbsp;sw,pri=3&nbsp;0&nbsp;0&nbsp; <br><br>5)检验Swap文件是否加上&nbsp; <br>/usr/sbin/swapon&nbsp;-s&nbsp; <br><br><br>删除多余的Swap空间。&nbsp; <br>1)成为超级用户&nbsp; <br><br>2)使用Swapoff命令收回Swap空间。&nbsp; <br>#/usr/sbin/swapoff&nbsp;swapfile&nbsp; <br><br>3)编辑/etc/fstab文件，去掉此Swap文件的实体。&nbsp; <br><br>4)从文件系统中回收此文件。&nbsp; <br>#rm&nbsp;swapfile&nbsp; <br><br>5)当然，如果此Swap空间不是一个文件，而是一个分区，则需创建一个新的文件系统，再挂接到原来的文件系统上。</p>
<img src ="http://www.blogjava.net/alex/aggbug/124940.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alex/" target="_blank">Alex</a> 2007-06-18 14:27 <a href="http://www.blogjava.net/alex/archive/2007/06/18/124940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ssh timeout</title><link>http://www.blogjava.net/alex/archive/2006/09/06/68048.html</link><dc:creator>Alex</dc:creator><author>Alex</author><pubDate>Wed, 06 Sep 2006 08:07:00 GMT</pubDate><guid>http://www.blogjava.net/alex/archive/2006/09/06/68048.html</guid><wfw:comment>http://www.blogjava.net/alex/comments/68048.html</wfw:comment><comments>http://www.blogjava.net/alex/archive/2006/09/06/68048.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alex/comments/commentRss/68048.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alex/services/trackbacks/68048.html</trackback:ping><description><![CDATA[how to set the SSH timeout?<br />a: set 'TMOUT=3600' in /etc/profile <br /><br />fine.<br /><img src ="http://www.blogjava.net/alex/aggbug/68048.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alex/" target="_blank">Alex</a> 2006-09-06 16:07 <a href="http://www.blogjava.net/alex/archive/2006/09/06/68048.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]OpenLDAP学习笔记</title><link>http://www.blogjava.net/alex/archive/2006/08/10/62716.html</link><dc:creator>Alex</dc:creator><author>Alex</author><pubDate>Thu, 10 Aug 2006 01:33:00 GMT</pubDate><guid>http://www.blogjava.net/alex/archive/2006/08/10/62716.html</guid><wfw:comment>http://www.blogjava.net/alex/comments/62716.html</wfw:comment><comments>http://www.blogjava.net/alex/archive/2006/08/10/62716.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alex/comments/commentRss/62716.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alex/services/trackbacks/62716.html</trackback:ping><description><![CDATA[key words : openldap ldap<br /><br /><div class="book" lang="en"><div class="titlepage"><div><div><h1 class="title"><a name="id2875167"></a></h1></div><div><div class="author"><h3 class="author"><span class="firstname">整理：Jims of <a href="http://www.ringkee.com/" target="_top">肥肥世家</a></span></h3><div class="affiliation"><div class="address"><p><tt class="email">&lt;<a href="mailto:jims.yang@gmail.com">jims.yang@gmail.com</a>&gt;</tt></p></div></div></div></div><div><p class="copyright">Copyright © 2004，2005， 本文遵从GNU 的自由文档许可证(Free Document License)的条款，欢迎转载、修改、散布。</p></div><div><p class="pubdate">发布时间:2004年04月07日</p></div><div><p class="pubdate">最近更新:2005年08月08日</p></div><div><div class="abstract"><p class="title"><b>Abstract</b></p><p>LDAP
(轻量级目录服务访问协议，Lightweight Directory Access
Protocol)基于X.500标准，支持TCP/IP，使用简单方便。现在越来越多的网络应用系统都支持LDAP。OpenLDAP是LDAP的一种
开源实现，本笔记基于OpenLDAP2.1.29。</p></div></div></div><hr /></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="chapter"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2809654">1. 目录服务简介</a></span></dt><dd><dl><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2809734">1.1. X.500和LDAP</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810057">1.2. LDAP产品</a></span></dt></dl></dd><dt><span class="chapter"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810083">2. OpenLDAP安装笔记</a></span></dt><dd><dl><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810091">2.1. 源码安装</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810479">2.2. 数据录入</a></span></dt><dd><dl><dt><span class="sect2"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810506">2.2.1. 手动录入方法</a></span></dt><dt><span class="sect2"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810743">2.2.2. 文件方式</a></span></dt><dt><span class="sect2"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810843">2.2.3. 脚本方式</a></span></dt></dl></dd><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810869">2.3. 常用命令介绍</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808359">2.4. 启用sasl验证</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808424">2.5. 配置服务器复制</a></span></dt></dl></dd><dt><span class="chapter"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808612">3. 管理工具</a></span></dt><dd><dl><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808628">3.1. phpldapadmin</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808639">3.2. gq</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808650">3.3. CPU</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808661">3.4. JXplore</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808672">3.5. LAM</a></span></dt></dl></dd><dt><span class="chapter"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808693">4. HowTo</a></span></dt><dd><dl><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808700">4.1. 禁止整个服务器的匿名访问</a></span></dt></dl></dd></dl></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="id2809654"></a>Chapter 1. 目录服务简介</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2809734">1.1. X.500和LDAP</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810057">1.2. LDAP产品</a></span></dt></dl></div><p>目
录是一个为查询、浏览和搜索而优化的专业分布式数据库，它成树状结构组织数据，就好象Linux/Unix系统中的文件目录一样。目录数据库和关系数据库
不同，它有优异的读性能，但写性能差，并且没有事务处理、回滚等复杂功能，不适于存储修改频繁的数据。所以目录天生是用来查询的，就好象它的名字一样。目
录服务是由目录数据库和一套访问协议组成的系统。类似以下的信息适合储存在目录中：</p><div class="itemizedlist"><ul type="disc"><li><p>企业员工和企业客户之类人员信息；</p></li><li><p>公用证书和安全密钥；</p></li><li><p>邮件地址、网址、IP等电脑信息；</p></li><li><p>电脑配置信息。</p></li><li><p>...</p></li></ul></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2809734"></a>1.1. X.500和LDAP</h2></div></div></div><p>现在国际上的目录服务标准有两个，一个是较早的X.500标准，一个是较新的LDAP标准。</p><div class="itemizedlist"><ul type="disc"><li><p>X.500是一个协议族，由一系列的概念和协议组成，包括：</p><div class="itemizedlist"><ul type="circle"><li><p>X.501是模型定义，定义目录服务的基本模型和概念；</p></li><li><p>X.509是认证框架，定义如何处理目录服务中客户和服务器认证；</p></li><li><p>X.511是抽象服务定义，定义X.500提供的功能性服务；</p></li><li><p>X.518是分布式操作过程定义，定义如何跨平台处理目录服务；</p></li><li><p>X.519
是协议规范，定义了X.500协议，包括DAP(Directory Access Protocol，目录访问协议)、DSP(Directory
System Protocol，目录系统协议)、DOP(Directory Operator
Protocol，目录操作绑定协议)、DISP(Directory Information Shadowing
Protocol，目录信息阴影协议 )；</p></li><li><p>X.520定义属性类型要求；</p></li><li><p>X.521定义对象类型；</p></li><li><p>X.525定义如果在目录服务器间复制内容。</p></li></ul></div><p>X.500标准中定义了很多内容，包括：</p><div class="itemizedlist"><ul type="circle"><li><p>定义了信息模型，确定目录中信息的格式和字符集，如何在项中表示目录信息(定义对象类、属性等模式)；</p></li><li><p>定义命名空间，确定对信息进行的组织和引用，如何组织和命名项-目录信息树DIT和层次命名模型；</p></li><li><p>定义功能模型，确定可以在信息上执行的操作；</p></li><li><p>定义认证框架，保证目录中信息的安全，如何实现目录中信息的授权保护-访问控制模型；</p></li><li><p>定义分布操作模型，确定数据如何分布和如何对分布数据执行操作，如何将全局目录树划分为管理域，以便管理。</p></li><li><p>定义客户端与服务器之间的通信的各种协议。</p></li></ul></div><p>由于X.500较复杂，且需严格遵照OSI七层协议模型。造成应用开发较困难。所以开发了LDAP，以便在INTERNET上使用。</p></li><li><p>LDAP协议于1993年获批准，产生LDAPv1版，1997年发布最新的LDAPv3版，该版本是LDAP协议发展的一个里程碑，它作为X.500的简化版提供了很多自有的特性，使LDAP功能更为完备，具有更强大的生命力。</p><p>LDAP也是一个协议族，包含以下内容：</p><div class="itemizedlist"><ul type="circle"><li><p>RFC 2251--LDAPv3核心协议，定义了LDAPv3协议的基本模型和基本操作；</p></li><li><p>RFC 2252--定义LDAPv3基本数据模式(Schema)(包括语法、匹配规则、属性类型和对象类)以及标准的系统数据模式；</p></li><li><p>RFC 2253--定义LDAPv3中的分辩名(DN)表达式；</p></li><li><p>RFC 2254--定义了LDAPv3中的过滤表达式；</p></li><li><p>RFC 2255--定义LDAPv3统一资源地址的格式；</p></li><li><p>RFC 2256--定义LDAPv3中使用X.500的Schema列表；</p></li><li><p>RFC 2829--定义了LDAPv3中的认证方式；</p></li><li><p>RFC 2830--定义了如何通过扩展使用TLS服务；</p></li><li><p>RFC 1823--定义了C的LDAP客户端API开发接口；</p></li><li><p>RFC 2847--定义了LDAP数据导入、导出文件接口LDIF。</p></li></ul></div><p>这些协议定义了LDAP的内容，包括：</p><div class="itemizedlist"><ul type="circle"><li><p>定义了一个信息模型，确定了LDAP目录中信息的格式和字符集，如何表示目录信息(定义对象类、属性、匹配规则和语法等模式)；</p></li><li><p>定义了命名空间，确定信息的组织方式--目录树DIT，以DN和RDN为基础的命名方式，以及LDAP信息的Internet表示方式；</p></li><li><p>定义了功能模型，确定在可以在信息上执行的操作及API。</p></li><li><p>定义了安全框架，保证目录中信息的安全，定义匿名、用户名/密码、SASL等多种认证方式，以及与TLS结合的通讯保护框架；</p></li><li><p>定义分布式操作模型，基于指引方式的分布式操作框架；</p></li><li><p>定义了LDAP扩展框架。</p></li></ul></div></li></ul></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2810057"></a>1.2. LDAP产品</h2></div></div></div><p>现
在市场上有关LDAP的产品已有很多，各大软件公司都在他们的产品中集成了LDAP服务，如Microsoft的ActiveDirectory、
Lotus的Domino
Directory、IBM的WebSphere中也集成了LDAP服务。LDAP的开源实现是OpenLDAP，它比商业产品一点也不差，而且源码开
放。</p></div></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="id2810083"></a>Chapter 2. OpenLDAP安装笔记</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810091">2.1. 源码安装</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810479">2.2. 数据录入</a></span></dt><dd><dl><dt><span class="sect2"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810506">2.2.1. 手动录入方法</a></span></dt><dt><span class="sect2"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810743">2.2.2. 文件方式</a></span></dt><dt><span class="sect2"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810843">2.2.3. 脚本方式</a></span></dt></dl></dd><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2810869">2.3. 常用命令介绍</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808359">2.4. 启用sasl验证</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808424">2.5. 配置服务器复制</a></span></dt></dl></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2810091"></a>2.1. 源码安装</h2></div></div></div><p>我的安装方法是以源码编译的方式进行的，以root用户进行安装。安装所需软件如下：</p><div class="itemizedlist"><ul type="disc"><li><p><a href="http://www.openldap.org/" target="_top">openldap-2.1.29</a></p></li><li><p><a href="http://www.sleepycat.com/" target="_top">Berkeley DB 4.2.52</a></p></li></ul></div><p>具体的安装步骤如下：</p><div class="orderedlist"><ol type="1"><li><p>由于openldap需要Berkeley DB来存放数据，所以需先安装Berkeley DB 4.2.52，可到它的网站下载，网址见上面。运行下面的命令解压：</p><pre class="screen"># tar -zxvf db-4.2.52.tar.gz<br /></pre><p>解完压后，会生成一个db-4.2.52目录,进行该目录下的build_unix目录。执行以下命令进行配置安装。</p><pre class="screen"># ../dist/configure<br /># make<br /># make install<br /></pre><p>也是按linux源码安装的三步曲完成，没有什么好说的了。该软件默认是安装在/usr/local/BerkeleyDB.4.2目
录下。安装完成后，要把/usr/local/BerkeleyDB.4.2/lib的库路径加到/etc/ld.so.conf文件内，添加完成后执行
一次ldconfig，使配置文件生效。这样编译openldap时才能找到相应的库文件。这样资料库就安装完成了，接下来可以安装openldap了。
ld.so.conf是什么东西？它就是系统动态链接库的配置文件。此文件内,存放着可被LINUX共享的动态链接库所在目录的名字(系统目录/lib,
/usr/lib除外)，各个目录名间以空白字符(空格，换行等)或冒号或逗号分隔。一般的LINUX发行版中，此文件均含一个共享目录
/usr/X11R6/lib，为X window窗口系统的动态链接库所在的目录。
ldconfig是它的管理命令，具体操作方法可查询man手册，这里就不细讲了。</p></li><li><p>到openldap官方网站下载最新
的稳定版源码，并解压。查看INSTALLT
和README文档，这个很重要，因为安装方法和一些注意事项都在里面有介绍。认真弄明白文档内容能节省你不少的安装调试时间。这也是开源软件的一个特
点，给用户提供了最大的灵活性和可配置性。但也增加了系统安装配置的难度，需要有相关的文档配置说明和指导。在官方网站上还有详细的帮助文件，在整个系统
配置中需要经常查询。</p><pre class="screen"># tar -zxvf openldap-stable-20040329.tgz<br /></pre><p>解压完成后，会生成一个openldap-2.1.29目录。进行该目录，执行以下命令进行配置安装。</p><pre class="screen"># env CPPFLAGS="-I/usr/local/BerkeleyDB.4.2/include" <br />LDFLAGS="-L/usr/local/BerkeleyDB.4.2/lib" ./configure --prefix=/usr/local/openldap <br />--enable-ldbm <br /></pre><p>注意以上配置语句，要设置资料库的include和lib路径，否则在配置到资料库相关内容时会提示Berkeley DB版本不兼容，并中断配置。如果没有--enable-ldbm选项，在make test时会提示ldbm找不到。为了减少出错，还是加上为好。</p><pre class="screen">#make depens<br />#make<br />#make test<br /></pre><p>在make test阶段要花费较长时间进行测试，好像有16项吧。你可以放松一下，上上网，聊聊天，听听歌，呵呵，开玩笑了，这个时间应该是最紧张的了。成与不成就看这下的了，如果没问题就可安装了。</p><pre class="screen">#make install<br /></pre><p>通过配置命令可以看出，我们把openldap安装到/usr/local/openldap目录下。建议以源码安装的软件都放到独立的目录下，不要放到软件默认的目录。好处是方便管理和控制，所有文件在统一的目录下，卸载软件只要删除整个目录就可以了。</p></li><li><p>安
装完相关软件后就可以着手配置了。Berkeley DB资料库没什么好配置的。主要是配置openldap
服务。配置文件在软件的安装目录的etc/openldap下，有四个文件，主要的是slapd.conf and
ldap.conf，其它两个是backup文件。首先，我们先来配置slapd.conf文档。系统默认的slapd.conf文件如下：</p><pre class="screen"># $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.23.2.8 2003/05/24 23:19:14 kurt Exp $<br /># <br /># See slapd.conf(5) for details on configuration options.<br /># This file should NOT be world readable. <br /># <br />include      /usr/local/openldap/etc/openldap/schema/core.schema  <br />#设置schema配置文档包含<br /><br /># Define global ACLs to disable default read access.<br /><br /># Do not enable referrals until AFTER you have a working directory<br /># service AND an understanding of referrals.<br />#referral       ldap://root.openldap.org<br /><br />pidfile         /usr/local/openldap/var/slapd.pid <br />#设置pid和args文档位置<br />argsfile        /usr/local/openldap/var/slapd.args<br /><br /># Load dynamic backend modules:<br /># modulepath    /usr/local/openldap/libexec/openldap<br /># moduleload    back_bdb.la <br /># moduleload    back_ldap.la<br /># moduleload    back_ldbm.la <br /># moduleload    back_passwd.la<br /># moduleload    back_shell.la<br /><br /># Sample security restrictions <br />#       Require integrity protection (prevent hijacking)<br />#       Require 112-bit (3DES or better) encryption for updates<br />#       Require 63-bit encryption for simple bind<br /># security ssf=1 update_ssf=112 simple_bind=64<br /><br /># Sample access control policy: <br />#       Root DSE: allow anyone to read it<br />#       Subschema (sub)entry DSE: allow anyone to read it<br />#       Other DSEs: <br />#       Subschema (sub)entry DSE: allow anyone to read it<br />#       Other DSEs:<br />#               Allow self write access<br />#               Allow authenticated users read access<br />#               Allow anonymous users to authenticate<br />#       Directives needed to implement policy:<br /># access to dn.base="" by * read<br /># access to dn.base="cn=Subschema" by * read<br /># access to *<br />#       by self write<br />#       by users read<br />#       by anonymous auth<br />#<br /># if no access controls are present, the default policy is:<br />#       Allow read by all<br />#<br /># rootdn can always write!<br /><br />#######################################################################<br /># ldbm database definitions<br />#######################################################################<br /><br />database        bdb                                <br />#设置使用的资料库，也可用lbdm。<br />suffix          "dc=my-domain,dc=com"              <br />#设置目录后缀<br />rootdn          "cn=Manager,dc=my-domain,dc=com"   <br />#设置目录管理员<br /># Cleartext passwords, especially for the rootdn, should<br /># be avoid.  See slappasswd(8) and slapd.conf(5) for details.<br /># Use of strong authentication encouraged.<br />rootpw          secret                             <br />#设置管理密码，这里用了明文的“secret”密码。这样设置不安全，需使用加密的密码，下面会讲到如何设置加密密码。<br /># The database directory MUST exist prior to running slapd AND <br /># should only be accessible by the slapd and slap tools.<br /># Mode 700 recommended.<br />directory       /usr/local/openldap/var/openldap-data  <br />#设置资料库路径<br /># Indices to maintain<br />index   objectClass     eq                        <br />#设置目录项索引<br /></pre><p>要服务器正常动作，要修改一些始初参数和设置，修改后的配置文档如下：</p><pre class="screen"># $OpenLDAP: pkg/ldap/servers/slapd/slapd.conf,v 1.23.2.8 2003/05/24 23:19:14 kurt Exp $<br />#<br /># See slapd.conf(5) for details on configuration options.<br /># This file should NOT be world readable.<br />#<br />#为了有效使用目录服务，包含相关的文件。注意，在包含文件时是要按一定顺序的，因为<br />#文件里的属性存在依赖关系。如果顺序不对，服务器启动不了，文档间的依赖关系在文档<br />#中都有说明，请仔细查看一下。如果懒得看也可以按我的顺序。<br />include         /usr/local/openldap/etc/openldap/schema/core.schema<br />include         /usr/local/openldap/etc/openldap/schema/corba.schema<br />include         /usr/local/openldap/etc/openldap/schema/cosine.schema<br />include         /usr/local/openldap/etc/openldap/schema/inetorgperson.schema    <br />include         /usr/local/openldap/etc/openldap/schema/misc.schema             <br />include         /usr/local/openldap/etc/openldap/schema/openldap.schema<br />include         /usr/local/openldap/etc/openldap/schema/nis.schema<br />include         /usr/local/openldap/etc/openldap/schema/samba.schema<br /># Define global ACLs to disable default read access.<br /><br /># Do not enable referrals until AFTER you have a working directory<br /># service AND an understanding of referrals.<br />#referral       ldap://root.openldap.org<br /><br />pidfile         /usr/local/openldap/var/slapd.pid<br />argsfile        /usr/local/openldap/var/slapd.args<br /><br />loglevel 1                       <br />#增加了日志功能，需修改syslog配置文件，在文件中增加一项：local4.* /var/log/ldap.log日志级别定义可查相官方网站的文档。<br />#1级记录的信息很多，可用于调试。<br /># Load dynamic backend modules:<br /># modulepath    /usr/local/openldap/libexec/openldap<br /># moduleload    back_bdb.la<br /># moduleload    back_ldap.la<br /># moduleload    back_ldbm.la<br /># moduleload    back_passwd.la<br /># moduleload    back_shell.la<br /><br /># Sample security restrictions<br />#       Require integrity protection (prevent hijacking)<br />#       Require 112-bit (3DES or better) encryption for updates<br />#       Require 63-bit encryption for simple bind<br /># security ssf=1 update_ssf=112 simple_bind=64<br /><br /># Sample access control policy:<br />#       Root DSE: allow anyone to read it<br />#       Subschema (sub)entry DSE: allow anyone to read it<br />#       Other DSEs:<br />#               Allow self write access<br />#               Allow authenticated users read access<br />#               Allow anonymous users to authenticate<br />#       Directives needed to implement policy:<br /># access to dn.base="" by * read<br /># access to dn.base="cn=Subschema" by * read<br /># access to *<br />#       by self write<br />#       by users read<br />#       by anonymous auth<br />#<br /># if no access controls are present, the default policy is:<br />#       Allow read by all<br />#<br /># rootdn can always write!<br /><br />#######################################################################<br /># ldbm database definitions<br />#######################################################################<br /><br />database        bdb<br />suffix          "dc=it,dc=com"<br />#改成你自已的目录后缀，<br />rootdn          "cn=root,dc=it,dc=com"<br />#设置root为管理员，与linux的root没有什么关系。<br /># Cleartext passwords, especially for the rootdn, should<br /># be avoid.  See slappasswd(8) and slapd.conf(5) for details.<br /># Use of strong authentication encouraged.<br />rootpw          {MD5}mjkiuPt0wXhpxxkdiOOO+0000000AKq0by<br />#设置root密码，用MD5加密。密码串用slappasswd -h {MD5}指令生成<br /># The database directory MUST exist prior to running slapd AND <br /># should only be accessible by the slapd and slap tools.<br /># Mode 700 recommended.<br />directory       /usr/local/openldap/var/openldap-data    <br /># Indices to maintain<br />index   objectClass     eq<br />#这里可根据你的需要设置相关索引，以加快查询速度。具体内容可查询官方网站管理手册。<br /><br />#ACL configure以下内容定义访问控制<br />access to  attr=userPassworduserPassword<br />#只能由自已修改，有效验证用户查询。<br />        by self write<br />        by anonymous auth<br />access to attr=mail<br />        by dn="cn=root,dc=it,dc=tigerhead" writemail<br />#只能由自已修改，有效验证用户查询。<br />        by self write<br />        by anonymous auth<br />access to dn=".*,dc=it,dc=tigerhead"<br />#允许所有人查询没受控制访问限制的信息。<br />        by self write<br />        by * read<br /></pre><p>到现在为止，服务器基本就配置完成了，可以启动了，服务器程序是位于安装目录的libexec下的slapd程序。注意，不是
sldap哦。ok，到现在为止，服务器基本就配置完成了，可以启动了，服务器程序是位于安装目录的libexec下的slapd程序。注意，不是
sldap哦。启动服务器执行以下命令：</p><pre class="screen"># ./slapd<br /></pre><p>如果没有提示什么出错信息，直接返回shell状态，就说明服务器正常启动了，你可以查询日志或用ps -aux查看。或用以下命令查询服务器:</p><pre class="screen">ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts<br /></pre><p>如果命令执行成功，返回一些信息，则说明服务器正常运行了。如果启动不成功，它会提示一些出错信息，多数是slapd.conf配置出错。回头仔细核查一下配置文档。</p></li><li><p>客户端配置文档是ldap.conf。该文档相当简单，其实不用配置也能正常操作。</p><pre class="screen"># $OpenLDAP: pkg/ldap/libraries/libldap/ldap.conf,v 1.9 2000/09/04 19:57:01 kurt Exp $<br />#<br /># LDAP Defaults<br />#<br /><br /># See ldap.conf(5) for details<br /># This file should be world readable but not world writable.<br /><br />BASE    dc=it, dc=com设置目录起点<br />#URI    ldap://ldap.example.com ldap://ldap-master.example.com:666<br /><br />#SIZELIMIT      12<br />#TIMELIMIT      15<br />#DEREF          never<br /></pre></li></ol></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2810479"></a>2.2. 数据录入</h2></div></div></div><p>服
务器正常运作后，就可以录入信息了。信息的录入有三种方法，一种是手工录入，一种是.ldif文件格式录入，一种是脚本自动录入。我们先从最基础的手工录
入方式开始介绍，了解录入信息的格式。明白了手工录入的格式，其它两种方式都很容易明白。信息录入用到ldapadd这个程序。可在安装目录的bin目录
下找到。</p><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2810506"></a>2.2.1. 手动录入方法</h3></div></div></div><div class="itemizedlist"><ul type="disc"><li><p>第一步是要建立DN：</p><pre class="screen"># ldapadd -x -D 'cn=root,dc=it,dc=com' -W<br />dn: dc=it,dc=com<br />objectClass: dcObject<br />objectClass: organization<br />dc: it<br />o: Corporation<br />description: d Corporation<br />注意：如果你用复制/粘贴功能把以上内容拷贝过去，一定要注意每行后面不要有空格，建议还是手工输入，按Ctrl+d存盘。<br /></pre></li><li><p>第二步是建立RDN:</p><pre class="screen"># ldapadd -x -D 'cn=root,dc=it,dc=com' -W        <br />#-x表示用简单验证，-D表示指定目录，-W表示弹出密码输入提示<br /></pre><p>输入密码，这里的密码是在配置文件中rootpw项设置的密码，不是操作系统中root用户的密码。验证通过后就可输入以下内容：</p><pre class="screen">dn: uid=qq,dc=it,dc=com<br />objectClass: person<br />objectClass: organizationalPerson<br />objectClass: inetOrgPerson<br />uid: qq<br />cn: qq<br />sn: qq<br />telephoneNumber: 138888888<br />description: openldap test<br />telexNumber: tex-8888888<br />street: my street<br />postOfficeBox: postofficebox<br />displayName: qqdisplay<br />homePhone: home1111111<br />mobile: mobile99999<br />mail:qq@qq.com<br /></pre><p>输入完所有信息后，按Ctrl+d结束存盘。如果出现出错信息，请查一下对象类和属性的对应关系有没有错或输入失误。初学者就容易出错
的地方是对象类和属性的对应关系没有处理好。对象类和属性是在schema文档中定义的。它们之间的关系是这样的，对象类中有些属性是必选的，有些属性是
可选的。录入信息的属性必须在对象类中有定义才能用。</p></li></ul></div><p>输入以下命令可查询到刚才输入的信息。</p><pre class="screen"># ldapsearch -x -b 'dc=it,dc=com'            <br />-b选项是设置目录起点，如果设置了客户端的BASE配置参数，该项可不用。<br /></pre><p>如果按以上配置文件设置了acl，用上面的查询命令是查询不到受保护的内容的。如上面的userPassword and mail。要查询到这些受限内容，需要通过验证才可以：</p><pre class="screen"># ldapsearch -x -LLL -h it.com -b 'dc=it,dc=com' -D 'uid=qq,dc=it,dc=com' -W 'uid=qq'<br />接着提示输入密码。输入userPassword的密码回车，所有信息就都出来了。<br /></pre></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2810743"></a>2.2.2. 文件方式</h3></div></div></div><p>.ldif文件方式也就是把以上手工输入的内容先写入一个.ldif文件中，然后，用ldapadd命令的-f参数导入。</p><pre class="screen"># ldapadd -x -D "cn=root,dc=it,dc=com" -W -f test.ldif<br /></pre><p>一个完整的global.ldif文件例子：</p><pre class="screen">dn: dc=info, dc=net<br />objectClass: top<br />objectClass: organization<br />o: info.net<br /><br />dn: ou=People, dc=info, dc=net<br />objectClass: top<br />objectClass: organizationalUnit<br />ou: People<br />description: User Info<br /><br />dn: cn=Admin, dc=info, dc=net<br />objectClass: top<br />objectClass: person<br />objectClass: organizationalPerson<br />cn: Admin<br />sn: Admin<br />userPassword: Admin<br />description: Administrator for info.net<br /><br />dn: id=1, ou=People, dc=info, dc=net<br />objectclass: top<br />objectclass: InfoPerson<br />id: 1<br />username: 张三<br />tel:021-63138990<br />card_id:ABC001<br /></pre><p>我们也可用slapadd命令来导入数据。该命令可以导入包含一些系统信息的ldif文件，如：</p><pre class="screen">dn: dc=it,dc=com<br />objectClass: top<br />objectClass: dcObject<br />objectClass: organization<br />dc: it<br />structuralObjectClass: organization<br />entryUUID: d97b06da-d77e-1028-9866-d4ec7ac00d12<br />creatorsName: cn=anonymous            #系统信息<br />createTimestamp: 20041201005115Z      #系统信息<br />o:: 5bm/5bee5biC6JmO5aS055S15rGg6ZuG5Zui5pyJ6ZmQ5YWs5Y+4<br />userPassword:: e01ENX14TXBDT0tDNUk0SU56RkNhYjNXRW13PT0=<br />entryCSN: 2004120603:50:08Z#0x0001#0#0000     #系统信息<br />modifiersName: cn=admin,dc=it,dc=com          #系统信息<br />modifyTimestamp: 20041206035008Z              #系统信息<br /></pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table summary="Note" border="0"><tbody><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="http://www.ringkee.com/note/opensource/images/note.png" /></td><th align="left"><br /></th></tr><tr><td colspan="2" align="left" valign="top">再次提醒，注意每行后面不要留有空格。</td></tr></tbody></table></div></div><div class="sect2" lang="en"><div class="titlepage"><div><div><h3 class="title"><a name="id2810843"></a>2.2.3. 脚本方式</h3></div></div></div><p>脚本录入方式需要自已编写脚本，或到网上下载。有一个用PHP写的LDAP管理工具不错，叫phpLDAPadmin。可以到以下网址下载：<a href="http://phpldapadmin.sourceforge.net/" target="_top">http://phpldapadmin.sourceforge.net</a>。安装方法也很简单，只要解压出来，拷贝到apache的web目录下，按说明配置一下设定文档,就ok了。</p></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2810869"></a>2.3. 常用命令介绍</h2></div></div></div><p>接着为大家介绍一下几个常用的ldap命令，如果你用了phpLDAPadmin程序，其实它已经有一个很好的图形介面帮你完成这些命令了。但了解一下还是对你还是很有益的，因为命令方法才是最根本的。</p><div class="itemizedlist"><ul type="disc"><li><p>删除命令ldapdelete</p><pre class="screen"># ldapdelete -x -D 'cn=root,dc=it,dc=com' -W 'uid=qq1,dc=it,dc=com'<br /></pre></li><li><p>重新索引ldap数据库命令slapindex</p><pre class="screen"># slapindex -f slapd.conf<br /></pre></li><li><p>设置使用者密码，当然了，你的用户需要有userPassword项了。</p><pre class="screen">#ldappasswd -x -D "cn=root,dc=it,dc=com" -W "uid=qq1,dc=it,dc=com" -S <br />New password: <br />Re-enter new password: <br />Enter bind password: <br />Result: Success (0)<br /></pre><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><table summary="Note" border="0"><tbody><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="http://www.ringkee.com/note/opensource/images/note.png" /></td><th align="left"><br /></th></tr><tr><td colspan="2" align="left" valign="top">"Enter bind password" 是 "cn=root,dc=it,dc=com"管理员的密码。</td></tr></tbody></table></div></li><li><p>管理员密码更改 </p><pre class="screen">#slappasswd <br />New password <br />Re-enter new password <br />{SSHA}83DJ4KVwqlk1uh9k2uDb8+NT1U4RgkEs <br /></pre><p>接下再拷贝到 path/to/sldap.conf 的 rootpw 即可,重启使用配置文件生效</p></li><li><p>通过ldapmodify修改目录内容</p><pre class="screen"># ldapmodify -x -D "cn=root,dc=it,dc=com" -W -f modify.ldif<br /></pre><p>通过ldif文件修改ldap数据，ldif文件格式如下：</p><pre class="screen">dn: cn=qq,dc=it,dc=com<br />changetype: modify<br />replace: mail<br />mail: modme@example.com<br />-<br />add: title<br />title: Grand Poobah<br />-<br />add: jpegPhoto<br />jpegPhoto:&lt; file:///tmp/modme.jpeg<br />-<br />delete: description<br />-<br /></pre></li></ul></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2808359"></a>2.4. 启用sasl验证</h2></div></div></div><p>前提是你在系统中安装了sasl认证库，并在编译openldap时支持它，默认就支持了。到<a href="http://asg.web.cmu.edu/cyrus" target="_top">http://asg.web.cmu.edu/cyrus</a>下载。安装方法见我写的sendmail安装笔记。安装好之后，需要在sasl中建立相应的帐号，用以下命令可完成。</p><pre class="screen"># saslpasswd2 -c test<br /></pre><p>接着配置slapd.conf文件，加入以下内容。</p><pre class="screen">sasl-regexp<br />        uid=(.*),cn=.*,cn=auth<br />        uid=$1,dc=it,dc=com<br /></pre><p>重启服务器使配置文件生效。这个配置是最大权限的配置，如果要细化请查阅相关文档。用以下命令测试。</p><pre class="screen"># ldapsearch -U qq  -b 'uid=qq,dc=it,dc=com' -D 'dc=it,dc=com' -Y DIGEST-MD5<br /></pre><p>采用digest-md5验证,提示密码，输入saslpasswd2的密码。</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2808424"></a>2.5. 配置服务器复制</h2></div></div></div><p>在
一些关键的应用场合，我们需设置多个ldap服务器实例，且数据要保持同步。当一台服务器出现故障或被黑客攻击时，我们就能继续保持应用的正常运行。通过
DNS的轮流查询功能，还能实现服务器的负载均衡，提高响应速度。在openldap中有一个slurpd进程，利用slurpd进程可帮助我们实现多台
ldap服务器数据的同步功能。下面简单介绍一下主、从ldap服务器的配置。</p><p>slurpd运行在主服务器上，它能把主服务器上的变化通过
LDAP协议传送到从服务器上。从服务器上的变化不能传送到主服务器上，也就是说是单向同步的。主从服务器的版本最好一样，以减少兼容性问题。主从服务器
的安装方法是一样的，关键是配置文件有所不同。我的操作系统是debian sarge，在确保主从服务器能正常运行的前提下进行以下配置：</p><div class="itemizedlist"><ul type="disc"><li><p>首先，把主从服务器关闭。通过以下三步操作静态同步主从服务器上的数据：</p><div class="orderedlist"><ol type="1"><li><p>把主服务器上/var/lib/ldap目录下的所有数据库文件全部拷贝到从服务器的同目录中，覆盖原有文件。</p></li><li><p>把主服务器上的/etc/ldap/schema目录下的所有schema文件拷贝到从服务器的同目录中，覆盖原有文件。</p></li><li><p>把主服务器上/etc/ldap/slapd.conf文件拷贝到从服务器的同目录中，覆盖原有文件。</p></li></ol></div></li><li><p>配置主服务器上的slapd.conf文件，取消replogfile指令前的注释符号，取消后的结果如下：</p><pre class="screen"># Where to store the replica logs for database #1<br />replogfile      /var/lib/ldap/replog<br /></pre><p>增加replica指令，如：</p><pre class="screen">#replace config<br />replica uri=ldap://192.168.6.195:389     #指定从服务器主机名和端口号<br />        binddn="cn=admin,dc=com"         #指定需同步的DN的管理员<br />        bindmethod=simple credentials=1  #指定验证方式和需同步的DN的管理员密码<br /></pre></li><li><p>配置从服务器上的slapd.conf文件，增加updatedn指令，如：</p><pre class="screen">updatedn "cn=admin,dc=com"          #与主服务器的binddn对应<br /></pre><p>在从服务器的配置文件中，不要包含replica和replogfile指令。</p></li><li><p>先启动主服务器的slapd和slurpd，再启动从服务器的slapd。</p></li></ul></div><p>配置完成后，我们可测试一下，在主服务器上修改一个目录项，在从服务器上可查看目录项的数据已同步。</p></div></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="id2808612"></a>Chapter 3. 管理工具</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808628">3.1. phpldapadmin</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808639">3.2. gq</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808650">3.3. CPU</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808661">3.4. JXplore</a></span></dt><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808672">3.5. LAM</a></span></dt></dl></div><p>开源的目录服务管理工具有很多，包括phpldapadmin，gq，CPU，JXplore等。这些工具可帮助我们方便维护目录服务器上的数据。这些工具各有优缺点，下面简要介绍一下，详细的内容可参考相关的官方网站。</p><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2808628"></a>3.1. phpldapadmin</h2></div></div></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2808639"></a>3.2. gq</h2></div></div></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2808650"></a>3.3. CPU</h2></div></div></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2808661"></a>3.4. JXplore</h2></div></div></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2808672"></a>3.5. LAM</h2></div></div></div><p>官方网站：<a href="http://lam.sourceforge.net/index.htm" target="_top">http://lam.sourceforge.net/index.htm</a></p></div></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="id2808693"></a>Chapter 4. HowTo</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="http://www.ringkee.com/note/opensource/openldap.htm#id2808700">4.1. 禁止整个服务器的匿名访问</a></span></dt></dl></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both;"><a name="id2808700"></a>4.1. 禁止整个服务器的匿名访问</h2></div></div></div><p>在slapd.conf配置文件中加入disallow bind_anon即可。</p></div></div></div><br /><img src ="http://www.blogjava.net/alex/aggbug/62716.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alex/" target="_blank">Alex</a> 2006-08-10 09:33 <a href="http://www.blogjava.net/alex/archive/2006/08/10/62716.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]使用 OpenLDAP 集中管理用户帐号</title><link>http://www.blogjava.net/alex/archive/2006/08/10/62714.html</link><dc:creator>Alex</dc:creator><author>Alex</author><pubDate>Thu, 10 Aug 2006 01:19:00 GMT</pubDate><guid>http://www.blogjava.net/alex/archive/2006/08/10/62714.html</guid><wfw:comment>http://www.blogjava.net/alex/comments/62714.html</wfw:comment><comments>http://www.blogjava.net/alex/archive/2006/08/10/62714.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alex/comments/commentRss/62714.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alex/services/trackbacks/62714.html</trackback:ping><description><![CDATA[key words : openldap ldap <br /><br /><br /><p>2006 年  6 月  26 日</p><blockquote>使用轻量级目录访问协议（LDAP）构建集中的身份验证系统可以减少管理成
本，增强安全性，避免数据复制的问题，并提高数据的一致性。随着 Linux® 的不断成熟，已经出现了很多工具用来简化用户帐号信息到 LDAP
目录的迁移。还开发了一些工具用来在客户机和目录服务器之间启用加密通信配置，并通过复制提供容错性。本文将向您展示如何配置服务器和客户机在 Red
Hat Linux 上使用 OpenLDAP。</blockquote><!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES--><p><a name="N1004F"><span class="atitle">简介</span></a></p><p>Linux 发行版中提供的 OpenLDAP 软件按照一个客户机/服务器模型实现了轻量级目录访问协议（LDAP）。LDAP
的设计目的是提供一种有效的方法来查找和管理信息。OpenLDAP
软件和包提供了创建目录信息树（一个主要进行读操作的数据库）的工具。本文向您展示如何存储用户的帐号信息，并修改身份验证服务来使用 LDAP
获取所需要的信息。内部细节并不重要，因为这些工具可以将数据库的内容以文本格式（LDAP 数据交换格式，LDIF）呈现在您的面前。</p><p>LDAP 信息被组织成属性和值的组合，称为 <i>条目（entry）</i>。条目可能会具有必须的属性或可选属性。一个条目的属性必须要遵循 /etc/openldap/schema/ 模式文件中定义的规则。规则包含在条目的 <i>objectclass</i> 属性中。看一下下面的关系，我们可以看出 <code>posixAccount</code> objectclass 中包含了密码文件条目的信息（<code>posixAccount userPassword</code> 是文件条目的 base64 编码）。</p><br /><a name="figure1"><b>图 1. LDAP 目录条目和 Linux 密码文件之间的关系</b></a><br /><img alt="LDAP 目录条目和 Linux 密码文件之间的关系" src="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/figure1.jpg" height="174" width="572" /><br /><p>文件 /etc/openldap/schema/nis.schema 为 posixAccount 对象类中的条目定义了所有的属性和 objectclass。例如，下面是对 <code>uidNumber</code> 属性的描述：</p><pre>attributetype ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'<br />   DESC 'An integer uniquely identifying a user in an administrative domain'<br />   EQUALITY integerMatch<br />   SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )<br /></pre><p>所有的属性类型都已经定义了，它们被收集到 <code>posixAccount</code> objectclass 中。例如：</p><pre>objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY<br />   DESC 'Abstraction of an account with POSIX attributes'<br />   MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )<br />   MAY ( userPassword $ loginShell $ gecos $ description ) )<br /></pre><p><code>ldapuser</code> 条目具有一个识别名属性 <code>dn</code>，它用作用户名，并与 <code>userPassword</code> 一起用来在 LDAP 目录中记录信息，或与 LDAP 目录绑定在一起使用。</p><p>LDAP 为作为容器使用的特殊条目提供了将这些条目组织成树结构的功能。在这个例子中，我们将使用一个容器 <code>People</code> 保存用户帐号信息，使用另外一个容器 <code>Groups</code> 保存组帐号信息。所生成的目录信息树如图 2 所示。</p><br /><a name="figure2"><b>图 2. 用户帐号信息使用的目录信息树</b></a><br /><img alt="用户帐号信息使用的目录信息树" src="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/figure2.gif" height="191" width="572" /><br /><p>让我们来看一下如何配置 OpenLDAP 服务器，如何将信息从系统文件迁移到 LDAP 目录中，如何配置 OpenLDAP 客户机通过
LDAP 对用户进行身份验证。在使用一个集中的身份验证数据库时，应该通过使用复制技术采用第二个 LDAP
服务器提供高可用性，这样在主服务器出现问题时，就可以使用第二个 LDAP
服务器响应客户机的请求。由于诸如密码之类的身份验证数据会通过网络进行传输，因此希望使用 TSL 协议建立加密通信连接。</p><p>我们的 OpenLDAP 服务器和客户机都是虚拟机，上面运行的是 Red Hat Enterprise Linux AS release 4（Nahant Update 1）。在我们的例子中使用了 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#table1">表 1</a> 所列出的系统。如果想模仿这些例子，请使用适合您自己的设置。</p><br /><a name="table1"><b>表 1. 系统网络信息</b></a><br /><table class="data-table-1" summary="System network information" border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><th>角色</th><th>主机名</th><th>IP 地址</th></tr><tr><td class="tb-row">OpenLDAP 主服务器</td><td>dhcp64-233.ibm.com</td><td>9.47.64.233</td></tr><tr><td class="tb-row">OpenLDAP 从服务器</td><td>dhcp64-253.ibm.com</td><td>9.47.64.253</td></tr><tr><td class="tb-row">OpenLDAP 客户机</td><td>dhcp64-251.ibm.com</td><td>9.47.64.251</td></tr></tbody></table><br /><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br /></td><td align="right" valign="top"><a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#main" class="fbox"><b>回页首</b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="configserver"><span class="atitle">配置 LDAP 服务器</span></a></p><p>我们使用 Red Hat Enterprise Linux release 4 Update 1 上的包来构建服务器：</p><ul><li><b>openldap-2.2.13-2</b>：包含 OpenLDAP 配置文件、库和文档</li><li><b>openldap-servers-2.2.13-2</b>：包含 slapd 和 slurpd 服务器、迁移脚本和相关文件</li><li><b>openldap-clients-2.2.13-2</b>：包含客户机程序，用来访问和修改 OpenLDAP 目录</li></ul><p>OpenLDAP 包在服务器上安装了很多程序：</p><ul><li>守护进程：
<ul><li><b>slapd</b>：主 LDAP 服务器</li><li><b>slurpd</b>：负责与复制 LDAP 服务器保持同步的服务器</li></ul></li><li>对网络上的目录进行操作的客户机程序。下面这两个程序是一对儿：
<ul><li><b>ldapadd</b>：打开一个到 LDAP 服务器的连接，绑定、修改或增加条目</li><li><b>ldapsearch</b>：打开一个到 LDAP 服务器的连接，绑定并使用指定的参数进行搜索</li></ul></li><li>对本地系统上的数据库进行操作的几个程序：
<ul><li><b>slapadd</b>：将以 LDAP 目录交换格式（LDIF）指定的条目添加到 LDAP 数据库中</li><li><b>slapcat</b>：打开 LDAP 数据库，并将对应的条目输出为 LDIF 格式</li></ul></li></ul><p>OpenLDAP 的主要服务器配置文件是 /etc/openldap/slapd.conf。本例所使用的完整 slapd.conf 文件如 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#listing18">清单 18</a> 所示。slapd.conf 文件中包括一系列全局配置选项，它们作为一个整体应用到 slapd 上面，后面是包含数据库特有信息的数据库后端定义。如果一行内容是以空格开始的，就认为它是上一行的延续。空行和以 “#” 字符开头的注释行都会被忽略。</p><p>如果您正把本文当作练习来做，那就可以按照下面指定的方式进行修改，从而启动 LDAP 服务器。一旦确认服务器正常工作之后，就可以添加复制功能，然后再添加安全性支持。首先是全局配置信息段的设置。其中每个选项的值都是我们想要的。</p><p>正如上面介绍的一样，信息被组织成属性和值的组合，称为条目。条目属性必须遵循的规则是使用 <code>objectclass</code> 专用属性进行组织的，这可以在 /etc/openldap/schema/ 模式文件中找到。对于身份验证来说，需要使用在 nis.schema 中定义的 <code>posixAccount</code> 和 <code>shadowAccount</code> objectclasses：</p><p><code>
include         /etc/openldap/schema/nis.schema
</code></p><p><code>loglevel</code> 行设置的是日志选项。可以将其设置为这样的级别：调试语句和操作统计信息都会被记录到 /var/log/slapd.log 中。日志级别是累加的：296 = 256 日志连接/操作/结果 + 32 搜索过滤器处理 + 8 连接管理：</p><p><code>
loglevel        296
</code></p><p>日志信息会被记录到 syslogd LOG_LOCAL4 机制中。还需要将下面的内容添加到 /etc/syslog.conf 中，并让 syslogd 重新读取自己的配置文件：</p><p><code>
local4.debug   /var/log/slapd.log
</code></p><p>access 行定义了谁可以访问目录中的内容。我们希望用户可以修改自己的密码，并更新自己的 shadow
信息来反映密码的变化。希望身份验证程序能够检索用户的密码。还希望用户能够读取所有其他条目。注意密码条目是不可读的，shadow
属性的惟一用处就是管理密码的过期问题。</p><pre>access to attrs=shadowLastChange,userPassword<br />      by self write<br />      by * auth<br /><br />access to *<br />      by * read<br /></pre><p>接下来，在 database 部分，要定义下面的内容。</p><p>使用新的 bdb 后端数据库：</p><p><code>
database        bdb
</code></p><p>指定后端数据库需要响应的查询的 DN 前缀。为了确保惟一性，根前缀应该从自己的网络域名构建出来。在本例的情况中，它是 .dc=svc,dc=beaverton,dc=ibm,dc=com.，但是在下面的例子中我们对其进行了简化：</p><p><code>
suffix              "dc=ibm,dc=com"
</code></p><p>指定管理 DN，它不用于访问控制或限制数据库的操作。也不需要在目录中为这个 DN 指定一个条目。为具有 rootpw 密码的管理员使用 DN 可以跳过 ACL 规则中的所有访问控制：</p><p><code>
rootdn           "cn=Manager,dc=ibm,dc=com"<br />
rootpw           {MD5}ijFYNcSNctBYg
</code></p><p>这就是我们现在想要设置的选项。稍后将返回 slapd.conf 文件来配置复制，然后在配置安全性。</p><p>现在，我们希望将数据添加到目录中，并确认可以访问这些信息。要实现这种功能，需要配置服务器来使用 ldap 客户机工具，例如
ldapadd 和 ldapsearch。ldap 客户机工具的配置文件是
/etc/openldap/ldap.conf。我们使用的这个文件的完整列表如本文末尾的 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#listing19">清单 19</a> 所示。要在 ldap 服务器上运行这些工具，只需要将该行修改成下面的内容：</p><p><code>
BASE dc=ibm,dc=com
</code></p><p>设置启动脚本在级别 2、3 和 5 时启动 LDAP：</p><br /><a name="listing1"><b>清单 1. 设置启动运行级别</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># chkconfig --levels 235 ldap on<br /></pre></td></tr></tbody></table><br /><p>从命令行中启动服务：</p><br /><a name="listing2"><b>清单 2. 启动服务</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># service ldap start<br />Starting slapd:                               [  OK  ]<br /></pre></td></tr></tbody></table><br /><p>OpenLDAP 守护进程 slapd 应该已经运行了：</p><br /><a name="listing3"><b>清单 3. 检查服务正在运行</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># ps -ef | grep slap<br />ldap   13521  1  0 Oct24 ?     00:00:00 /usr/sbin/slapd -u ldap -h ldap:/// ldaps:///<br /></pre></td></tr></tbody></table><br /><p><code>ldapsearch -x</code> 命令应该可以成功完成，但不会返回任何数据。</p><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br /></td><td align="right" valign="top"><a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#main" class="fbox"><b>回页首</b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="N101F5"><span class="atitle">迁移密码和 shadow 信息</span></a></p><p>Red Hat 所提供的 openldap-servers 包包含 PADL Software Pty Ltd. 公司的
MigrationTools 工具。我们将使用这些工具将数据从 Linux 系统文件（例如 /etc/group 和
/etc/password）转换成 LDAP LDIF 格式，这是数据库信息的一种文本格式的表示。这种格式是行界定、冒号分隔的属性-值对。</p><p>有一组 Perl 脚本被安装到 /usr/share/openldap/migration/ 中执行迁移。这些 Perl
脚本的配置信息包含在 migrate_common.ph
文件的开头。对于我们的目的来说，只需要修改命名前缀的变量来使用条目的识别名就足够了，如下所示：</p><p><code>
$DEFAULT_BASE = "dc=ibm,dc=com"
</code></p><p>在进行这些修改之后，请运行脚本 migrate_base.pl，它会创建根项，并为 Hosts、Networks、Group 和 People 等创建低一级的组织单元：</p><br /><a name="listing4"><b>清单 4. 运行 migrate_base.pl</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># migrate_base.pl &gt; base.ldif<br /></pre></td></tr></tbody></table><br /><p>编辑 base.ldif，删除除下面之外的所有条目：</p><br /><a name="listing5"><b>清单 5. base.ldif 条目</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># cat base.ldif<br />dn: dc=ibm,dc=com<br />dc: ibm<br />objectClass: top<br />objectClass: domain<br /><br />dn: ou=People,dc=ibm,dc=com<br />ou: People<br />objectClass: top<br />objectClass: organizationalUnit<br /><br />dn: ou=Group,dc=ibm,dc=com<br />ou: Group<br />objectClass: top<br />objectClass: organizationalUnit<br /></pre></td></tr></tbody></table><br /><p>在 LDAP 服务器上，使用 OpenLDAP 客户机工具 ldapadd 将以下条目插入到数据库中。简单身份验证必须要使用 <code>-x</code> 选项指定。在 slapd.conf 中定义的 <code>rootdn</code> 身份验证识别名是 “cn=Manager,dc=ibm,dc=com”。对于简单身份验证来说，必须使用密码。选项 <code>-W</code> 强制提示输入密码。这个密码就是在 slapd.conf 文件中指定的 <code>rootpw</code> 参数的值。包含这些条目的 LDIF 文件是使用 <code>-f</code> 选项指定的：</p><br /><a name="listing6"><b>清单 6. 使用 ldapadd 插入条目</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># ldapadd -x -D "cn=Manager,dc=ibm,dc=com" -W -f base.ldif<br /></pre></td></tr></tbody></table><br /><p>接下来，从 /etc/group 中迁移 ldapuser 组：</p><br /><a name="listing7"><b>清单 7. 迁移 ldapuser 组</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># grep ldapuser /etc/group &gt; group.in<br /># ./migrate_group.pl group.in &gt; group.ldif<br /><br />#  cat group.ldif<br />dn: cn=ldapuser,ou=Group,dc=ibm,dc=com<br />objectClass: posixGroup<br />objectClass: top<br />cn: ldapuser<br />userPassword: {crypt}x<br />gidNumber: 500<br /><br /># ldapadd -x -D "cn=Manager,dc=ibm,dc=com" -W -f group.ldif<br /></pre></td></tr></tbody></table><br /><p>最后，从 /etc/passwd 和 /etc/shadow 中迁移 ldapuser 的信息：</p><br /><a name="listing8"><b>清单 8. 迁移 ldapuser 信息</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># grep ldapuser /etc/passwd &gt; passwd.in<br /># ./migrate_passwd.pl passwd.in &gt; passwd.ldif<br /><br /># cat passwd.ldif<br />dn: uid=ldapuser,ou=People,dc=ibm,dc=com<br />uid: ldapuser<br />cn: ldapuser<br />objectClass: account<br />objectClass: posixAccount<br />objectClass: top<br />objectClass: shadowAccount<br />userPassword: {crypt$1$TeOlOcMc$cpQaa0WpLSFRC1HIHW5bt1<br />shadowLastChange: 13048<br />shadowMax: 99999<br />shadowWarning: 7<br />loginShell: /bin/bash<br />uidNumber: 500<br />gidNumber: 500<br />homeDirectory: /home/ldapuser<br />gecos: ldapuser<br /><br /># ldapadd -x -D "cn=Manager,dc=ibm,dc=com" -W -f passwd.ldif<br /></pre></td></tr></tbody></table><br /><p>现在检查已经添加到数据库中的信息。清单 9 给出了全部输出结果：</p><br /><a name="listing9"><b>清单 9. 以 LDIF 格式填充的 OpenLDAP 数据库</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># ldapsearch -x<br /><br /># extended LDIF<br />#<br /># LDAPv3<br /># base &lt;&gt; with scope sub<br /># filter: (objectclass=*)<br /># requesting: ALL<br />#<br /><br /># ibm.com<br />dn: dc=ibm,dc=com<br />dc: ibm<br />objectClass: top<br />objectClass: domain<br /><br /># People, ibm.com<br />dn: ou=People,dc=ibm,dc=com<br />ou: People<br />objectClass: top<br />objectClass: organizationalUnit<br /><br /># Group, ibm.com<br />dn: ou=Group,dc=ibm,dc=com<br />ou: Group<br />objectClass: top<br />objectClass: organizationalUnit<br /><br /># ldapuser, Group, ibm.com<br />dn: cn=ldapuser,ou=Group,dc=ibm,dc=com<br />objectClass: posixGroup<br />objectClass: top<br />cn: ldapuser<br />gidNumber: 500<br /><br /># ldapuser, People, ibm.com<br />dn: uid=ldapuser,ou=People,dc=ibm,dc=com<br />uid: ldapuser<br />cn: ldapuser<br />objectClass: account<br />objectClass: posixAccount<br />objectClass: top<br />objectClass: shadowAccount<br />shadowMax: 99999<br />shadowWarning: 7<br />loginShell: /bin/bash<br />uidNumber: 500<br />gidNumber: 500<br />homeDirectory: /home/ldapuser<br />gecos: test2<br /><br /># search result<br />search: 2<br />result: 0 Success<br /><br /># numResponses: 6<br /># numEntries: 5<br /></pre></td></tr></tbody></table><br /><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br /></td><td align="right" valign="top"><a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#main" class="fbox"><b>回页首</b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="N10281"><span class="atitle">配置 LDAP 客户机</span></a></p><p>用来设置客户机的 Red Hat Enterprise Linux release 4 Update 1 包包括：</p><ul><li><b>nss_ldap-226-6</b>：包括两个 LDAP 访问客户机：nss_ldap 和 pam_ldap
<ul><li><b>nss_ldap</b> 是一组 C 库扩展，它允许 LDAP 目录服务器用作一个用户和组信息的主源</li><li><b>pam_ldap</b> 是一个 Linux-PAM 模块，它支持身份验证功能</li></ul></li></ul><p>LDAP 身份验证要想正确地工作，需要配置两个服务：系统命名服务和身份验证服务。</p><p>系统命名服务（NSS）需要配置为使用 LDAP 来解析诸如用户和组帐号之类的资源。例如，在运行命令 <code>ls -l</code> 时，如果某个文件 inode 给出文件的所有者是 “user 501”，那么命名服务就需要将 “uid 501” 解析成用户名，并在 <code>ls</code>
命令输出结果中输出。通常来说，这是通过查找 /etc/passwd 文件中的所有用户帐号实现的。由于用户现在都存储在 LDAP
目录中，因此系统需要配置成同时对 passwd 文件和 LDAP 目录中的帐号进行解析。这种功能是通过
/usr/lib/libnss_ldap.so 库提供的。</p><p>身份验证服务是实际向 LDAP 验证用户身份的服务。可插入身份验证模块（PAM）提供了本地 Linux 身份验证服务。下面我们将配置
PAM 先对本地的 /etc/passwd 文件检查用户帐号，然后再对 LDAP 服务器进行检查。PAM LDAP
模块可以用来将身份验证重定向到 LDAP 目录上。/lib/security/pam_ldap.so PAM 模块提供了 LDAP
身份验证功能。</p><p>身份验证本身是由 PAM 程序执行的，它从身份验证候选机制中获取用户名，将其绑定到 OpenLDAP 服务器上，检索与这个 uid
条目（用户名条目）相关的 DN；从身份验证候选机制中获取密码，然后使用这个 DN 和密码试图将其绑定到 OpenLDAP
服务器上。如果绑定成功，PAM 会报告说这个用户已经成功通过了 pam_ldap.so 提供的身份验证测试。根据 PAM
的配置不同，在用户看到命令行提示符之前可能会执行其他测试。</p><p>我们可以采用两种方法来配置 LDAP 客户机。一种快速而简单的方法是运行
/usr/sbin/authconfig，并在两个屏幕中输入信息。另外一种方法是通过编辑客户机 LDAP 配置文件
/etc/ldap.conf，然后修改 /etc/nsswitch.conf、/etc/sysconfig/authconfig 和
/etc/pam.d/system-auth。首先让我们来看一下如何运行 authconfig。</p><p>如图 3 所示进行选择，然后点击 <b>Next</b>。</p><br /><a name="figure3"><b>图 3. 执行 authconfig 命令的第一个页面</b></a><br /><img alt="执行 authconfig 命令的第一个页面" src="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/figure3.jpg" height="398" width="572" /><br /><p>在如图 4 所示的第二个屏幕中输入对应的信息，然后点击 <b>OK</b>。</p><br /><a name="figure4"><b>图 4. 执行 authconfig 命令的第二个页面</b></a><br /><img alt="执行 authconfig 命令的第二个页面" src="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/figure4.jpg" height="398" width="572" /><br /><p>要手工配置 OpenLDAP 客户机，请遵循下面的步骤。</p><p>用来跟踪特定身份验证机制是否已经启用的文件是 /etc/sysconfig/。我们可以希望以下条目的值都是 “yes”：</p><p><code>
USELDAP=yes<br />
USELDAPAUTH=yes<br />
USEMD5=yes<br />
USESHADOW=yes<br />
USELOCAUTHORIZE=yes
</code></p><p>PAM 和 NSS 模块使用的基本配置文件是 /etc/ldap.conf。host 选项指定 LDAP 服务器，base 选项指定这个目录使用的 DN，最初我们希望关闭加密功能：</p><p><code>
host dhcp64-233.ibm.com<br />
base dc=ibm,dc=com<br />
ssl off
</code></p><p>要让 NSS 服务使用 OpenLDAP 服务器，需要将 “ldap” 添加到 /etc/nsswitch.conf 文件的 passwd、shadow 和 group 行中，如下所示： </p><p><code>
passwd:     files ldap<br />
shadow:     files ldap<br />
group:      files ldap
</code></p><p>要让 PAM 身份验证服务使用 OpenLDAP 服务器，请将 pam_ldap 行加入到 /etc/pam.d/system-auth 中，位置在对应的标准 pam_unix.so 条目之后。尽管其他设置也可以实现相同的结果，但是我使用下面的文件设置：</p><p><code>
auth        required      /lib/security/$ISA/pam_env.so<br />
auth        sufficient    /lib/security/$ISA/pam_unix.so likeauth nullok<br />
auth        sufficient    /lib/security/$ISA/pam_ldap.so use_first_pass<br />
auth        required      /lib/security/$ISA/pam_deny.so<br /><br />
account     required      /lib/security/$ISA/pam_unix.so broken_shadow<br />
account     sufficient    /lib/security/$ISA/pam_localuser.so<br />
account     sufficient    /lib/security/$ISA/pam_succeed_if.so uid %lt; 100 quiet<br />
account     [default=bad success=ok user_unknown=ignore] /lib/security/$ISA/pam_ldap.so<br />
account     required      /lib/security/$ISA/pam_permit.so<br /><br />
password    requisite     /lib/security/$ISA/pam_cracklib.so retry=3<br />
password    sufficient    /lib/security/$ISA/pam_unix.so nullok use_authtok md5 shadow<br />
password    sufficient    /lib/security/$ISA/pam_ldap.so use_authtok<br />
password    required      /lib/security/$ISA/pam_deny.so<br /><br />
session     required      /lib/security/$ISA/pam_limits.so<br />
session     required      /lib/security/$ISA/pam_unix.so<br />
session     optional      /lib/security/$ISA/pam_ldap.so
</code></p><p>现在，用户帐号信息可以从客户机系统中删除并从 LDAP 目录中进行获取了。当用户试图登录客户机系统时，PAM 身份验证服务就会从用户那里获取用户名，在我们的例子中是 <code>ldapuser</code>。PAM 会从 LDAP 服务器中检索识别名（DN）条目 <code>.dn: uid=ldapuser, ou=People, dc=ibm, dc=com.</code>。PAM
然后会从用户那里获取密码。然后 PAM 试图使用这个 DN 和密码与 LDAP 服务器进行绑定。DN 和密码都以正文文本的格式发送给 LDAP
服务器。在对密码进行散列操作之后，如果服务器可以让用户登录，就会向 PAM 报告说已经成功进行了绑定。成功绑定可以完全满足 PAM 对
pam_ldap 模块汇报成功的标准，如果所有其他 PAM 标准都已经满足了，那么就允许用户登录到系统中。</p><p>当 LDAP 服务器对身份验证进行处理时，需要解决另外两个问题才能满足提供可靠安全的身份验证的目标。现在，任何客户机系统不能成功地与
LDAP 服务器进行通信都会阻止用户登录客户机系统。在下一节中我们将看到如何消除这种单点故障，这将显示客户机如何从备份服务器上访问 LDAP
目录。由于用户密码是在网络上以正文文本格式传输的，因此这并不能满足安全身份验证的需求。<a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#configtls">配置 TLS 安全性</a> 将解决这个问题。</p><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br /></td><td align="right" valign="top"><a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#main" class="fbox"><b>回页首</b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="N1034A"><span class="atitle">配置复制</span></a></p><p>为了防止出现客户机由于 LDAP 服务器的问题而不能登录的情况，我们需要采用复制技术来实现可靠性目标。复制是通过 OpenLDAP
复制进程 slurpd
提供的，它会周期性地唤醒，并检查主服务器上的日志文件，从而确定是否有任何更新。这些更新然后会传播到从服务器上。读请求可以由任何一个服务器进行解
析，而更新请求则只能由主服务器进行解析。客户机需要负责在推荐地址上重试更新操作。</p><p>要配置复制，需要停止 OpenLDAP 服务器的 slapd 守护进程：</p><br /><a name="listing10"><b>清单 10. 停止服务</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># service ldap stop<br /></pre></td></tr></tbody></table><br /><p>将以下内容添加到服务器的 /etc/openldap/slapd.conf 文件中，从而启用对新从服务器的复制。<code>replogfile</code> 行的内容指定类 LDIF 变化应该写入的文件。<code>replica</code> 原语定义了变化应该传播到的主机：</p><pre>#Replicas of this database<br />replogfile /var/lib/ldap/replog<br />replica host=dhcp64-253.ibm.com:389<br />        binddn="cn=Manager,dc=ibm,dc=com"<br />        credentials=secret<br />        bindmethod=simple<br /></pre><p>在运行从 OpenLDAP 服务器的系统上，请遵循 <a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#configserver">配置 LDAP 服务器</a> 一节给出的步骤。然后通过将信息导出到一个 ldif 文件中并将其添加到从服务器数据库上，从而将数据库从主服务器拷贝到复制服务器上。</p><p>在主服务器上：</p><br /><a name="listing11"><b>清单 11. 将数据导出到 LDIF 文件中</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># ldapsearch -x &gt; database.ldif<br /></pre></td></tr></tbody></table><br /><p>在复制服务器上：</p><br /><a name="listing12"><b>清单 12. 将数据添加到从服务器数据库中</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># ldapadd -x -D "cn=Manager,dc=ibm,dc=com" -W -f database.ldif<br /></pre></td></tr></tbody></table><br /><p>将以下内容添加到复制服务器的 /etc/openldap/slapd.conf 文件中。<code>updatedn</code> 指定了在更新从目录时主 slurpd 守护进程使用的 DN。<code>updateref</code> 指定的是主目录服务器。当一个 LDAP 客户机请求从服务器进行更新时，从服务器就将客户机重定向到这个主服务器上。</p><p><code>
updatedn  "cn=Manager,dc=ibm,dc=com"<br />
updateref ldap://dhcp64-233.ibm.com:389/
</code></p><p>启动复制 OpenLDAP 服务器，当它运行之后，再启动主 OpenLDAP 服务器。在主服务器上，slapd 和 slurpd 都会启动。</p><p>现在，可以让 OpenLDAP 客户机除了主服务器之外还可以使用复制服务器，这可以通过运行 authconfig 并将复制主机名添加到第二个屏幕中的 Server 行中实现，也可以通过在 /etc/ldap.conf 中修改 host 实现：</p><p><code>
host dhcp64-253.ibm.com dhcp64-233.ibm.com
</code></p><p>为了确认复制可以正常工作，需要研究一下在更新 <code>gecos</code> 属性时到底发生了什么。复制日志使用了与 LDIF
类似的格式。在读取 replogfile 之后，slurpd 会将这个条目拷贝到自己的重做日志中。实际的变化都以 LDIF 格式保存在主
LDAP 服务器上 /var/lib/ldap/replica/ 中的 slurpd.replog 文件中。</p><p>使用文件 user_mod 中的变化，客户机程序 ldapmodify 应用这些变化：</p><br /><a name="listing13"><b>清单 13. 应用 user_mod 的变化</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># cat user_mod<br />dn: uid=ldapuser,ou=People,dc=ibm,dc=com<br />changetype: modify<br />replace: gecos<br />gecos: test2<br /><br /># tail -f /var/lib/ldap/replog &amp;<br /><br /># ldapmodify -x -r -f /home/ldapuser/user_mod -D'cn=Manager,dc=ibm,dc=com' -W<br />Enter LDAP Password:<br />modifying entry "uid=ldapuser,ou=People,dc=ibm,dc=com"<br /><br />replica: dhcp64-253.ibm.com:389<br />time: 1130111686<br />dn: uid=ldapuser,ou=People,dc=ibm,dc=com<br />changetype: modify<br />replace: gecos<br />gecos: test2<br />-<br />replace: entryCSN<br />entryCSN: 20051023235446Z#000001#00#000000<br />-<br />replace: modifiersName<br />modifiersName: cn=Manager,dc=ibm,dc=com<br />-<br />replace: modifyTimestamp<br />modifyTimestamp: 20051023235446Z<br />-<br /></pre></td></tr></tbody></table><br /><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br /></td><td align="right" valign="top"><a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#main" class="fbox"><b>回页首</b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="configtls"><span class="atitle">配置 TLS 安全性</span></a></p><p>LDAP 是以明文的格式通过网络来发送所有信息的，包括密码。我们将采用 TLS 所提供的加密机制（SSL 的后继者）来解决这个问题。在传输层，数据使用 TLS 协议进行加密和封装，然后通过网络进行传输。用来配置加密的工具都是由 OpenSSL 包提供的。</p><p>虽然加密是一个复杂的主题，但是要使用 OpenSSL 包，我们依然需要简要介绍一下 TLS
是如何工作的。数据块使用一个对称密钥算法进行加密，它使用一个密钥来实现对数据的加密和解密。我们还有一个问题：如何防止出现以正文文本格式将密钥从
LDAP 服务器发送到 LDAP
客户机上的情况。我们使用公钥算法来解决这个问题，其中客户机可以使用一个自由获取的公钥对自己的密钥进行加密，而只有服务器才可以对这个密钥进行解密。</p><p>公钥是作为证书的一部分来创建和分发的，其中包含了一些支持信息，例如 ID、过期日期、提供这个证书的 LDAP
服务器的完整域名（FQDN）。在 LDAP
客户机使用证书进行加密之前，它会验证自己正在与之进行交谈的服务器拥有这个证书，这是通过加密一个挑战并验证服务器可以对其进行解密实现的。</p><p>要验证发行这个证书的服务器是一个已经批准过的 LDAP 服务器，客户机被配置为只接受本地证书机构（CA）所签署的证书。它使用 CA 所生成的证书中的公钥，这个公钥保存到客户机中以验证这个 LDAP 所产生的证书是有效的。</p><p>在这个例子中，我们将自己的 LDAP 服务器设置为证书机构，并创建一个自签署的证书供 LDAP 客户机和服务器在加密信息中使用。</p><p>用来构建 TLS 服务器的 Red Hat Enterprise Linux release 4 Update 1 包是：</p><ul><li><b>openssl-0.9.7a-43.1</b>：包括一个证书管理工具和提供各种加密算法和协议的共享库</li></ul><p>要构建证书机构的工作环境并生成自己的自签署证书，需要运行 /usr/share/ssl/misc/CA shell 脚本，这是一个对 <code>openssl</code> 命令的封装程序。私密性增强邮件（PEM）是一种用来对数据进行加密和编码的格式：</p><br /><a name="listing14"><b>清单 14. 运行 CA shell 脚本</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># cd /usr/share/ssl/misc<br /># ./CA -newca<br />CA certificate filename (or enter to create)<br /><br />Making CA certificate ...<br />Generating a 1024 bit RSA private key<br />.........++++++<br />......++++++<br />writing new private key to './demoCA/private/./cakey.pem'<br />Enter PEM pass phrase:<br />Verifying - Enter PEM pass phrase:<br />Enter PEM pass phrase:<br />Verifying - Enter PEM pass phrase:<br />-----<br />You are about to be asked to enter information that will be incorporated into<br />your certificate request.<br />What you are about to enter is what is called a Distinguished Name or a DN.<br />There are quite a few fields but you can leave some blank<br />For some fields there will be a default value,<br />If you enter '.', the field will be left blank.<br />-----<br />Country Name (2 letter code) [GB]:US<br />State or Province Name (full name) [Berkshire]:Oregon<br />Locality Name (eg, city) [Newbury]:Beaverton<br />Organization Name (eg, company) [My Company Ltd]:IBM<br />Organizational Unit Name (eg, section) []:its<br />Common Name (eg, your name or your server's hostname) []:dhcp64-233.ibm.com<br />Email Address []:root@dhcp64-233.ibm.com<br /></pre></td></tr></tbody></table><br /><p>接下来，要生成由证书机构进行签署的服务器证书。其余的步骤只会对主 LDAP 服务器执行一次，此时指定的是 <code>CN=dhcp64-233.ibm.com</code>；然后对从服务器执行一次，此时指定的是 <code>CN=dhcp64-253.ibm.com</code>。还要使用 <code>nodes</code> 选项，这样就不用在每次启动 OpenLDAP 服务器守护进程 slapd 时都需要输入密码了。签署后的公钥被嵌入到证书请求 slapd-req.pem 中，与之匹配的私钥嵌入在 slapd-key.pem 中：</p><br /><a name="listing15"><b>清单 15. 生成服务器证书</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># openssl req -new -nodes -subj<br />   '/CN=dhcp64-233.ibm.com/O=IBM/C=US/ST=Oregon/L=Beaverton'<br />   -keyout slapd-key.pem -out slapd-req.pem -days 365<br />Generating a 1024 bit RSA private key<br />...............++++++<br />.....................................++++++<br />writing new private key to 'slapd-key.pem'<br />-----<br /></pre></td></tr></tbody></table><br /><p>使用在第一个步骤中创建的 CA 证书对这个证书进行签署：</p><br /><a name="listing16"><b>清单 16. 对证书进行签署</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># openssl ca -out slapd-cert.pem -infiles slapd-req.pem<br />Using configuration from /usr/share/ssl/openssl.cnf<br />Enter pass phrase for ./demoCA/private/cakey.pem:<br />Check that the request matches the signature<br />Signature ok<br />Certificate Details:<br />        Serial Number: 1 (0x1)<br />        Validity<br />            Not Before: Oct 25 02:50:05 2005 GMT<br />            Not After : Oct 25 02:50:05 2006 GMT<br />        Subject:<br />            countryName               = US<br />            stateOrProvinceName       = Oregon<br />            organizationName          = IBM<br />            commonName                = dhcp64-233.ibm.com<br />        X509v3 extensions:<br />            X509v3 Basic Constraints:<br />            CA:FALSE<br />            Netscape Comment:<br />            OpenSSL Generated Certificate<br />            X509v3 Subject Key Identifier:<br />            11:A2:FB:59:42:A4:B3:26:73:1D:6D:F5:4D:2F:80:F0:FA:10:38:F5<br />            X509v3 Authority Key Identifier:<br />            keyid:F7:6A:25:F5:76:BE:20:E7:8D:0F:51:EF:D8:86:7B:AF:2C:74:2F:80<br />            DirName:/C=US/ST=Oregon/L=Beaverton/O=IBM/OU=its/CN=dhcp64-233.ibm.com<br />/emailAddress=root@dhcp64-233.ibm.com<br />            serial:00<br /><br />Certificate is to be certified until Oct 25 02:50:05 2006 GMT (365 days)<br />Sign the certificate? [y/n]:y<br /><br />1 out of 1 certificate requests certified, commit? [y/n]y<br />Write out database with 1 new entries<br />Data Base Updated<br /></pre></td></tr></tbody></table><br /><p>下一个步骤将所有需要的证书拷贝到 slapd 可以找到的地方。另外，还要对每个文件强制采用正确的权限：</p><br /><a name="listing17"><b>清单 17. 拷贝证书并强制设置权限</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section"># cp -p slapd-key.pem /etc/openldap/slapdkey.pem<br /># cp -p slapd-cert.pem /etc/openldap/slapdcert.pem<br /># chown ldap:ldap /etc/openldap/slapdcert.pem<br /># chmod 644 /etc/openldap/slapdcert.pem<br /># chown ldap:ldap /etc/openldap/slapdkey.pem<br /># chmod 400 /etc/openldap/slapdkey.pem<br /><br /># mkdir /etc/openldap/cacerts/<br /># cp /usr/share/ssl/misc/demoCA/cacert.pem /etc/openldap/cacerts/cacert.pem<br /># chown ldap:ldap /etc/openldap/cacerts cacert.pem<br /># chmod 644 /etc/openldap/cacerts cacert.pem<br /></pre></td></tr></tbody></table><br /><p>在 OpenLDAP 服务器上，将以下内容添加到 /etc/openldap/slapd.conf 文件的 <code>global</code> 段下面。<code>TLSCertificateFile</code> 和 <code>TLSCertificateKeyFile</code> 指定了证书文件和私钥文件的路径。<code>TLSCipherSuite</code> 指定了一个 OpenSSL 密码的列表，slapd 在与 TLS 协商建立连接时可以从中按照降序顺序依次选择。<code>HIGH</code> 的意思是 “所有密钥的长度都大于 128 位”；<code>MEDIUM</code> 表示 “所有密钥的长度都等于 128 位”；<code>+SSLv2</code> 表示 “不管密钥强度如何，所有密码都是以 SSL 协议版本 2 的形式指定的”。</p><p><code>
TLSCipherSuite  HIGH:MEDIUM:+SSLv2<br />
TLSCACertificateFile    /etc/openldap/cacerts/cacert.pem<br />
TLSCertificateFile      /etc/openldap/slapdcert.pem<br />
TLSCertificateKeyFile   /etc/openldap/slapdkey.pem
</code></p><p>将以下内容添加到 LDAP 服务器的第二个配置文件 /etc/openldap/ldap.conf 中：</p><p><code>
TLS_CACERTDIR /etc/openldap/cacerts<br />
TLS_REQCERT allow
</code></p><p>
为了允许从 OpenLDAP 客户机上使用安全连接，需要将以下内容添加到 /etc/openldap/ldap.conf 文件中：</p><p><code>
ssl start_tls<br />
tls_checkpeer yes<br />
tls_cacertfile /etc/openldap/cacerts/cacert.pem
</code></p><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br /></td><td align="right" valign="top"><a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#main" class="fbox"><b>回页首</b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="N104A2"><span class="atitle">结束语</span></a></p><p>按照本文给出的提示，我们现在已经使用轻量级目录访问协议（LDAP）构建了一个集中的身份验证系统。我们最初是通过配置 LDAP
服务器来响应对 “dc=ibm,dc=com” 的基本请求开始入手的。我们使用了一组 Perl 脚本来将用户帐号信息迁移到 LDAP
目录中。我们对 Linux 用户帐号服务、PAM 和 NSS 服务进行了修改，从而可以从 LDAP 服务器中检索用户信息。还设置了一个
LDAP 服务器副本作为备用服务器来响应客户机的请求。然后，使用 TLS 协议在 LDAP 客户机和服务器之间对通信进行安全加密。恭喜！</p><p>为了参考方便，下面给出了本文中使用的配置文件的完整清单。</p><br /><a name="listing18"><b>清单 18. 本文例子中使用的服务器 /etc/openldap/slapd.conf 文件</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section">#<br /># See slapd.conf (5) for details on configuration options.<br />#<br />include         /etc/openldap/schema/core.schema<br />include         /etc/openldap/schema/cosine.schema<br />include         /etc/openldap/schema/inetorgperson.schema<br />include         /etc/openldap/schema/nis.schema<br /><br />loglevel        256<br />pidfile         /var/run/slapd.pid<br />argsfile        /var/run/slapd.args<br /><br /># The next three lines allow use of TLS for encrypting connections.<br />TLSCipherSuite  HIGH:MEDIUM:+SSLv2<br />TLSCACertificateFile    /etc/openldap/cacerts/cacert.pem<br />TLSCertificateFile      /etc/openldap/slapdcert.pem<br />TLSCertificateKeyFile   /etc/openldap/slapdkey.pem<br /><br /># access control policy:<br /># Restrict password access to change by owner and authentication.<br /># Allow read access by everyone to all other attributes.<br /><br />access to attrs=shadowLastChange,userPassword<br />   by self write<br />   by * auth<br /><br />access to *<br />   by * read<br /><br />#######################################################################<br /># database definition<br />#######################################################################<br /><br />database        bdb<br />suffix          "dc=ibm,dc=com"<br /><br />rootdn          "cn=Manager,dc=ibm,dc=com"<br />rootpw          {MD5}ijFYNcSNctBYg<br /><br />directory       /var/lib/ldap<br /><br /># Indices to maintain for this database<br />index objectClass                       eq,pres<br />index ou,cn,mail,surname,givenname      eq,pres,sub<br />index uidNumber,gidNumber,loginShell    eq,pres<br />index uid,memberUid                     eq,pres,sub<br />index nisMapName,nisMapEntry            eq,pres,sub<br /><br />#Replicas of this database<br />replica host=dhcp64-253.ibm.com:389<br />        binddn="cn=Manager,dc=ibm,dc=com"<br />        credentials=secret<br />        bindmethod=simple<br />replogfile /var/lib/ldap/replog<br /></pre></td></tr></tbody></table><br /><br /><a name="listing19"><b>清单 19. 本文例子中使用的服务器 /etc/openldap/ldap.conf 文件</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section">#<br /># LDAP Defaults<br />#<br /><br /># See ldap.conf(5) for details<br /><br />HOST 127.0.0.1<br />BASE dc=ibm,dc=com<br /><br />TLS_CACERTDIR /etc/openldap/cacerts<br />TLS_REQCERT allow<br /></pre></td></tr></tbody></table><br /><br /><a name="listing20"><b>清单 20. 本文例子中使用的客户机 /etc/ldap.conf 文件</b></a><br /><table bgcolor="#eeeeee" border="1" cellpadding="5" cellspacing="0" width="100%"><tbody><tr><td><code></code><pre class="section">a<br /># @(#)$Id: ldap.conf,v 1.34 2004/09/16 23:32:02 lukeh Exp $<br />#<br /># This is the configuration file for the LDAP nameservice<br /># switch library and the LDAP PAM module.<br />#<br /># PADL Software<br /># http://www.padl.com<br />#<br /><br /># Your LDAP server.<br /># Multiple hosts may be specified, each separated by a<br /># space.<br /><br />host dhcp64-233.ibm.com dhcp64-233.ibm.com<br /><br /># The distinguished name of the search base.<br /><br />base dc=ibm,dc=com<br /><br /># OpenLDAP SSL mechanism, start_tls mechanism uses the normal LDAP port 389<br />ssl start_tls<br /><br />#Require and verify server certificate<br />tls_checkpeer yes<br /><br /># CA certificates for server certificate verification<br />tls_cacertfile /etc/openldap/cacerts/cacert.pem<br /><br />pam_password md5<br /></pre></td></tr></tbody></table><br /><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br /></td><td align="right" valign="top"><a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#main" class="fbox"><b>回页首</b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="resources"><span class="atitle">参考资料 </span></a></p><b>学习</b><br /><ul><li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/linux/library/l-openldap/?S_TACT=105AGX52&amp;S_CMP=cn-a-l" target="_blank">英文原文</a> 。<br /><br /></li><li><a href="http://www.openldap.org/">OpenLDAP 主页</a> 是 OpenLDAP 项目的主页。其中包含了有关如何配置 OpenLDAP 的丰富信息，以及将来的路线图和版本信息。请确保阅读 <a href="http://www.openldap.org/doc/admin23/">OpenLDAP Software 2.3 Administrator's Guide</a>。
<br /><br /></li><li>
在 <a href="http://www.openssl.org/">OpenSSL Project</a> 中，可以找到有关 SSL 和 TLS 的信息。
<br /><br /></li><li>
在 <a href="http://www.linux.com/howtos/LDAP-HOWTO/index.shtml">LDAP Linux HOWTO</a> 中，我们可以找到有关在 Linux 机器上安装、配置、运行和维护 LDAP（Lightweight Directory Access Protocol）服务器的详细信息。请在 <a href="http://www.linux.com/howtos/LDAP-Implementation-HOWTO/index.shtml">LDAP Implementation HOWTO</a> 中阅读使用 pam_ldap 和 nss_ldap 进行 LDAP 身份验证的讨论。
<br /><br /></li><li><a href="http://www.padl.com/">PADL 主页</a> 提供了 Perl 迁移脚本 nss_ldap 和 pam_ldap 以及很多其他有用的 LDAP 工具。
<br /><br /></li><li>
在 <a href="http://www.ibm.com/developerworks/cn/linux/">developerWorks Linux 专区</a> 中可以找到为 Linux 开发人员准备的更多资源。
<br /><br /></li><li>
随时关注 <a href="http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGX52&amp;S_CMP=cn-a-l">developerWorks 技术活动和网络广播</a>。
</li></ul><br /><b>获得产品和技术</b><br /><ul><li><a href="http://www.ibm.com/developerworks/offers/sek/?S_TACT=105AGX52&amp;S_CMP=cn-a-l">索取免费的 SEK for Linux</a>，这有两张 DVD，包括最新的 IBM for Linux 的试用版软件，包括 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere®。
<br /><br /></li><li>

在您的下一个开发项目中采用 <a href="http://www.ibm.com/developerworks/downloads/?S_TACT=105AGX52&amp;S_CMP=cn-a-l">IBM 试用版软件</a>，这可以从 developerWorks 上直接下载。
<br /><br /></li></ul><br /><b>讨论</b><br /><ul><li><a href="http://www.openldap.org/lists/">OpenLDAP 邮件列表</a> 是讨论 OpenLDAP 的主要论坛。
<br /><br /></li><li>
通过参与 <a href="http://www.ibm.com/developerworks/blogs/?S_TACT=105AGX52&amp;S_CMP=cn-a-l">developerWorks blogs</a> 加入  developerWorks 社区。
<br /><br /></li></ul><br /><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td><img src="http://www.ibm.com/i/v14/rules/blue_rule.gif" alt="" height="1" width="100%" /><br /><img alt="" src="http://www.ibm.com/i/c.gif" border="0" height="6" width="8" /></td></tr></tbody></table><table class="no-print" align="right" cellpadding="0" cellspacing="0"><tbody><tr align="right"><td><img src="http://www.ibm.com/i/c.gif" alt="" height="4" width="100%" /><br /><table border="0" cellpadding="0" cellspacing="0"><tbody><tr><td valign="middle"><img src="http://www.ibm.com/i/v14/icons/u_bold.gif" alt="" border="0" height="16" width="16" /><br /></td><td align="right" valign="top"><a href="http://www-128.ibm.com/developerworks/cn/linux/l-openldap/#main" class="fbox"><b>回页首</b></a></td></tr></tbody></table></td></tr></tbody></table><br /><br /><p><a name="author"><span class="atitle">关于作者</span></a></p><table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody><tr><td colspan="3"><img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="100%" /></td></tr><tr align="left" valign="top"><td><p><img alt="Mike O'Reilly" src="http://www.ibm.com/developerworks/i/p-moreilly.jpg" align="left" border="0" height="80" width="64" /></p></td><td><img alt="" src="http://www.ibm.com/i/c.gif" height="5" width="4" /></td><td width="100%"><p>Mike O'Reilly 是 IBM Linux 和 VMware ESX 产品支持小组的一员，他为 Linux 产品提供支持已经有 5 年的时间了。另外，他支持 VMware 超</p></td></tr></tbody></table><br /><img src ="http://www.blogjava.net/alex/aggbug/62714.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alex/" target="_blank">Alex</a> 2006-08-10 09:19 <a href="http://www.blogjava.net/alex/archive/2006/08/10/62714.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]bash编程教学实例</title><link>http://www.blogjava.net/alex/archive/2006/06/16/53293.html</link><dc:creator>Alex</dc:creator><author>Alex</author><pubDate>Fri, 16 Jun 2006 06:20:00 GMT</pubDate><guid>http://www.blogjava.net/alex/archive/2006/06/16/53293.html</guid><wfw:comment>http://www.blogjava.net/alex/comments/53293.html</wfw:comment><comments>http://www.blogjava.net/alex/archive/2006/06/16/53293.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alex/comments/commentRss/53293.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alex/services/trackbacks/53293.html</trackback:ping><description><![CDATA[key words: bash编程 <br /><br />转自 <a href="http://www.gd-linux.org/bbs/archive/index.php/t-126.html">这里</a><br /><br />另一篇 <a href="http://www.linuxsir.org/main/?q=node/134">详解Bash命令行处理</a><br /><br />bash编程教学实例<br /><br />
bash编程<br /><br />
--------------------------------------------------------------------------------<br />
時間：2004/03/02　　　　來源：不详<br /><br />
　　Shell Script(bash)简介<br /><br />
　　众所皆知地，UNIX上以小工具著名，利用许多简单的小工具，来完成原本需要大量软体开发的工作，这一点特色，使得UNIX成为许多人心目中理想的系统平台。　<br />
　　在众多的小工具中，Shell Script算得上是最基本、最强大、运用最广泛的一个。它运用围之广，不但从系统启动、程式编译、定期作业、上网连线，甚至安装整个Linux系统，都可以用它来完成。　<br /><br />
　　因为Shell
Script是利用您平日在使用的一些指令，将之组合起来，成为一个"程式"。如果您平日某些序列的指令下得特别频繁，便可以将这些指令组合起来，成为另
一个新的指令。这样，不但可以简化并加速操作速度，甚至还可以干脆自动定期执行，大大简化系统管理工作。　<br /><br />
　　*************************<br />
　　Bash(GNU Bourne-Again
SHell)是许多Linux平台的内定Shell，事实上，还有许多传统UNIX上用的Shell，像tcsh、csh、ash、bsh、ksh等等，
Shell Script大致都类同，当您学会一种Shell以后，其它的Shell会很快就上手，大多数的时候，一个Shell
Script通常可以在很多种Shell上使用。　<br />
　　这里我介绍您bash的使用方法。事实上，当您"man
bash"时，就可以看到bash的说明书，不过对许多人来说，这份说明书犹如"无字天书"一样难懂。这份文件，主要资料来源为"man
bash"，我加上一些实际日常的应用例来说明。希望这样能让那些始终不得其门而入的人们，多多少少能有点概念。　<br /><br /><br />
　　教学例子<br /><br />
　　"Hello world" Shell Script　<br />
　　照传统程式教学例，这一节介绍Shell Script的"Hello World"如何撰写。　<br /><br />
　　*************************<br /><br />
　　#!/bin/sh　<br />
　　# Filename : hello　<br />
　　echo "Hello world!"　<br /><br />
　　*************************<br /><br />
　　大家应该会注意到第一行的"#!/bin/sh"。在UNIX下，所有的可执行Script，不管是那一种语言，其开头都是"#!"，例如Perl是
"#!/usr/bin/perl"，tcl/tk是"#!/usr/bin/wish"，看您要执行的Script程式位置在那里。您也可以用"#!
/bin/bash"、"#!/bin/tcsh"等等，来指定使用特定的Shell。　<br />
　　echo是个bash的内建指令。　<br /><br />
　　*************************<br /><br />
　　接下来，执行hello这个script:　<br />
　　要执行一个Script的方式有很多种。　<br /><br />
　　*************************<br /><br />
　　第一种 : 将hello这个档案的权限设定为可执行。　<br />
　　[foxman@foxman bash]# chmod 755 hello　<br />
　　执行　<br />
　　[foxman@foxman bash]# ./hello　<br />
　　hello world　<br /><br />
　　*************************<br /><br />
　　第二种 : 使用bash内建指令"source"或"."。　<br />
　　[foxman@foxman bash]# source hello　<br />
　　hello world　<br />
　　或　<br />
　　[foxman@foxman bash]# . hello　<br />
　　hello world　<br /><br />
　　*************************<br /><br />
　　第三种 : 直接使用sh/bash/tcsh指令来执行。　<br />
　　[foxman@foxman bash]# sh hello　<br />
　　hello world　<br />
　　或　<br />
　　[foxman@foxman bash]# bash hello　<br />
　　hello world　<br /><br />
　　*************************<br /><br />
　　Bash执行选项　<br /><br />
　　*************************<br /><br />
　　-c string : 读取string来当命令。　<br />
　　-i : 互动介面。　<br />
　　-s : 由stdin读取命令。　<br />
　　- : 取消往后选项的读取。　<br />
　　-norc : 不要读~/.bashrc来执行。　<br />
　　-noprofile : 不要读/etc/profile、~/.bash_profile、~/.bash_login、~/.profile等等来执行。　<br />
　　-rcfile filename : 执行filename，而非~/.bashrc　<br />
　　-version : 显示版本。　<br />
　　-quiet : 启动时不要哩唆。　<br />
　　-login : 确保bash是个login shell。　<br />
　　-nobraceexpansion : 不要用curly brace expansion({}符号展开)。　<br />
　　-nolineediting : 不用readline来读取命令列。　<br />
　　-posix : 改采Posix 1003.2标准。　<br /><br /><br />
　　用于自动备份的Shell Script<br /><br /><br />
　　一个用于自动备份的Shell Script<br />
　　我们先前提到，可利用Shell Script搭配crond来作定期的工作。要作定期性的工作，在UNIX上，就是与crond的搭配运用。　<br /><br />
　　*************************<br /><br />
　　首先我们先来研究如何对系统进行备份。　<br />
　　要对系统进行备份，不外乎便是利用一些压缩工具。在许多UNIX系统上，tar及gzip是de
facto的资料交换标准。我们经常可以看见一些tar.gz或tgz档，这些档案，被称为tarball。当然了，您也可以用bzip2、zip等等压
缩工具来进行压缩，不必限定于gzip。但tar配合gzip是最普遍的，也是最方便的方式。　<br /><br />
　　要将我们想要的资料压缩起来，进行备份，可以结合tar及gzip一起进行。方式有很多种，最常用的指令是以下这一种:　<br /><br />
　　tar -c file/dir ... | gzip -9 &gt; xxxx.tar.gz　<br /><br />
　　您也可以分开来做:　<br /><br />
　　tar -r file/dir ... -f xxxx.tar　<br />
　　gzip -9 xxxx.tar　<br /><br />
　　或　<br /><br />
　　tar -r file/dir ... -f xxxx.tar　<br />
　　gzip -9 &lt; xxxx.tar &gt; xxxx.tar.gz　<br /><br />
　　*************************<br /><br />
　　在解过Linux下档案备份的基本知识后，我们来写一个将档案备份的Script。　<br />
　　#!/bin/sh　<br />
　　# Filename : backup　<br /><br />
　　DIRS="/etc /var /your_directories_or_files"　<br />
　　BACKUP="/tmp/backup.tgz"　<br /><br />
　　tar -c $DIRS | gzip -9 &gt; $BACKUP　<br /><br />
　　其中DIRS放的是您要备份的档案及目录，BACKUP是您的备份档。可不要将/tmp放进DIRS中，那样做，您是在做备份的备份，可能将您的硬碟塞爆。　<br /><br /><br />
　　*************************<br /><br />
　　接下来测试　<br />
　　[foxman@foxman bash]# chmod 755 backup　<br />
　　[foxman@foxman bash]# ./backup　<br /><br />
　　执行完成后在/tmp就会有一个backup.tgz，里面储存了您重要的资料。您可用　<br /><br />
　　gzip -dc /tmp/backup.tgz | tar -vt　<br />
　　或　<br />
　　tar vtfz /tmp/backup.tgz　<br /><br />
　　来看看里面的档案列表。　<br /><br />
　　要解开时，可用以下指令来完成复原:　<br /><br />
　　gzip -dc /tmp/backup.tgz | tar -xv　<br />
　　或　<br />
　　tar xvfz /tmp/backup.tgz　<br /><br />
　　备份通常是仅备份系统通常最重要的部份，/etc可说是不可缺少的一部份。另外，看您系统中有那些重要的资料需要备份。通常来说，您没有必要备份
/bin、/sbin、/usr/bin、/usr/sbin、/usr/X11R6/bin等等这些执行档目录。只要备份您重要的档案即可，别把整个硬
碟备份，那是蛮呆的动作。　<br /><br />
　　*************************<br /><br />
　　如果您有许多台机器，可利用其中一台任务较轻的内部网路主机，做为主要备份主机。将所有机器都自动执行备份，然后利用NFS/Coda/Samba等网路档案系统，将备份的资料放到该备份机器中，该机器则定时收取备份资料，然后您再由该机器中进行一次备份。　<br />
　　这里是整个系统备份方案的图示。　<br /><br />
　　在您进行之前，先解一下，系统中那些是要备份的，那些是不需要的。　<br /><br />
　　*************************<br /><br />
　　新的backup<br />
　　#!/bin/sh　<br />
　　HOSTNAME=`hostname`　<br />
　　DIRS="/etc /var /your_important_directory"　<br />
　　BACKUP="/tmp/$HOSTNAME.tgz"　<br />
　　NFS="/mnt/nfs"　<br /><br />
　　tar -c $DIRS | gzip -9 &gt; $BACKUP　<br />
　　mv -f $BACKUP $NFS　<br /><br /><br />
　　*************************<br /><br />
　　备份主机内的Script : collect_backup<br />
　　#!/bin/sh　<br />
　　NFS="/mnt/nfs"　<br />
　　BACKUP="/backup"　<br /><br />
　　mv -f $NFS/*.tgz $BACKUP　<br /><br /><br />
　　在此，您不能够将所有备份都直接放在/mnt/nfs，这是危险的。万一任一台机器不小心将/mnt/nfs所有内容删除，那么备份就会消失。因此，您需要将/mnt/nfs移到一个只有该备份主机可存取的目录中。　<br /><br /><br />
　　*************************<br /><br />
　　当这些个别的Script都测试好以后，接下来我们将他们放到crontab里面。找到您的crontab，它的位置可能在/var/spool/cron/crontabs/root、/etc/crontab、/var/cron/tabs/root。　<br />
　　在crontab中选择以下之一加入(看您定期的时间):　<br /><br />
　　Slackware : /var/spool/cron/crontabs/root<br />
　　01 * * * *　/full_backup_script_path/backup 1&gt; /dev/null 2&gt; /dev/null # 每小时(太过火一点)　<br />
　　30 16 * * *　/full_backup_script_path/backup 1&gt; /dev/null 2&gt; /dev/null # 每日16:30，下班前备份　<br />
　　30 16 * * 0　/full_backup_script_path/backup 1&gt; /dev/null 2&gt; /dev/null # 每周一16:30　<br />
　　0 5 1 * *　/full_backup_script_path/backup 1&gt; /dev/null 2&gt; /dev/null # 每月一号5:0　<br />
　　RedHat/Debian : /etc/crontab<br />
　　RedHat可直接将backup放入/etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly。或采用如上加入/etc/crontab的方式:　<br />
　　有关crontab的用法，可查"man 5 crontab"，在此不详述。　<br /><br />
　　备份主机的设定类同。　<br /><br />
　　注意: 所有机器不要同时进行备份，否则网路会大塞车。备份主机收取备份的时间要设为最后，否则会收不到备份资料。您可以在实作后，将时间间隔调整一下。　<br /><br /><br />
　　*************************<br /><br />
　　看看，两个小小不到三行的Shell Script，配合cron这个定时工具。可以让原本需要耗时多个小时的人工备份工作，简化到不到十分钟。善用您的想像力，多加一点变化，可你让您的生活变得轻松异常，快乐悠哉。<br /><br /><br />
　　档案系统检查<br /><br />
　　系统安全一向是大多数电脑用户关心的事，在UNIX系统中，最重视的事，即系统中有没有"木马"(Trojan horse)。不管Trojan
horse如何放进来的，有一点始终会不变，即被放置木马的档案，其档案日期一定会被改变，甚至会有其它的状态改变。此外，许多状况下，系统会多出一些不
知名的档案。因此，平日检查整个档案系统的状态是否有被改变，将所有状态有改变的档案，以及目前有那些程式正在执行，自动报告给系统管理员，是个避免坐上
"木马"的良方。　<br /><br />
　　*************************<br /><br />
　　#!/bin/sh　<br />
　　# Filename : whatever_you_name_it　<br />
　　DIRS="/etc /home /bin /sbin /usr/bin /usr/sbin /usr/local /var /your_directory"　<br />
　　ADMIN="email@your.domain.com"　<br />
　　FROM="admin@your.domain.com"　<br />
　　# 写入Sendmail的标头　<br />
　　echo "Subject: $HOSTNAME filesystem check" &gt; /tmp/today.mail　<br />
　　echo "From: $FROM" &gt;&gt; /tmp/today.mail　<br />
　　echo "To: $ADMIN" &gt;&gt; /tmp/today.mail　<br />
　　echo "This is filesystem report comes from $HOSTNAME" &gt;&gt; /tmp/today.mail　<br />
　　# 报告目前正在执行的程式　<br />
　　ps axf &gt;&gt; /tmp/today.mail　<br />
　　# 档案系统检查　<br />
　　echo "File System Check" &gt;&gt; /tmp/today.mail　<br />
　　ls -alR $DIRS | gzip -9 &gt; /tmp/today.gz　<br />
　　zdiff /tmp/today.gz /tmp/yesterday.gz &gt;&gt; /tmp/today.mail　<br />
　　mv -f /tmp/today.gz /tmp/yesterday.gz　<br />
　　# 寄出信件　<br />
　　sendmail -t &lt; /tmp/today.mail　<br /><br />
　　然后把它放到一个不显眼的地方去，让别人找不到。　<br /><br />
　　把它加入crontab中。　<br /><br />
　　30 7 * * *　/full_check_script_path/whatever_you_name_it 1&gt; /dev/null 2&gt; /dev/null #上班前检查　<br /><br />
　　有些档案是固定会更动的，像/var/log/messages、/var/log/syslog、/dev/ttyX等等，不要太大惊小怪。<br /><br /><br />
　　控制圈for<br /><br />
　　演示了几个简单的Shell Script，相信您应该对Shell Script有点概念了。现在我们开始来仔细研究一些较高等的Shell
Script写作。一些进一步的说明，例如"$"、"&gt;"、"&lt;"、"&gt;&gt;"、"1&gt;"、"2&gt;"符号的使用，会在
稍后解释。　<br /><br />
　　*************************<br /><br />
　　for name [ in word; ] do list ; done<br />
　　控制圈。　<br />
　　word是一序列的字，for会将word中的个别字展开，然后设定到name上面。list是一序列的工作。如果[in word;]省略掉，那么name将会被设定为Script后面所加的参数。　<br /><br /><br />
　　*************************<br /><br />
　　例一:　<br />
　　#!/bin/sh　<br /><br />
　　for i in a b c d e f ; do　<br />
　　echo $i　<br />
　　done　<br /><br />
　　它将会显示出a到f。　<br /><br /><br />
　　*************************<br /><br />
　　例二: 另一种用法，A-Z<br />
　　#!/bin/sh　<br />
　　WORD="a b c d e f g h i j l m n o p q r s t u v w x y z"　<br /><br />
　　for i in $WORD ; do　<br />
　　echo $i　<br />
　　done　<br /><br />
　　这个Script将会显示a到z。　<br /><br /><br />
　　*************************<br /><br />
　　例三 : 修改副档名<br />
　　如果您有许多的.txt档想要改名成.doc档，您不需要一个一个来。　<br />
　　#!/bin/sh　<br /><br />
　　FILES=`ls /txt/*.txt`　<br /><br />
　　for txt in $FILES ; do　<br />
　　doc=`echo $txt | sed "s/.txt/.doc/"`　<br />
　　mv $txt $doc　<br />
　　done　<br /><br />
　　这样可以将*.txt档修改成*.doc档。　<br /><br /><br />
　　*************************<br /><br />
　　例四 : meow<br />
　　#!/bin/sh　<br />
　　# Filename : meow　<br />
　　for i ; do　<br />
　　cat $i　<br />
　　done　<br /><br />
　　当您输入"meow file1 file2 ..."时，其作用就跟"cat file1 file2 ..."一样。　<br /><br /><br />
　　*************************<br /><br />
　　例五 : listbin　<br />
　　#!/bin/sh　<br />
　　# Filename : listbin　<br /><br />
　　for i in /bin/* ; do　<br />
　　echo $i　<br />
　　done　<br /><br />
　　当您输入"listbin"时，其作用就跟"ls /bin/*"一样。　<br /><br /><br />
　　*************************<br /><br />
　　例六 : /etc/rc.d/rc　<br />
　　拿一个实际的例来说，Red Hat的/etc/rc.d/rc的启动程式中的一个片断。　<br /><br />
　　for i in /etc/rc.d/rc$runlevel.d/S*; do　<br />
　　# Check if the script is there.　<br />
　　[ ! -f $i ] &amp;&amp; continue　<br /><br />
　　# Check if the subsystem is already up.　<br />
　　subsys=${i#/etc/rc.d/rc$runlevel.d/S??}　<br />
　　[ -f /var/lock/subsys/$subsys ] || \　<br />
　　[ -f /var/lock/subsys/${subsys}.init ] &amp;&amp; continue　<br /><br />
　　# Bring the subsystem up.　<br />
　　$i start　<br />
　　done　<br /><br />
　　这个例中，它找出/etc/rc.d/rcX.d/S*所有档案，检查它是否存在，然后一一执行。　<br /><br /><br />
　　流程控制case<br /><br />
　　case word in [ pattern [ | pattern ] ... ) list ;; ] ... esac<br />
　　case/esac的标准用法大致如下:　<br />
case $arg in　<br />
　　pattern | sample) # arg in pattern or sample　<br />
　　;;　<br />
　　pattern1) # arg in pattern1　<br />
　　;;　<br />
　　*) #default　<br />
　　;;　<br />
esac　<br />
　　arg是您所引入的参数，如果arg内容符合pattern项目的话，那么便会执行pattern以下的程式码，而该段程式码则以两个分号";;"做结尾。　<br /><br />
　　可以注意到"case"及"esac"是对称的，如果记不起来的话，把"case"颠倒过来即可。　<br /><br /><br />
*************************<br /><br />
　　例一 : paranoia<br />
#!/bin/sh　<br />
case $1 in　<br />
　　　　start | begin)　<br />
　　　　　echo "start something"　<br />
　　　　;;　<br />
　　　　stop | end)　<br />
　　　　　echo "stop something"　<br />
　　　　;;　<br />
　　　　*)　<br />
