xinetd

ArticleCategory:

System Administration

AuthorImage:

[Frederic Raynal]

TranslationInfo:

Original in fr Fr�d�ric Raynal

fr to en Georges Tarbouriech 

en to nl HJ Heins

AboutTheAuthor:

Fr�d�ric Raynal schrijft een these over het aanbrengen van een watermerk in digitale afbeeldingen aan het INRIA (Institut National de Recherche en Informatique et Automatique).

Abstract

xinetd - eXtended InterNET services daemon - levert goede beveiligingsmogelijkheden tegen indringers en verkleint de kans op de risico's van een Denial of Services (DoS) aanval. Net als het beter bekende paar (inetd+tcpd), geeft xinetd de mogelijkheid om de toegangsrechten voor een machine te configureren, maar xinetd kan nog veel meer. In dit artikel zullen we de vele mogelijkheden leren kennen.

ArticleIllustration

security

ArticleBody

xinetd, Wat is dat?

Het klassieke inetd helpt bij het controleren en instellen van netwerk connecties naar een computer. Wanneer er een aanvraag wordt gedaan aan een poort die beheerd wordt door inetd, stuurt inetd deze door naar een ander programma, geheten tcpd. Tcpd beslist, volgens eerder vastgelegde regels in de hosts.{allow, deny} bestanden, of een aanvraag in behandeling wordt genomen of niet. Als de aanvraag toegestaan is, wordt het server proces dat bij de betreffende poort hoort (bijvoorbeeld ftp bij poort 21), gestart. Dit mechanisme wordt ook wel tcp_wrapper genoemd.

xinetd levert toegangscontrole mogelijkheden op een manier zoals die ook worden geleverd door tcp_wrapper. De mogelijkheden zijn echter veel groter:

Het belangrijkste nadeel is, zoals al gezegd, de slecht ondersteunde RPC aanroepen. Echter, portmap kan blijven bestaan naast xinetd om dit probleem op te lossen.

Het eerste deel van dit artikel legt uit hoe xinetd werkt. We zullen wat uitleggen over service instellingen, enkele specifieke opties noemen (koppelen aan interfaces, verwijzingen...) en dit alles demonstreren met wat voorbeelden. In het tweede deel laten we een werkende xinetd zien, de door hem gegenereerde log bestanden en we eindigen met een handige tip.

Compilatie & Installatie

xinetd kan je op http://www.xinetd.org/ krijgen. Voor dit artikel zullen we versie 2.1.8.9pre10 gebruiken.
De Compilatie en installatie worden op de gebruikelijke manier uitgevoerd: ./configure; make; make install verzorgen alles :) configure ondersteunt de gebruikelijke opties. Er zijn drie speciale opties beschikbaar bij de compilatie:
  1. --with-libwrap: met deze optie controleert xinetd de tcpd instellings- bestanden (/etc/hosts.{allow, deny}) en of toegang wordt toegestaan, daarna gebruikt het z'n eigen controle functies. Om deze optie te kunnen gebruiken, moet tcp_wrapper met z'n bibliotheken geïnstalleerd zijn op de computer. (Opmerking van de Auteur: wat de wrapper kan, kan xinetd ook. Door deze compatibiliteit kunnen er meerdere configuratie bestanden met dezelfde functie bestaan, en dat maakt het beheer lastiger... in het kort moet ik zeggen dat ik het niet aanraadt);
  2. --with-loadavg: deze optie laat xinetd de "max_load" configuratie optie beheren. Deze zorgt ervoor dat enkele services worden gedeactiveerd bij overbelasting van de computer. Dit is een optie die essentieel is bij het voorkomen van DoS aanvallen (controleer het attribuut max_load in tabel 1);
  3. --with-inet6 : waneer je IPv6 wilt gaan gebruiken, ondersteunt deze optie dat. Zowel IPv4 als IPv6 verbindingen kunnen nu worden beheerd, maar IPv4 adressen worden veranderd in IPv6 formaat.
Voordat je xinetd start, hoef je inetd niet te stoppen. Maar het is verstandig om dat wel te doen, daar het anders kan leiden tot onvoorspelbaar gedrag van beide daemons!

Er zijn enkele signalen die kunnen worden gebruikt om het gedrag van xinetd te veranderen:

