摘要
目前介绍软件工程和项目管理的书是越来越多了。遍历各家之说,体会最深的是两个字:“沟通”。没有沟通,开发人员单枪匹马,重复着“前辈们”走过的路,缓慢的成长着。没有沟通,测试和开发团队就在没完没了的争吵中迎接项目的延期。没有沟通,部门之间的鸿沟足可以吓退客户。没有沟通,公司的决策人还在期盼着项目的成功的那一天,而不知道危险已经临近。作为 IT 从业人员,如果我们在不断为别人提供软件产品来提高工作效率,而自己却不能利用软件来改进项目的沟通,实在是一种悲哀。
本文先探讨通过建立新闻组服务器作为项目的沟通管理工具的途径和方法。
(编译自版本: 3038a6f,最后更新时间: 2007-07-31)
目录
News vs. Email
Email 保存在客户端,只有收件人能够查看和保存,而 NEWS 存储在服务器端, 可以随时查阅。
设想如果团队的知识分散保存在各个人的邮箱里,当团队中加入了新成员, 如何能够让知识传递到新员工哪里?难道要把 Email 重新传递一份?
News vs. Document
News 可以进行知识传递,文档也可以,中华五千年的文明就是通过文字、书籍来 传播的。News的优越性在于时效性和便于沟通,文档的优越性在于条理性和归档保存。
News 的精华需要及时提炼出相应的精华文档。而文档的格式呢?推荐用 DocBook,参见:Johnson's DocBook Homepage。
News vs. mail-list
群发的 mail-list 将很浪费网路资源和其它各方面的资源,而 USENET news 的特点是 将文章集中在一个host,允许订阅者定自己想读的提供 index,cross-referencing(cross post), 和砍掉过期的文章的功能,这样可以减轻网路的负担,因为当你想看 news 时才要连到 server 去看,而且也可以挑自己想看的东西,不必像 mailing list 一样要把所有的 messages 照单全收。
News 具有线索和图形化的客户端支持,而通过 mail-list 订阅的邮件组则没有了线索, 只是在邮箱中按照发布时间顺序排列。
但是 mail-list 也具有 News没有的优势。News的使用方式是:“拉”,mail-list是“推”。 如果news server位于内部网络,而且拒绝外部访问,则 mail-list 是外部访问 新闻组的唯一方式。
因此,可以把邮件列表拿来和新闻组服务器协同工作,互为补充。
News vs. bbs
News 的实时性没有 bbs 好,但是客户端不必登录到服务器,安全性相对要好;
News 服务可以借助 mail-list,实现“推”的技术;
News 可以提供分布式服务,知道大名鼎鼎的 USEnet 么?
四个字:知识管理。
技术讨论
大家都想坐在高手的旁边,就是希望开发中遇到的困难能够尽快解决。与其排座位而让我绞尽脑汁,不如进一步完善内部沟通机制。
技术跟踪
我们每个人都对我们的产品的发展都会有些想法,NewsGroup将是一个不作的归纳总结的地方。
软件发布
研发和测试的接口,是我们的自动编译系统+Bug Tracking系统。 但是我们的 Release Note 的规范一直没有很好的完善起来。不是由于开发 人员不遵守开发规范,而是制度制定的不合理。 也许 ReleaseNote 新闻组,加上 docbook 格式的文档,会是我们的这个工作 能够走上正轨。
在新闻组中建立一个发布专版,每一个功能变更,界面变化,bugfix,都以 news 的方式 提交到这个版中;编译工程师,在完成一次版本提升,也在此版发布一条信息; 文档工程师,根据两次版本提升之间的 news,组织 ReleaseNotes 的内容。
攻击和测试技术论坛
研发的测试技术正处于持续的改善过程中,开发和收集的新工具,越来越多,除了 内部讲座和内部培训外,也需要一个论坛,来统一组织。
FAQ
除了公司范围的入职培训外,研发内部还为新员工准备了相应的技术培训。 但也存在着培训教师的讲课水平不一致,讲义不完备,如何持久培训的问题。
针对开发必须掌握的专题,分别开辟相应的 FAQ NewsGroup,可以减轻培训教师的负担。
USENET在1979年末,UNIX V7公布、引进UUCP後不久诞生。由Duke University 两位研究生Tom Truscott 及Jim Ellis提出构想、用来在UNIX间交换讯息。由南加 大的Steve Bellovin设计。Steve Daniel用C程式语言重新改写,经Tom Truscott 修改後为第一个正式版本(RELEASE A)。
1981年Berkeley的研究生Mark Horton及高中生Matt Glickman重新改写,以增 加功能,并且处理日益增加的News流量。此版本为B ── B News。
在Center for Seismic Studies的Rick Adams接替维护B News的工作。在1986 年年末,B News 2.11 公布,奠定了目前USENET的规模。现在B News已经退休了, 为C News或INN所取代。
1986年三月,公布了一个新的套装程式,使用一种新的传输News的协定 Network News Transfer Protocol (NNTP) 。此协定使用TCP/IP的方法交换资料, 而非传统使用UUCP的方法。
1987年秋,C News公布。
1992年八月二十InterNetNews公布 (INN)。
目前最常用的 NEWS Server 有 CNEWS和INN。
至于新闻组中的中文发展的沉浮,可以参考这篇文档《新闻组是什么?》。
INN 2.3.3
Sendmail 8.12.8
Majordomo 1.94.5
MHonArc
htdig
MAILMAN
MAIL-ARCHIVE
Apache
这里介绍用 INN 构建具备基本功能的新闻服务器。
设置 news 用户帐号
确认系统中包含 news 用户和 news 组,如果没有,需要添加:
$ groupadd news $ useradd -g news -d /usr/local/news
安装
建议perl support,这样会安装一些维护工具,如 scanspool等。 |
$ tar zxvf inn-2.3.3.tar.gz $ cd inn-2.3.3/ $ ./configure --with-perl $ make && make install Do not forget to update your cron entries, and also run makedbz if you need to. If this is a first-time installation a minimal active file has been installed. You will need to touch history and run "makedbz -i" to initialize the history database. See INSTALL for more information.
缺省安装在 /usr/local/news 目录下,并已经设置好相应权限。
设定新闻组
db/active
the list of newsgroups you carry.
$ cat /usr/local/news/db/active
control 0000000000 0000000001 n
control.cancel 0000000000 0000000001 n
control.checkgroups 0000000000 0000000001 n
control.newgroup 0000000000 0000000001 n
control.rmgroup 0000000000 0000000001 n
junk 0000000000 0000000001 n
active 文件中至少要有 control 和 junk 两行。 |
db/active.times
初始为空文件。该文件被有些 news 客户端用来检查是否有新邮件组。该文件由 innd/ctlinnd 自动维护。
db/newsgroups
该文件记录各个新闻组的描述。格式如下:
control Various control messages (no posting). control.cancel Cancel messages (no posting). control.checkgroups Hierarchy check control messages (no posting). control.newgroup Newsgroup creation control messages (no posting). control.rmgroup Newsgroup removal control messages (no posting). junk Unfiled articles (no posting). 测试灌水 For newbie test. local.announce Announcement for all.
完整性检查
可以用命令scanspool -v,检验 active 文件和 spool中文件的正确配置。
在news服务启用状态维护 active 文件,需要:
$ ctlinnd pause 'edit active' $ vi active $ inncheck $ scanspool $ ctlinnd reload active 'new active' $ ctlinnd go 'edit active'
inn 基本资料配置文件:inn.conf
修改文件etc/inn.conf
,注意其中的如下内容:
fromhost: foo0.com.tw pathhost: foo0.com.tw organization: 公司大名 (Foo's Co.,) server: foo0.com.tw domain: com.tw hiscachesize: 256 artcutoff: 60 maxartsize: 100000 localmaxartsize: 100000 enableoverview: true ovmethod: tradindexed spoolfirst: false
执行inncheck,检查 inn.conf 配置 |
文章过期策略设置
修改配置文件 expire.ctl
如下:
/remember/:10 ## This entry uses the syntax appropriate when groupbaseexpiry is true in inn.conf. *:A:10:never:never ## This is an entry based on storage class, used when groupbaseexpiry is false. #0:10:never:never
详细说明参见:INN 过期设置。
初始化 history 文件
$ cd /usr/local/news/db $ touch history $ ../bin/makedbz -i $ for i in history.n*; do i=${i#history.n.}; mv history.n.$i history.$i ;done $ chown news:news history* $ chmod 644 history*
如果已存在的数据,可以用如下命令重建 history 和 overview 数据库。
$ ctlinnd throttle "throttle due to maintaining" $ scanspool $ makehistory -F -b -I $ cat /usr/local/news/db/history | wc -l $ find /usr/local/news/spool/articles/ -type f | wc -l $ cd /usr/local/news/db $ ../bin/makedbz -i $ for i in history.n*; do i=${i#history.n.}; mv history.n.$i history.$i ;done $ rm -rf /usr/local/news/spool/overview/* $ makehistory -O -F -b -x $ find /usr/local/news/spool/articles/ -type f | wc -l $ find /usr/local/news/spool/overview/ -type f -name "*.DAT" -exec cat {} \; | wc -l $ ctlinnd go "maintaining success"
确认 active 中的 himark 和 lowmark 是否正确设置。参见:active 文件格式。 |
|
重建 history 文件。参见:makehistory 命令参考。 |
|
重建overview 数据库前,先要将已有 overview 数据库删除。 |
|
重建 overview 数据库。参见:makehistory 命令参考。 |
设置喂信方式
如果没有另外的外部喂信者,照此配置 incoming.conf
。
peer ME { hostname: "localhost, 127.0.0.1" }
即使不向外部喂信,仍然需要配置 newsfeeds
。
ME:*,!junk::
含义为:外发除了 junk 外所有新闻组,并且允许接收所有的 distributions (该配置中distributions部分省略)。虽然我们可能不向外部喂信,但是仍然配置外发所有新闻组,因为除了用于向外喂信之外,还用于和配置其它程序通讯,如 news2mail。
配置 syslog,记录日志
$ touch /usr/local/news/log/news.crit $ touch /usr/local/news/log/news.err $ touch /usr/local/news/log/news.notice $ chown news /usr/local/news/log/news.* $ chgrp news /usr/local/news/log/news.* $ cat >> /etc/syslog.conf << END news.crit /usr/local/news/log/news.crit news.err /usr/local/news/log/news.err news.notice /usr/local/news/log/news.notice END $ kill -1 `cat /var/run/syslog.pid`
启动 news 服务 su news -c /usr/local/news/bin/rc.news
停止 news 服务 su news -c /usr/local/news/bin/rc.news stop
以SRV4方式启动。
#!/bin/sh # Script to control news server # # PATH=${SAMBADIR}/bin:${SAMBADIR}/sbin:/bin:/usr/sbin:/usr/bin export PATH case "$1" in 'start') echo "starting news server ... " su news -c /usr/local/news/bin/rc.news echo done ;; 'stop') echo "stopping news server ... " su news -c "/usr/local/news/bin/rc.news stop" echo done ;; *) echo "usage: news.sh {start | stop}" ;; esac
在服务器端将新闻组的日志文件输出到控制台,用以对服务器进行实时诊断:
# tail -f /usr/local/news/log/news/news.notice & # tail -f /usr/local/news/log/news/news.err & # tail -f /usr/local/news/log/news/news.crit &
在客户端使用 telnet 连接服务器,测试新闻组:
$ su news -c /usr/local/news/bin/rc.news Starting innd. Scheduled start of /usr/local/news/bin/innwatch. $ telnet 127.0.0.1 nntp Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. 200 news.worldhello.net InterNetNews server INN 2.3.3 ready list newsgroups 215 control Various control messages (no posting). control.cancel Cancel messages (no posting). control.checkgroups Hierarchy check control messages (no posting). control.newgroup Newsgroup creation control messages (no posting). control.rmgroup Newsgroup removal control messages (no posting). cn.comp.book Sucked from cn99 junk Unfiled articles (no posting). . listgroup control 411 No such group control listgroup cn.comp.book 211 Article list follows 1 ... 21 . authinfo user johnson 381 PASS required authinfo pass mypassword 281 Ok listgroup control 211 Article list follows . quit 205 . Connection closed by foreign host.
设置 crontab,完成诸如过期文章删除、日志回滚等工作。
修改 crontab 如下:
0 3 * * * su -c "/usr/local/news/bin/news.daily delayrm" news 0 7 * * 7 su -c '/usr/local/news/bin/expireover -s' news #0,10,20,30,40,50 * * * * /usr/local/news/bin/nntpsend
参见:news.daily 命令参考。
INN帮助文档中经常提到 feeder(喂食者) 和 reader(读者),也有人将其翻译为上游和下游。但是根据新闻组的架构,往往难以分清这两个角色。
对于集中控制(单一服务器)的新闻组,结构非常简单,只需要一台机器控制外部来的喂信(incoming feed)、向外部喂信(outgoing feed),建立和用户的连接,提供文章发布(posting)和阅读(reading)。缺点是存在单点故障。
分布式结构有使用共享池,文章复制等结构。参见:《INN Architecture Guide》。
当INN被设定为批处理方式进行 newsfeed的情况下, News的工作流程为:
News 使用者是透过News Reader软体来读取(Read) 或发送 (Post) , 这类软体可以称之为News界面软体或者News读取软体。 当使用者发送出一封讨论信时, News Server 立刻接手处理。首先Server 会把该封讨论信放在自己的News Spool (/var/spool/news) 之下, 同时 在外送预备区 (通常是/var/spool/news/out.going/site 或 /var/spool /news/out.going/site/togo) 留下一份记录。 这里, News Server对 News Reader的服务是即时的, 也就是说, 以上这些流程是一瞬间完成, 而且是连贯的。
接下来就由News Transport软体接手, 不过, News Server到News Transport之间就不一定是即时进行, 正常的话, 负责执行传输的软体 是由 cron 定时启动, 之後依照/var/spool/news/out.going/site这份 记录, 把News外送到下游的News Server。 照内定状态, INN 与 C-News 的传输工作都必须透过 cron 来带动, 这是典型的批次处理模式。
整个Usenet的架构, 就是这样一个News Server 把讨论信传给另一 部News Server, 如此由点而面, 构成一个资讯传输网。 再次提醒读者, Usenet 中的 诸多News Server彼此之间的差异可能非常大, 诸多常见的 传送方法包括卫星传送、 NNTP over TCP/IP传送、 UUCP dialup、 UUCP over TCP/IP、 E-mail (用任何可能的Mail Transport Agent)等 等, 一部Server Server只要使用何其上下游News Server 相同的传输 方法即可, 而无须顾虑外面世界究竟如何。
另外还有一点与News Transport相关的观念, 对NNTP传输方式来说, News 的喂送, 通常是上游的News Server「主动」将News喂送到下游的 News Server。 举个例子来说, 我们所需要的Newsgroups, 是我们的上 游News依照我们所要求的 (也就是我们指定订阅的) 讨论区newsgroups, 不多不少的传送过来, 我们只需要「被动」的接受即可, 换个角度, 对 於我们这一端产生的东西, 也是我们主动传给我们的上游News Server。 这个说明适用於大部分的情况, 至於其例外, 我会在後面专门来介绍News 传输的篇幅中, 更详细的介绍。
一个典型的新闻文章结构:头部信息、一个空行、正文部分。头部信息的每一行又是由关键字、冒号、空格和内容构成。
头信息中必须包含的有:"From", "Date", "Newsgroups", "Subject", "Message-ID", 和 "Path"。可选的关键字有:"Followup-To", "Expires", "Reply-To", "Sender", "References", "Control", "Distribution", "Keywords", "Summary", "Approved", "Lines", "Xref", 和 "Organization"。
From: jerry@eagle.ATT.COM (Jerry Schwarz) Path: cbosgd!mhuxj!mhuxt!eagle!jerry Newsgroups: news.announce Distribution: nj,ny Subject: Usenet Etiquette -- Please Read Message-ID: <642@eagle.ATT.COM> Date: Fri, 19 Nov 82 16:14:55 GMT Followup-To: news.misc Expires: Sat, 1 Jan 83 00:00:00 -0500 Organization: AT&T Bell Laboratories, Murray Hill The body of the message comes here, after a blank line.
INN (innd) 决定收哪些 newsgroups 主要由 active 来决定.
active档案格式为 name himark lomark flags, 我们用下例来说明。
tw.bbs.comp.network 0000000000 0000000001 y tw.bbs.netnews 0000000000 0000000001 y tw.bbs.announce 0000000000 0000000001 m
active 配置文件有四个域, 各域间以一个空格为间隔, 注意, 最后的域(也就是flags)之后没有空格。 最后的flags域, 最常见者为y 与 m,如下:
y
允许本地投递
m
受控新闻组。受控新闻组设有专门管制人来看管, 读者若post到这的讨论区, 该post通常会自动被转到该讨论区管制人(Moderator)的E-mail信箱中,该管制人若认可您post的内容, 他(或她) 会帮你post到该newsgroup。
n
不允许本地投递,但允许远程投递。
x
关闭的新闻组。
j
文章不投递到组中,如果没有交替投递到其它组,直接投递到 junk 组。注意在定义 newsfeeds 时,如果不排除 junk 组,投递到 j 标记的新闻组也会进行喂信。
=foo.bar
重定义新闻组
检验 active 文件正确性的方法:
$ inncheck $ scanspool
history 的功用:
do expire
check duplicate message ID (收 article 时)
find article to be cancelled
因此 history 不小心误杀, entry 有缺, 或毁损, 通常非必要不用重新 rebuild. 因为其影响顶多涉及:
article 无法 expire 掉 (有不用停 server 的方法, 已 post 在前)
重复收到相同 article (不会太多)
无法 cancel (影响不大)
命令 makehistory 用来维护 history 和overview 数据库。
-O
生成新的 overview 数据库。如果使用了buffindexed方式的数据库,在调用 makehistory -O 重新生成 overview 前,先清除现有的 overview 数据。注意只有需要提供客户端服务的新闻组服务器才有必要建立 overview 数据库,对于只提供新闻中转的,无需建立和维护 overview 数据库。
-F
启用另外的进程写 overview 数据库。优点是效率高,但是资源要求高。只有同时使用参数 -O 才有意义。对于buffindexed方式,调用overchan处理overview数据库。
-I
对于文章ID低于 active 文件中的最低ID值的,不建立 overview 数据库。这适合于磁盘中存在旧的文章,但并不想让用户看到的情况。
-x
不改动 history 文件。适合于只想重建 overview 数据库(使用 -O 参数),但是不影响现有 history 文件。
-b
删除没有 Message-ID 的文章。
-f <filename>
将 history 文件写入指定文件
"News Overview" 顾名思义, overview 就是先大略看看 article 的相关资讯。
举例而言, 假设一个 user 用 Netscape 的 News reader, 连上某个 News server 後, ( 当然用其它的 news reader, 情况也是类似的 )
会出现一些 newsgroups ( subscribed ), 试窗里除了 newsgroups 名称之外, 还有一些数字, 表示有多少篇 articles 他还没有读过, ..
选定某个 newsgroup 後, 接下来视窗里, 会出现许多不同主题的 articles 列表, 可能照时间 ( Date), 照标题 ( Subject ), 照作者姓名 ( From ) 排列,... 除了标题外, 可能还有作者( From address ) 列表, 另外还有一些数字, 表示某一主题的 articles 共有几篇, ...
当 user 找到某个有兴趣的标题後, 按 <Enter>, 你的 News reader 才到 News server 那里, 要求将该篇 article 传过来.
这些 Subjects, From, Dates 等资讯, 基本上是藏在 News articles 里面. 一个 News reader 要得到这些, 就只好向 News server 要.
以往, News articles 数目不多时, 某一个 client 向 news server 要这 些 index 资料时, news server 自己到 spool directory 去 scan, open news articles, 将这些东西找出来, 丢给 client.
现在 newsgroups/news articles 数量多了, 还是用这样的方法, 系统自然 就很可能忙不过来. 所以, 现在改成建 NOV ( News OverView database), 从 News server 收到某一篇文章的同时, 就把这些 threading 需要的东西, 挑出来, 放到 NOV database 中. ( 通常是一个 newsgroups, 一个档 )
这样一来, 某一个 client 来要某一个 newsgroups 的 indexing 资料, news server 就把对应的 ".overview" file 打开, 将资料读出来, 送回给 news client. 不需要像从前一样, 到该 newsgroups 对应的 目录中, 将所有的 articles 都 open 一次.
而且, 因为是 articles 一进到系统时, ".overview" file 就被 updated, 这样对 system loading 的 impact 比较小, 不像有些系统 , 必须另外 透过 cron, 定时再去 scan spool, 再造出 indexing 资料, ...
还有, 需要强调的是, NOV (".overview") database 最好和一般的 articles 分开, 分别不同的 directory。
在配置文件 inn.conf 中的 ovmethod 指定 overview 的方式。
目前 overview 有三种:tradindexed,buffindexed,以及 ovdb。tradindexed 是读取快速,但是由于对每个新的 article 都要更新两个文件因此写入非常慢。buffindexed 使用了一的大缓冲区来存储所有的 overvew,因此在大量喂送(large feed)的时候非常胜任,但是对于使用者而言会觉得有点慢。ovdb 将 overview 的数据除存储在 Berkeley DB version 3 的 数据库中,不但快速而且非常健壮(robust),只是要多花点空间来存储而已。要注意的是没有像其他两个 Mechanism 经过了常时间的考验,因此是有风险存在的。
文章过期,NOV 会自动更新。但是如果文章被 cancel,NOV不会被更新。这样当文章过期后,文章在 spool 中不存在,而 NOV 中仍存在。这就需要用如下命令定期清理(可以把该命令加入到 crontab 中):
$ expireover -s
重建 overview 数据库,使用 makehistory 命令(参见:makehistory 命令参考):
$ makehistory -O -F -b -I -x
news.daily 应该以 news 管理员身份运行,而不是以 root 用户运行。它能完成:状态报告,删除过期文章,日志文件处理,处理active文件等功能。
通常在 crontab 中建立 news.daily 的调用。如果要在一天内多次运行,应该加上 norotate 参数,避免日志文件过快的回滚。
命令格式:news.daily 参数...
delayrm
暗含 expireover 的调用。以 -z 参数运行 expire 和 expireover。要删除的文件ID先写入一个文件,再调用 expirerm 删除文件。
notdaily
将不进行需要一天一次的诸如日志处理、回滚的工作。
noexpire
确省将删除过期文章。使用该参数则不进行文章过期工作。
noexpireover
确省将过期文章从overview数据库中删除。对于只负责上下游喂信,不提供客户端连接的,无需设置overview数据库,则调用该参数则不进行更新overview的工作。
noexplog
不输出过期日志
nologs
禁止日志处理
norotate
不进行日志回滚
norenumber
禁用 ctlinnd 为 active 文件重建 low-water mark。
lowmark
如果以该参数调用,则通过 ctlinnd lowmark 来重建active的数字。以减少 ctlinnd 操作的时间。如果调用 lowmark 参数,则 norenumber 参数默认。
inn.conf - Configuration data for InterNetNews programs
修改文件etc/inn.conf
,修改之处已经加亮显示:
## $Id$ ## ## inn.conf -- INN configuration data ## ## Format: ## <parameter>:<whitespace><value> ## ## Blank values are allowed for certain parameters. ## ## See the inn.conf(5) man page for a full description of each of these ## options. This sample file is divided into two sections; first, there ## are the parameters that must be set (or should be set in nearly all ## cases), and then all parameters are given with their defaults for ## reference in the same order and with the same organization as the ## inn.conf(5) documentation. # The following parameters are most likely to need setting, although the # defaults generated by configure may be reasonable. mta: /usr/sbin/sendmail -oi -oem %s organization: Unknown ovmethod: tradindexed pathhost: news pathnews: /usr/local/news # General Settings domain: worldhello.net innflags: mailcmd: /usr/local/news/bin/innmail server: # Feed Configuration artcutoff: 60 bindaddress: hiscachesize: 256 ignorenewsgroups: false immediatecancel: false linecountfuzz: 0 maxartsize: 500000 maxconnections: 50 pathalias: pgpverify: false port: 119 refusecybercancels: false remembertrash: true sourceaddress: usecontrolchan: false verifycancels: false wanttrash: false wipcheck: 5 wipexpire: 10 # Article Storage cnfscheckfudgesize: 0 enableoverview: true groupbaseexpiry: true mergetogroups: false overcachesize: 15 ovgrouppat: storeonxref: false useoverchan: false wireformat: false xrefslave: false # Reading allownewnews: true articlemmap: false clienttimeout: 600 nnrpdcheckart: true nnrpperlauth: false nnrppythonauth: false noreader: false readerswhenstopped: false readertrack: false # Reading -- Keyword Support # # Enabling this without stopping innd and deleting the existing overview # database and adding will probably confuse a lot of things. You must # have compiled this support in too. keywords: false keyartlimit: 100000 keylimit: 512 keymaxwords: 250 # Posting addnntppostingdate: true addnntppostinghost: true checkincludedtext: false complaints: fromhost: localmaxartsize: 500000 moderatormailer: nnrpdauthsender: false nnrpdposthost: nnrpdpostport: 119 spoolfirst: false strippostcc: false # Posting -- Exponential Backoff backoffauth: false backoffdb: backoffk: 1 backoffpostfast: 0 backoffpostslow: 1 backofftrigger: 10000 # Monitoring doinnwatch: true innwatchbatchspace: 800 innwatchlibspace: 25000 innwatchloload: 1000 innwatchhiload: 2000 innwatchpauseload: 1500 innwatchsleeptime: 600 innwatchspoolnodes: 200 innwatchspoolspace: 8000 # Logging docnfsstat: false logartsize: true logcancelcomm: false logcycles: 3 logipaddr: true logsitename: true nnrpdoverstats: false nntpactsync: 200 nntplinklog: false status: 0 timer: 0 # System Tuning badiocount: 5 blockbackoff: 120 chaninacttime: 600 chanretrytime: 300 icdsynccount: 10 maxforks: 10 nicekids: 4 nicenewnews: 0 nicennrpd: 0 pauseretrytime: 300 peertimeout: 3600 rlimitnofile: -1 # Paths patharchive: /usr/local/news/spool/archive patharticles: /usr/local/news/spool/articles pathbin: /usr/local/news/bin pathcontrol: /usr/local/news/bin/control pathdb: /usr/local/news/db pathetc: /usr/local/news/etc pathfilter: /usr/local/news/bin/filter pathhttp: /usr/local/news/log pathincoming: /usr/local/news/spool/incoming pathlog: /usr/local/news/log pathoutgoing: /usr/local/news/spool/outgoing pathoverview: /usr/local/news/spool/overview pathrun: /usr/local/news/run pathspool: /usr/local/news/spool pathtmp: /usr/local/news/tmp
配置文件:/etc/readers.conf
,被程序 nnrpd 用来进行权限控制。控制谁可以连接新闻服务器以及用户的访问权限。
配置文件中有两种不同的配置组组成:auth 和 access。auth 组用来判定用户身份——是谁? access 组用来判定用户的权限——能干什么?
如何将 auth 和 access 配置组联系在一起呢?首先遍历所有的 auth 配置组,最后一个匹配的 auth 配置组负责分配一个标识,通常(参见下面的例子)通过 auth 配置组中的 default 和 default-domain 组合成形如 default@default-domain 的 ID 标识。这个标识去和 access 配置组的 users 去匹配。匹配通过,则分配 access 配置组中相应的权限。
对如下的 auth 配置组:
auth <name> { hosts: <host-wildmat> auth: <auth-program> res: <res-program> default: <defuser> default-domain: <defdomain> # ...possibly other settings }
如果定义了 "res: <res-program>",则用程序 res-program 检查用户的连接信息,如果返回一个 用户名(不带 @ 字符),则 auth 配置组返回的标识为 用户名@<defdomain>;如果带 @ 字符,则直接返回 res-program 的返回值;如果 res-program 返回 false 或者根本没有定义 res 参数,则返回 <defuser>@<defdomain>
如果用户连接之后,发出认证的命令(AUTHINFO USER/PASS commands),则用户名和口令传递给程序 <auth-program>,如果定义了 auth 参数的话。 <auth-program>认证通过,则返回新的用户标识,即用户提供的用户名,而不再使用 <defuser> 名称。
如果有多个 auth 配置组,则最后一个匹配用户连接状态或者认证状态的配置组才是最终起作用的。
然后进行第二个步骤,用获得的唯一用户标识去和各个 access 配置组匹配。一个 access 配置组如下:
access <name> { users: <identity-wildmat> newsgroups: <group-wildmat> # ...possibly other settings }
同样 access 后面的 <name> 除了可视之外,没有其它用途。起作用的是 users 参数,它的值用来匹配 auth 配置组返回的用户标识,如果匹配则具有该 access 配置组赋予的相应权限。同样对于多个 access 配置组,类似的最后一个匹配的 access 配置组起作用。
在权限设置复杂的情况下,还可以通过 auth 配置组中的 key 字段,限制匹配范围。即只去检查具有相通 key 字段的 access 配置组,如果 auth 配置组返回的用户标识和对应的 access 配置组的 key 匹配,则分配相应 access 组定义的权限。
基于 IP 地址认证示例:
auth rd { hosts: 10.0.0.0/24 default: intranet default-domain: worldhello } access rd { users: intranet@worldhello newsgroups: "*,!control.*,!junk,!control" localtime: yes access: "Read Post" } auth "localhost" { hosts: "localhost, 127.0.0.1, stdin" default: "<localhost>" } access "localhost" { users: "<localhost>" newsgroups: "*" access: RPA } access fail { users: "<FAIL>@<UNKNOWN>" newsgroups: !* }
口令验证方式需要在 auth 配置组中提供 auth 字段。auth 字段的值是用来验证口令的应用程序,该程序必须位于路径 PATH_NEWS/bin/auth/passwd/
下。
auth "passwords" { hosts: "*" key: "pwd" auth: "ckpasswd -d /usr/local/news/db/newsusers" auth: "ckpasswd -s" } access "passwords" { key: "pwd" newsgroups: "*,!local.newstest,!control*,!junk" access: "Read Post" } access "admin" { users: "johnson" key: "pwd" newsgroups: "*" access: "Read Post" }
定义了两组用户,可以从任何地址访问(hosts: "*")。外部程序check_password ,用来和客户端通讯,完成口令认证。
如果用户通过了身份验证,并且用户名为:johnson,则通过名为“admin”的控制域,为用户赋予更大的权限(能够访问包括 control.*, junk 在内的所有新闻组)。
如果用户通过了身份认证,但是是其它用户名,则通过名为“passwords”的控制域,为用户赋予权限。
测试口令验证,参见:测试新闻服务器。
参见 MAN 手册: readers.conf(5), ckpasswd(1) |
受控新闻组(Moderated Groups)就如同受控邮件列表一样,不允许用户直接发表文章,而是转发到管理员,由管理员审核后,再次发布到新闻组中,从而实现受控新闻。
受控新闻组,约定俗成的名字为:group_name.mod ,但这不是强制的。
管理员的邮件地址列在 moderators 文件中。
受控新闻参见:NetNews Moderator's Handbook。
撤销和管理文章,实际上是再次发表带有控制信息的文章,服务器根据其包含的控制信息进行相应动作。
显而易见的问题是,如何确定控制信息不是伪造的?
最广泛使用的方法是:将发信人的邮件地址列在 control.ctl 文件中,定义哪些用户是可以信任的,哪些用户不能信任(忽略其控制信息)。
control.ctl 示例:
## ------------------------------------------------------------------------- ## DEFAULT ## ------------------------------------------------------------------------- # Default to dropping control messages that aren't recognized to allow # people to experiment without inadvertently mailbombing news admins. all:*:*:drop ## ------------------------------------------------------------------------- ## CHECKGROUPS MESSAGES ## ------------------------------------------------------------------------- # Default to mailing all checkgroups messages to the administrator. checkgroups:*:*:mail ## ------------------------------------------------------------------------- ## NEWGROUP/RMGROUP MESSAGES ## ------------------------------------------------------------------------- ## Default (for any group) newgroup:*:*:mail rmgroup:*:*:mail
配置文件 incoming.conf
,用来控制来自外部的喂信(incoming feed);配置文件 newsfeeds
,用来控制本服务器向外部的喂信(outgoing feed)。
配置接收外部新闻服务器喂信非常简单,只需要修改配置文件incoming.conf
即可。注意其中的 peer ME 的设置,不正确的设置,导致不能收到文章。
streaming: true # streaming allowed by default max-connections: 8 # per feed peer ME { hostname: "localhost, 127.0.0.1" }
另外一个要注意的是,配置文件 newsfeeds
中的 ME 项。其中的 distributions 域用于判断允许接收哪些文章,错误设置也可导致无法收到文章。
ME:!*/!local,!collabra-internal::
下面的配置,将限制主机 example.com,不能向本地主机发送 local.* 的文章。
peer remote.example.com { patterns: "*, @local.*" hostname: "remote.example.com, news.example.com" }
只设置了本地服务器的 incoming.conf,还不行,还需要通知上游站点,主动向本服务器喂信。
如果无法通知上游向本地喂信,想要从其它服务器获取新闻消息,可以使用 suck 从上游取信。suck 可以认为是一个 news 客户端,负责从新闻组服务器获取新闻,并可以以各种格式存储,交给 innfeed,innxmit 等inn软件包的程序进一步处理(如投递到本地)。
suck 的下载网址:http://www.sucknews.org/。
中国的网络新闻组发展相对落后,不但和美国没法比,就是和台湾也比不了,比较一下 cn.comp.* 上的新闻数量和 comp.*, tw.* 的发贴数量就看出来了。还有一个问题是,国内的用户量比较大的新闻组,如:新帆、万千等都维护自己独立的新闻组,新闻组名称互不相同,而且不同的服务器之间更没有新闻互转。
我用 suck 实现了将互不相通的新闻组的服务器的新闻收集,归类在本地统一配置的新闻组服务器中,但是没有实现将新闻向外同步,因为本地的一个组可能是外部好多的新闻组汇集而来。
配置步骤
安装 suck
创建 suck 工作目录
因为 suck 要到不同的新闻服务器取信(新闻服务器互不相通),要为每个服务器建立不同的目录。
suck 工作根目录: /usr/local/news/suck,新帆新闻组的工作目录 /usr/local/news/suck/news.newsfan.net,希网网络新闻组的工作目录 /usr/local/news/suck/news.yaako.com,万千新闻组的工作目录 /usr/local/news/suck/news.webking.com.cn,...
$ mkdir -p /usr/local/news/suck/news.newsfan.net/Msgs $ mkdir -p /usr/local/news/suck/news.yaako.com/Msgs $ mkdir -p /usr/local/news/suck/news.webking.com.cn/Msgs
创建运行脚本
/usr/local/news/suck/suck.sh
#!/bin/sh basedir=/usr/local/news/suck/ run=$basedir/get.news.inn for i in `ls $basedir`; do if [ -d $basedir/$i ]; then sh $run $i fi done
脚本:/usr/local/news/suck/get.news.inn
#!/bin/sh #BEFORE USING - check to ensure all the paths defined below are correct!! #NOTE: this script probably needs to be run by root. Most systems will # not let a normal user run ctlinnd REMOTE_HOST=$1 LOCAL_HOST=localhost SPOOLDIR=/usr/local/news/spool # base directory for articles to be rposted NEWSDIR=/usr/local/news # base directory for news binaries BASEDIR=/usr/local/news/suck/$1/ # base directory for scripts and data files CTLINND=${NEWSDIR}/bin/ctlinnd # location of binary SHLOCK=${NEWSDIR}/bin/shlock # location of binary TMPDIR=${BASEDIR} # location for suck.* files MSGDIR=${BASEDIR}/Msgs # where to put MultiFile messages when getting them SITE=$1 # name of site from newsfeeds file OUTGOING=${SPOOLDIR}/outgoing/${SITE} # location of the list of articles to upload OUTGOINGNEW=${OUTGOING}.new # file to contain the list temporarily OUTGOINGFAIL=${OUTGOINGNEW}.fail # file with failed xfers SCRIPT=${BASEDIR}/news.filter # my filter for rpost OUTFILE=/tmp/tmp$$ # used by rpost as article after it is filtered LOCKFILE=${BASEDIR}/getnews.lock # lock file to prevent multiple instances of script NEWSGROUP=news # which group owns the file in out.going, typically either news or uucp. BATCHFILE=${BASEDIR}/suckbatch.xmit TRANSTAB=${BASEDIR}/transtab TESTHOST=/usr/local/bin/testhost RPOST=/usr/local/bin/rpost SUCK=/usr/local/bin/suck INNXMIT=/usr/local/bin/innxmit # if we are already running, abort trap 'rm -f ${LOCKFILE} ; echo "Aborting" ; exit 1' EXIT 1 2 3 15 ${SHLOCK} -p $$ -f ${LOCKFILE} if [ $? -ne 0 ]; then echo "Already running, can't run two at one time" exit fi # is the local host up and running so we can post messages we download? ${TESTHOST} ${LOCAL_HOST} -s LOCAL_RESULT=$? # is the remote host up and running so we can download messages? ${TESTHOST} ${REMOTE_HOST} -s REMOTE_RESULT=$? if [ ${REMOTE_RESULT} -ne 0 ]; then echo "remote server cannot be connected!" exit 1 fi if [ ${LOCAL_RESULT} -ne 0 ]; then echo "local server cannot be connected!" exit 1 fi if [ -f "${BASEDIR}/shutdown" ]; then echo "not update, due to shutdown file exist" exit 0 fi # now upload messages while [ -s $BATCHFILE ] ; do echo "warning: batchfile - $BATCHFILE already exist!" ${INNXMIT} ${LOCAL_HOST} ${BATCHFILE} sleep 10 done # download messages ${SUCK} ${REMOTE_HOST} -c -bi ${BATCHFILE} -dt ${TMPDIR} -dm ${MSGDIR} -dd ${BASEDIR} -HF /usr/local/news/db/history SUCK_STATUS=$? if [ ${SUCK_STATUS} -eq 0 ]; then echo "Downloaded Articles" elif [ ${SUCK_STATUS} -eq 1 ]; then echo "No articles to download" elif [ ${SUCK_STATUS} -eq 2 ]; then echo "Unexpected answer from remote server to an issued command" elif [ ${SUCK_STATUS} -eq 4 ]; then echo "Can't do NNTP authorization" elif [ ${SUCK_STATUS} -eq -1 ]; then echo "General failure" fi # filter messages if [ -f ${TRANSTAB} ]; then for x in `ls ${MSGDIR}`; do x="${MSGDIR}/${x}" header="`grep -m 1 "^Newsgroups:" $x | sed -e 's/^Newsgroups:[ ]*//' -e 's/,/ /g' `" newheader="" if [ -z "$header" ]; then rm -f $x continue fi for y in $header; do value=`grep -m 1 "$y:" $TRANSTAB | awk -F : '{ print $2; }'` if [ "x$value" != "x" ]; then newheader="${newheader},${value}" fi done newheader=${newheader#,} if [ "x$newheader" != "x" ]; then tmpfile=`mktemp /tmp/suck.XXXXXX` sed -e "s/^Newsgroups:.*$/Newsgroups: $newheader/" $x > $tmpfile mv -f $tmpfile $x else rm -f $x fi done fi # now upload messages ${INNXMIT} ${LOCAL_HOST} ${BATCHFILE} if [ ! -f $BATCHFILE ] ; then cd $MSGDIR echo "clear cache" rm -f * fi
在每个新闻组服务器的工作目录下,创建配置文件 sucknewsrc
sucknewsrc 示例: 示例:/usr/local/news/suck/news.newsfan.net/sucknewsrc
计算机.软件.编程 -100 计算机.软件.编程.API -50 计算机.软件.编程.C语言 1 计算机.软件.编程.C语言.BCB 2584 计算机.软件.编程.C语言.C++ 10494 计算机.软件.编程.Perl 1550 计算机.软件.编程.Vc 24864 计算机.软件.病毒 10292 计算机.软件.操作系统 5110 计算机.软件.操作系统.FreeBSD 709 计算机.软件.操作系统.Linux 25333 计算机.软件.操作系统.Linux.常见问题 554 计算机.软件.操作系统.MACOS 473 计算机.软件.操作系统.Unix 1790 计算机.软件.软件工程 1712 计算机.网络.网络安全 11222 计算机.网络.协议.TCPIP 3783 精华信区.计算机 61 精华信区.计算机.软件 43 精华信区.计算机.软件.办公软件 2 精华信区.计算机.软件.编程 27 精华信区.计算机.软件.编程.ASP 38 精华信区.计算机.软件.编程.C语言 14 精华信区.计算机.软件.操作系统 50 精华信区.计算机.软件.数据库 2 精华信区.计算机.软件.图形图像 3 精华信区.计算机.软件.主页制作 8 精华信区.计算机.网络 64 精华信区.计算机.网络.网络安全 61 精华信区.计算机.网络.硬件 8 精华信区.计算机.硬件 150 精华信区.计算机.硬件.故障维修 13 精华信区.精华推荐 292 精华信区.休闲娱乐.讽刺与幽默 116
该文件一次创建,以后 suck 自动维护该文件
在每个新闻组服务器的工作目录下,创建配置文件 transtab
transtab 示例:/usr/local/news/suck/news.newsfan.net/transtab
计算机.软件.编程:cn.comp.lang 计算机.软件.编程.API:cn.comp.lang 计算机.软件.编程.C语言:cn.comp.lang.c 计算机.软件.编程.C语言.BCB:cn.comp.lang.c 计算机.软件.编程.C语言.C++:cn.comp.lang.c 计算机.软件.编程.Perl:cn.comp.lang.perl 计算机.软件.编程.Vc:cn.comp.lang.vc 计算机.软件.病毒:cn.comp.security.virus 计算机.软件.操作系统:cn.comp.os 计算机.软件.操作系统.FreeBSD:cn.comp.os.freebsd 计算机.软件.操作系统.Linux:cn.comp.os.linux 计算机.软件.操作系统.Linux.常见问题:cn.comp.os.linux 计算机.软件.操作系统.MACOS:cn.comp.os.macos 计算机.软件.操作系统.Unix:cn.comp.os.unix 计算机.软件.软件工程:cn.comp.softeng 计算机.网络.网络安全:cn.comp.security 计算机.网络.协议.TCPIP:cn.comp.network 精华信区.休闲娱乐.讽刺与幽默:休闲娱乐.讽刺与幽默
用冒号分隔的新闻组名称对应表,前面是该新闻组实际名称,后面是欲替换的名称。
在 crontab 中加入如下内容,每小时自动同步一次:
40 * * * * /bin/sh /usr/local/news/suck/suck.sh
由配置文件newsfeeds
控制。newsfeeds档案的设定, 算是INN News Server最重要的工作, 也是困难度最高的部份。 innd 靠 newsfeeds 来决定要丢哪些 newsgroups 的 articles 给哪些 site 负责的程序 (nntplink) 或产生批处理, 让其它的程序来转送。
INN newsfeeds档案至少必须定义自己(ME)以及一个喂送下游 Server。
该文件由一系列 feed 项构成。每一个配置项由四个部分构成,用冒号分开。
sitename[/exclude,exclude,...]\ :pattern,pattern...[/distrib,distrib...]\ :flag,flag...\ :param
ME:!*/!local,!collabra-internal::
配置项 ME,是必不可少的一个配置项,有着特殊作用。其 newsgroup pattern 部分(本例为“!*”),将加到所有其它的配置项的 newsgroup pattern 的前面,定义了确省的向外喂信的新闻组列表。亦即定义所有 site, 共同的 pre-subscription list。
而其 distribution pattern 则通过匹配文章头部的 Distribution 域,确定允许接收哪些文章。不过distribution 作为一个限制流传的功能, 很少有人用,已几乎名存实亡。
remote.example.com/news.example.com\ :<newsgroups>\ :Tf,Wnm:
这条配置项,将对匹配的文章的 Message-ID, storage token 写入文件 ~news/spool/outgoing/remote.example.com。crontab 中的配置将会定期根据文件外发数据。
innfeed!\ :!*\ :Tc,Wnm*:/usr/local/news/bin/startinnfeed -y remote.example.com/news.example.com\ :<newsgroups>\ :Tm:innfeed!
funnel feed 示例,注意 innfeed 后面的感叹号。
上例采用 innfeed 向外部服务器 remote.example.com 喂信。正确运行 innfeed 还需要配置文件 innfeed.conf。
对于如何管理文章的存储方式,有四种存储方法,可供选择。
tradspool
在INN 2.0之前就已经使用的存储方式。文章以单独的文件存储,并分布在基于新闻组名的目录中。这种存储方式非常简单,并且很多第三方的INN插件依赖这种存储方式。缺点是效率不高。
timehash
文章也是以单独的文件存储,但是目录名依据文章的时间而确定。这就保障了一个目录下不会存在有过多的文件。缺点是依旧没有解决过多文件操作造成的效率地下,而且文件的存储方式决定了难以像 tradspool 方式那样确定某个新闻组的文章数量和手工修改之。
timecaf
类似于 timehash,文章根据时间分类。不同点是,不再每篇文章一个文件,取而代之的是使用一个文件来存储。缺点是更难以理解和手工修改服务器端的存储结构,而且作为一种新的存储方式,并没有被广泛使用和测试。
cnfs
文章存储在预先定义好的文件缓冲区中,循环使用文件缓冲区,缓冲区满则覆盖前面的文章,因而对于 cnfs 存储方式,文章的过期设置比较特殊,且没有那么重要。
配置文件 storage.conf
:用来配置存储方式。
该配置文件由一个或多个存储配置规则构成。
method <methodname> { class: <storage_class> newsgroups: <wildmat> size: <minsize>[,<maxsize>] expires: <mintime>[,<maxtime>] options: <options> }
修改文件etc/storage.conf
中加入如下内容。
method tradspool { newsgroups: * class: 1 }
tradspool 是最为简单的一种存储方式,我们也可以使用另外一种比较简单,但效率更高的存储方式 timehash。如下:
method timehash { newsgroups: * class: 0 }
还有其它存储方式,如 CNFS 效率更高,但更为复杂。
创建文件 spool/tradspool.map
$ touch spool/tradspool.map
配置文件 expire.ctl
,控制文章的过期设置
全局的设置
/remember/:10
history 文件保持 Message-IDs 的时间。在这段时间内,将不允许相同 Message-IDs 的文章进入,防止重复粘贴。
当 inn.conf 中有配置:groupbaseexpiry: false 时的语法
<storage_class>:<keep>:<default>:<purge>
<storage_class> 是在 storage.conf 中存储配置定义的 class number。
对于普通的文章(没有在头信息中定义 Expires),<default>定义了文章保持的天数。
对于在头信息中定义了 Expires 的文章,<keep>和<purge>有作用。
不管文章头信息中的 Expires 日期,所有文章至少要保持 <keep> 天,并且在 <purge> 天后过期,即使 Expires 定义的时间更长。
如果 <default> 定义为 never,则没有定义 Expires 头信息的普通文章永不过期;
如果 <keep> 定义为 never,则定义了 Expires 头信息的文章永不过期。忽略 <purge> 的配置。
如果 <purge> 定义为 never,则定义了 Expires 头信息的文章永不过期。
当 inn.conf 中有配置:groupbaseexpiry: true 时的语法
<wildmat>:<flag>:<keep>:<default>:<purge>
<wildmat> 匹配新闻组名。注意 <wildmat> 只能有一个表达式,且不能使用 ! 和 @。
<flag> 可以取值为:M(受控), U(非受控), A(任何一种)。
<keep>,<default>,<purge> 的含义和前面的一样。
news expire 的过程:expire 五部曲
expire
扫描 history file, 找出应被 expire 的 article pathname, 写到 /home/inn/log/expire.rm. 此一过程很短, 只要10分钟即可找到10万封该 expire 掉的 article.
expireover
读入 /home/inn/log/expire.rm, 把此档案内所有 entry 位於 overview db 对应之 index 移除.
fastrm
根据 /home/inn/log/expire.rm, 把内含之 pathname 全数移除, 相当於完成: cat /home/inn/log/expire.rm | xargs rm
expired entries in history removed, active renumber,
疑除该 expire 掉 article 的 history entries,
rebuild dbz database (history.pag,.dir)
根据 spool 内 article low/high number 调整 active 的 low/high number.
此过程约数分钟, 此时不接受 nnrp connection request, post request 会延迟.
innstat
run awk -f /home/inn/news/innlog.awk /home/inn/log/news.notice
df spool-dir, overview-dir, newslib-dir, out.going-dir
cat /home/inn/log/errlog
mail result to user usenet.
inncheck 检查的文件有:
active control.ctl expire.ctl incoming.conf inn.conf moderators newsfeeds overview.fmt nntpsend.ctl passwd.nntp
inncheck -v 显示了检查的相近过程:
$ inncheck -v Looking at /usr/local/news/db/active... Looking at /usr/local/news/etc/control.ctl... Looking at /usr/local/news/etc/expire.ctl... Looking at /usr/local/news/etc/incoming.conf... Looking at /usr/local/news/etc/inn.conf... Looking at /usr/local/news/etc/moderators... Looking at /usr/local/news/etc/newsfeeds... ME, done. Looking at /usr/local/news/etc/nntpsend.ctl... Looking at /usr/local/news/etc/overview.fmt... Looking at /usr/local/news/etc/passwd.nntp... Looking at /usr/local/news/etc/readers.conf...
$ ctlinnd newgroup local.announce y johnson.AT.worldhello.net $ ctlinnd newgroup local.test y johnson.AT.worldhello.net ... 修改文件 newsgroups ... $ cat >> db/newsgroups << EOF local.announce Announcement for all. local.test For newbie test. EOF
或者
$ ctlinnd pause 'edit active' $ vi active $ inncheck -v active $ ctlinnd reload 'edit active' $ ctlinnd go 'edit active' ... 修改文件 newsgroups ...
如果只有一两个 newsgroups 要砍, 可直接执行 ctlinnd rmgroup <group-name> 来砍, 如果一次有好几百个 newsgroups 要砍, 请依照以下步骤:
$ ctlinnd pause "removing idle newsgroups" ... 改动 active 文件,删除相应的行 $ ctlinnd reload active "removing idle newsgroups" $ ctlinnd go "removing idle newsgroups"
Outlook Express
新闻组入门,最好用 OE。
Forte Agent
高级用户,可以考虑使用环保产品:Agent。
希网网络
新帆
万千
东方热线
NetFront
Hong Kong LUG
新闻组固然会给沟通带来便利之处,但是也有不足,采用如下方法来增强新闻组,甚至取代新闻组。
无法通过 URL 定位到具体的文章,只能笼统的说在某某版在几月几号有关于这个问题的一篇文章。通过将 News 转换为 Web 存档,可以解决这个难题。 参见:Web Archive Howto。
不能进行检索。没有检索就不能叫做成功的知识管理系统,建立新闻组到网页的存档为建立全文检索准备了条件。 参见:Web Archive Howto。
不能实现内容的推,重要的通知信息,还要经常提醒用户上来查看。邮件列表是一个更好的替代方案。 参见:Maillist Howto。
配置负责,安全性差
配置起来非常麻烦,否则也不会写这么一篇文档专题介绍。再有从安全性考虑,新闻组作为单独的一项服务要开放新的服务端口,增加了网络安全隐患,而邮件列表借助电子邮件,而不再单独开辟端口。
有些信息需要限制在一定的范围内,禁止非授权用户订阅。新闻组的权限配置非常麻烦,而邮件列表则简单的多,只要控制订阅邮件列表的用户名单,限制订阅的用户即可。
如果想要使新闻组和邮件列表协同工作,就涉及到 Mail-News Gateway,即Mail和News的互转。
inn 提供的 perl 脚本 —— mailpost,可以完成邮件到新闻组的转换。配置方法:
配置邮件别名
在 sendmail 的别名文件中加入邮件别名,如:
test: "|/usr/local/news/bin/mailpost -r mailpost local.test"
发往 test 的邮件,将由 mailpost 发到新闻组 local.test。"-d mailpost" 的目的是为文章的信头 Distribution 部分加上 mailpost 以作标记,并在后面的 news2mail 中禁止此类别的新闻以邮件形式外发,防止死循环。
执行 newalias
使邮件别名生效。
如果 sendmail 配置了 smrsh,需要将 mailpost 加入可用程序列表中。
ln -s /usr/local/news/bin/mailpost /usr/adm/sm.bin/
检查 inews 的执行权限
mailpost 脚本通过 inews,执行 post 动作,因此运行 sendmail 的用户需要具有 inews 的执行权限。或者修改 mail 用户(亦可能为其它用户),使之属于 news 组,或者 chmod a+x /usr/local/news/bin/inews。
inn 提供的 perl 脚本 —— news2mail,可以将新闻组文章以邮件方式转发。
new2mail 通过在配置文件 newsfeeds 中,添加相应的 channel feed 实现。还有一个重要的配置文件 news2mail.cf,用来和相应的 channel feed 的地址名匹配,提供相应的邮件地址。
例如:下面的示例,将新闻组:internal.list.linux.kernel ,发往邮件地址:linux-kernel@vger.kernel.org 。
配置文件:newsfeeds
ME:!*:: # ^^ the exclamation mark is absolutely important, because without it everything will be send out to all feeds, # also to the mailing lists (again: EVERYTHING) n2m!:!*:Tc,Ac,Wn*:/usr/lib/news/bin/news2mail #^^^ this entry only once # #the following entry only once per newsgroup, which should be send out via news2mail news-internal.list.linux.kernel@example.com:internal.list.linux.kernel/!mailpost:Tm,Ac:n2m! #^^sender email addresse for outgoing mails ^^the newsgroup ^ ^^ flags # | this is the filter key; every articel which has # | this key in his Distribution: header will not be mailed; # | all news articles that will enter via mailpost # | will have this key in the Distribution: header -> no loop!
配置文件:news2mail.cf
#one entry per newsgroup: news-internal.list.linux.kernel@example.com linux-kernel@vger.kernel.org #^^ sender address ^^ recipient addresse # it is important that the first field of both files is identical (sender)
new2mail 为防止DOS攻击,将邮件排入队列,而不是直接发送。因此邮件发送是否及时,由 sendmail 启动时的 -q 参数决定,或者将 "sendmail -q" 放入 crontab。 但是我在调试过程中,发现以参数 "-odq" 调用 sendmail,邮件队列中没有邮件,邮件发送失败!因此需要修改脚本 news2mail,修改调用 sendmail 的参数。
还有在调试 news2mail 过程中,发现 perl 脚本的 syslog 调用并不能出现预期结果。原因是 syslogd 启动时默认不接收外部的 syslog 事件,导致 perl 的 syslog 调用不能显示。修改文件 /etc/sysconfig/syslog
,加上 '-r' 参数启动 syslogd。
Copyright © 2006 WorldHello 开放文档之源 计划 |