1 ene 2018

Cómo conectarme a un servidor remoto en una red protegida - Versión actualizada

En un artículo anterior describí cómo conectarse a un equipo remoto en una red protegida http://diego-k.blogspot.mx/2014/12/como-conectarme-un-servidor-remoto-con.html .

Esta vez vamos a perfeccionar el método, hacerlo más práctico y a la vez más estable.

El objetivo es el mismo:

"Quieres alcanzar un servidor desde tu PC pero estás detrás del firewall de tu modem y el servidor se encuentra detrás del firewall corporativo. Ambos pueden salir a Internet, pero ninguno publica puertos. "


Tenemos diferentes pasos a seguir: 

1) Podemos usar la capa gratuita de Amazon Web Services con un Linux AMI. Hay muchas guías de cómo configurarlo, como la siguiente: How to setup a Linux server on Amazon AWS
En caso de querer hacerlo nosotros mismos necesitaremos una vieja PC, Netbook o Notebook donde instalaremos Linux (puede ser Ubuntu con OpenSSH) y deberemos abrir un puerto para el SSH (recomiendo 443) en el firewall del router. La configuración depende del equipo y el proveedor, pero siempre hay tutoriales. 

2) En el IBM i o un Linux dentro de la infraestructura donde se encuentra el servidor debemos instalar OpenSSH y AUTOSSH. AutoSSH tiene una sintaxis similar a SSH, pero valida si se ha caído la conexión y la restablece. Con eso evitamos estar validando la conexión. Es muy util en conexiones poco estables.

3) Creamos una cuenta en DynU para que el IBM i encuentre nuestro servidor por nombre en lugar de IP. Si llegara a cambiar y la conexión cayera el AUTOSSH volverá a reconectar de forma correcta. 
Instalamos el cliente de DYNU en Linux o podemos agregar un trabajo CRON que ejecute lo siguiente:

* * * * * curl  "http://api.dynu.com/nic/update?hostname=myserver.dynu.com&password=MYPASSWORD">/dev/null 2>&1

Este ejemplo refrescará cada minuto la IP pública del servidor myserver.dynu.com . Recuerden, este es el servidor de Amazon o la PC/N*tbook que rehabilitamos para hacer de puente.

4) En el servidor IBM i o Linux creamos un tunnel reverso que publique el puerto de SSH (debe estar encendido el *SSHD)  en el puerto 8022 usando AutoSSH.
El script puede ser algo así:

autossh -M 10988 -f -N  -R 8022:127.0.0.1:22  -p 443 USUARIO@myserver.dynu.com -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3"  

NOTA: Es importante que contemos con una llave de SSH para que nos podamos conectar SIN password al servidor Linux en Amazon/Casa/Oficina, como se indica en el artículo que publiqué con anterioridad.


5) En nuestra PC nos conectamos al mismo equipo, redirigiendo el puerto 8022 a nuestra PC:

autossh -M 10986 -f -N  -L 8022:127.0.0.1:8022  -p 443 USUARIO@myserver.dynu.com -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3"  


(en caso de usar Linux)

o bien con PuTTY:



5) Ahora creamos una 2da conexión, pero esta vez a LOCALHOST, en el puerto 8022, para crear el tunel dinámico:

autossh -M 10984 -f -N  -D 3128  -p 8022 USUARIO@myserver.dynu.com -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3"  

(Linux)

o bien en PuTTY:



Listo, ya tenemos una conexión a través de un equipo que nos hace de puente:




Ahora podemos usar el puerto 3128 en Localhost como un proxy SOCKS 5 en nuestro navegador, en PuTTY, en TN5250j o incluso con Proxychains/TSOCKS o ProxyFier








Necesitas saber que usuarios NO se han conectado en los últimos 3 meses a tu IBM i / AS/400?

Usando la UDTF USER_INFO ya no necesitamos enviar la lista de usuarios a un *OUTFILE, simplemente ejecutamos lo siguiente en nuestro equipo (siempre que tengamos las PTFs adecuadas ) SELECT AUTHORIZATION_NAME,PREVIOUS_SIGNON, STATUS, PASSWORD_CHANGE_DATE,USER_CLASS_NAME,SPECIAL_AUTHORITIES, TEXT_DESCRIPTION FROM QSYS2.USER_INFO WHERE CURRENT TIMESTAMP - 3 MONTHS > PREVIOUS_SIGNON AND STATUS = '*ENABLED' ORDER by PREVIOUS_SIGNON ASC Si usamos SQUIRRELSQL o DBVisualizer podemos exportar la salida a Excel sin mayor dificultad