Er zijn nog enkele andere signalen (we noemen een fout in de documentatie en de man pagina's: SIGHUP schrijft een "dump" naar het bestand /var/run/xinetd.dump en niet naar /tmp/xinetd.dump), maar de drie genoemde signalen kunnen zeer eenvoudig gebruikt worden in een klein script dat de start, stop, herstart en zachte en harde opties beheert ( de laatste twee corresponderen respectievelijk met SIGUSR1 en SIGUSR2).

Configuratie

Het bestand /etc/xinetd.conf is het standaard configuratie bestand voor de xinetd daemon (met behulp van een commandoregel optie kan er een andere locatie worden aangegeven). De xinetd configuratie is niet zo complex, maar het kan veel werk zijn en de syntax is helaas heel anders dan die van z'n voorganger inetd.

Er worden twee gereedschappen (itox en xconv.pl) meegeleverd bij xinetd en die kunnen het /etc/inetd.conf bestand converteren naar een configuratie bestand voor xinetd. Dit is absoluut niet voldoende, aangezien de regels die aangegeven zijn in de wrapper configuratie, niet worden meegenomen. Het itox programma wordt nog steeds onderhouden, maar het wordt niet verder ontwikkeld. Het xconv.pl programma is een betere oplossing, ook al moet de uitvoer nog steeds worden bijgewerkt, aangezien xinetd nog mogelijkheden heeft die inetd niet kent:

>>/usr/local/sbin/xconv.pl < /etc/inetd.conf > /etc/xinetd.conf
Het configuratiebestand begint met een standaard sectie. De attributen in deze sectie zullen worden gebruikt door iedere service die xinetd beheert. Hierna zal je net zoveel secties als er services zijn vinden. Iedere service kan specifieke instellingen in relatie tot de standaard instellingen wijzigen.

De sectie met de standaard instellingen ziet er als volgt uit:

defaults
{
    attribute operator value(s)
    ...
}
Ieder attribuut dat in deze sectie gedefinieerd wordt, heeft de aangegeven waarde voor alle services die daarna worden aangegeven. Dus het only_from attribuut, staat het geven van een lijst van toegestane adressen van machines die mogen inloggen op de servers toe:
only_from = 192.168.1.0/24 192.168.5.0/24 192.168.10.17
Iedere service die hierna wordt aangegeven, staat machines die een adres hebben dat in de lijst staat toe in te loggen. Deze waarden kunnen voor iedere service afzonderlijk worden aangepast (controleer wel de operanden; deze worden even verderop uitgelegd). Dit proces is echter een beetje riskant. Het is in feite, om het makkelijker en veiliger te maken, slimmer om geen standaard waarden aan te geven en ze later binnen een service te veranderen. Als je bijvoorbeeld over toegangsrechten praat, is het eenvoudigste beleid het niet toestaan van toegang aan iedereen en daarna toegang toestaan per service aan degenen die de toegang echt nodig hebben (met tcp_wrapper, wordt dit gedaan met behulp van een hosts.deny bestand dat ALL:ALL@ALL, en een hosts.allow bestand bevat dat alleen geautoriseerde services en adressen toestaat).

Ieder deel beschrijft een service die in het configuratiebestand staat, dat ziet er als volgt uit:

serviceservice_name
{
    attribute operator value(s)
    ...
}
Er zijn drie operanden beschikbaar: '=', '+=' en '-='. De meeste attributen ondersteunen alleen de '=' operand, die gebruikt wordt om een vaste waarde toe te wijzen aan een attribuut. De operand '+=' voegt een item toe aan een lijst met waardes, en de operand '-=' verwijdert dit item.

tabel 1 beschrijft enkele van deze attributen in het kort. We zullen zien hoe ze gebruikt moeten worden met behulp van een aantal voorbeelden. Het lezen van de man pagina's van xinetd.conf geeft nog meer informatie.
 
   

Attribuut Waarden en omschrijving
flags Slechts de huidige waarden worden hier genoemd, bekijk de documentatie voor nieuwere waarden:
  • IDONLY : accepteer alleen verbindingen van clienten die een identificatie server hebben;
  • NORETRY : vermijdt het opnieuw "Forken" van een nieuw proces in geval van een fout;
  • NAMEINARGS : het eerste argument van het attribuut server_args wordt gebruikt als argv[0] voor de server. Dit maakt het mogelijk om tcpd te gebruiken door hem in het server attribuut te plaatsen, daarna kan je de servernaam en z'n argumenten zoals server_args schrijven zoals je dat ook zou doen bij inetd.
log_type xinetd maakt standaard gebruik van syslogd en dedaemon.info selectie.
  • SYSLOG selector [level] : maakt het mogelijk om te kiezen uit daemon, auth, user or local0-7 van syslogd ;
  • FILE [max_size [absolute_max_size]] : het aangegeven bestand ontvangt de gegevens. De twee opties geven de maximale bestandsgrootte aan. Wanneer de maximale grootte bereikt is, stuurt de eerste optie een bericht naar syslogd, en de tweede stopt met loggen voor deze service (wanneer het een gewoon bestand is - of een bestand dat als standaard is ingesteld - kan het hierbij voor meerdere services gelden).
log_on_success Verscheidene types informatie kunnen worden gelogd zodra een server start:
  • PID : De PID van de server (wanneer het een interne xinetd service is, heeft de PID een waarde van 0);
  • HOST : het adres van de client;
  • USERID : de identiteit van de gebruiker die ergens anders zit, volgens het door RFC1413 gedefinieerde identificatie protocol;
  • EXIT : de beëindigings status van het proces;
  • DURATION : de duur van de sessie.
log_on_failure Ook hier kan xinetd zeer veel gegevens loggen zodra een server niet kan opstarten, of dat nu komt door een tekort aan bronnen of vanwege de toegangsrechten:
  • HOST, USERID : zoals hierboven genoemd;
  • ATTEMPT : logt een poging tot toegang. Dit wordt een automatisch ingestelde optie zodra er een andere waarde aan wordt gegeven;
  • RECORD : logt alle informatie die beschikbaar is op de client.
nice Verandert de prioriteits-status van de server zoals het commando nice dat doet.
no_access Geeft een lijst van clienten die geen toegang hebben op deze service.
only_from Geeft een lijst van geautoriseerde clienten. Wanneer dit attribuut geen waarde heeft, wordt de toegang tot de service geweigerd.
port De poort die geassocieerd wordt met de service. Wanneer dit ook is gedefinieerd in het bestand /etc/services, moeten de 2 poortnummers overeenkomen.
protocol Het aangegeven protocul moet bestaan in het bestand /etc/protocols. Wanneer hier geen protocol wordt aangegeven, wordt het standaard protocol van de service gebruikt.
server Het pad naar de server.
server_args Argumenten die voor de server bedoeld zijn.
socket_type stream (TCP), dgram (UDP), raw (IP directe toegang) of seqpacket ().
type xinetd kan 3 typen services beheren:
  1. RPC : voor diegenen die worden gedefinieerd in het /etc/rpc bestand... maar dit werkt niet al te best;
  2. INTERNAL : voor services die direct door xinetd worden beheerd (echo, time, daytime, chargen and discard) ;
  3. UNLISTED : voor services die noch in het bestand /etc/rpc, noch in het bestand /etc/services worden gedefinieerd;
Het valt hierbij op dat het mogelijk is om verschillende waarden te combineren, zoals we zullen zien bij de interne services servers, services en xadmin.
wait Geeft aan hoe de service zich gedraagt met betrekking tot "threads". Er zijn twee acceptabele waarden:
  • yes : de service bestaat uit een "thread", er kan slechts een connectie van dit type worden beheerd door de service;
  • no : xinetd start een nieuwe server voor iedere nieuwe service aanvraag tot aan het gedefinieerde maximum (Let op, standaard staat deze limiet op oneindig).
cps Beperkt het mogelijke aantal inkomende connecties. Het eerste argument is hier het nummer zelf. Wanneer de limiet wordt overschreden, wordt de service voor een bepaalde tijd, aangegeven in seconden, die worden gegeven door het tweede argument, gedeactiveerd.
instances Definieert het maximum aantal servers van een zelfde type dat op eenzelfde moment actief mag zijn.
max_load Deze waarde geeft de maximale belasting voor een server (bijvoorbeeld 2 of 2,5). Wordt deze limiet overschreden, dan worden aanvragen aan de server niet gehonoreerd.
per_source Hetzij een geheel getal of ongelimiteerd is de waarde hier die het aantal verbindingen van eenzelfde bron  aan een server  beperkt.
Tab. 1 : een aantal attributen voor xinetd

De vier laatste atributen die genoemd worden in tabel1 maken het mogelijk om de bronnen per server in te stellen en te beheren. Dit is een zeer effectieve methode om je te verdedigen tegen Denial of Service (DoS) aanvallen (het laten "bevriezen" van een machine door alle bronnen te bezetten)

In dit deel zijn enkele nieuwe xinetd mogelijkheden besproken. Het volgende deel laat zien hoe je deze kan gebruiken en geeft enkele regels om te zorgen dat alles goed werkt.

Toegangscontrole

Zoals we al eerder hebben gezien is het mogelijk om toegang te geven (of te verbieden) op je computer door gebruik te maken van IP adressen. xinetd heeft echter meer mogelijkheden :

Om het geheel enigzins te optimaliseren, is het systeem van de IP adressen duidelijk beter (sneller dus), op die manier kan je het nazoeken van namen van clienten vermijden voor de service. Als je de toegangscontrole wel moet uitvoeren met behulp van namen, dan kan je deze procedure een heel stuk versnellen door lokaal (tenminste een caching) naamserver te draaien. Het is nog beter wanneer je domein "sockets" gebruikt om het opzoeken van namen mogelijk te maken (plaats geen nameserver regel in /etc/resolv.conf).

Service standaard instellingen

De defaults (standaarden) sectie maakt het mogelijk om waarden in te stellen voor enkele attributen (zie de documentatie voor de hele lijst). Enkele van deze attributen (only_from, no_access, log_on_success, log_on_failure, ...) bevatten zowel de waarde die ze is toegekend in deze sectie als degene die aangegeven worden per service.

De standaard instelling om iedereen buiten te sluiten van een machine,  is de eerste stap naar een betrouwbaar veiligheidsbeleid. Daarna kan er per service worden aangegeven wie er toegang heeft. We hebben twee attributen gezien om te toegang tot een machine te beheren, gebaseerd op IP adres: only_from en no_access. We kiezen de tweede optie en schrijven:

no_access = 0.0.0.0/0
dit maakt toegang tot de services volledig onmogelijk. Als je echter iedereen toegang wilt geven echo (ping) bijvoorbeeld, dan zou je het volgende moeten schrijven in de echo service:
only_from = 0.0.0.0/0
Dit is het log bericht dat je krijgt bij deze configuratie:
Sep 17 15:11:12 charly xinetd[26686]: Service=echo-stream: only_from list and no_access list match equally the address 192.168.1.1
Dit houdt in dat de toegangscontrole wordt uitgevoerd door het vergelijken van de lijst met adressen die in beide attributen zit. Zodra het gastadres in beide lijsten voorkomt, wordt de voorkeur gegeven aan degene die het meest specifiek is. Wanneer ze gelijk zijn, zoals in dit geval, kan xinetd niet kiezen en wordt de verbinding geweigerd.  Om dit probleem te vermijden, moet je het volgende schrijven:
only_from = 192.0.0.0/8
Een eenvoudigere oplossing is het controleren van de toegang met behulp van het volgend attribuut:
only_from =
Niets aangeven betekent dat iedere connectie geweigerd wordt :) Daarna geeft iedere service toegang volgens ditzelfde attribuut.

