Securizando el listener

Vamos a ver una serie de entradas sencillas sobre securización básica de la base de datos

La securización del listener es una de las tareas mas sencillas y de las primeas que tenemos que hacer con la instalación de la base de datos.
Esta securización consta de varias partes:

  • Securizacion del S.O
  • Restringir las IPs desde las que se permite el acceso
  • Añadir autenticacion al listener.
  • Auditar listeners
  • Parametrizar conexiones
  • Cifrar tráfico

Securización del S.O

Como en todo componente de Oracle, la securización del Sistema Operativo es primordial.
Oracle por defecto cuenta con una estructura de permisos en directorios que no deben de variarse.
En cualquier caso siempre es conveniente seguir los aparatados de managing security de los documentos de instalacion de los productos

Restringir las IPs desde las que se permite el acceso

Este apartado es muy relativo, ya que puede no aplicar a nuestro sistema, sin embargo, en la mayoría de los casos estaremos tratando arquitecturas de 3 capas donde los accesos a las bases de datos son desde nuestra capa de servidor de aplicación.

Para habilitar las whitelists usaremos los parámetros tcp.invited_nodes y tcp.validnode_checking en el fichero $TNS_ADMIN/sqlnet.ora de la siguiente manera

tcp.validnode_checking = YES
tcp.invited_nodes = ( X.X.X.X, hostname, ... )

La documentación de estos parámetros la tenemos en Configuring Database Access Control

Añadir autenticación al listener.

Esta opcion está desoportada en la version 12c Desupport of Oracle Net Listener Password
Una de las primeras vulnerabilidades que van a encontrarte en una auditoria de seguridad es la falta de autenticacion del listener.
Poner password al listener previene a la base de datos de ejecución de los comandos de control del mismo desde ubicaciones remotas. Es importante destacar que , desde la version 10g «the listener password is no longer required as the listener implements OSAuthentication,«, esto quiere decir que el usuario del sistema operativo propietario del listener no necesita el password para pararlo o arrancarlo ( que es el principal miedo del DBA cuando pone password al listener)

Para poner password al listener ejecutaremos:

$ lsnrctl
LSNRCTL> change_password
Old password:
New password:
Reenter new password: 
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=BBDD1)(PORT=1521)))
Password changed for LISTENER
The command completed successfully
LSNRCTL> set password
Password:
The command completed successfully
LSNRCTL> save_config
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=BBDD1)(PORT=1521)))
Saved DBLSNR configuration parameters.
Listener Parameter File /oracle/product/BBDD/network/admin/listener.ora
Old Parameter File /oracle/product/BBDD/network/admin/listener.bak
The command completed successfully

Esto nos habrá añadido unas lineas al listener.ora

This added the following lines to listener.ora:
#----ADDED BY TNSLSNR 21-JUN-2016 13:47:56---
PASSWORDS_VSEC = D911537DUT5E6546

Auditar el listener

Toda securizacion de un elemento debe incluir la habilitación de un registro del mismo.
Para habilitar el regitro del log de listener añadiremos al fichero $TNS_ADMIN/listener.ora las siguientes lineas :

LOG_STATUS = ON
LOG_DIRECTORY_ = $TNS_ADMIN
LOG_FILE_ = $ORACLE_SID

Esto ya se lleva a cabo por defecto a partir de la versión 11.5.10.

Parametrizar conexiones

El ultimo y no menos importante de los apartados es el de parametrizar los parámetros del listener ,un ejemplo de uno de estos parámetros es CONNECT_TIMEOUT
Añafiendo en el $TNS_ADMIN/listener.ora el parámetro

CONNECT_TIMEOUT_ = 10

Especificamos el tiempo en segundos que el listener esperará para que se complete una conexion de cliente.

Cifrar tráfico

El cifrado del tráfico de la base de datos es posiblemente uno de los puntos mas importantes a la hora de securizar una conexion.
¿Por que la hemos dejado para el final?
La respuesta es sencilla, por que este cifrado implica una opcion de pago que es la Advanced Security
Option (ASO).

Si estás interesado en ahondar en esta opcion tienes la informacion en el grupo Advanced Security Option del MSOC

Detectar trabajos suspendidos

Vamso a ver una entrada rápida y sencilla.

¿Como sabemos cuando y por que se nos ah quedado parado un impdp?

La respuesta es muy sencilla, y es chequeando la table DBA_RESUMABLE


SELECT NAME,STATUS, TIMEOUT, ERROR_NUMBER, ERROR_MSG FROM DBA_RESUMABLE;

