Eliminar usuarios/contraseñas de base de datos del código de las aplicaciones
30/09/2014 -
Es habitual que tanto algunas aplicaciones como shell scripts tengan los datos de conexión a base de datos (incluyendo el usuario y la contraseña) almacenados en ficheros de texto. Esto implica, principalmente, un problema de seguridad, ya que cualquiera que tenga acceso a estos ficheros tendrá acceso a los datos de conexión a la base de datos, pero además, supone un serio problema a la hora de modificar las contraseñas de los usuarios, porque esto provoca que haya que modificar el código de las aplicaciones y los shell scripts.
Para solucionar esto, Oracle posee la opción Secure External Password Store (SEPS) que, mediante la creación de un wallet que almacena las credenciales, permite que las aplicaciones y los shell scripts se conecten a la base de datos utilizando ‘/@<cadena_de_conexión>’. SEPS está disponible a partir de la versión 10gR2 y no necesita licenciamiento adicional, es posible utilizarlo con cualquier edición de la base de datos, ya sea Standard o Enterprise.
La configuración de SEPS se deberá efectuar en todos los clientes que se vayan a conectar a la base de datos y quieran hacer uso de esta opción. En la imagen siguiente está configurado en un servidor de aplicaciones y en una máquina con un cliente Oracle.
Vamos a explicar con un paso a paso como realizar la configuración de Secure External Password Store para conectarse a nuestra base de datos. Esto nos permitirá tener acceso sin explicitar las credenciales. Todos los pasos que se muestran se han efectuado con una versión 11gR2 en un Oracle Linux 5. En este caso, el cliente y la base de datos son la misma máquina, pero se procedería de manera similar si el cliente estuviera en otra máquina.
En primer lugar, definimos en el fichero tnsnames.ora una entrada nueva que será la que se utilice posteriormente en SEPS (aunque se podría hacer utilizando una ya existente). En este caso la hemos llamado SEPS_ORCL porque es idéntica a la principal, ORCL:
1
2
3
4
5
6
7
8
9
10
11
|
ORCL = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost.localdomain)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = ORCL)) ) SEPS_ORCL = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost.localdomain)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = ORCL)) ) |
A continuación se debe crear el wallet. Para ello se puede ejecutar el comando ‘mkstore -wrl -create’. El problema con este comando es que cualquiera con acceso al wallet podría copiarlo, llevárselo a otra máquina y hacer uso de él. A partir de la versión 11gR2, esto se puede evitar creando el wallet con el comando orapki, ejecutando ‘orapki wallet create -wallet -pwd -auto_login_local’:
1
2
3
4
5
6
7
8
9
|
[oracle@localhost ~]$ orapki wallet create -wallet "/u01/app/oracle/wallet/" -pwd "welcome1" -auto_login_local Oracle PKI Tool : Version 11.2.0.1.0 - Production Copyright (c) 2004, 2009, Oracle and / or its affiliates. All rights reserved. [oracle@localhost ~]$ cd /u01/app/oracle/wallet/ [oracle@localhost wallet]$ ll total 8 -rw ------- 1 oracle oracle 3957 Jun 27 15:37 cwallet.sso -rw ------- 1 oracle oracle 3880 Jun 27 15:37 ewallet.p12 |
Una vez creado el wallet, se introducen en él las credenciales de conexión a base de datos, esto es, nombre TNS, usuario y contraseña. Se utiliza el comando ‘mkstore -wrl -createCredential’:
1
2
3
4
5
6
7
|
[oracle@localhost ~]$ mkstore -wrl "/u01/app/oracle/wallet/" -createCredential SEPS_ORCL scott tiger Oracle Secret Store Tool : Version 11.2.0.1.0 - Production Copyright (c) 2004, 2009, Oracle and / or its affiliates. All rights reserved. Enter wallet password : Create credential oracle.security.client.connect_string1 |
Comprobamos las credenciales que posee el wallet:
1
2
3
4
5
6
7
8
|
[oracle@localhost ~]$ mkstore -wrl "/u01/app/oracle/wallet" -listCredential Oracle Secret Store Tool : Version 11.2.0.1.0 - Production Copyright (c) 2004, 2009, Oracle and / or its affiliates. All rights reserved. Enter wallet password : List credential ( index : connect_string username) 1: SEPS_ORCL scott |
Configuramos el fichero sqlnet.ora para que reconozca el wallet y que podamos conectarnos a la base de datos haciendo uso de él. El parámetro ‘SSL_CLIENT_AUTHENTICATION’ indica si los clientes van a utilizar SSL para autenticarse. El parámetro WALLET_OVERRRIDE se configura a TRUE para forzar a que se utilice la información del wallet:
1
2
3
4
5
|
[oracle@localhost admin]$ cd $ORACLE_HOME/network/admin [oracle@localhost admin]$ more sqlnet.ora WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/u01/app/oracle/wallet))) SQLNET.WALLET_OVERRIDE= TRUE SSL_CLIENT_AUTHENTICATION = FALSE |
Probamos a conectarnos haciendo uso de la entrada de TNS definida inicialmente:
1
2
3
4
5
6
7
8
9
10
11
12
|
[oracle@localhost ~]$ sqlplus /@SEPS_ORCL SQL*Plus: Release 11.2.0.1.0 Production on Sun Jun 29 20:57:45 2014 Copyright (c) 1982, 2009, Oracle. All rights reserved. Connected to : Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> show user USER is "SCOTT" |
Comprobamos que utilizando otra entrada TNS, cuyas credenciales no están en el wallet, el intento de conexión falla:
1
2
3
4
5
6
7
8
|
[oracle@localhost ~]$ sqlplus /@ORCL SQL*Plus: Release 11.2.0.1.0 Production on Sun Jun 29 20:58:21 2014 Copyright (c) 1982, 2009, Oracle. All rights reserved. ERROR: ORA-01017: invalid username/ password ; logon denied |
Comprobamos que utilizando una entrada TNS que no existe, el mensaje de error es significativo:
1
2
3
4
5
6
7
8
|
[oracle@localhost ~]$ sqlplus /@ASDF SQL*Plus: Release 11.2.0.1.0 Production on Sun Jun 29 20:59:02 2014 Copyright (c) 1982, 2009, Oracle. All rights reserved. ERROR: ORA-12154: TNS:could not resolve the connect identifier specified |
A continuación probamos con un usuario diferente, el cual no posee privilegios de acceso al wallet, vemos que se permite la conexión a la base de datos especificando usuario y contraseña:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
[usuario@localhost ~]$ sqlplus SQL*Plus: Release 11.2.0.1.0 Production on Mon Jul 7 13:02:46 2014 Copyright (c) 1982, 2009, Oracle. All rights reserved. Enter user - name : scott Enter password : Connected to : Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options SQL> exit Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options |
Pero si utilizando el mismo usuario se intenta conectar utilizando SEPS falla, ya que el usuario no tiene acceso al wallet:
1
2
3
4
5
6
7
8
|
[usuario@localhost ~]$ sqlplus /@SEPS_ORCL SQL*Plus: Release 11.2.0.1.0 Production on Mon Jul 7 13:03:15 2014 Copyright (c) 1982, 2009, Oracle. All rights reserved. ERROR: ORA-12578: TNS:wallet open failed |
La conclusión es que con Secure External Password Store se solucionan los problemas que hemos comentado en un principio: ya no tenemos ninguna contraseña en ficheros de texto y si se modificase el password de un usuario no hay que revisar todos los scripts que hacen uso de él.
A primera vista podría parecer que seguimos teniendo un problema de seguridad grave (igual que cuando se almacenaba usuario/contraseña en ficheros de texto plano) ya que cualquiera puede conectarse a la base de datos haciendo una llamada del tipo ‘/@’ con la información almacenada en el wallet. Pero, tal y como se ha mostrado en el último ejemplo, hay que tener en cuenta que este tipo de conexión a base de datos únicamente se puede hacer desde las máquinas en las que se ha realizado la configuración de SEPS, y siempre que sea con el usuario propietario del software y del wallet. Debido a lo anterior, el problema se reduce a tener controlado quien tiene acceso a la máquina con el usuario privilegiado, como en prácticamente todos los entornos productivos.