Belangrijk, om niet te zeggen essentieel is het volgende: in het geval dat er helemaal geen toegangsregels zijn (dus noch only_from, noch no_access) voor een bepaalde service (niet in de eigen sectie en niet in de standaard) sectie, dan wordt de toegang tot de service toegestaan!

Hier is een voorbeeld van standaard instellingen:

standaard instellingen
{
  instances       = 15
  log_type        = FILE /var/log/servicelog
  log_on_success  = HOST PID USERID DURATION EXIT
  log_on_failure  = HOST USERID RECORD
  only_from       =
  per_source      = 5

  disabled = shell login exec comsat
  disabled = telnet ftp
  disabled = name uucp tftp
  disabled = finger systat netstat

  #INTERNAL
  disabled = time daytime chargen servers services xadmin

  #RPC
  disabled = rstatd rquotad rusersd sprayd walld
}

van de interne services staan, servers, services, en  xadmin beheer van xinetd toe. Later meer hierover.

Het configureren van een service

Om een service te kunnen configureren, hebben we nodig...niets :) Alles werkt zoals het hoort met standaard instellingen: je hoeft alleen maar de attributen en hun waarden te specificeren om een service te beheren. Dit betekent dat je ofwel een andere waarde moet aangeven ofwel een ander attribuut moet instellen voor een service.

