Newsgroup: it.comp.os.linux.sys
Titolo: xinetd + openssl problema bizzarro

Salve a tutti, porgo un quesito nella speranza che qualche malcapitato 
si sia già imbattuto in errori simili e sia riuscito a risolverli con 
qualche hack
 
 
Ho preparato uno script ocspserver.sh
 
#!/bin/bash
/usr/bin/openssl ocsp -index /../index.txt \
	-port 2560 \
	-CA /../cacert.pem \
         -rsigner /../cacert.pem \
         -rkey /../cakey-nopass.pem \
         -text
 
Sorvoliamo sul fatto che ca/rsigner sono la stessa cosa e rkey non è 
crittata è solo a scopo di test
 
lancio da shell e ottengo come prevedibile
 
  ./ocspserver.sh
Waiting for OCSP client connections...
 
verifico con lsof |grep *:ocsp
 
openssl 11690 root  3u  IPv4  39342 TCP *:ocsp (LISTEN)
 
ok, quindi da host *esterno* lancio ./ocspverify.sh
 
#!/bin/bash
openssl ocsp -issuer cacert.pem \
	-nonce \
	-CAfile cacert.pem \
	-cert 25.pem \
	-url http://..../ \
	-resp_text
 
e ottengo la risposta corretta
 
...
Zml6MXxEd7az/9+u5vzekI8Tr+1/+hVUqCZntDWC4wcNBRMzReLn6EkFmn6MHTMi
F7ISiWrHHXRbRHO2Mn3cmsrH0WOHiizUPGFOUx5I19dJEsFcRkyzElsBvt6ZaJR6
RL1Kq+FnKkSJIs+GDFde/3FMKlaR
-----END CERTIFICATE-----
Response verify OK
25.pem: revoked
	This Update: Nov 24 08:40:22 2011 GMT
	Reason: keyCompromise
	Revocation Time: Nov 15 01:18:15 2011 GMT
 
al ché procedo lato server ad inserire lo script in xinetd
 
service ocsp
{
	disable	= no
	socket_type	= stream
	wait		= no
	user		= root
	server		= /../ocspserver.sh
	log_type	= FILE /var/log/ocspd
	log_on_success  = PID HOST EXIT
	log_on_failure  += USERID
}
 
riavvio xinetd, verifico /var/log/messages
xinetd Version 2.3.14 started with libwrap loadavg labeled-networking 
options compiled in.
 
Started working: 1 available service
 
faccio un lsof |grep *:ocsp
xinetd 11797 root 5u IPv4 39801 TCP *:ocsp (LISTEN)
 
quindi torno sull'host esterno (sempre quello di prima)
 
ri-lancio ./ocspverify.sh
 
ma questa volta anziché funzionare
 
Error querying OCSP responsder
 
Ogni suggerimento è ben accetto ovviamente.
 
 
 
 
 
 
 
 
 
 
 
 

Ogni suggerimento è ben accetto ovviamente.
 
Verifica che il path di quello che hai in ocspserver.sh sia accessibile
al PATH di xinetd. Eventualmente guarda il log di xinetd, oppure fai un
 
	telnet HOST 2560
 
lasciandolo fermo in modo che si impicchi e sul server, con pstree, vai
a verificare cosa parte con e senza xinetd.
 
Cosi' senza sforzarmici, scommetterei su una diversita' del PATH.
 
Leonardo
 
-- 
Tell us whether you spy, in the light of the morn,
what saluted was fiercely at the fall of the past day:
whose pips and whose bands in the very heart of the fray
bravely floated from the bulwarks to which we were sworn?


 
Allora ti aggiorno, ho aggiunto /opt al path nel file /etc/init.d/xinetd
 
che ora è PATH=/sbin:/bin:/usr/bin:/usr/sbin:/opt
 
spostato lo script e tutti i cert in /opt
 
cat /opt/ocspserver.sh
 
#!/bin/bash
/usr/bin/openssl ocsp -index /opt/index.txt -port 2560 -CA 
/opt/cacert.pem -rsigner /opt/cacert.pem -rkey /opt/cakey-nopass.pem -text
 
