=head1 NAME

nnrpd - NNTP server for reader clients

=head1 SYNOPSIS

B<nnrpd> [B<-BDfnoSt>] [B<-4> I<address>] [B<-6> I<address>] [B<-b> I<address>]
[B<-c> I<configfile>] [B<-i> I<initial>] [B<-I> I<instance>]
[B<-p> I<port>] [B<-P> I<prefork>] [B<-r> I<reason>] [B<-s> I<padding>]

=head1 DESCRIPTION

B<nnrpd> is an NNTP server for newsreaders.  It accepts commands on its
standard input and responds on its standard output.  It is normally
invoked by innd(8) with those descriptors attached to a remote client
connection.  B<nnrpd> also supports running as a standalone daemon.

Unlike innd(8), B<nnrpd> supports all NNTP commands for user-oriented
reading and posting.  B<nnrpd> uses the F<readers.conf> file to control
who is authorized to access the Usenet database.

On exit, B<nnrpd> will report usage statistics through syslog(3).

B<nnrpd> is run from B<innd> (the default) or from inetd(8), xinetd(8), or
some equivalent.  As often as not, it is also run as a daemon, with the B<-D>
option, to provide TLS support on a dedicated port.

B<nnrpd> only reads config files (F<readers.conf>, F<inn.conf> and
F<inn-secrets.conf>) when it is spawned.  You can therefore never change the
behaviour of a client that's already connected.  As a new B<nnrpd> process is
spawned for every connection, any changes to these configuration files will be
immediately effective for all new connections.  There's only one exception:
when B<nnrpd> is run as a daemon with the B<-D> option, any configuration
changes in F<inn.conf> won't take effect until B<nnrpd> is restarted.

The F<inn.conf> setting I<nnrpdflags> can be used to pass any of the
options below to instances of B<nnrpd> that are spawned directly from
B<innd>.  Many options only make sense when B<-D> is used, so these
options should not be used with I<nnrpdflags>.  See also the discussion
of I<nnrpdflags> in inn.conf(5).

When I<nnrpdloadlimit> in F<inn.conf> is not C<0>, it will also reject
connections if the load average is greater than that value (typically
C<16>).  B<nnrpd> can also prevent high-volume posters from abusing
your resources.  See the discussion of exponential backoff in inn.conf(5).

B<nnrpd> injects articles into the local server running B<innd> through a
UNIX domain socket, or an INET domain socket if not supported.  If another
server should be used for injection, you can set it with the I<nnrpdposthost>
parameter in F<inn.conf>.  In case authentication credentials are requested
during the injection, B<nnrpd> will use the F<passwd.nntp> file in I<pathetc>.

=head1 OPTIONS

=over 4

=item B<-4> I<address>

The B<-4> parameter instructs B<nnrpd> to bind to the specified IPv4
address when started as a standalone daemon using the B<-D> flag.  This
has to be a valid IPv4 address belonging to an interface of the local
host.  It can also be C<0.0.0.0>, saying to bind to all addresses (this
is the default).

=item B<-6> I<address>

The B<-6> parameter instructs B<nnrpd> to bind to the specified IPv6
address when started as a standalone daemon using the B<-D> flag.  This
has to be a valid IPv6 address belonging to an interface of the local
host.  It can also be C<::0>, saying to bind to all IPv6 addresses.

By default, B<nnrpd> in daemon mode listens to both IPv4 and IPv6
addresses.  With this option, it will listen only to the specified
IPv6 addresses.  On some systems however, a value of C<::0> will cause
it to listen to all IPv4 addresses as well.

=item B<-b> I<address>

Similar to the B<-4> flag.  B<-b> is kept for backwards compatibility.

=item B<-B>

If specified, B<nnrpd> will report login attempts to blacklistd(8)
for automatic blocking after a number of failed attempts.  To use this
flag, the blacklist library must have been found at configure time, or
B<--with-blacklist> specified at configure time.  For more information, see
L<BLACKLISTD SUPPORT> below.

=item B<-c> I<configfile>