Enkele attributen moeten aanwezig zijn volgens het type service (INTERNAL, UNLISTED of RPC) :
 
 

Attribuut Commentaar
socket-type Iedere service.
user Alleen voor niet INTERNE services
server Alleen voor niet INTERNE services
wait Iedere service.
protocol Iedere RPC service en degenen die niet zijn aangegeven in /etc/services.
rpc_version Iedere RPC service.
rpc_number Iedere RPC service, die niet staat in /etc/rpc.
port Iedere niet RPC service, die niet staat in /etc/services.
Tab. 2: benodigde attributen

Dit voorbeeld laat zien hoe services gedefinieerd moeten worden:

service ntalk
{
  socket_type   = dgram
  wait          = yes
  user          = nobody
  server        = /usr/sbin/in.ntalkd
  only_from     = 192.168.1.0/24
}

service ftp
{
  socket_type  = stream
  wait         = no
  user         = root
  server       = /usr/sbin/in.ftpd
  server_args  = -l
  instances    = 4
  access_times = 7:00-12:30 13:30-21:00
  nice         = 10
  only_from    = 192.168.1.0/24
}

 Let er op dat de services alleen aangesproken worden vanaf het lokale netwerk (192.168.1.0/24). Voor FTP moeten er wat meer restricties worden aangebracht: er mogen slechts vier aanvragen tegelijk worden gedaan en de service is alleen bereikbaar gedurende bepaalde dagdelen.

