inn+suck - instalacja.

Rafał Czeczótka, michu@amg.gda.pl

v2.02, 1 listopad 1998


Tekst ten opisuje procedurê instalacji lokalnego serwera news (inn), sposób wymiany postów (suck) oraz metodê kompresji newsów w drodze (ssh). Oryginał tego dokumentu można znaleźæ na stronie www.amg.gda.pl/~michu/linux.html. Zostało użyte kodowanie ISO-8859-2.

1. Wstêp.

1.1 Przedmowa.

Całą treśæ tego dokumentu stanowi opis mojej instalacji duetu suck+inn w systemie RedHat5.1, w oparciu o konkretne pakiety (inn-1.7.2-13 i suck-3.9.4-2). Impulsem do napisania tego tekstu były moje początkowo nieudane próby instalacji oraz nikły odzew na moje posty na grupie pl.comp.os.linux (pewnie jak zwykle moje zapytania zaginêły gdzieś w potoku informacji i zapytañ docierających tu codziennie). Nie mam zamiaru pretendowaæ do miana fachowca od konfiguracji serwerów news (po prostu u mnie już to działa), tym nie mniej mam nadziejê, że opis minimalnej, działającej konfiguracji bêdzie dla kogoś przydatny.

Wszelkie sugestie i poprawki są mile widziane i należy je wysyłaæ pod adres michu@amg.gda.pl.

W tym dokumencie w paru miejscach porównujê inn'a do leafnode'a, którego wcześniej używałem.

1.2 Podziêkowania.

Nastêpujący ludzie przyczynili siê do postania tego dokumentu, taką czy inną drogą, świadomie lub nieświadomie (w kolejności alfabetycznej):

2. Słowo o programach, instalacja i konfiguracja.

2.1 Co to jest inn i suck.

Inn jest to "InterNetNews daemon" czyli program umożliwiający wielu użytkownikom korzystanie z zasobów news.