Esto nos dará una salida del estilo :

NAME                                STATUS            TIMEOUT, ERROR_NUMBER, ERROR_MSG
SYSTEM.IMPORT_REGENERACION2	NORMAL	       7200	0
SYSTEM.IMPORT_REGENERACION2.1	SUSPENDED	7200	1652	ORA-01652:      no se ha podido ampliar el segmento temporal con 1024 en el tablespace USERS

Donde podemos ver claramente que estamos parados por un ORA-01652 por culpa de espacio en un tabelspace

Estudio de traza de un Deadlock

Hoy vamos a ver como obtener algo mas de información de una incidencia que probablemente tengamos a menudo.

Los deadlocks no implican mal funcionamiento de la base de datos

Lo primero que tenemos que tener muy claro es que un deadlock no es un mal funcionamiento de la base de datos, un deadlock (la traducción posiblemente sea interbloqueo) es una situación en la que dos o mas usuarios están esperando cada uno a un recurso bloqueado por el otro.
La manera en la que Oracle soluciona esta situación es rolling back una de las sentencias implicadas en el deadlock, al liberar uno de estos bloqueos la otra finaliza su solicitud.
Cuando esta situación ocurre, Oracle deja un fichero de traza en el $DIAG_DEST , que nos indica cuales eran los procesos y sentencias implicados. El análisis de esa traza es lo que vamos a mirar hoy.

Deadlock Graph

Seguramente el apartado mas importante de la traza sea el llamado «deadlock graph», estas dos líneas que parecen tan crípticas son las que mas información nos van a dar sobre el bloqueo.

Deadlock graph:
--------Blocker(s)------- --------Waiter(s)--------
Resource Name           process session_holds waits process session_holds waits
TX-000e001a-002dd880     65               414    X       24          9       X
TX-00090006-01e831ca     24                 9    X        65        414      X

Viendo el tipo de bloqueo en «resource_name» y los distintos waits podremos obtener el tipo de bloqueo que ha sido, para ello tenemos una tabla maestra en la nota de soporte How to Identify ORA-00060 Deadlock Types Using Deadlock Graphs in Trace (Doc ID 1507093.1).
En nuestro caso, por ejemplo,tendríamos según soporte un claro caso de bloqueo de aplicación.
Bloqueo TX X X

Información de la sesión

Otro apartado interesante es el de la información de la sesión. En este apartado nos indica de manera mas sencilla cuales son las sesiones implicadas y cuales son los objectos en los que hemos tenido el problema .
Mediante esta información podemos buscar los objetos por los que se han causado el interbloqueo

session 414: DID 0001-0041-000592FB session 9: DID 0001-0018-00004FD9 
session 9: DID 0001-0018-00004FD9 session 414: DID 0001-0041-000592FB
Rows waited on:
Session 414: obj - rowid = 001272E0 - AAExowAQAAAACF5AAUv (dictionary objn - 1209056, file - 1024, block - 8569, slot - 20)
Session 9:   obj - rowid = 001272E0 - AAExowAQAAAACMNAAJ  (dictionary objn - 1209056, file - 1024, block - 8973, slot - 9)

SQL implicado

Finalmente llegamos al apartado que puede ser mas clarificador de cara al equipo de desarrollo encargado de depurar el código.
Este tercer bloque nos amplia la información de las sesiones implicadas, contándonos esquema, terminal y las consultas implicadas en el deadlock

----- Information for the OTHER waiting sessions -----
Session 9:
sid: 9 ser: 37801 audsid: 206118217 user: 103/SCHEMA1    flags: (0x45) USR/- flags_idl: (0x1) BSY/////- flags2: (0x40009) //INC  pid: 24 O/S info: user: SYSTEM, term: SERVERTEST, ospid: 12260  image: ORACLE.EXE (SHAD)

client details:
O/S info: user: launcherusr, term: , ospid: 13041768  machine: client2 program: schema2@client2 (TNS V1-V3)  application name: schema2@client2 (TNS V1-V3), hash  alue=54028978

current SQL:
UPDATE SCOTT2.TIPO_COCHE  SET COLOR = :1, CILINDRADA = :2 WHERE MATRICULA = :3 AND ANCHO = :4
----- End of information for the OTHER waiting sessions -----

Information for THIS session:
----- Current SQL Statement for this session (sql_id=8zqxt1a6d7ts1) -----
UPDATE SCOTT2.TIPO_COCHE SET TIPO = :1, PERSONA = :2 WHERE MATRICULA = :3 AND LARGO = :4