Port binding: het bind attribuut

Dit attribuut maakt het mogelijk om een service te koppelen aan een specifiek IP adres. Dit is alleen zinvol wanneer een machine minimaal twee netwerk kaarten bezit, bijvoorbeeld bij een computer die deel is van een lokaal netwerk en die met behulp van een andere kaart aan Internet is gekoppeld.

Wanneer een bedrijf bijvoorbeeld een FTP server voor z'n werknemers wil installeren (om bedrijfsgeheime documentatie te kunnen ophalen en lezen). Dit bedrijf wil z'n klanten FTP toegang geven zodat ze bij productinformatie kunnen: bind is gemaakt voor zo'n soort bedrijf :) De oplossing is het aanleggen van twee verschillende FTP services, een die voor iedereen toegankelijk is en een die alleen voor intern gebruik is. xinetd moet echter een verschil maken tussen de twee services: de oplossing hiervoor is het gebruik van het id attribuut. Dit definieert een service op een unieke manier (wanneer deze niet wordt gedefinieerd, wordt voor de waarde de standaard naam van de service gebruikt).

service ftp
{
  id           = ftp-public
  wait         = no
  user         = root
  server       = /usr/sbin/in.ftpd
  server_args  = -l
  instances    = 4
  nice         = 10
  only_from    = 0.0.0.0/0 #staat iedereen toe
  bind         = 212.198.253.142 #het publieke IP adres voor deze server
}

service ftp
{
  id           = ftp-internal
  socket_type  = stream
  wait         = no
  user         = root
  server       = /usr/sbin/in.ftpd
  server_args  = -l
  only_from    = 192.168.1.0/24 #alleen voor intern gebruik
  bind         = 192.168.1.1  #het lokale IP adrss van deze server (charly)
}

Het gebruik van bind maakt het mogelijk om de corresponderende daemon aan te roepen volgens het doel van de pakketten. Bij deze configuratie moet een client op het lokale netwerk het lokale adres van de server opgeven (of de bijbehorende naam) om bij de gegevens te kunnen komen. In het log bestand kan je nu het volgende lezen:
00/9/17@16:47:46: START: ftp-public pid=26861 from=212.198.253.142
00/9/17@16:47:46: EXIT: ftp-public status=0 pid=26861 duration=30(sec)
00/9/17@16:48:19: START: ftp-internal pid=26864 from=192.168.1.1
00/9/17@16:48:19: EXIT: ftp-internal status=0 pid=26864 duration=15(sec)
Het eerste deel wordt gegenereerd door het commando ftp 212.198.253.142, terwijl het tweede deel wordt gegenereerd door het commando van charly aan zichzelf: ftp 192.168.1.1.