riadattato /etc/xinet.d/ocsp
 
service ocsp
{
	disable	= no
	socket_type	= stream
	wait		= no
	user		= root
	server		= /opt/ocspserver.sh
	log_type	= FILE /var/log/ocspd
	log_on_success  = PID HOST EXIT
	log_on_failure  += USERID
}
 
ritestato il tutto, ma lanciando da shell funziona,
se mi connetto via telnet
 
telnet 192.168.1.12 2560
Trying 192.168.1.12...
Connected to ocsp.xxx.xxx.
Escape character is '^]'.
 
pstree mi da
 
├─sshd─┬─sshd───bash───pstree
        └─sshd───bash───ocspserver.sh───openssl
├─syslogd
├─udevd
├─watchdog/0
└─yum-updatesd
 
ma non mi è chiaro cosa intendi per *lasciare fermo* dato che
a questo punto se avvio xinetd ottengo ovviamente
 
bind failed (Address already in use (errno = 98)). service = ocsp
Service ocsp failed to start and is deactivated.
 
se lo killo per riavviare xinetd ovviamente sul terminale mi apparità
 
Connection closed by foreign host.
 
Comunque, se rilancio xinetd e pstree
├─sshd─┬─sshd───bash───tail
│      └─sshd───bash───pstree
├─syslogd
├─udevd
├─watchdog/0
├─xinetd
└─yum-updatesd
 
e di la
telnet 192.168.1.12 2560
Trying 192.168.1.12...
telnet: connect to address 
192.168.1.12
: Connection refused
telnet: Unable to connect to remote host
 
Il ché di conferma sostanzialmente ciò che già sapevamo.
 
Sfortunatamente i log di xinetd non risultano particolarmente utili
 
 
 
 
 
 
 
 

Escape character is '^]'.
 
Okay... apparentemente allora è proprio il "dialogo" con openssl che non
funziona. Forse nello script puoi provare ad aggiungere
 
	2> /tmp/openssl-stderr.log
 
nella speranza che dica qualcosa.
 
Non mi pare che xinetd abbia problemi a collegarsi a stdin/stdout di uno
script bash.
 
Come altra prova, cambiare "openssl" nel server script con uno strace di
quello stesso openssl, ridiretta su un file. E confrontare lo script che
parte da shell con quello da xinetd.
 
Misteriosa, 'sta cosa. Se mi c'entra, ci provo anch'io stasera...


 parte da shell con quello da xinetd.
 
ora indago meglio poi vi aggiorno


 parte da shell con quello da xinetd.
 
