All documentation from this point on assumes that you have set up the news user on your system as suggested in Installing INN so that the root of your INN installation is ~news/. If you've moved things around with by using the options to configure, you'll need to adjust the instructions to account for that.
All of INN's configuration files are located in ~news/etc. Unless noted otherwise, any files referred to below are in this directory. When you first install INN, samples of each file (containing lots of comments) are installed in ~news/etc; refer to them for concrete examples of everything discussed in this section.
All of INN's configuration files, all of the programs that come with it, and some of its library routines have documentation in the form of man pages. These man pages were installed in ~news/man as part of the INN installation process and are the most complete reference to how INN works. You're strongly encouraged to refer to the man pages frequently while configuring INN, and for quick reference afterwards. Any detailed questions about individual configuration files or the behavior of specific programs should be answered in them. You may want to add ~news/man to your MANPATH environment variable; otherwise, you may have to use a command like:
man -M ~news/man inn.conf
to see the man page for inn.conf (for example).
Before we begin, it is worth mentioning the wildmat pattern matching syntax used in many configuration files. These are simple wildcard matches using the asterisk (*) as the wildcard character, much like the simple wildcard expansion used by Unix shells.
In many cases, wildmat patterns can be specified in a comma-separated list to indicate a list of newsgroups. When used in this fashion, each pattern is checked in turn to see if it matches, and the last pattern in the line that matches the group name is used. Patterns beginning with ! mean to exclude groups matching that pattern. For example:
*, !comp.*, comp.os.*
In this case, we're saying we match everything (*), except that we don't match anything under comp (!comp.*), unless it is actually under the comp.os hierarchy (comp.os.*). This is because non-comp groups will match only the first pattern (so we want them), comp.os groups will match all three patterns (so we want them too, because the third pattern counts in this case), and all other comp groups will match the first and second patterns and will be excluded by the second pattern.
Some uses of wildmat patterns also support ``poison'' patterns (patterns starting with @). These patterns behave just like ! patterns when checked against a single newsgroup name. Where they become special is for articles crossposted to multiple newsgroups; normally, such an article will be considered to match a pattern if any of the newsgroups it is posted to matches the pattern. If any newsgroup the article is posted to matches an expression beginning with @, however, that article will not match the pattern even if other newsgroups to which it was posted match other expressions.
See wildmat(5) for full details on wildmat patterns.
In most INN configuration files, blank lines and lines beginning with a # symbol are considered comments and are ignored. Any deviations from this practice will be noted in the description for that particular file.
The first, and most important file is inn.conf. This file is organized as a series of parameter-value pairs, one per line. The parameter is first, followed by a colon and one or more whitespace characters and the value itself. For some parameters the value is a string or a number; for others it is ``yes'' or ``no.''
inn.conf contains dozens of changeable parameters (see inn.conf(5) for full details), but only a few really need to be edited during normal operation:
Used to set the value of the X-Complaints-To: header which is added to all articles posted locally. The usual value would be something like abuse@example.com or postmaster@example.com. If not specified, the newsmaster email address will be used.
Set this to the name of your organization as you want it to appear in the Organization: header of all articles posted locally. This will be overridden by the value of the ORGANIZATION environment variable (if it exists). If neither this parameter nor the environment variable or set then no Organization: header will be added.
This is the name of your news server as you wish it to appear in the Path: header of all postings which travel through your server (this includes local posts and incoming posts that you forward out to other sites). If no pathhost is specified then the fully-qualified domain name (FQDN) of the machine will be used instead. Please use the FQDN of your server or an alias for your server unless you have a very good reason not to; a future version of the news RFCs may require this.
If set to ``yes'' then INN will support the NEWNEWS command for news readers. This will really kill your server performance if clients use it heavily, so it is strongly suggested that you set this to ``no'' (the default).
The size in kilobytes to use for caching recently used history file entries. Setting this to 0 disables history caching. History caching can greatly increase the number of articles per second that your server is capable of processing. A value of 16384 (16 MB) is a good choice if you can spare the RAM.
If set to ``yes'' (the default), INN will log the IP address of the remote host from which it received an article. If set to ``no'', the trailing Path: header entry is logged instead. If you are using controlchan (see below) and need to process ihave/sendme control messages (this is very, very unlikely, so if you don't know what this means, don't worry about it), make sure you set this to ``no''.
FIXME: Er... why does controlchan have to figure it out from the logs? Can't it retrieve the message and look at the Path header? This doesn't make any sense to me....
If set to a non-negative value (the default is -1), INN (both innd and innfeed) will try to raise the maximum number of open file descriptors to this value when it starts. This may be needed if you have lots of incoming and outgoing feeds. Note that the maximum value for this setting is very operating-system-dependent, and you may have to reconfigure your system (possibly even recompile your kernel) to increase it. See File Descriptor Limits for complete details.
If set to ``yes'', all control messages except for cancels will be ignored by innd so that they can be processed by an external program (controlchan). This is highly recommended, since controlchan will serialize control message processing and prevent your system load from exploding when you get a flood of control messages. The only reason why it isn't enabled by default is that it requires you to set up a special feed in newsfeeds (see below) and requires you to run:
# cd /usr/include # h2ph * sys/*
so that the Sys::Syslog Perl module works correctly. (Otherwise, controlchan will log messages to errlog, which probably isn't what you want.)
Sets the domain name for your server. Normally this is determined automatically by INN, but in some cases it is necessary to set it manually. For example, if you are running NIS on a SunOS system and your hostnames are not fully-qualified (ie, your systems are named xxxx instead of xxxx.example.com) then you will need to use this option to set your domain name manually. If in doubt, leave this option commented out or remove it completely.
There are tons of other possible settings; you may want to read through inn.conf(5) to get a feel for your options. Don't worry if you don't understand the purpose of most of them right now. Some of the settings are only needed for very obscure things, and with more experience running your news server the rest will make more sense.
newsfeeds determines how incoming articles are redistributed to your peers and to other INN processes. newsfeeds is very versatile and contains dozens of options; we will touch on just the basics here. newsfeeds(5) contains more detailed information.
newsfeeds is organized as a series of feed entries. Each feed entry is composed of four fields separated by colons. Entries may span multiple lines by using the backslash (\) to indicate that the next line is a continuation of the current line.
The first field in an entry is the name of the feed. It must be unique, and for feeds to other news servers it is usually set to the actual hostname of the remote server (this makes things easier). The name can optionally be followed by a slash and a comma-separated exclude list. If the feed name or any of the names in the exclude list appear in the Path line of an article, then that article will not be forwarded to the feed as it is assumed that it has passed through that site once already. The exclude list is useful when a news server's hostname is not the same as what it puts in the Path header of its articles, or when you don't want a feed to receive articles from a certain source.
The second field specifies a set of desired newsgroups and distribution lists, given as newsgroup-pattern/distribution-list. The distribution list is not described here; newsfeeds(5) for information (it's not used that frequently in practice). The newsgroup pattern is a wildmat-style pattern list as described above (supporting @).
The third field is a comma-separated list of flags that determine both the type of feed entry and sets certain parameters for the entry. See newsfeeds(5) for information on the flag settings; you can do a surprising amount with them. The three most common patterns, and the ones mainly used for outgoing news feeds to other sites, are Tf,Wnm (to write out a batch file of articles to be sent, suitable for processing by nntpsend and innxmit), Tm (to send the article to a funnel feed, used with innfeed), and Tc,Wnm* (to collect a funnel feed and send it via a channel feed to an external program, used to send articles to innfeed).
The fourth field is a multi-purpose parameter whose meaning depends on the settings of the flags in the third field. To get a feel for it using the examples above, for file feeds (Tf) it's the name of the file to write, for funnel feeds (Tm) it's the name of the feed entry to funnel into, and for channel feeds (Tc) it's the name of the program to run and feed references to articles.
Now that you have a rough idea of the file layout, we'll begin to add the actual feed entries. First we'll set up the special ME entry. This entry is required and serves two purposes: the newsgroup pattern specified here is prepended to the newsgroup list of all other feeds, and the distribution pattern for this entry determines what distributions (from the Distribution: header of incoming articles) are accepted from remote sites by your server. The example in the sample newsfeeds file is a good starting point; if you are going to create a local hierarchy that should not be distributed off of your system, make sure to exclude it from the default subscription pattern.
FIXME: This file originally recommended ME:*,!junk,!local*/!local::, which is considerably different than the current sample newsfeeds file. This should be reconciled....
The ME entry tends to confuse a lot of people, so this point is worth repeating: The newsgroup patterns set the default subscription for outgoing feeds, and the distribution patterns set the acceptable Distribution: header entries for incoming articles. This is confusing enough that it may change in later versions of INN.
There are two basic ways to feed articles to remote sites. The most common for large sites and particularly for transit news servers is innfeed, which sends articles to remote sites in real time (the article goes out to all peers that are supposed to receive it immediately after your server accepts it). For smaller sites, particularly sites where the only outgoing messages will be locally posted articles, it's more common to batch outgoing articles and send them every ten minutes or so from cron using nntpsend and innxmit. Batching gives you more control and tends to be extremely stable and reliable, but it's much slower and can't handle lots of articles well.
Batching outgoing posts is easy to set up; for each peer, add an entry to newsfeeds that looks like:
remote.example.com/news.example.com\ :<newsgroups>\ :Tf,Wnm:
where <newsgroups> is the wildmat pattern for the newsgroups that site wants. In this example, the actual name of the remote site is remote.example.com, but it puts news.example.com in the Path: header. If the remote site puts its actual hostname in the Path: header, you won't need the /news.example.com part.
This entry will cause innd to write out a file in ~news/db/outgoing named remote.example.com and containing the message ID and storage token of each message to send to that site. innxmit knows how to read this format of file and send those articles to the remote site. For information on setting it up to run periodically, see Setting Up the Cron Jobs below.
If instead you want to use innfeed to send outgoing messages (recommended for sites with more than a couple of peers), you need some slightly more complex magic. You still set up a separate entry for each of your peers, but rather than writing out batch files, they all ``funnel'' into a special innfeed entry. That special entry collects all of the separate funnel feeds and sends the data through a special sort of feed to an external program, called a channel feed.
First, the special channel feed entry for innfeed that will collect all the funnel feeds:
innfeed!\ :!*\ :Tc,Wnm*:/usr/local/news/bin/startinnfeed -y
(adjust the path to startinnfeed if you installed it elsewhere). Note that we don't feed this entry any articles directly (its newsgroup pattern is !*). Note also that the name of this entry ends in an exclamation point. This is a standard convention for all special feeds; since the delimiter for the Path: header is !, no site name containing that character can match the name of a real site.
FIXME: The original entry had an S16384 flag as well. Is that desired?
Next, set up entries for each remote site to which you will be feeding articles. All of these entries should be of the form:
remote.example.com/news.example.com\ :<newsgroups>\ :Tm:innfeed!
specifying that they funnel into the innfeed! feed. As in the previous example for batching, remote.example.com is the actual name of the remote peer, news.example.com is what they put in the Path: header (if different than the actual name of the server), and <newsgroups> is the wildmat pattern of newsgroups they want.
Finally, if you set usecontrolchan to ``yes'' in inn.conf, you need to set up an entry for the controlchan program. This entry should look like:
controlchan!\ :!*,control,control.*,!control.cancel\ :Tc,Wnsm:/usr/local/news/bin/controlchan
(modified for the actual path to controlchan if you put it somewhere else). You should be able to just uncomment the example entry in the sample newsfeeds file, making sure the path is correct.
For those of you upgrading from earlier versions of INN, note that the functionality of overchan and crosspost is now incorporated into INN and neither of those programs are necessary (and running them could cause problems). Unfortunately, crosspost currently will not work even with the tradspool storage method.
This file specifies which machines are permitted to connect to your host and feed it articles. Remote servers you peer with should be listed here. Connections from hosts not listed in this file will (if you don't allow readers) be rejected or (if you allow readers) be handed off to nnrpd and checked against the access restrictions in readers.conf.
Start with the sample incoming.conf and, for each remote peer, add an entry like:
peer remote.example.com { }
This uses the default parameters for that feed and allows incoming connections from a machine named remote.example.com. If that peer could be connecting from several different machines, instead use an entry like:
peer remote.example.com { hostname: "remote.example.com, news.example.com" }
This will allow either remote.example.com or news.example.com to feed articles to you. (In general, you should add new peer lines for each separate remote site you peer with, and list multiple host names using the hostname key if one particular remote site uses multiple servers.)
You can restrict the newsgroups a remote site is allowed to send you using the same sort of pattern that newsfeeds uses. For example, if you want to prevent example.com hosts from sending you any articles in the local.* hierarchy (even if they're crossposted to other groups), change the above to:
peer remote.example.com { patterns: "*, @local.*" hostname: "remote.example.com, news.example.com" }
There are various other things you can set, including the maximum number of connections the remote host will be allowed. See incoming.conf(5) for all the details.
Note for those familiar with older versions of INN: This file replaces the old hosts.nntp configuration file.
CNFS stores articles in logical objects called metacycbuffs. Each of the metacycbuffs is in turn composed of one or more physical buffers called cycbuffs. As articles are written to the metacycbuff each article is written to the next cycbuff in the list in a round-robin fashion. This is so that you can distribute the individual cycbuffs across multiple physical disks and balance the load between them.
There are two ways to create your cycbuffs:
Use a raw disk partition (best). This will give you the most speed, but it required that your OS support mmap() on a block device. Solaris supports this, FreeBSD and Linux do not. Also on many PC-based Unixes it is difficult to create more than eight partitions, which may limit your options.
Use a real file on a filesystem. This will be a bit slower than using a raw disk partition, but it should work on any Unix system.
If you're having doubts, use option #2.
Now you need to decide on the sizes of your cycbuffs and metacycbuffs. You'll probably want to separate the heavy-traffic groups (alt.binaries.* and maybe a few other things like *.jobs* and news.lists.filters) into their own metacycbuff so that they don't overrun the server and push out articles on the more useful groups. If you have any local groups that you want to stay around for a while then you should put them in their own metacycbuff as well, so that they don't get pushed out by other traffic. For each metacycbuff, you now need to determine how many cycbuffs will make up the metacycbuff, the size of those cycbuffs and where they will be stored. Some OSs do not support files larger than 2GB which will force all of your cycbuffs to be < 2GB (even if they are stored on raw disk partitions). Linux is known to have this limitation, FreeBSD does not. If in doubt, keep your cycbuffs smaller than 2GB. Also when laying out your cycbuffs, you will want to try to arrange them across as many physical disks as possible (or use a striped disk array and put them all on that).
For each cycbuff you will be creating, add a line to cycbuff.conf like the following:
cycbuff:BUFFNAME:/path/to/buffer:SIZE
BUFFNAME must be unique and must be < 8 characters in length. Something simple like ``BUFF00'', ``BUFF01'', etc. is a decent choice, or you may want to use something that includes the SCSI target and slice number of the partition. SIZE is the buffer size in kilobytes (if you're trying to stay under 2GB, keep your sizes below 2097152).
Now, you need to tell INN how to group your cycbuffs into metacycbuffs. This is similar to creating cycbuff entries:
metacycbuff:BUFFNAME:CYCBUFF,CYCBUFF,CYCBUFF
BUFFNAME is the name of the metacycbuff, and like cycbuff names must be unique and <= 8 characters long. These should be a bit more meaningful than the cycbuff names since they will be used in other config files as well. Try to name them after what will be stored in them; for example, if this metacycbuff will hold alt.binaries postings, ``BINARIES'' would be a good choice. The last part of the entry is a comma-separated list of all of the cycbuffs that should be used to build this metacycbuff. Each cycbuff should only appear in one metacycbuff line, and all metacycbuff lines must occur after all cycbuff lines in the file.
storage.conf determines where incoming articles will be stored (what storage method, and in the case of CNFS, what metacycbuff). Each entry in the file defines a storage class for articles. The first matching storage class is used to store the article; if no storage class matches, INN will reject that article. (This is almost never what you want, so make sure this file ends in a catch-all entry that will match everything.)
A storage class definition looks like this:
method <methodname> { newsgroups: <wildmat> class: <storage_class> size: <minsize>[,<maxsize>] expires: <mintime>[,<maxtime>] options: <options> }
<methodname> is the name of the storage method to use to store articles in this class (``cnfs'', ``timehash'', ``timecaf'', ``tradspool'', or the special method ``trash'' that accepts the article and throws it away).
The first parameter is a wildmat pattern in the same format used by the newsfeeds file, and determines what newsgroups are accepted by this storage class.
The second parameter is a unique number identifying this storage class and should be between 0 and 255. It is used primarily to control article expiration. The easiest way to deal with this parameter is to just number all storage classes in storage.conf sequentially.
The third parameter can be used to accept only articles in a certain size range into this storage class. A <maxsize> of zero (or a missing <maxsize>) means no upper limit (and of course a <minsize> of 0 would mean no lower limit, because an article is always great than zero bytes long). If you don't want to limit the size of articles accepted by this storage class, leave this parameter out entirely.
The fourth parameter you probably don't want to use; it lets you assign storage classes based on the Expires: header of incoming articles. The exact details are in storage.conf(5). It's very easy to use this parameter incorrectly; leave it out entirely unless you've read the man page and know what you're doing.
The fifth parameter is the options parameter. Currently only CNFS uses this field; it should contain the name of the metacycbuff used to store articles in this storage class.
If you're using CNFS exclusively, just create one storage class for each metacycbuff that you have defined (in cycbuff.conf) and set the newsgroups pattern according to what newsgroups should be stored in that buffer.
If you're using timehash or timecaf, the storage class IDs are used to store articles in separate directory trees so that different expiration policies can be applied to each storage class. You will need to divide up your newsgroups based on how long you want to retain articles in those groups, and create a storage class for each such collection of newsgroups. Make note of the storage class IDs you assign as they will be needed when you edit the expire.ctl file a bit later.
This file sets the expiration policy for articles stored on the server. Only one entry is required for all storage classes; it looks like:
/remember/:14
This entry says how long to keep the message IDs for articles that have already expired in the history file so that the server doesn't accept them again. Occasionally, fairly old articles will get regurgitated somewhere and offered to you again, so even after you've expired articles from your spool, you want to keep them around in your history file for a little while to ensure you don't get duplicates.
INN will reject any articles more than a certain number of days old (the artcutoff parameter in inn.conf, defaulting to 14); the number on the /remember/ line should match that.
CNFS makes no further use of expire.ctl, since articles stored in CNFS buffers expire automatically when the buffer runs out of free space. For timehash and timecaf (and currently for tradspool), expire.ctl takes additional entries of the form:
<storage_class>:<keep>:<default>:<purge>
<storage_class> is the number assigned to a storage class in storage.conf. <default> is the number of days to keep normal articles in that storage class (decimal values are allowed). For articles that don't have an Expires: header, those are the only two values that matter. For articles with an Expires: header, the other two values come into play; the date given in the Expires: header of an article will be honored subject to the contraints set by <keep> and <purge>. All articles in this storage class will be kept for at least <keep> days, regardless of their Expires: header, and all articles in this storage class will be expired after <purge> days, even if their Expires: headers specify a longer life.
All three of these fields can also contain the special keyword never. If <default> is never, only articles with explicit Expires: headers will ever be expired. If <keep> is never, even those articles will be kept forever. Setting <purge> to never says to honor Expires: headers even if they specify dates far into the future.
FIXME: The meaning of never in various places isn't fully specified in expire.ctl(5); the above is what I intuitively think it should mean, but it may not match what the code actually does.
Provided that noreader is set to false in inn.conf, any connection from a host that doesn't match an entry in incoming.conf (and any connection from a host that does match such an entry but that then issues a MODE READER command) will be handed off to nnrpd, the part of INN that supports newsreading clients. nnrpd uses readers.conf to determine whether a given connection is allowed to read news, and if so what newsgroups they can read and post to.
There are a variety of fairly complicated things that one can do with readers.conf, things like run external authentication programs that can query RADIUS servers. See readers.conf(5) and the example file for all the gory details. Here's an example of probably the simplest reasonable configuration, one that only allows clients in the example.com domain to read from the server and allows any host in that domain to read and post to all groups:
auth "example.com" { hosts: "example.com, *.example.com" default: "<user>" default-domain: "example.com" }
access "all" { users: "*@example.com" newsgroups: "*" access: "Read Post" }
If you're running a server for one particular domain, want to allow all hosts within that domain to read and post to any group on the server, and want to deny access to anyone outside that domain, just use the above and change example.com in the above to your domain and you're all set. Lots of examples of more complicated things are in the example file.