Er is dus duidelijk iets fout: Wat gebeurt er wanneer een machine geen twee statische IP adressen heeft? Dit kan gebeuren met ppp verbindingen of wanneer je gebruik maakt van het dhcp protocol. Het ziet er naar uit dat het beter is om de services te koppelen aan de netwerkkaart dan aan adressen. Dit wordt echter nog niet ondersteund door xinetd en het is dan ook een serieus probleem (bijvoorbeeld bij het schrijven van een C module om toegang te verkrijgen tot een netwerkkaart of adres, dat hangt af van het besturingssysteem, en aangezien xinetd onder vele besturingssystemen wordt ondersteund...). Door gebruik te maken van een script kan je dit probleem oplossen:

#!/bin/sh

PUBLIC_ADDRESS=`/sbin/ifconfig $1 | grep "inet addr" | awk '{print $2}'| awk -F: '{print $2}'`
sed s/PUBLIC_ADDRESS/"$PUBLIC_ADDRESS"/g /etc/xinetd.base > /etc/xinetd.conf

Dit script neemt het /etc/xinetd.base bestand dat de gewenste configuratie bevat met als vervanging voor het dynamische adres  PUBLIC_ADDRESS, en veranderd dat in /etc/xinetd.conf, daardoor wordt de string PUBLIC_ADDRESS vervangen door het adres dat hoort bij de betreffende kaart en dat als een argument wordt opgeroepen in het script. De aanroep van het script hangt hierna af van het type verbinding: het is het eenvoudigst om de aanroep toe te voegen aan het correcte ifup-* bestand en dan xinetd opnieuw te starten.

Een service verwijzen naar een andere machine: het redirect attribuut

xinetd kan worden gebruikt als een transparante proxy, tenminste, (zo ongeveer... zoals we later zullen zien) met het verwijs-attribuut. Dit maakt het mogelijk om een service aanvraag door te sturen naar een andere machine op de gewenste poort.
service telnet
{
  flags  = REUSE
  socket_type = stream
  wait  = no
  user  = root
  server = /usr/sbin/in.telnetd
  only_from = 192.168.1.0/24
  redirect = 192.168.1.15 23
}
Laten we eens kijken wat er nu gebeurt:
>>telnet charly
Trying 192.168.1.1...
Connected to charly.
Escape character is '^]'.
 

Digital UNIX (sabrina) (ttyp1)

login:

In eerste instantie lijkt het erop dat er een verbinding tot stand komt op charly, maar het volgende laat zien dat sabrina (een machine met een Alpha processor, met dus "Digital UNIX") de verbinding heeft overgenomen. Dit mechanisme is zowel zeer bruikbaar als gevaarlijk. wanneer je het instelt, moet je de logfunctie aanzetten aan beide kanten van de verbinding. Bovendien wordt voor dit type service het gebruik van een DMZ (de-militarised zone) en een firewall ten sterkste aangeraden;-)

Speciale services

Er bestaan drie services die alleen kunnen draaien onder xinetd. Aangezien deze services niet gevonden kunnen worden in /etc/rpc of /etc/services, moeten ze de UNLISTED flag gebruiken (behalve de INTERNE flag die aangeeft dat ze xinetd services zijn)
  1. servers: geeft informatie over de servers die in gebruik zijn;
  2. services: geeft informatie over de beschikbare services, de door hun gebruikte protocollen en hun poort;
  3. xadmin: combineert de functies van de twee bovenstaanden.
Deze services maken je computer duidelijk kwetsbaarder. aangezien ze belangrijke informatie verschaffen. Op dit moment wordt de toegang tot deze gegevens niet beschermd (door bijvoorbeeld een wachtwoord). Je zou ze alleen moeten gebruiken bij het configureren. Daarna moet je hun gebruik in de standaarden sectie verbieden:
defaults {
  ...
  disabled = servers services xadmin
  ...
}
Voordat je ze activeert moet je enkele voorzorgsmaatregelen nemen:
  1. De machine die xinetd gebruikt moet de enige zijn die een verbinding kan opbouwen met deze services
  2. Beperk het aantal te draaien gevallen van deze services tot 1
  3. Sta alleen toegang toe vanaf de machine die de server draait.