caso 1 lanciando senza xinetd
##############################
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(2560), 
sin_addr=inet_addr("0.0.0.0")}, 16) = 0
listen(3, 128)                          = 0
open("/opt/cacert.pem", O_RDONLY|O_LARGEFILE) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=3443, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 
0) = 0xb7f88000
read(4, "Certificate:\n    Data:\n        V"..., 4096) = 3443
close(4)                                = 0
munmap(0xb7f88000, 4096)                = 0
open("/opt/cacert.pem", O_RDONLY|O_LARGEFILE) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=3443, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 
0) = 0xb7f88000
read(4, "Certificate:\n    Data:\n        V"..., 4096) = 3443
close(4)                                = 0
munmap(0xb7f88000, 4096)                = 0
open("/opt/cakey-nopass.pem", O_RDONLY|O_LARGEFILE) = 4
fstat64(4, {st_mode=S_IFREG|0644, st_size=887, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 
0) = 0xb7f88000
read(4, "-----BEGIN RSA PRIVATE KEY-----\n"..., 4096) = 887
close(4)                                = 0
munmap(0xb7f88000, 4096)                = 0
write(2, "Waiting for OCSP client connecti"..., 39Waiting for OCSP 
client connections...
) = 39
accept(3, 0x2d26b0, [16])               = ? ERESTARTSYS (To be restarted)
################################
 
lanciandolo da xinetd
 
###############################
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(2560), 
sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EADDRINUSE (Address already in use)
close(3)                                = 0
write(2, "Error setting up accept BIO\n", 28Error setting up accept BIO
) = 28
write(2, "10338:error:02006062:system libr"..., 
8910338:error:02006062:system library:bind:Address already in 
use:b_sock.c:677:port='2560'
) = 89
write(2, "10338:error:20069075:BIO routine"..., 
9210338:error:20069075:BIO routines:BIO_get_accept_socket:unable to bind 
socket:b_sock.c:679:
) = 92
exit_group(1)                           = ?
##################################
 
Quindi pare che xinetd lanci una prima istanza che apre la porta, ma 
quando l'utente tenta di connettersi xinetd lanci una seconda istanza 
che ovviamente non parte perché la porta è già impegnata dalla 
precedente giusto?
 

 Ogni suggerimento è ben accetto ovviamente.
 
  Io proverei a mettere wait = yes per vedere se il servizio funziona in
modalità single-thread.  In modalità multi-threaded xinetd accetta sempre le
connessioni per il server, mentre in modalità single-thread è solo il server
a farlo.  Potrebbe essere che lasciar gestire le connessioni a ocspserver.sh
possa cambiare le cose.
 
 
  Ciao,
 
 
-- 
Alessandro Selli, 
http://alessandro.route-add.net
 
AVVERTENZA: i messaggi inviati a "trappola" non mi arriveranno.
WARNING: messages sent to "trappola" will never reach me.
Chiave PGP/GPG: EC885A8B

Il ché mi pare assurdo francamente.
 
Aaaah. Ma allora è logico: NON PUOI lanciare da xinetd un processo che fa
la daemonizzazione per conto proprio.
 
Xinetd serve per rendere daemon uno script che comunica via stdin/stdout.
 
Mi scuso - avrei dovuto leggere e riflettere con piu' attenzione. La cosa
era ovvia fin dal primo messaggio: una opzione "-port 2560" dentro ad uno
script con xinetd si classificava come clue-by-four :-)


 script con xinetd si classificava come clue-by-four :-)
 
  'Azz!  Come stare a cercare gli occhiali avendoli sopra la fronte!  :-/


 script con xinetd si classificava come clue-by-four :-)
 
Punti di vista?
 
The xinetd daemon is a TCP-wrapped super service which controls access 
to a subset of popu- lar network services, including FTP, IMAP, and 
Telnet. It also provides service-specific configur- ation options for 
access control, enhanced logging, binding, redirection, and resource 
utilization control.
When a client attempts to connect to a network service controlled by 
xinetd, the super service receives the request and checks for any TCP 
Wrappers access control rules.
If access is allowed, xinetd verifies that the connection is allowed 
under its own access rules for that service. It also checks that the 
service can have more resources allotted to it and that it is not in 
breach of any defined rules.
If all these conditions are met (that is, access is allowed to the 
service; the service has not reached its resource limit; and the service 
is not in breach of any defined rule), xinetd then starts an instance of 
the requested service and passes control of the connection to it. After 
the connection has been established, xinetd takes no further part in the 
communication between the client and the server. ;-)
 

of the connection to it.
 
Come fa a passargli il controllo della connessione? Facendo un bind degli
standard stream sul socket. Fatto questo, se ne lava le mani. Il servizio
addirittura potrebbe non saper gestire il networking... potrebbe non aver
idea che esistono le reti.
 
http://en.wikipedia.org/wiki/Inetd#Function
 
 
"Furthermore, no network code is required in the application-specific
daemons, as inetd hooks the sockets directly to stdin, stdout and stderr
of the spawned process"
 
Naturalmente, se lo "spawned process" e' ESSO STESSO UN SERVER, che usa i
socket... e la stessa porta di xinetd... si verifica un conflitto.
 
Quel che vuoi fare tu si fa creando un init-script che lanci il server, e
non passando da xinetd.
 
Ho cercato se openssl puo' operare in modalita' stdin/stdout, ma *sembra*
di no, o prende -port o prende -url. Questo escluderebbe xinetd.


 addirittura potrebbe non saper gestire il networking...
 
  Infatti.  Un caso tipico:
 