IBM i/AIX/PowerLinux: Acelerando el equipo con OverClocking

En la prehistoria del cómputo personal, cuando teníamos que pedir prestada una computadora de un vecino para poder revisar un documento en un diskette flexible, las computadoras XT contaban con un botón con la leyenda TURBO.
Todo sabíamos que si apretábamos ese botón de TURBO las cosas se harían más rápido. Este botón simplemente permitía que el procesador ejecutara a una mayor frecuencia, lo cual se traducía en una mayor velocidad.
La mayoría de los procesadores cuentan con una velocidad nominal y una velocidad máxima. Esto es para no sobre exigir al procesador empujándolo a los umbrales de su capacidad, ya que mayor frecuencia se traduce en mayor disipación de calor y por consiguiente mayor consumo eléctrico. Si el calor no es disipado correctamente podríamos tener fallas e incluso dañar al procesador.
Pero los años han pasado y los procesadores de Intel finalmente incorporaron la tecnología Turbo Boost y luego Turbo Boost 2 en las versiones de escritorio, que aceleran la frecuencia del procesador de forma temporal cuando se presentan picos en las cargas. Al ser cambios temporales en la velocidad no corremos el riesgo de "freir" nuestro procesador, ya que este cambio lo administra el mismo equipo.
Obviamente también existe el overclocking que hacen los gamers, forzando al procesador a correr en velocidades por arriba de las especificaciones y empleando sistemas de enfriamiento especiales. Definitivamente no es algo que recomiende para trabajar...
En los procesadores Power contamos con características de administración de energía desde hace años, sólo que en versiones anteriores a Power7 necesitábamos software para poder hacer ajustes.
En procesadores Power7 o Power8 contamos con una opción en el ASMI para hacer este tipo de ajustes. Recuerden que para entrar en el ASMI tienen que conectarse desde la HMC o con un cable de red desde una PC al puerto de HMC, según sea el caso. Gracias a los ventiladores vectoriales que cambian de velocidad según la temperatura, no corremos riesgo alguno, salvo de incrementar la cuenta con la compañía de electricidad.Si necesitan detalles de cómo hacerlo pueden consultarme por comment o mensaje.
Debemos ir a System Configuration->Power Management->Power Management Mode Setup
Aquí veremos diferentes opciones. Por defecto la administración de energía está desactivada. Las opciones son:
  • Disable Power Saver Mode: no hay ahorro de energía. Trabajamos a la velocidad nominal del equipo
  • Enable Static Power Saver Mode: Ahorramos energía sin variaciones. El procesador baja la velocidad para ahorrar energía
  • Enable Dynamic Power Saver (favor power) mode: El equipo puede aumentar o disminuir la velocidad del procesador para tratar de ahorrar energía
  • Enable Dynamic Power Saver (favor performance) mode: El equipo puede aumentar o disminuir la velocidad del procesador para tratar de mejorar el rendimiento.
  • Enabled Fixed Maximum Frequency mode (en Power8): este valor mantiene el equipo en la frecuencia más alta posible, lo cual mejora el rendimiento.
Si activamos esta última opción podremos lograr que el equipo eleve los ciclos de CPU incluso por arriba de la velocidad nominal, logrando entre un 7% y un 11% adicional de potencia, a costa de consumir más energía eléctrica.
No tengo noticias de que alguien haya tenido problemas por este ajuste y obviamente el equipo está preparado para esto, gracias a sus dispositivos para medir la temperatura del procesador y ventiladores que reducen o aumentan la velocidad de acuerdo a las condiciones.
Espero les sea útil y si tienen dudas pueden dejarme un comentario

6 dic 2017

Subiendo archivos a OneDrive desde IBM i / AS/400




Quieren subir archivos a OneDrive ?