Laten we eens de xadmin service als voorbeeld nemen (de andere twee kunnen op dezelfde manier worden geconfigureerd, behalve het poort nummer ;-) :
service xadmin
{
  type  = INTERNAL UNLISTED
  port  = 9100
  protocol = tcp
  socket_type = stream
  wait  = no
  instances = 1
  only_from = 192.168.1.1  #charly
}
De service xadmin kent 5 commando's:
  1. help ...
  2. show run : net als de servers service, laat dit zien welke servers op dit moment draaien
  3. show avail : net als de services service, laat dit zien welke services beschikbaar zijn (en nog iets meer)
  4. bye of exit ...
Nu je weet dat ze bestaan, moet je ze vergeten ;-) Je kan tests ook zonder deze services uitvoeren. Commando's als (netstat, fuser, lsof, ... laten je weten wat er gebeurt op je machine, zonder dat ze deze kwetsbaar maken zoals bovenstaande services!

Laten we eens wat gaan spelen...

Beginnend met een raadsel

Hier is een kleine oefening voor degenen die het tot hier gered hebben ;-) Allereerst zal ik de, in deze oefening, gebruikte configuratie uitleggen en daarna gaan we proberen om uit te vinden wat er gebeurt en waarom het niet werkt.

We hebben alleen de service finger nodig:

service finger
{
  flags  = REUSE NAMEINARGS
  server = /usr/sbin/tcpd
  server_args = in.fingerd
  socket_type = stream
  wait  = no
  user  = nobody
  only_from = 192.168.1.1  #charly
}
xinetd is niet gecompileerd met de optie --with-libwrap (zie het attribuut server). De standaarden sectie ziet er hetzelfde uit als degen die we al eerder gebruikten: alle toegang op charly wordt geweigerd, het maakt niet waar de verbinding vandaan wordt gelegd. De service finger is echter niet gedeactiveerd:
pappy@charly >> finger pappy@charly
[charly]
pappy@charly >>

pappy@bosley >>  finger pappy@charly
[charly]

pappy@bosley >>


Het lijkt erop dat de aanvraag niet goed verwerkt werd, noch vanaf charly (192.168.1.1), een machine die toegang heeft, noch vanaf bosley (192.168.1.10). Laten we eens kijken nar de log bestanden:

/var/log/servicelog :
00/9/18@17:15:42: START: finger pid=28857 from=192.168.1.1
00/9/18@17:15:47: EXIT: finger status=0 pid=28857 duration=5(sec)
00/9/18@17:15:55: FAIL: finger address from=192.168.1.10
De aanvraag vanaf charly (de eerste twee regels) werkt wel goed, volgens xinetd: de verbinding wordt toegestaan en de aanvraag neemt 5 seconden. De aanvraag van bosley aan de andere kant, wordt geweigerd (FAIL).
Als we kijken naar de instellingen van de service finger, is de server die gebruikt wordt niet echt in.fingerd, maar de service tcp_wrapper tcpd. Het log bestand van de "wrapper" zegt:
/var/log/services :
Sep 18 17:15:42 charly in.fingerd[28857]: refused connect from 192.168.1.1
We zien dat er maar een regel is die overeenkomt met onze twee aanvragen! Die van bosley (de tweede) is onderschept door xinetd, dus het is heel logisch dat je die niet vind in dit log bestand. De geselecteerde regel komt overeen met de aanvraag die xinetd toestond, gestuurd door charly naar charly (de eerste aanvraag): de tijd en de PID komen overeen.

Laten we eens samenvatten wat we nu weten:

  1. xinetd stond de aanvraag toe;
  2. de finger aanvraag loopt via tcpd ;
  3. in.fingerd stond de aanvraag niet toe.
Wat gebeurt er dan? Aangezien xinetd de aanvraag honoreert, wordt deze doorgestuurd naar de aangegeven server (hier is dat tcpd). Maar, tcpd staat deze verbinding niet toe. Nu moeten we kijken naar hosts. {allow,deny}. Het bestand /etc/hosts.deny bevat alleen maar ALL:ALL@ALL, dit geeft aan waarom de aanvraag door de "wrapper" niet wordt gehonoreerd!