El fichero de traza es mucho mas amplio, pero, como habéis podido ver, mediante el estudio de la cabecera de la traza podemos recopilar mucha información para poder depurara el código de aplicación para que no vuelva a ocurrir

Como siempre, tenemos mas información en soporte, en las notas

  • Master Note for Database Error ORA-00060 «deadlock detected while waiting for resource» (Doc ID 1509919.1)
  • Master Note: Locks, Enqueues and Deadlocks (Doc ID 1392319.1)
  • How to Identify ORA-00060 Deadlock Types Using Deadlock Graphs in Trace (Doc ID 1507093.1)

Error «Update home dependency failed» desplegando agentes del oem12c

Tras un periodo demasiado largo sin publicar , vamos a ver la solución a un problema muy sencillo, pero que nos puede traer de cabeza.

Llevando a cabo la instalación del agente para unix (AIX 64) del Enterprise Manager12c, me he encontrado con el error

Update home dependency failed.

2016-05-13_09-42-17:INFO:Action description Ejecución del comando  /bin/sh -c '/applics/oem12c/agente_12c/ADATMP_2016-05-13_08-53-57-AM/agentDeploy.sh -ignorePrereqs ORACLE_HOSTNAME=servertarget.pamplona.name AGENT_BASE_DIR=/applics/oem12c/agente_12c OMS_HOST=ascoem.gseguros.com EM_UPLOAD_PORT=4904 AGENT_INSTANCE_HOME=/applics/oem12c/agente_12c/agent_inst b_doDiscovery=false b_startAgent=false b_forceInstCheck=true AGENT_PORT=3872'  en el host servertarget.pamplona.name
2016-05-13_09-42-17:INFO:Attempt :1 pty required false  with no inputs
2016-05-13_09-46-14:INFO:/bin/sh -c '/applics/oem12c/agente_12c/ADATMP_2016-05-13_08-53-57-AM/agentDeploy.sh -ignorePrereqs ORACLE_HOSTNAME=servertarget.pamplona.name AGENT_BASE_DIR=/applics/oem12c/agente_12c OMS_HOST=ascoem.gseguros.com EM_UPLOAD_PORT=4904 AGENT_INSTANCE_HOME=/applics/oem12c/agente_12c/agent_inst b_doDiscovery=false b_startAgent=false b_forceInstCheck=true AGENT_PORT=3872' execution failed on host servertarget.pamplona.name
2016-05-13_09-46-14:INFO:Pattern ERROR: found in file /u01/app/oracle/gc_inst/em/EMGC_OMS1/sysman/agentpush//2016-05-13_08-53-57-AM/logs/servertarget.pamplona.name/install.log Line ERROR: Update home dependency failed.
2016-05-13_09-46-14:INFO:Error Message found  Update home dependency failed.
2016-05-13_09-46-14:INFO: ACTION Ejecución del comando  /applics/oem12c/agente_12c/ADATMP_2016-05-13_08-53-57-AM/agentDeploy.sh -ignorePrereqs ORACLE_HOSTNAME=servertarget.pamplona.name AGENT_BASE_DIR=/applics/oem12c/agente_12c OMS_HOST=ascoem.gseguros.com EM_UPLOAD_PORT=4904 AGENT_INSTANCE_HOME=/applics/oem12c/agente_12c/agent_inst b_doDiscovery=false b_startAgent=false b_forceInstCheck=true AGENT_PORT=3872 en el host servertarget.pamplona.name
2016-05-13_09-46-14:INFO: OUT null
2016-05-13_09-46-14:INFO: ERR  Update home dependency failed.
2016-05-13_09-46-14:INFO: EXIT CODE1
2016-05-13_09-46-14:INFO:InvocationTargetException Exception
2016-05-13_09-46-14:INFO:Printing Exception :java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at oracle.sysman.core.agentpush.ui.deployer.BaseDeployerOps.executeActions(BaseDeployerOps.java:1862)
        at oracle.sysman.core.agentpush.ui.deployer.NewAgentDeployer.deploy(NewAgentDeployer.java:59)
        at oracle.sysman.core.agentpush.ui.deployfwk.DeploymentWorker.run(DeploymentWorker.java:26)
        at oracle.sysman.util.threadPoolManager.WorkerThread.run(Worker.java:311)
Caused by: CommandException: err:  Update home dependency failed.  out: null exitcode: 1
 stacktrace:
null
        at oracle.sysman.core.agentpush.ui.deployer.DeployerOps.executeCommandOnNodeInteractive(DeployerOps.java:1199)
        at oracle.sysman.core.agentpush.ui.deployer.DeployerOps.executeCommandOnNodeInteractive(DeployerOps.java:1045)
        at oracle.sysman.core.agentpush.ui.deployer.DeployerOps.executeCmdOnNode(DeployerOps.java:639)
        at oracle.sysman.core.agentpush.ui.deployer.DeployerOps.executeCmdOnNode(DeployerOps.java:593)
        at oracle.sysman.core.agentpush.ui.deployer.BaseDeployerOps.doInstall(BaseDeployerOps.java:437)
        ... 8 more

2016-05-13_09-46-14:INFO:=========Command Exception :Mensaje de Error: Update home dependency failed. 

Código de Salida :1 2016-05-13_09-46-14:INFO:Updating Action Installwith Status FAILED and error Message :Mensaje de Error: Update home dependency failed.

Código de Salida :1 and problem Ejecución del comando /applics/oem12c/agente_12c/ADATMP_2016-05-13_08-53-57-AM/agentDeploy.sh -ignorePrereqs ORACLE_HOSTNAME=servertarget.pamplona.name AGENT_BASE_DIR=/applics/oem12c/agente_12c OMS_HOST=ascoem.gseguros.com EM_UPLOAD_PORT=4904 AGENT_INSTANCE_HOME=/applics/oem12c/agente_12c/agent_inst b_doDiscovery=false b_startAgent=false b_forceInstCheck=true AGENT_PORT=3872 en el host servertarget.pamplona.name Fallo and recommendation Corrija la causa del error y vuelva a intentar la operación 2016-05-13_09-46-14:INFO:=================action status is not empty FAILED 2016-05-13_09-46-14:INFO:Breaking since the action has failed 2016-05-13_09-46-14:INFO:Skipping action SecureAgent since some previous step has failed 2016-05-13_09-46-14:INFO:Skipping action RunRootSH since some previous step has failed 2016-05-13_09-46-14:INFO:Not Skipping action CollectLog since some previous step has failed 2016-05-13_09-46-14:INFO:sudo exists value false 2016-05-13_09-46-14:INFO:==SUDO EXISTS false SUDO PRIV false

Si buscamos en los foros de soporte e oracle o en el propio metalink,encontraremos que es un error que puede deberse a bastantes casos, sin embargo, hay una causa que ( en mi caso era la razón) es muy sencilla de comprobar, y que puede ser la causa principal del error.


If the warning from the installer is bypassed, failure of the console to effectively deploy an agent can be just one of the resulting symptoms.
Unpublished BUG OMS CONFIG FAILING IF SWAP SPACE IS LESS THAN 6GB

Así que, ante este tipo de error , lo mas rápido, sencillo e inmediato es comprobar si tenemos al menos 6 Gb de swap space, es un requisito no publicado que hace que falle la instalacion.

Paquete UTL_MAIL en 12c

El paquete UTL_MAIL es uno de esos paquetes que, aunque en mi opinión no debería de usarse nunca, siempre nos encontramos con casos de aplicaciones que hacen uso del mismo.
Si migramos (no update) a la 12c (creo que los ultimos patchsets de la 11g puede pasar también), nos encontramos con que aparece este error:

PLS-00201: el identificador 'SYS.UTL_MAIL' se debe declarar
PLS-00201: identifier 'SYS.UTL_MAIL' must be declared

El motivo de este error queda bastante claro en la entrada de Database PL/SQL Packages and Types Reference UTL_MAIL de la documentación de los paquetes de la 12g.

UTL_MAIL no está instalado de forma predeterminada debido al requisito de configuración SMTP_OUT_SERVER y la exposición de la seguridad que ello implica.
Con la instalación de UTL_MAIL, usted deberá configurar el sistema para agregar la salida a los puertos definidos en SMTP_OUT_SERVER .

Así pues nos tocará instalarlo a mano con:

sqlplus sys/
SQL> @$ORACLE_HOME/rdbms/admin/utlmail.sql
SQL> @$ORACLE_HOME/rdbms/admin/prvtmail.plb

y dar los permisos al esquema que nos necesite

GRANT EXECUTE ON UTL_MAIL TO esquema;

En cualquier caso, aunque lo instalemos a mano, tendremos que empezar a lidiar con el paquete UTL_SMTP, con lo que nos vendrá bien tener a mano las entradas :