Recuerden, si tienen Office 365 personal cuentan con 1 TB de datos mientras dure la suscripción. Es super simple: Tienen que ir primero a la siguiente URL y descargar en la PC el Java OneDrive Client del usuario "wootie": http://bit.ly/2Ah1wJiIBM i /AIX : Luego seguir las instrucciones de cómo compilar con Java 7, lo cual también es simple (deben instalar Java 7 SDK y Maven):  mvn clean package -DskipTests   Luego deben ejecutar lo siguiente: java -jar onedrive-java-client.jar -a  (cuidado, en la documentación no está correcto el comendo) Deben ir a la dirección que les aparece en el navegador, presionar SI en el botón que aparecerá, copiar la URL que quede en el navegador cuando la pantalla se ponga en blanco y pegar el contenido en el archivo "onedrive.key" dentro del mismo directorio. Con estos datos podemos transferir el archivo JAR y el archivo .key al IBM i o a AIX.  Para subir archivos simplemente haremos: java -jar onedrive-java-client.jar --direction UP --local /home/dkesselman/ARCHIVOS --remote IBMiArchivos/IBM i /AIX : * /home/dkesselman/ARCHIVOS es la carpeta a "sincronizar" * UP es el sentido de la sincronización (del IBMi hacia OneDrive) * IBMiArchivos  es la carpeta remota donde dejaremos los archivos enviados 

Si se complican en la compilación, con gusto puedo enviarles el archivo .JAR listo para usarse.

IBM i: Journal de auditoría - Buscando las migajas de pan



La mayoría de quienes trabajamos con IBM i sabemos de qué se trata el journal de auditoría. Lamentablemente no todos lo usan, muchos menos lo consultan.
Con el journal de auditoría podemos saber quien está intentando hacer algo indebido, podemos determinar la IP, desde que estación de trabajo se conectó, que comandos intentó usar, etc.
Si nos ponemos a definir las razones por las cuales mucho no lo explotan podríamos mencionar:
  • Espacio en disco: Es cierto, puede ocupar mucho espacio si no lo controlamos
  • Desconocimiento: Aunque muchos teman admitirlo, no todos lo conocen al 100%
  • Tiempo: Si, hay que invertir tiempo en revisar la información.
  • Complejidad y/o volumen de la información que se recupere
Que pasaría si podemos reducir estos problemas para sacarle el jugo a este recurso fantástico que incluye nuestro servidor?
Si podemos separar sólo la información que nos interesa y almacenarlo en tablas quizá podamos ir depurando los journals antiguos.
Si automatizamos la conversión y la generación de reportes podríamos reducir el tiempo que empleamos
Si pudiéramos tener una serie de templates o una forma simple de hacer consultas podríamos reducir la complejidad de información a leer.
Manos a la obra
Primero lo primero, debemos activarlo. Esto requiere de los siguientes pasos:
1) Crear una biblioteca para los receivers
CRTLIB LIB(AUDJRN) TEXT('Journal Receivers de auditoria') AUT(*EXCLUDE) CRTAUT(*EXCLUDE) 

2) Creo el 1er receiver 
CRTJRNRCV JRNRCV(AUDJRN/AUDJRN0000)  

3) Creo el journal de auditoría
CRTJRN JRN(QSYS/QAUDJRN) JRNRCV(AUDJRN/AUDJRN0000) JRNOBJLMT(*MAX10M)   

Ahora debemos configurar los valores del sistema para "encender" el journal e indicar que información queremos guardar
1) Activo el journal
CHGSYSVAL SYSVAL(QAUDCTL) VALUE('*AUDLVL *NOQTEMP *OBJAUD')

2) Valores a auditar (Según la necesidad, estos son algunos básicos)
CHGSYSVAL SYSVAL(QAUDLVL) VALUE('*AUDLVL2')
CHGSYSVAL SYSVAL(QAUDLVL2) VALUE('*AUTFAIL *CREATE  *DELETE  *JOBDTA  *NETCMN  *SAVRST  *SECURITY *SERVICE *SYSMGT  *PGMFAIL')

Y luego debemos indicar los comandos, objetos y usuarios a auditar:
1) Usuarios
CHGUSRAUD USRPRF(USRTST01) OBJAUD(*CHANGE) AUDLVL(*CMD *NETBAS *JOBDTA *CREATE *DELETE)

2) Objetos/comandos
CHGOBJAUD OBJ(QSYS/CHGJOB) OBJTYPE(*CMD) OBJAUD(*ALL)

