El mecanismo Kerberos es compatible con varios sondeos de DTrace para decodificar varios mensajes de protocolo. Para obtener una lista, consulte Appendix A, Sondeos de DTrace para Kerberos. Los sondeos de DTrace tienen una ventaja sobre otros inspectores de protocolos, ya que DTrace permite a un usuario con privilegios ver fácilmente los datos de Kerberos y de aplicación sin cifrar.
En los ejemplos siguientes se indica lo que se puede ver con los sondeos de DTrace de Kerberos.
Ejemplo 8-1 Uso de DTrace para realizar un seguimiento de los mensajes de KerberosLa siguiente secuencia de comandos utiliza sondeos de DTrace para visualizar detalles sobre los mensajes de Kerberos que envía y recibe el sistema. Tenga en cuenta que los campos que aparecen se basan las estructuras que se asignan a los sondeos krb_message-recv y krb_message-send Para obtener más información, consulte Definiciones de sondeos de DTrace de Kerberos.
kerberos$target:::krb_message-recv { printf("<- krb message recved: %s\n", args[0]->krb_message_type); printf("<- krb message remote addr: %s\n", args[1]->kconn_remote); printf("<- krb message ports: local %d remote %d\n", args[1]->kconn_localport, args[1]->kconn_remoteport); printf("<- krb message protocol: %s transport: %s\n", args[1]->kconn_protocol, args[1]->kconn_type); } kerberos$target:::krb_message-send { printf("-> krb message sent: %s\n", args[0]->krb_message_type); printf("-> krb message remote addr: %s\n", args[1]->kconn_remote); printf("-> krb message ports: local %d remote %d\n", args[1]->kconn_localport, args[1]->kconn_remoteport); printf("-> krb message protocol: %s transport: %s\n", args[1]->kconn_protocol, args[1]->kconn_type); printf("\n"); } kerberos$target:::krb_error-read { printf("<- krb error code: %s\n", args[1]->kerror_error_code); printf("<- krb error client: %s server: %s\n", args[1]->kerror_client, args[1]->kerror_server); printf("<- krb error e-text: %s\n", args[1]->kerror_e_text); printf("\n"); }
La secuencia de comandos anterior se puede llamar desde la línea de comandos o con el daemon krb5kdc. A continuación se muestra un ejemplo de la llamada a la secuencia de comandos, que se denomina krb-dtrace.d, de la línea de comandos. El comando hace que Kerberos envíe y reciba mensajes. Tenga en cuenta que LD_NOLAZYLOAD=1 es necesario para forzar la carga de la biblioteca mech_krb5.so de Kerberos que contiene los sondeos de DTrace de Kerberos.
# LD_NOLAZYLOAD=1 dtrace -s ./krb\-dtrace.d -c kinit dtrace: script './krb-dtrace' matched 4 probes kinit: Client 'root@DEV.ORACLE.COM' not found in Kerberos database while g etting initial credentials dtrace: pid 3750 has exited CPU ID FUNCTION:NAME 2 74782 k5_trace_message_send:krb_message-send -> krb message sent: KR B_AS_REQ(10) -> krb message remote addr: 10.229.168.163 -> krb message ports: local 62029 remote 88 -> krb message protocol: ipv4 transport: udp 2 74781 k5_trace_message_recv:krb_message-recv <- krb message recved: KRB_ERROR(30) <- krb message remote addr: 10.229.168.163 <- krb message ports: local 62029 remote 88 <- krb message protocol: ipv4 transport: udp 2 74776 krb5_rd_error:krb_error-read <- krb error code: KDC_ERR_C_ PRINCIPAL_UNKNOWN(6) <- krb error client: root@DEV.ORACLE.COM server: krbtgt/DEV.ORACLE.COM@DEV .ORACLE.COM <- krb error e-text: CLIENT_NOT_FOUND
Para utilizar la secuencia de comandos con el daemon krb5kdc, el servicio svc:/network/security/krb5kdc:default debe estar activado y en línea. Tenga en cuenta que el siguiente comando no utiliza LD_NOLAZYLOAD=1 porque la biblioteca mech_krb5.so carga el daemon krb5kdc.
# dtrace -s ./krb\-dtrace.d -p $(pgrep -x krb5kdc)Ejemplo 8-2 Uso de DTrace para ver los tipos de autenticación previa de Kerberos
El siguiente ejemplo muestra la autenticación previa seleccionada por el cliente. El primer paso consiste en crear una secuencia de comandos de DTrace, como se muestra a continuación:
cat krbtrace.d kerberos$target:::krb_message-recv { printf("<- krb message recved: %s\n", args[0]->krb_message_type); printf("<- krb message remote addr: %s\n", args[1]->kconn_remote); printf("<- krb message ports: local %d remote %d\n", args[1]->kconn_localport, args[1]->kconn_remoteport); printf("<- krb message protocol: %s transport: %s\n", args[1]->kconn_protocol, args[1]->kconn_type); } kerberos$target:::krb_message-send { printf("-> krb message sent: %s\n", args[0]->krb_message_type); printf("-> krb message remote addr: %s\n", args[1]->kconn_remote); printf("-> krb message ports: local %d remote %d\n", args[1]->kconn_localport, args[1]->kconn_remoteport); printf("-> krb message protocol: %s transport: %s\n", args[1]->kconn_protocol, args[1]->kconn_type); printf("\n"); } kerberos$target:::krb_kdc_req-make { printf("-> krb kdc_req make msg type: %s\n", args[0]->krb_message_type); printf("-> krb kdc_req make pre-auths: %s\n", args[1]->kdcreq_padata_types); printf("-> krb kdc_req make auth data: %s\n", args[1]->kdcreq_authorization_data); printf("-> krb kdc_req make client: %s server: %s\n", args[1]->kdcreq_client, args[1]->kdcreq_server ); } kerberos$target:::krb_kdc_req-read { /* printf("<- krb kdc_req msg type: %s\n", args[0]->krb_message_type); */ printf("<- krb kdc_req client: %s server: %s\n", args[1]->kdcreq_client, args[1]->kdcreq_server ); printf("\n"); } kerberos$target:::krb_kdc_rep-read { /* printf("<- krb kdc_rep msg type: %s\n", args[0]->krb_message_type); */ printf("<- krb kdc_rep client: %s server: %s\n", args[1]->kdcrep_client, args[1]->kdcrep_enc_server ); printf("\n"); } kerberos$target:::krb_ap_req-make { printf("-> krb ap_req make server: %s client: %s\n", args[2]->kticket_server, args[2]->kticket_enc_client ); } kerberos$target:::krb_error-read { printf("<- krb error code: %s\n", args[1]->kerror_error_code); printf("<- krb error client: %s server: %s\n", args[1]->kerror_client, args[1]->kerror_server); printf("<- krb error e-text: %s\n", args[1]->kerror_e_text); printf("\n"); }
A continuación, ejecute la secuencia de comandos krbtrace.d como usuario con privilegios en el sistema Kerberos. Para ello, escriba el siguiente comando:
# LD_BIND_NOW=1 dtrace -qs krbtrace.d -c "kinit -k" . . -> krb kdc_req make pre-auths: FX_COOKIE(133) ENC_TIMESTAMP(2) REQ_ENC_PA_REP(149)
Los tipos de autenticación previa se mostrarán en el resultado. Para obtener más información acerca de los distintos tipos de autenticación previa, consulte RFC 4120.
Ejemplo 8-3 Uso de DTrace para volcar una mensaje de error de Kerberos# dtrace -n 'krb_error-make { printf("\n{"); printf("\n\tctime = %Y", (uint64_t)(args[1]->kerror_ctime * 1000000000)); printf("\n\tcusec = %d", args[1]->kerror_cusec); printf("\n\tstime = %Y", (uint64_t)(args[1]->kerror_stime * 1000000000)); printf("\n\tsusec = %d", args[1]->kerror_susec); printf("\n\terror_code = %s", args[1]->kerror_error_code); printf("\n\tclient = %s", args[1]->kerror_client); printf("\n\tserver = %s", args[1]->kerror_server); printf("\n\te_text = %s", args[1]->kerror_e_text); printf("\n\te_data = %s", ""); printf("\n}"); }' dtrace: description 'krb_error-make ' matched 1 probe CPU ID FUNCTION:NAME 0 78307 krb5_mk_error:krb_error-make { ctime = 2012 May 10 12:10:20 cusec = 0 stime = 2012 May 10 12:10:20 susec = 319090 error_code = KDC_ERR_C_PRINCIPAL_UNKNOWN(6) client = testuser@EXAMPLE.COM server = krbtgt/EXAMPLE.COM@EXAMPLE.COM e_text = CLIENT_NOT_FOUND e_data = }Ejemplo 8-4 Uso de DTrace para ver el ticket de servicio para un servidor SSH
# LD_PRELOAD_32=/usr/lib/gss/mech_krb5.so.1 dtrace -q -n ' kerberos$target:::krb_kdc_req-make { printf("kdcreq_server: %s",args[1]->kdcreq_server); }' -c "ssh local@four.example.com" -o dtrace.out Last login: Wed Sep 10 10:10:20 2014 Oracle Solaris 11 X86 July 2014 $ ^D # cat dtrace.out kdcreq_server: host/four.example.com@EXAMPLE.COMEjemplo 8-5 Uso de DTrace para ver la dirección y el puerto de un KDC no disponible cuando se solicita un TGT inicial
# LD_BIND_NOW=1 dtrace -q -n ' kerberos$target:::krb_message-send { printf("%s:%d\n",args[1]->kconn_remote, args[1]->kconn_remoteport) }' -c "kinit local4" 10.10.10.14:88 10.10.10.14:750 10.10.10.14:88 10.10.10.14:750 10.10.10.14:88 10.10.10.14:750 kinit(v5): Cannot contact any KDC for realm 'EXAMPLE.COM' while getting initial credentialsEjemplo 8-6 Uso de DTrace para ver las solicitudes de los principales de Kerberos
# LD_BIND_NOW=1 dtrace -qs /opt/kdebug/mykdtrace.d \ -c 'kadmin -p kdc/admin -w test123 -q listprincs' Authenticating as principal kdc/admin with password. krb kdc_req msg type: KRB_AS_REQ(10) krb kdc_req make client: kdc/admin@TEST.NET server: kadmin/interop1.example.com@TEST.NET krb message sent: KRB_AS_REQ(10) krb message recved: KRB_ERROR(30) Err code: KDC_ERR_PREAUTH_REQUIRED(25) Err msg client: kdc/admin@TEST.NET server: kadmin/interop1.example.com@TEST.NET Err e-text: NEEDED_PREAUTH krb kdc_req msg type: KRB_AS_REQ(10) krb kdc_req make client: kdc/admin@TEST.NET server: kadmin/interop1.example.com@TEST.NET krb message sent: KRB_AS_REQ(10) krb message recved: KRB_AS_REP(11) kadmin: Database error! Required KADM5 principal missing while initializing kadmin interface krb kdc_req msg type: KRB_AS_REQ(10) krb kdc_req make client: kdc/admin@TEST.NET server: kadmin/interop2.example.com@TEST.NET krb message sent: KRB_AS_REQ(10) krb message recved: KRB_ERROR(30) Err code: KDC_ERR_S_PRINCIPAL_UNKNOWN(7) Err msg client: kdc/admin@TEST.NET server: kadmin/interop2.example.com@TEST.NET Err e-text: SERVER_NOT_FOUND krb kdc_req msg type: KRB_AS_REQ(10) krb kdc_req make client: kdc/admin@TEST.NET server: kadmin/interop2.example.com@TEST.NET
La siguiente secuencia de comandos se utilizó para producir la salida anterior.
kerberos$target:::krb_message-recv { printf("krb message recved: %s\n", args[0]->krb_message_type); } kerberos$target:::krb_message-send { printf("krb message sent: %s\n", args[0]->krb_message_type); } kerberos$target:::krb_kdc_req-make { printf("krb kdc_req msg type: %s\n", args[0]->krb_message_type); printf("krb kdc_req make client: %s server: %s\n", args[1]->kdcreq_client, args[1]->kdcreq_server ); } kerberos$target:::krb_ap_req-make { printf("krb ap_req make server: %s client: %s\n", args[2]->kticket_server, args[2]->kticket_enc_client ); } kerberos$target:::krb_error-read { printf("Err code: %s\n", args[1]->kerror_error_code); printf("Err msg client: %s server: %s\n", args[1]->kerror_client, args[1]->kerror_server); printf("Err e-text: %s\n", args[1]->kerror_e_text); }