Suck jest to zasysacz newsów; pośredniczy on w wymianie newsów pomiêdzy dwoma serwerami: naszym i zdalnym (emulując zachowanie normalnego czytnika; protokół wymiany postów pomiêdzy serwerami (wbudowany w inn'a) odbywa siê na trochê innej zasadzie i wymaga specjalnej konfiguracji po obu stronach, czego chcemy uniknąæ).

2.2 Kiedy instalowaæ inn+suck.

Jeśli uważasz, że spełnione są poniższe warunki:

  1. Nudzi Ci siê i potrzebujesz jakiejś odmiany (warunek konieczny, bo przecież tak naprawdê jeśli potrzebujesz lokalnego serwera newsów, to z pewnością wystarczy Ci dużo prostszy w konfiguracji i używaniu leafnode, poza tym ten eksperyment może Ciê kosztowaæ sporo czasu i nadszarpniêtych nerwów),
  2. Z newsów na twoim komputerze korzysta wiêcej niż jeden użytkownik (bo dla jednego usera zupełnie wystarczające jest "rtin -SQ") ewentualnie "twój" komputer służy jako serwer news dla całej sieci (np. w firmie),
  3. Możliwości leafnode'a już Ci nie wystarczają (potrzebujesz killfile'i, różnych ograniczeñ na ściąganą pocztê newsową, ...),
  4. Ściąganie newsów trwa u Ciebie zbyt długo i potrzebujesz ich kompresji,

to znaczy, że powinieneś zainstalowaæ duet inn+suck.

Jeśli już bêdziesz chciał zainstalowaæ to oprogramowanie, to bêdą Ci potrzebne nastêpujące (lub inne wersje) pakiety:

  1. cleanfeed (np. cleanfeed-0.95.5a-1),
  2. inn (np. inn-1.7.2-13, UWAGA: oryginalny pakiet z dystrybucji RH5.1 jest niepoprawny),
  3. perl-MD5 (np. perl-MD5-1.7-2),
  4. suck (np. suck-3.9.4-2).

Ja skorzystałem z niżej wymienionych adresów:

2.3 Wady i zalety tego rozwiązania.

Zalety inn+suck:

  1. Szybki (piekielnie),
  2. Znaczne możliwości (killfile, ...), choæ tu należy raczej patrzeæ na możliwości suck'a (ponieważ dopiero po ściągniêciu pliki są przesyłane do inn'a a jak coś już w całości przeszło przez modem, to moim zdaniem niech już zostanie),
  3. Można tak skonfigurowaæ inn+suck, że newsy są ściągane skompresowane, czyli czas transmisji można skróciæ parokrotnie,
  4. Można grep'owaæ pliki z zawartością grup bez żadnych "skutków ubocznych" (ta uwaga odnosi siê do dużo prostszego leafnode'a, gdzie czas do expire jest liczony od daty ostatniego dostêpu do pliku, wiêc jeśli "to siê zrobiło", to czas ten oczywiście przedłużał siê),
  5. Instalując ten serwer jesteś "wśród najlepszych" (wiêkszośæ dużych serwerów news działa właśnie na inn'ie).

Wady inn+suck:

  1. Dośæ pogmatwana konfiguracja i hermetyczna dokumentacja (przynajmniej na początek) ale ten dokument powstał właśnie aby wyeliminowaæ tê niedogodnośæ,
  2. Pamiêciożernośæ:

2.4 Instalacja i konfiguracja.

Proces instalacji i "konfiguracji" jest prosty (przynajmniej do pierwszego "ruszenia", ale o tym, bez tego wstêpu, przeciêtny zjadacz newsów możne przekonaæ siê dopiero po parodniowych dociekaniach):

  1. Zainstalowaæ inn i suck (i jeszcze parê wymienionych wcześniej drobiazgów),
  2. W pliku "/etc/news/innfeed.conf" usunąæ sekcjê peers,
  3. W pliku "/etc/news/newsfeeds" dodaæ własną sekcjê z feeds, tj.:
    ----- ciach -----
    ...
    news.task.gda.pl\
            :!junk,!test,!to\
            :Tf,Wnm:
    ...
    ----- ciach -----
    
    gdzie news.task.gda.pl to nazwa mojego serwera news, oraz do definicji dystrybucji akceptowanych przez nasz serwer dodaæ polską:
    ----- ciach -----
    ...
    ME\
        :*,@alt.binaries.warez.*,!junk,!control*,!local*,!foo.*\
        /pl,world,usa,na,gnu,bionet,pubnet,u3b,eunet,vmsnet,inet,ddn,k12\
        ::
    ##   ^^ - to jest to pl
    ...
    ----- ciach -----
    
  4. W pliku "/usr/lib/suck/get.news.innxmit" wstawiæ nazwê serwera news (REMOTE_HOST=news.task.gda.pl) oraz "sajtu" (tego samego co w punkcie 3., tj. SITE=news.task.gda.pl),
  5. W suck'u w pliku "/usr/lib/suck/sucknewsrc" zapisaæ wszystkie interesujące nas grupy i numery postów, od których ma siê zacząæ "ściąganie", np.:
    ----- ciach -----
    ...
    pl.comp.ogonki 1
    pl.comp.os.linux 1
    ...
    ----- ciach -----
    
    UWAGA!!! Zaczynając od pierwszego postu jesteśmy narażeni na ściąganie dużej ilości danych a co siê z tym wiąże znaczne koszty. W koñcu i tak zapewne okaże siê, że wiêkszośæ postów jest za stara i zostanie odrzucona przez inn'a. Lepiej wiêc nie zaczynaæ od początku ale od kilku(set) postów wstecz. U mnie 57 grup (w całości) z dostêpem online (ethernet "wpiêty do" TASKu, transfer osiągał 160KB/sec, jednak to było bardziej ograniczenie zdalnego serwera niż łącza) ściągało siê prawie godzinê,
  6. Usunąæ pliki "/etc/cron.daily/inn-cron-rnews" oraz "/etc/cron.hourly/inn-cron-nntpsend" (ich funkcje przejmuje suck),
  7. Teraz możemy już wystartowaæ serwer np. poleceniem "/etc/rc.d/init.d/innd start". Można/trzeba także dodaæ odpowiednie linki do katalogów "/etc/rc.d/rc0-6].d/" (np. poleceniem ntsysv),
  8. Dodaæ grupy do inn'a. Można to zrobiæ rêcznie poleceniem "ctlinnd newgroup nazwa.grupy" lub skorzystaæ z poniższego skryptu:
    ----- ciach -----
    #!/bin/bash
    #
    # Ten skrypt tworzy automatycznie grupy w inn-ie, ktore podales w pliku
    # /usr/lib/suck/sucknewsrc - konfiguracyjnym dla suck-a.
    # UWAGA !!!
    # Wymagany format tego pliku to:
    ############################
    # nazwa.grupy numer.artykulu
    ############################
    #
    # Mozesz podac inna lokalizacje
    SUCK_FILE=/usr/lib/suck/sucknewsrc
    #
    # Podaj sciezke do programu ctlinnd. Skrypt sprobuje sam zgadnac, ale
    # lepiej podaj jak wiesz.
    CTLINND=`which ctlinnd`
    
    cat ${SUCK_FILE} | while read ln; do
            set -e $ln >/dev/null
            ${CTLINND} newgroup $1
            if [ $? -eq 1 ]; then
                    echo Blad podczas zakladania grupy $1 !!!
                    exit
            fi
    done
    ----- ciach -----
    
  9. Aby nie ściągaæ grup "control", "junk", "test" ani "to" (z pewnością nam siê nie przydadzą), musimy stworzyæ plik "/usr/lib/suck/active-ignore":
    ----- ciach -----
    control
    junk
    test
    to
    ----- ciach -----
    
    Oczywiście grup tych nie należy umieszczaæ w pliku "/usr/lib/suck/sucknewsrc",
  10. Wymianê newsów ze zdalnym serwerem inicjujemy skryptem "/usr/lib/suck/get.news.innxmit".

2.5 Kompresja newsów w drodze.

Ponieważ newsy są danymi tekstowymi, wiêc ich kompresja zdecydowanie skraca czas transmisji, dziêki czemu z pewnością zaoszczêdzimy trochê pieniêdzy kosztem naszego operatora telekomunikacyjnego (pieniądze te mogą byæ wysłane do autora powyższego tekstu, za ewentualne straty autor oczywiście nie bierze żadnej odpowiedzialności ;-). Osobiście wydaje mi siê, że przedstawione tu rozwiązanie jest najbardziej naturalne i elastyczne. Nie oznacza to oczywiście, że nie można tego zrobiæ lepiej. Podczas eksperymentów okazało siê także, że zwykłe tunelowanie komunikacji w skompresowanym kanale ssh nie daje oczekiwanych rezultatów, stąd wyniknêła potrzeba wywołania suck'a na zdalnym komputerze (po prostu komunikacja pomiêdzy komputerami jest na tyle duża, że po uwzglêdnieniu opóżnieñ wystêpujących w trakcie transferu, niemal całkowicie niweczony jest efekt zmniejszonej objêtości danych).

Opisując poniższe rozwiązanie zakładam, że masz już poprawnie zainstalowane i skonfigurowane pakiety inn+suck. Aby z niego korzystaæ niezbêdne nam także bêdą:

  1. na domowym komputerze musi byæ zainstalowny klient ssh,
  2. musimy mieæ dostêp do konta na zdalny komputerze z zainstalowanym systemem Unix'opodobnym, podłączony w miarê szybkim łączem stałym do internetu, z zainstalowanym suck'iem oraz uruchomionym demonem ssh.

Pakiety ssh w wersji miêdzynarodowej (te z literką "i" na koñcu) można ściągnąæ z ftp.task.gda.pl/pub/linux/redhat-crypto/i386/. Podczas pisania tego dokumentu najnowszymi wersjami były: ssh-1.2.26-1i, ssh-clients-1.2.26-1i, ssh-extras-1.2.26-1i i ssh-server-1.2.26-1i.

Cała przedstawiona poniżej idea opiera siê na możliwości uruchomienia suck'a na zdalnym komputerze tak, aby wiadomości były wysyłane w postaci strumienia danych, który jest przesyłany w skompresowanym kanale ssh (opcja "-C"). Dopiero później, lokalnie, za pomocą skryptu filter2rnews, strumieñ ten jest dzielony na poszczególne wiadomości, które są wpuszczane za pomocą programu rnews do lokalnego serwera innd.

W tym celu musimy:

  1. Usunąæ z pliku "/usr/lib/suck/get.news.innx" całą sekcjê służącą do wysyłania wiadomości, czyli skrypt ten powinien byæ postaci:
    ----- ciach -----
    #!/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=news.task.gda.pl
    LOCAL_HOST=localhost
    
    SPOOLDIR=/var/spool/news  # base directory for articles to be rposted
    NEWSDIR=/usr/lib/news     # base directory for news binaries 
    BASEDIR=/usr/lib/suck     # 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=news.task.gda.pl       # name of site from newsfeeds file
    
    OUTGOING=${SPOOLDIR}/out.going/${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}/put.news  # 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.
    
    TESTHOST=testhost
    RPOST=rpost
    SUCK=suck
    
    # if we are already running, abort 
    
    trap 'rm -f ${LOCKFILE} ; echo "Aborting" ; exit 1' 1 2 3 15
    ${SHLOCK} -p $$ -f ${LOCKFILE}
    if [ $? -ne 0 ]; then
      echo "Already running, can't run two at one time"
      exit
    fi
    
    # now upload messages
    if [ -s ${OUTGOING}  -o -s ${OUTGOINGNEW} ]; then
      ${TESTHOST} ${REMOTE_HOST} -s
    
      if [ $? -ne 0 ]; then
        echo "Remote posting host not responding"
      else
        if [ ! -s ${OUTGOINGNEW} ]; then
          mv ${OUTGOING} ${OUTGOINGNEW}
          ${CTLINND} flush ${SITE}
        fi
    
        # outgoing messages to post
        ${RPOST} ${REMOTE_HOST} -d -b ${OUTGOINGNEW} -p ${SPOOLDIR} \
            -f \$\$o=${OUTFILE} ${SCRIPT} \$\$i ${OUTFILE}
        ERRLEV=$?
    
        if [ ${ERRLEV} -eq 0 ]; then
          echo "Remotely posted articles"
          rm ${OUTFILE}
        elif [ ${ERRLEV} -eq 1 ]; then
          echo "Error posting a message"
        elif [ ${ERRLEV} -eq 2 ]; then
          echo "Unable to do NNTP authorization with remote server"
        elif [ ${ERRLEV} -eq 3 ]; then
          echo "Unexpected answer from remote server to a command"
          echo "while doing NNTP authorization"
        elif [ ${ERRLEV} -eq -1 ]; then
          echo "Fatal error"
        fi
    
        if [ -f ${OUTGOINGFAIL} ]; then
          mv ${OUTGOINGFAIL} ${OUTGOINGNEW} # so we can re do it
          chown news.${NEWSGROUP} ${OUTGOINGNEW}
          chmod 664 ${OUTGOINGNEW}
        fi
      fi
    fi      
    
    rm -f ${LOCKFILE}
    ----- ciach -----
    
    Oczywiście należy pamiêtaæ o właściwym ustawieniu zmiennych REMOTE_HOST i SITE.
  2. Skopiowaæ z lokalnego katalogu "/usr/lib/suck/" pliki "active-ignore", "suck.killlog", "suckkillfile" oraz "sucknewsrc" do zdalnego katalogu "$HOME/suck/" (jeśli nie jest tam zainstalowany suck, a tamta maszyna ma taką samą architekturê jak nasza, to możemy skopiowaæ tam także program "/usr/bin/suck").
  3. Stworzyæ możliwośæ logowania siê na zdalnym komputerze za pomocą ssh bez użycia hasła (tylko na podstawie znajomości klucza RSA):
    1. wygenerowaæ parê kluczy RSA komendą ssh-keygen (w pass phrase nie podawaæ hasła),
    2. nastêpnie skopiwaæ plik "$HOME/.ssh/identity.pub" na zdalny komputer do pliku "$HOME/.ssh/authorized_keys".
    UWAGA!!! Należy zdawaæ sobie sprawê z tego, że mimo, iż takie rozwiązanie jest o wiele bezpieczniejsze od logowania siê za pomocą hasła, to krytyczną rolê dla bezpieczeñstwa odgrywa tutaj nie ujawnianie zawartości pliku "$HOME/.ssh/identity", czyli prywatnej połowy klucza. Istnieje także rozwiązanie umożliwiające wygenerowanie klucza z hasłem i podawanie go tylko raz na sesjê (patrz program ssh-agent).
  4. Utworzyæ skrypt "/usr/local/bin/filter2rnews":
    ----- ciach -----
    #!/usr/bin/perl -w
    
    while (not eof(STDIN)) {
        @POST = "";
        do {
            $linia = <>;
            push @POST, $linia if $linia !~ /^\.$/;
        } until ($linia =~ /^\.$/);
        $dlug = length(join('',@POST));
        print "#! rnews $dlug\n";
        print @POST;
    }
    ----- ciach -----
    
  5. Po dokonaniu wszystkich powyższych kroków możemy już pobieraæ newsy komendą:
    ----- ciach -----
    ssh -C -l username serwer.name \
      '~/suck/suck news.task.gda.pl -dd ~/suck -dt ~/suck -M -c' | \
      filter2rnews | rnews -N -vvv -S localhost
    ----- ciach -----
    
    gdzie username to nazwa użytkownika na komputerze serwer.name a news.task.gda.pl jest nazwą naszego serwera news. Wiadomości wysyłamy tak jak poprzednio, czyli za pomocą skryptu "/usr/lib/suck/get.news.innxmit".

2.6 Uwagi i kruczki.

  1. Usuwanie grup odbywa siê przez "ctlinnd rmgroup nazwa.grupy" (jeśli wywołujemy suck'a lokalnie, to on sam usunie taką grupê z pliku sucknewsrc, jeśli zdalnie (patrz kompresja) to musimy to zrobiæ rêcznie),
    UWAGA!!! Nie należy usuwaæ grup "control", "junk", "test" ani "to", inn bardzo źle to znosi.
  2. Opisy grup można dodawaæ w pliku "/var/lib/news/newsgroups", np.:
    ----- ciach -----
    ...
    pl.comp.ogonki O polskich literkach w komputerach.
    pl.comp.os.linux Linux - system operacyjny dla kazdego.
    ...
    ----- ciach -----
    
  3. Dane o przeterminowaniach są w pliku "/etc/news/expire.ctl", usuwanie przeterminowanych postów można wymusiæ uruchamiając skrypt "/etc/cron.daily/inn-cron-expire" (przecież nie każdy ma włączony komputer całą dobê).
  4. Wyłączenie odrzucania artykułów przez innd (już to przecież robi suck) dokonuje siê komendą "ctlinnd perl n".
  5. Aby usunąæ limit linii dla postów ściągniêtych przez inn'a (już po zaakceptowaniu przez suck'a) należy dodaæ w pliku "/etc/rc.d/rc.news" do opcji FLAGS flagê "-l0".
  6. Jeśli podczas ściągania newsów pojawi siê komunikat "GROUP command not recognized, try the -M option" oczywiście dodaj w pliku "/usr/lib/suck/get.news.innxmit" opcjê "-M" do wywołania suck'a.
  7. Od czasu do czasu można wyczyściæ skrytkê pocztową użytkownika news np. z konta root'a komendą "su - news -c pine".
  8. W pliku "/etc/news/inn.conf" możemy zmieniæ parametry "organization" (bo napis "A poorly-installed InterNetNews site" w postach wygląda nieelegancko) oraz ustawiæ "pathhost" (ułatwia czytanie logów).
  9. Sprawdzenie kolejki postów wychodzących można dokonaæ poniższym skryptem (jest to przerobiony skrypt newsq z pakietu leafnode):
    ----- ciach -----
    #!/usr/bin/perl
    
    $spooldir = "/var/spool/news";
    
    if ( chdir "$spooldir/out.going" && opendir( DIR, "." ) ) {
        @sites = readdir( DIR );
        closedir( DIR );
    
        foreach (@sites) {
            if ( open(F, "< $_") ) {
                while(<F>) { 
                    push @posts, (split)[0];
                }
                close F;
            }
        }
    
        undef $/;
        foreach (@posts) {
            if ( open(F, "< $spooldir/$_") ) {
                undef $subject, $newsgroups, $from;
                $_ = <F>;
                close F;
                s/\n\n.*//s;
                s/\r//gs;
                s/\n\s+/ /sg;
                foreach ( split( /\n/, $_ ) ) {
                    $subject = $1 if ( /^Subject:\s+(.*)/i );
                    $newsgroups = $1 if ( /^Newsgroups:\s+(.*)/i );
                    $from = $1 if ( /^From:\s+(.*)/i );
                }
                print $from, " in ", $newsgroups, "\n\t", $subject, "\n", 
                    if ( $subject ne "" && $from ne "" && $newsgroups ne "" );
            }
        }
    }
    ----- ciach -----
    
  10. Jeśli suck odsyła ściągniête posty z powrotem do zdalnego serwera, to możemy zmieniæ sekcjê feeds w pliku "/etc/news/newsfeeds" w nastêpujący sposób:
    ----- ciach -----
    ...
    news.task.gda.pl/news.task.gda.pl\
            :!junk,!test,!to\
            :Tf,Wnm:
    ...
    ----- ciach -----
    
    UWAGA!!! Nie jestem przekonany do tego rozwiązania, ale podobno działa (w każdym razie komuś taki wpis rozwiązał problem).
  11. Jeśli zobaczymy na ekranie napis typu:
    ----- ciach -----
    ...
    stdin: rejected 437 Unwanted newsgroup "pl.rec.radio" [Path:\
    news.task.gda.pl!orion.cst.tpsa.pl...]
    ...
    ----- ciach -----
    
    nie należy wpadaæ w panikê. Najprawdopodobniej jest to wynik błêdu w zdalnym inn'ie (wersja 2.1) związanego z bazami overview.

3. Prawa autorskie/legalnośæ.

Prawa autorskie należą do (C) Rafała Czeczótki michu@amg.gda.pl. Dokument ten jest rozpowszechniany na podstawie GPL (Gnu Public License).

Znaki towarowe należą do ich właścicieli. Nie ma żadnych gwarancji co do dokładności czy przydatności informacji zawartych w tym dokumencie.