A partir de ejecutar todos estos comandos estaremos recogiendo información, según los valores que hayamos indicado.
El punto está, cómo podemos ver la información ? Naturalmente usamos el comando DSPJRN, pero la información no se ve en una forma muy amigable, aunque sí es bastante veloz. Toda la información se muestra agolpada, lo cual dificulta su lectura.
Por otro lado, sólo podemos verlo desde pantalla verde, lo cual no siempre es lo ideal. Quienes tengan departamento de auditoría muchas veces deben lidiar con el desconocimiento de la plataforma y la separación de roles.
No sería mejor poder hacer consultas usando SQL sin mayor trámite? En este ejemplo listamos las entradas PW (fallas de password) de las últimas 48 horas en direcciones diferentes a 10.* y 192.* para determinar conexiones externas (claro, si ese es nuestro direccionamiento interno)
SELECT *                                              
FROM TABLE(QSYS2.Display_Journal('QSYS', 'QAUDJRN',   
STARTING_TIMESTAMP => CURRENT TIMESTAMP - 48 HOURS , 
STARTING_RECEIVER_NAME => '*CURCHAIN'                 
)) AS x                                               
where JOURNAL_entry_type = 'PW'                       
and REMOTE_ADDRESS not like '10.%'                    
and REMOTE_ADDRESS not like '192.%'                   

IBM nos provee de una serie de UDTFs que podemos usar para consultas de este tipo. Sin embargo el resultado sigue siendo genérico, no tendremos campos específicos.
Para poder ver la información en forma más amigable, IBM nos provee de plantillas que podemos copiar y usar como un "cascarón" donde copiamos la información, pero si queremos hacerlo de forma más simple, podemos usar el comando CPYAUDJRNE:
CPYAUDJRNE ENTTYP(AF PW CP SV DS VC VN VS X0)          
             OUTFILE(ESSELWARE/QAUDIT) OUTMBR(*FIRST 
             *ADD) JRNRCV(*CURCHAIN) FROMTIME(28112017 000000)                                    

Si creamos un par de tablas con las descripciones que aparecen en los manuales, podríamos hacer consultas que sean más legibles:
SELECT PWTSTP as Fecha,
PWUSRN as Usuario, 
PWJOB as Trabajo,
PWNBR as Nro_Trabajo, 
PWPGM as Programa,
PWPGMLIB as Biblioteca,
trim(PWRADR) as Direccion_IP, 
B.PWTYPEDS as Tipo_de_Intento 
from ESSELWARE.QAUDITPW a, 
ESSELWARE.AUDPWTYPE b  
where a.PWTYPE = b.PWTYPE 
and PWTSTP >= '2017-11-01' 
and PWTSTP < '2017-12-01' 
order by PWTSTP

Podemos crear un simple CL que corra el comando CPYAUDJRNE todas las madrugadas para descargar la información en tablas auxiliares de los valores que nos interesan:
PW: Fallas de autenticación
AF: Fallas de autorización (intentos fallidos de acceder a objetos)
SV: Cambios a valores del sistema
CD: Comandos
CP: Cambios, creación o restauración de perfiles de usuarios
DS: Reset de password del usuario de DST (recuerden que con el DST podemos recuperar el QSECOFR)
ST: Uso de Herramientas de Servicio (recuerden que con el DST podemos recuperar el QSECOFR)
VS: Iniciando o terminando una sesión de servidor
... y los valores que consideren necesarios.
Luego podríamos enviar mediante un ETL, DataPump o CSV->FTP los datos a una base de datos auxiliar (MySQL? SQLite? SQL Server?) para la explotación por parte los oficiales de seguridad.
En mi caso uso unos pequeños programas PHP para generar los reportes. Si les interesa el código con gusto se los comparto. Envíen comentarios o mensajes para solicitarlos.
Algunos consejos
  • Controlen el espacio en disco
  • Revisen las entradas sensibles de forma periódica. Incluso hay gente que cuenta con un programa de envío diario de reportes en PDF. Esto se podría hacer sin mucha complicación con un CL bastante simple.
  • Protejan la biblioteca de los receivers
  • Respalden los journals antes de borrarlos. La mejor práctica es hacerlo en una cinta separada, quizá junto con los journals de tablas (tema para otro artículo).
  • Algunas entradas tienen información parcial o de forma poco amigable, como podrían ser las conexiones ODBC/JDBC/OleDB/ADO. En esos casos quizá convenga generar logs en tablas usando Exit Point Programs.
  • Si existen requerimientos regulatorios siempre recomiendo usar herramientas, que ayudan a automatizar la generación de reportes y suelen tener plantillas para las auditorías. Algunas de estas herramientas incluso se llevan la información de forma continua a otra base de datos por aquello de la separación de roles.
  • Si el período a analizar es grande (3 o más meses) y el espacio a emplear es considerable, nuevamente, hay herramientas que administran de forma eficiente el espacio y suelen llevarse el análisis a un equipo separado. Recuerden que el costo x TB en IBM i suele ser más alto que 1 TB en la nube o en un servidor con Intel y MariaDB/MySQL/SQLite