# default: on
# description: Quote Of The Day
service qotd
{
        socket_type     = stream
        wait            = no
        user            = root
        log_on_success  += USERID
        log_on_failure  += USERID
        server          = /usr/bin/fortune
        server_args     = -a
        disable         = no
        flags           = IDONLY
}
 
  "fortune" non è molto bravo con il networking... :-)


>> la daemonizzazione per conto proprio.
 
Illustrissimo Dott. Serni, non so in quale ambiente sia abituato ad 
operare ma da che ricordo io, Red Hat ha sempre utilizzato xinetd per 
lanciare alcuni demoni quali WSFtpd poi sostituito da ProFTPD, vecchi 
sistemi POP3 (ipop3d) e IMAP, noché Telnet per consentire il 
funzionamento del TCP wrapper (/etc/host.allow /etc/host.deny)
 
In rete googlando troverà abbondante documentazione in merito
 
Posso solo ipotizzare che nel suo ambiente xinetd sia compilato in modo 
diverso, non conosco tutti gli Unix like sul mercato ma certamente in 
RH/CentOS funziona così.

 funzionamento del TCP wrapper (/etc/host.allow /etc/host.deny)
 
Sono tutti software pensati e progettati per funzionare sia standalone 
che da (x)inetd. A volte con un flag in compilazione, altre (quasi tutte) 
con uno switch all'avvio.
 
Se openssl non lo permette, sei del gatto. :)
 
Bye.

 Leonardo
 
Forse è semplicemente perché le funzionalità di demone della sezione 
ocsp sono scritte per puro scopo di test e vanno migliorate.
 

RH/CentOS funziona così.
 
Temo di dovermi dire in disaccordo.
 
In effetti, anzi, se andiamo a controllare i sorgenti di xinetd sul
sito ufficiale - il file che ci interessa e' questo
 
http://www.xinetd.org/cgi-bin/cvsweb.cgi/xinetd/xinetd/child.c?rev=1.9&content-type=text/x-cvsweb-markup
 
 
...nella funzione exec_server, il servizio appena forkato riceve un
file descriptor relativo al socket, e fa questo:
 
   for ( fd = 0 ; fd <= MAX_PASS_FD ; fd++ )
   {
      if ( dup2( descriptor, fd ) == -1 )
      {
         msg_resume();
         msg( LOG_ERR, func,
               "dup2( %d, %d ) failed: %m", descriptor, fd ) ;
         _exit( 1 ) ;
      }
   }
 
...essendo MAX_PASS_FD pari a 2, significa che i descrittori 0, 1 e
2 per il servizio che sta per andare in execv sono in realta' alias
di "descriptor". Non chiude i fd: li rimappa. E se non ci riesce lo
considera addirittura un errore fatale.
 
Questa sezione del codice non e' condizionale: comunque compilato e
in qualsiasi distribuzione, il comportamento sara' identico.
 
E i descrittori 0, 1 e 2 sono appunto stdin, stdout e stderr.


ocsp sono scritte per puro scopo di test e vanno migliorate.
 
Questa è senz'altro la strada migliore... ma non c'e' altro che supporti
il protocollo OCSP?


 il protocollo OCSP?
 
Oddio, ci sarebbe Red Hat Certificate System.. ma sarebbe come impegnare 
l'intera flotta navale degli Stati Uniti per affondare un canotto.
 
Ci sarebbe OCSPD di OpenCA (che non ho mai testato a dire il vero) ma 
sapendo come lavorano da quelle parti la cosa mi inpensierisce.
 
Serviva un semplicissimo ocsp responder basato sul classico 
/etc/pki/CA/index.txt dato che deve fare *solo* quello, openssl pareva 
la soluzione più ovvia, non avevo messo nel conto che avrebbe fatto a 
cazzotti con xinetd.
 
Il tutto mi serviva per fornire un semplice script per chi volesse 
implementare in house una propria mini PKI che fosse compatibile con 
quelle "accreditate" il ché mi avrebbe permesso di scrivere meno codice 
PHP, ma alla peggio posso sempre implementare uno script che converte 
una CRL in un DB MySQL ed inserire codice php che anziché verificare la 
validità del certificato via OCSP faccia una query al DB.
 
Mi sa che farò proprio così.