|
|
Dit document is beschikbaar in: English Castellano Deutsch Francais Nederlands Turkce |
door Frédéric Raynal <pappy/at/users.sourceforge.net> Over de auteur: 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).
|
xinetdKort:
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.
|
xinetd levert toegangscontrole mogelijkheden op een manier zoals die ook worden geleverd door tcp_wrapper. De mogelijkheden zijn echter veel groter:
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.
Er zijn enkele signalen die kunnen worden gebruikt om het gedrag van xinetd te veranderen:
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.confHet 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:
defaultsIeder 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:
{
attribute operator value(s)
...
}
only_from = 192.168.1.0/24 192.168.5.0/24 192.168.10.17Iedere 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_nameEr 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.
{
attribute operator value(s)
...
}
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:
|
log_type | xinetd maakt standaard gebruik van syslogd
en dedaemon.info selectie.
|
log_on_success | Verscheidene types informatie kunnen worden gelogd zodra een server start:
|
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:
|
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:
|
wait | Geeft aan hoe de service zich gedraagt met betrekking tot "threads".
Er zijn twee acceptabele waarden:
|
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. |
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.
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 :
nameserver
regel in /etc/resolv.conf
).
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/0dit 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/0Dit 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.1Dit 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/8Een 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 instellingenvan de interne services staan, servers, services, en xadmin beheer van xinetd toe. Later meer hierover.
{
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 = 5disabled = 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
}
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. |
Dit voorbeeld laat zien hoe services gedefinieerd moeten worden:
service ntalkLet 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.
{
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
}
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 ftpHet 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:
{
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)
}
00/9/17@16:47:46: START: ftp-public pid=26861 from=212.198.253.142Het 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.
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)
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/shDit 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.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
service telnetLaten we eens kijken wat er nu gebeurt:
{
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
}
>>telnet charlyIn 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;-)
Trying 192.168.1.1...
Connected to charly.
Escape character is '^]'.
Digital UNIX (sabrina) (ttyp1)
login:
defaults {Voordat je ze activeert moet je enkele voorzorgsmaatregelen nemen:
...
disabled = servers services xadmin
...
}
service xadminDe service xadmin kent 5 commando's:
{
type = INTERNAL UNLISTED
port = 9100
protocol = tcp
socket_type = stream
wait = no
instances = 1
only_from = 192.168.1.1 #charly
}
We hebben alleen de service finger nodig:
service fingerxinetd 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:
{
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
}
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 :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).
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
/var/log/services :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.
Sep 18 17:15:42 charly in.fingerd[28857]: refused connect from 192.168.1.1
Laten we eens samenvatten wat we nu weten:
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.
chroot [options] new_rootDit 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 ftpDus, 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.
{
id = ftp
socket_type = stream
wait = no
user = root
server = /usr/sbin/chroot
server_args = /var/servers/ftp /usr/sbin/in.ftpd -l
}
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
serverpop3
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 :
identd
server op alle clienten zodat je log bestanden
zeer duidelijk zijn (let erop dat niemand de gegevens in identd
kan
veranderen) ;
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
|
Site onderhouden door het LinuxFocus editors team
© Frédéric Raynal, FDL LinuxFocus.org |
Vertaling info:
|
2004-01-03, generated by lfparser version 2.43