Espero que les haya sido de utilidad.

IBM i - AS/400 : Capturando las instrucciones SQL ... (2) - Plan Cache Snapshots



Retomando el tema de las instrucciones ODBC, hoy vamos a verlas desde el punto de vista del rendimiento. Esto no significa que no podamos usarlo con fines de auditoria o forensia, pero no ha sido pensado con ese fin, aunque pueda resultar efectivo.
Normalmente cuando tenemos problemas con el rendimiento de la base de datos y no encontramos que está ocurriendo, lo primero que nos dice el especialista suele ser arrancar el DBMon o un supervisor de SQL.
Estos mecanismos son muy útiles para poder determinar problemas de rendimiento, errores en los queries, comportamientos anómalos, etc. Sin embargo tienen la gran desventaja de un volumen de información exageradamente alto, lo cual impide correrlos por períodos prolongados. Por prologado hablamos de más de 1 o 2 horas. A esto debemos sumar que en algunos casos generan carga y puede entorpecer la ejecución de procesos en su tiempo óptimo.
A nuestro rescate llega el IBM i ACS (el reemplazo Java del Cliente Access), que desde BASE DE DATOS-> SQL Performance Center-> Plan Cache Snapshots nos permite crear un volcado del plan cache en un archivo, pudiendo aplicar filtros.
Es importante tener el IBM Navigator for i funcionando. Deben recordar instalar los PTFs de HTTP, DB2 y Java, aparte de los acumulativos correspondientes. Si no lo tenemos funcionando también podremos tomar el snapshot usando Client Access o línea de desde línea de mandatos con STRSQL:
  CALL qsys2.dump_plan_cache('ESSELWARE','BMPRD171120');
El primer parámetro es la biblioteca, el 2do el nombre del snapshot.
Este volcado nos mostrará la mayoría de los comandos SQL que se hayan ejecutado desde el último IPL. Es importante destacar que no todos los comandos SQL son salvados en memoria, ya que algunos programas recalculan el plan, dando flush a mucha información valiosa.
Sin embargo, es un mecanismo veloz, consume pocos recursos, y podemos indicar que queremos las instrucciones que se están ejecutando o sólo la información histórica.
Con botón derecho sobre el snapshot nos permite ver diferentes opciones:
  • Analizar
  • Mostrar instrucciones SQL
  • Investigar
  • Comentarios
Nos centraremos en los 2 primeros puntos
Analizar
Nos permite ver información estadística de las instrucciones SQLs, desde el tipo de instrucción, hasta la duración o grado de proceso paralelo empleado, el tipo de denominación usada, etc.
Si selecciono de la lista junto a Sentencias SQL la opción de Resumen podré ver un resumido de las instrucciones que guardó en los archivos de estadísticas de forma tabular. Con Detalle aparecerán todas, incluso las repetidas.
Moviéndome hacia la derecha se pueden ver las instrucciones capturadas y datos estadísticos de cada uno, incluyendo ID del proceso.
Pero lo interesante es poder ver el Visual Explain, que es una de las gemas del iACS y del Client Access.
Parados sobre el registro que nos interesa damos click derecho y seleccionamos Trabajar con sentencias SQL. Luego, en la ventana de Run SQL Scripts podemos darle al botón que indica Explain. Algunas veces deberemos corregir el nombre de la biblioteca o reemplazar una "/" por un "."
Los resultados pueden ser más que interesantes, ya que nos puede advertir de falta de índices, operaciones de full-scan, búsquedas no optimizadas con simples filtrados, etc. y podemos descomponer la instrucción en diferentes tareas para entender al forma en que ejecuta.
Recuerdo haber envidiado a los DBAs de Oracle por una herramienta que permitía ver el plan de ejecución, pero con Visual Explain quedé satisfecho.
Lo importante es que podemos capturar toda esta información sin tener que hacer un trace, y el tiempo de tomar el snapshot, que obviamente tiene relación con la cantidad de instrucciones a guardar, es aceptable (por lo general no supera los 5 o 10 minutos).
Espero que les sea útil. Pueden dejarme comentarios si tienen dudas o consultas.