Volgens de manier waarop de regels server en server_args worden gedefinieerd, is de "wrapper' nog steeds toegankelijk (banner - er bestaat een attribuut banner in xinetd-, spawn, twist, ...). Onthoud dat de --with-libwrap compilatie optie slechts toegangsrechten controle doet (met behulp van hosts.{allow,deny} bestanden), voordat het proces xinetd start. In dit voorbeeld hebben we gezien dat deze configuratie ons toestaat om de wrapper functies te blijven gebruiken.

Deze overlap van functies kan, als hij al werkt, leiden tot vreemd gedrag. Om xinetd te gebruiken met inetd en portmap, is het veel slimmer om een service met slechts een van deze "super-daemons" te beheren.

Een service "chroot-en"

Er wordt vaak voorgesteld om het werkterrein van services te beperken, of om er een geheel nieuwe omgeving voor te creëren. Het commando chroot maakt het mogelijk om de root-directory voor een commando (of script) te veranderen:
chroot [options] new_root
Dit wordt vaak gedaan om services als bind/DNS of ftp te beveiligen. Om dit gedrag na te bootsen en nog steeds gebruik te kunnen maken van de mogelijkheden van xinetd, moet je chroot instellen als server. Daarna kan je, gebruik maken van andere argumenten met behulp van het attribuut server_args :)
service ftp
{
  id           = ftp
  socket_type  = stream
  wait         = no
  user         = root
  server       = /usr/sbin/chroot
  server_args  = /var/servers/ftp /usr/sbin/in.ftpd -l
}
Dus, zodra er een aanvraag wordt gestuurd naar deze service, is de eerste instructie die wordt gebruikt chroot. Daarna wordt het eerste argument dat wordt verwerkt het eerste van server_args dat is dan de nieuwe root. Tenslotte wordt de server zelf gestart.

Conclusie

Je kan je afvragen je moet kiezen, inetd of xinetd. xinetd levert meer functies, maar het vraagt ook meer configuratie, vooral totdat het standaard wordt meegeleverd bij distributies (dat gebeurt nu al bij de meesten). De meest veilige oplossing is het gebruik van xinetd op machines met toegang voor iedereen (zoals Internet), aangezien dit een betere verdediging biedt. Voor machines binnen een lokaal netwerk is inetd over het algemeen voldoende.


pop3 server

pop3 is kennelijk zeer populair : Ik heb verscheidene e-mails ontvangen met de vraag hoe je dit kan doen met behulp van xinetd. Hier is een voorbeeld-configuratie :

     service pop3
     {
             disable = no
             socket_type             = stream
             wait                    = no
             user                    = root
             server                  = /usr/sbin/ipop3d
     #       log_on_success          += USERID
     #       log_on_failure          += USERID
     }
Je moet natuurlijk je eigen pad voor het server-attribuut invullen.

het gebruik van pop3 via xinetd kan lastig zijn, dat is afhankelijk van de waardes die je gebruikt voor het loggen. Het gebruik van USERID bijvoorbeeld, stuurt een aanvraag van je xinetd naar een identd server die wordt gedraaid door de client van de pop. Als zo'n server niet beschikbaar is, wordt er 30 seconden gewacht op een timeout.

Dus, wanneer iemand z'n e-mail probeert op te halen,moet hij tenminste 30 seconden wachten wanneer er geen identd server antwoordt. Je moet kiezen tussen :

  1. installeer een identd server op alle clienten zodat je log bestanden zeer duidelijk zijn (let erop dat niemand de gegevens in identd kan veranderen) ;
  2. verlaag de kwaliteit van je logs voor die service zodat je gebruikers hun e-mail sneller kunnen krijgen.


Slechte instellingen bij RH7.0, Mandrake 7.2 en misschien nog enkele anderen...

bug 24279 gestuurd naar bugzilla.

Enkele services die ingesteld zijn in /etc/xinetd.d worden niet gedefinieerd in het bestand /etc/services.

[pappy@rootdurum xinetd.d]# grep service *udp
chargen-udp:service chargen-udp
daytime-udp:service daytime-udp
echo-udp:service echo-udp
time-udp:service time

Ik heb een fix aangeleverd... maar de mensen van RH vonden het geen goede oplossing ;-( Ze zeggen dat de fix problemen kan opleveren bij andere gereedschappen zoals chkconfig en ntsysv. Als ik zou moeten kiezen tussen die gereedschappen en xinetd, dan zou ik wel weten wat ik zou kiezen ;-)
Last modified: Wed Feb 28 10:15:27 CET 2001