By default, B<nnrpd> reads the F<readers.conf> configuration file to determine
how to authenticate connections.  The B<-c> flag specifies an alternate file
for this purpose.  If the file name isn't fully qualified, it is taken to
be relative to I<pathetc> in F<inn.conf>.  (This is useful to have several
instances of B<nnrpd> running on different ports or IP addresses with
different settings.)

=item B<-D>

If specified, this parameter causes B<nnrpd> to operate as a daemon.  That
is, it detaches itself and runs in the background, forking a process for
every connection.  By default, B<nnrpd> listens on the NNTP port (119), so
either innd(8) has to be started on another port or the B<-p> parameter
used.  Note that with this parameter, B<nnrpd> continues running
until killed.  This means that it reads F<inn.conf> once on startup and
never again until restarted.  B<nnrpd> should therefore be restarted if
F<inn.conf> is changed.

When started in daemon mode, B<nnrpd> will write its PID into a file in
the I<pathrun> directory.  The file will be named F<nnrpd.pid> if B<nnrpd>
listens on port 119 (default), or F<nnrpd-%d.pid>, where C<%d> is replaced
with the port that B<nnrpd> is configured to listen on (B<-p> option is
given and its argument is not C<119>).

You may also want to use B<-s> when running B<nnrpd> as a daemon.

=item B<-f>

If specified, B<nnrpd> does not detach itself and runs in the
foreground when started as a standalone daemon using the B<-D> flag.

=item B<-i> I<initial>

Specify an initial command to B<nnrpd>.  When used, I<initial> is taken
as if it were the first command received by B<nnrpd>.  After having
responded, B<nnrpd> will close the connection.

=item B<-I> I<instance>

If specified, I<instance> is used as an additional static portion within
Message-IDs generated by B<nnrpd>, when I<virtualhost> is set in access groups
in F<readers.conf>; typically this option would be used where a cluster of
machines exist with the same virtual hostname and must be disambiguated during
posts.

=item B<-n>

The B<-n> flag turns off resolution of IP addresses to names.  If you
only use IP-based restrictions in F<readers.conf> and can handle IP
addresses in your logs, using this flag may result in some additional
speed.

=item B<-o>

The B<-o> flag causes all articles to be spooled instead of sending
them to innd(8).  B<rnews> with the B<-U> flag should be invoked from
cron on a regular basis to take care of these articles.  This flag is
useful if B<innd> is accepting articles and B<nnrpd> is started
standalone or using inetd(8).

=item B<-p> I<port>

The B<-p> parameter instructs B<nnrpd> to listen on I<port> when
started as a standalone daemon using the B<-D> flag.

=item B<-P> I<prefork>

The B<-P> parameter instructs B<nnrpd> to prefork I<prefork> children
awaiting connections when started as a standalone daemon using the
B<-D> flag.

=item B<-r> I<reason>

If the B<-r> flag is used, then B<nnrpd> will reject the incoming
connection giving I<reason> as the text.  This flag is used by innd(8)
when it is paused or throttled.  I<reason> should be encoded in UTF-8.

=item B<-s> I<padding>

As each command is received from a client, B<nnrpd> tries to change its
C<argv> array containing the process title so that commands like ps(1) will
print out the hostname of the connected client and the command being executed.
To get a full display, the B<-s> flag may be used with a long string as its
argument, which will be overwritten when B<nnrpd> changes its title.

When B<innd> spawns B<nnrpd>, this flag is used with an argument made of 48
spaces.

=item B<-S>

If specified, B<nnrpd> will start a negotiation for a TLS session
as soon as connected.  To use this flag, the OpenSSL SSL and crypto
libraries must have been found at configure time, or B<--with-openssl>
specified at configure time.  For more information on running B<nnrpd>
with TLS support, see L<TLS SUPPORT>.

=item B<-t>

If the B<-t> flag is used, then all client commands and initial
responses will be traced by reporting them in syslog.  This flag is set
by innd(8) under the control of the ctlinnd(8) C<trace> command, and
is toggled upon receipt of a SIGHUP; see signal(2).