IBM i - AS/400 : Capturando las instrucciones SQL que están ejecutando en este momento - ODBC/JDBC



Cuando tenemos programas que se conectan por JDBC u ODBC y al mirar con WRKACTJOB en los trabajos QZDASOINIT nos comenzamos a rascar la cabeza tratando de adivinar que está ocurriendo.
Si nuestra aplicaciones son Cliente/Servidor y cada usuario se conecta con un perfil diferente al menos podemos distinguir a quien corresponde cada conexión con el CURRENT USER y podemos obtener su dirección IP revisando dentro del trabajo.
Cuando tenemos aplicaciones web, por lo general todos se conectan usando un mismo perfil de usuario y una misma dirección IP , lo cual se puede volver desconcertante. Los usuarios suelen estar declarados en tablas de la base de datos o en un directorio activo o LDAP, lo cual no es fácil de filtrar y detectar.
Ni hablemos de saber que está ocurriendo en ese momento en que queremos ver su SQL, porque en ninguno de los dos casos podremos verlo a menos que activemos el DBMON o un supervisor de SQL para luego analizarlo.
No sería fantástico poder ver las instrucciones SQL de la misma forma que usamos el WRKACTJOB?
Prueben esto:
WITH ACTIVE_USER_JOBS (Q_JOB_NAME,  CPU_TIME, RUN_PRIORITY) 
AS (SELECT JOB_NAME, CPU_TIME, RUN_PRIORITY 
FROM TABLE (QSYS2.ACTIVE_JOB_INFO('NO','','','')) x 
WHERE JOB_TYPE <> 'SYS'SELECT Q_JOB_NAME, 
CPU_TIME, 
RUN_PRIORITY, 
CURRENT TIMESTAMP - V_SQL_STMT_START_TIMESTAMP AS SQL_STMT_DURATION, 
B.* 
FROM ACTIVE_USER_JOBS, TABLE(QSYS2.GET_JOB_INFO(Q_JOB_NAME)) B 
WHERE V_SQL_STMT_STATUS = 'ACTIVE'
ORDER BY SQL_STMT_DURATION DESC
Esto les mostrará los comandos SQL de los trabajos activos.
En pocas palabras, estamos usando una serie de UDTFs nuevos que corresponden a V7R2 y que proveen servicios similares al WRKACTJOB, pero con mayor nivel de detalle.
Ahora bien, entre todos los valores que podemos recuperar hay unos registros especiales y EDITABLES!!! Esto significa que de forma programática podríamos guardar valores desde nuestro programa como si fueran variables y consultarlos.
V_CLIENT_WRKSTNNAME CHAR(255) Value of the SQL CLIENT_WRKSTNNAME special register.
V_CLIENT_APPLNAME CHAR(255) Value of the SQL CLIENT_APPLNAME special register.
V_CLIENT_ACCTNG     CHAR(255) Value of the SQL CLIENT_ACCTNG special register.
V_CLIENT_PROGRAMID CHAR(255) Value of the SQL CLIENT_PROGRAMID special register.
V_CLIENT_USERID     CHAR(255) Value of the SQL CLIENT_USERID special register.

Qué podríamos guardar?
IP del usuario final, Nombre de la aplicación, Nombre del programa que ejecuta, Usuario local al sistema y cualquier otro valor que nos permita identificar la sesion.
Para poder actualizar esos valores deberemos comandos como este, o jugar con las propiedades de la conexión. Me quedo con el stored procedure:
  CALL SYSPROC.WLM_SET_CLIENT_INFO('MyUser', 'https://www.linkedin.com/redir/invalid-link-page?url=192%2e168%2e123%2e123', 
     'CORE Banking', 'Modulo1', 'ProgramaXYZ02')

Y eso permitirá combinar la información de SQL, el programa asociado, la IP del cliente y su nombre de usuario.
Es un poco lo que usamos con WEBACTJOB, aunque con algunos agregados para poder terminar el trabajo, ver su joblog ,etc.
En un próximo artículo les explicaré como podemos tomar una "foto" de todos los trabajos corriendo con sus conexiones y comandos SQL para poder analizar que ocurre, sin tener que ejecutar el DBMON.
Suerte

Cómo conectarme a un servidor remoto en una red protegida - Versión actualizada

En un artículo anterior describí cómo conectarse a un equipo remoto en una red protegida http://diego-k.blogspot.mx/2014/12/como-conectarme...