=back

=head1 TLS SUPPORT

If INN is built with B<--with-openssl> or if the OpenSSL SSL and crypto
libraries are found at configure time, B<nnrpd> will support news reading
over TLS (also known as SSL).  For clients that use the STARTTLS command,
no special configuration is needed beyond creating a TLS/SSL certificate
for the server.  You should do this in exactly the same way that you
would generate a certificate for a web server.

If you're happy with a self-signed certificate (which will generate
warnings with some news reader clients), you can create and install one in
the default path by running C<make cert> after C<make install> when
installing INN, or by running the following commands:

    umask 077
    openssl req -new -x509 -nodes -out <pathetc>/cert.pem \
        -days 366 -keyout <pathetc>/key.pem
    chown news:news <pathetc>/cert.pem
    chmod 640 <pathetc>/cert.pem
    chown news:news <pathetc>/key.pem
    chmod 600 <pathetc>/key.pem

Replace the paths with something appropriate to your INN installation.
This will create a self-signed certificate that will expire in a year.
The B<openssl> program will ask you a variety of questions about
your organization.  Enter the fully qualified domain name of your news
service (either the server canonical name or a dedicated alias for the
news service) as the name the certificate is for.

You then have to set these F<inn.conf> parameters with the right paths:

    tlscapath:      <pathetc>
    tlscertfile:    <pathetc>/cert.pem
    tlskeyfile:     <pathetc>/key.pem

If you want to use a complete certificate chain, you can directly put
it in I<tlscertfile> (like Apache's I<SSLCertificateFile> directive).
Alternately, you can put a single certificate in I<tlscertfile> and use
I<tlscafile> for additional certificates needed to complete the chain,
like a separate authority root certificate.

More concretely, when using S<Let's Encrypt> certificates, Certbot's
files can be installed as follows:

    tlscapath:      /etc/letsencrypt/live/news.server.com
    tlscertfile:    /etc/letsencrypt/live/news.server.com/fullchain.pem
    tlskeyfile:     /etc/letsencrypt/live/news.server.com/privkey.pem

or:

    tlscapath:      /etc/letsencrypt/live/news.server.com
    tlscafile:      /etc/letsencrypt/live/news.server.com/chain.pem
    tlscertfile:    /etc/letsencrypt/live/news.server.com/cert.pem
    tlskeyfile:     /etc/letsencrypt/live/news.server.com/privkey.pem

Make sure that the permission rights are properly set so that the
news user or the news group can read these directories and files
(typically, he should access F</etc/letsencrypt/live/news.server.com> and
F</etc/letsencrypt/archive/news.server.com> where the real keys are located,
and the private key should not be world-readable).

If you prefer to point to files outside the directory of S<Let's Encrypt>, you
may add a post-renewal hook for S<Let's Encrypt> to copy the generated files
to another location, and give them the expected rights.

There are two common ways for a news client to negotiate a TLS
connection: either via the use of a dedicated port (usually 563)
on which TLS is immediately negotiated upon connection, or via the
now discouraged way (per S<RFC 8143>) to use the STARTTLS command on
the usual NNTP port (119) to dynamically upgrade from unencrypted
to TLS-protected traffic during an NNTP session.  B<innd> does not,
however, know how to listen for connections to that separate port (563).
You will therefore need to arrange for B<nnrpd> to listen on that port
through some other means.  This can be done with the B<-D> flag along
with C<-p 563> and put into your init scripts:

    su news -s /bin/sh -c '<pathbin>/nnrpd -D -p 563 -S'

but the easiest way is probably to add a line like:

    nntps stream tcp nowait news <pathbin>/nnrpd nnrpd -S

to F</etc/inetd.conf> or the equivalent on your system and let B<inetd>
run B<nnrpd>.  (Change the path to B<nnrpd> to match your installation.)
You may need to replace C<nntps> with C<563> if C<nntps> isn't defined in
F</etc/services> on your system.  You may also want to use the lowercase B<-s>
flag with a long string as its argument to see more information about incoming
connections in ps(1) output.

Optionally, you may set the I<tlsciphers>, I<tlsciphers13>,
I<tlscompression>, I<tlseccurve>, I<tlspreferserverciphers>, and
I<tlsprotocols> parameters in F<inn.conf> to fine-tune the behaviour
of the TLS/SSL negotiation whenever a new attack on the TLS protocol
or some supported cipher suite is discovered.

=head1 BLACKLISTD SUPPORT

blacklistd(8) is a FreeBSD/NetBSD daemon for preventing brute force attacks by
blocking attackers after a number of failed login attempts.  When B<nnrpd> is
built with blacklistd support, it will report login attempts to the blacklistd
daemon for potential blocking.

Adding the configuration below to F</etc/blacklistd.conf> under the C<[local]>
section, assuming B<nnrpd> is listening on port 563, would lead to attackers
being blocked for 10 minutes after 5 failed login attempts.

    # adr/mask:port type    proto owner name nfail disable
    563             stream  *     *     *    5     10m

See the blacklistd(8) documentation for more information.

=head1 PROTOCOL DIFFERENCES

B<nnrpd> implements the NNTP commands defined in S<RFC 3977> (NNTP),
S<RFC 4642> updated by S<RFC 8143> (TLS/NNTP), S<RFC 4643> (NNTP
authentication), S<RFC 6048> (NNTP LIST additions) and S<RFC 8054>
(NNTP compression) with the following differences:

=over 4

=item 1.

The XGTITLE [I<wildmat>] command is provided.  This extension is used by
ANU-News and documented in S<RFC 2980>.  It returns a C<282> reply code,
followed by a one-line description of all newsgroups that match the
pattern.  The default is the current group.

Note that LIST NEWSGROUPS should be used instead of XGTITLE.

=item 2.

The XHDR I<header> [I<message-ID>|I<range>] command is implemented.  It
returns a C<221> reply code, followed by specific header fields for the
specified range; the default is to return the data for the current article.
See S<RFC 2980>.

Note that HDR should be used instead of XHDR.

=item 3.

The XOVER [I<range>] command is provided.  It returns a C<224> reply code,
followed by the overview data for the specified range; the default is to
return the data for the current article.  See S<RFC 2980>.

Note that OVER should be used instead of XOVER.

=item 4.

A new command, XPAT I<header> I<message-ID>|I<range> I<pattern>
[I<pattern> ...], is provided.  The first argument is the case-insensitive
name of the header field to be searched.  The second argument is either an
article range or a single message-ID, as specified in S<RFC 2980>.  The third
argument is a I<uwildmat>-style pattern; if there are additional arguments,
they are joined together separated by a single space to form the complete
pattern.  This command is similar to the XHDR command.  It returns a C<221>
response code, followed by the text response of all article numbers that
match the pattern.

=item 5.

A newsgroup name is case-sensitive for B<nnrpd>.

=item 6.

If IHAVE has been advertised, it will not necessarily be advertised for
the entire session (contrary to section 3.4.1 of S<RFC 3977>).  B<nnrpd>
only advertises the IHAVE capability when it is really available.

=item 7.

B<nnrpd> allows a wider syntax for wildmats and ranges (especially C<->
and C<-I<article-number>>).

=item 8.

When keyword generation is used, an experimental feature enabled with the
I<keywords> parameter in F<inn.conf>, C<Keywords:full> is advertised in
LIST OVERVIEW.FMT even though overview information is computed and does not
necessarily come from Keywords header fields.

=back

=head1 HISTORY

Written by Rich $alz <rsalz@uunet.uu.net> for InterNetNews.  Overview
support added by Rob Robertston <rob@violet.berkeley.edu> and Rich in
January, 1993.  Exponential backoff (for posting) added by Dave Hayes in
Febuary 1998.

=head1 SEE ALSO

blacklistd(8), ctlinnd(8), innd(8), inn.conf(5), inn-secrets.conf(5),
libinn_uwildmat(3), nnrpd.track(5), passwd.nntp(5), readers.conf(5),
signal(2).

=cut
