SELECT * FROM TABLE(QSYS2.TRACKED_JOB_INFO(JOB_QUEUE_LIBRARY_FILTER => ‘GG’, JOB_QUEUE_FILTER => ‘GGTEST’)) ORDER BY INTERNAL_JOB_IDENTIFIER, ROUTING_STEP;
https://www.gaia.fr/wp-content/uploads/2017/02/team3.png600600Pierre-Louis BERTHOIN/wp-content/uploads/2017/05/logogaia.pngPierre-Louis BERTHOIN2024-05-10 15:35:052024-05-10 15:35:06Gestion du suivi des tâches soumises
Vous pouvez demander un tas d’informations d’audit pour tracer les violations de sécurité par exemple
Vous devez avoir le droit *AUDIT sur votre profil pour la mettre en place, c’est valeurs système qui permettent de le paramétrer les informations souhaitées
QAUDCTL, QAUDLVL, QAUDLVL2
Pour chaque information demandée, vous allez avoir un poste qui est créé dans le journal d’audit QAUDJRN.
Pour consolider ces informations, vous devez les copiez dans des fichiers il existait jusqu’à présent 2 méthodes
1) Les fichiers modèles utilisables dans des commandes IBMi
exemple pour les types PW, c’est le fichier QASYPWJ5 que vous devez dupliquer dans votre bibliothèque DSPJRN JRN(QAUDJRN) ENTTYP(‘PW’) OUTPUT(OUTFILE) OUTFILFMT(TYPE5) OUTFILE(MABIB/WASYPWJ5)
La stratégie est la suivante , la première fois vous demandez la création du fichier de sortie par un crtdupobj et après vous ajoutez à ce fichier tous les soirs à 23 h 59 les postes PW
2) Les Technology Refresh nous apportent régulièrement des services
Ces services permettent de lire directement ces informations par SQL. c’est les fonctions tables qui se trouve dans SYSTOOLS et qui s’écrivent SYSTOOLS.AUDIT_JOURNAL_XX() XX étant le type exemple pour les types PW SYSTOOLS.AUDIT_JOURNAL_PW()
voici un exemple
select A.VIOLATION_TYPE_DETAIL, A.AUDIT_USER_NAME , A.REMOTE_ADDRESS, A.ENTRY_TIMESTAMP from table (SYSTOOLS.AUDIT_JOURNAL_PW(STARTING_TIMESTAMP => current timestamp – 1 days)) A order by A.ENTRY_TIMESTAMP desc
La stratégie est la suivante , la première fois vous demandez la création du fichier de sortie par un create table as() et après vous ajoutez à ce fichier tous les soirs à 23 h 59 les postes PW par un insert
3) Avec la TR (4 pour V7R5 et 10 pour V7R4)
elle vous apporte une solution intégrée pour créer votre DATAMART https://www.ibm.com/support/pages/ibm-i-75-tr4-enhancements Vous avez 2 services
Vous avez une vue qui vous permet de suivre vos mises à jour de datamart
SELECT DATA_MART_LIBRARY, DATA_MART_TABLE, JOURNAL_ENTRY_TYPE, BUILD_END, FAILURE_DETAIL FROM QSYS2.AUDIT_JOURNAL_DATA_MART_INFO WHERE JOURNAL_ENTRY_TYPE = ‘PW’ AND DATA_MART_LIBRARY = ‘MALIB’ ;
Vous pourrez également manager par Navigator for i
Remarque :
Bien sur vous avez toujours aussi un onglet dans Navigator for i qui vous permet de voir sous forme de graphique les résultats , mais attention uniquement sur les postes en cours . Si vous avez déjà une solution, c’est compliqué de revenir dessus, mais si vous n’avez rien ca vous simplifier considérablement les taches. Attention dans tous les cas c’est à vous d’épurer les récepteurs quand vous les avez traité
https://www.gaia.fr/wp-content/uploads/2017/02/team3.png600600Pierre-Louis BERTHOIN/wp-content/uploads/2017/05/logogaia.pngPierre-Louis BERTHOIN2024-05-10 10:08:422024-05-10 15:25:50Manager les informations d’audit avec la TR4
il faut savoir qu’un fichier SAVF est un fichier PF de 528 de long.
Vous pouvez avoir besoin pour différentes raisons de convertir SAVF en PF pour manipuler plus simplement par SQL, pour contourner des restrictions d’utilisations etc ..
Vous trouverez ici 2 commandes qui vont vous permettent de réaliser cette opération : https://github.com/Plberthoin/PLB/tree/master/CPYSAVF
Copier un SAVF dans un PF
Voir le PF
Copier un PF dans un SAVF
Voir le Résultat
Pour voir ce résultat taper la commande DSPSAVF , Voir WRKSAVF si vous avez installez notre outil
Remarque :
Outil simple mais efficace qui peut rendre des services à des administrateurs
https://www.gaia.fr/wp-content/uploads/2017/02/team3.png600600Pierre-Louis BERTHOIN/wp-content/uploads/2017/05/logogaia.pngPierre-Louis BERTHOIN2024-05-03 09:10:562024-05-03 09:10:58Convertir un SAVF en PF
Vous devrez lui indiquer dans la paramètre PGMDTA la commande qualifiée à tracer exemple : ‘STRDBG QSYS’
Les données reçues sont sur le format CHGC0100 qui vous donne le découpage du buffer reçu par votre programme
Vous pouvez faire un programme générique qui va loguer l’utilisation d’une commande, vous pouvez en mettre plusieurs et la prise en compte est immédiate
Il y a plusieurs solutions, la plus simple est sans doute celle la ,vous devrez avoir accès à la console et connaitre un mot de passe sur la console (HSCROOT par exemple)
Il faut savoir que vous pouvez vous connecter à celle ci, même si vous avez un mot de passe désactivé.
A partir d’ACS
Sélectionner Console 5250
Vous devez rentrer un mot de passe de votre HMC, exemple HSCROOT
Vous devez choisir votre partition
et saisir le mot passe même *DISABLED sur la mire d’ouverture
Une fois connecter il suffit de réactiver le profil
==>CHGUSRPRF USRPRF(QSECOFR) STATUS(*ENABLED)
Remarque:
Il est malgré tout conseillé d’avoir un compte de secours que vous dédiez à une reprise derrière une désactivation intempestive.
Par exemple :
SECOURS qui sera dédié à ca avec des droits identiques à QSECOFR et avec un mot de passe gardé au coffre
plus d’informations ici : https://www.ibm.com/support/pages/qsecofr-profile-disabled
https://www.gaia.fr/wp-content/uploads/2017/02/team3.png600600Pierre-Louis BERTHOIN/wp-content/uploads/2017/05/logogaia.pngPierre-Louis BERTHOIN2024-03-27 14:27:542024-03-27 15:40:15Mot de passe QSECOFR désactivé
C’est une bibliothèque qui contient les sources d’environ 15 outils IBMi, le plus connu est NETS qui permet de gérer les partages en mode 5250. Elle est développée par Jim Sloan, ce sont les outils TAATOOLS et depuis la version V3.7 ce sont eux qui gérent les licences.
Donc vous pouvez acquérir une licence du produit en vous adressant ici : support@taatool.com
Vous pouvez également avoir une version des outils sur votre machine : en effet avant la version 3.7 IBM distribuait gratuitement ce produit
Dans ce menu vous avez par exemple l’option 12 qui permet de gérer les utilisateurs désactivés, c’est une alternative simple à Navigator for i dans certains cas.
Pour rappel, les listes de validation sont des objets sur IBMi, de type VLDL.
Par ligne de commande, on peut seulement créer une liste ou la supprimer.
L’utilisation classique des listes d’autorisation est la sécurisation de vos serveurs IWS par authentification basique. Celles-ci permettent l’utilisation d’un profil qui n’est pas un réel utilisateur IBM i.
La gestion, de ces listes, se passe dans navigator for i, dans le HTTPAdmin :
Onglet « Advanced »
Ce que vous pouvez faire :
Ajouter une entrée dans la liste, si la liste de validation n’existe pas, elle sera créé pour l’occasion. A minima, il faut renseigner la liste de validation, un profil et un mot de passe
Changer le mot de passe d’une entrée
Supprimer une entrée
Lister les entrées d’une liste
Ce que vous ne pouvez pas faire :
Consulter le mot de passe en cours d’une entrée, un classique en terme de sécurité.
Supprimer une liste de validation, il faut utiliser la commande 5250 DLTVLDL
Pour mettre en place la sécurisation d’un serveur via ces listes, il faut, toujours depuis le HTTPAdmin, au niveau de la gestion des sécurités de votre serveur HTTP*, sélectionner l’option liste de validation :
Avantage :
Ne pas créer de réel utilisateur IBMi pour l’authentification.
Permettre à des tiers extérieurs d’avoir un login ne pouvant servir que dans le cadre d’appel HTTP à un serveur protéger par la liste d’autorisation dont est issu le login
Encryption de la liste au niveau OS. Pas de possibilité d’accès aux données de la liste de façon simple.
En cas d’appel depuis l’extérieur du réseau de confiance, ça semble une bonne option.
Inconvénient :
Il faut connaître en amont le client qui va se connecter, et donc avoir une gestion de demande /création de compte
L’interface de gestion n’est pas compatible avec un grand nombre d’entrées dans la liste. Dans ce cas il faudra, soit trouver une autre solution pour sécuriser son serveur, soit utiliser les API misent à disposition par IBM
* Sur les versions récentes, la sécurité peut aussi être gérée au niveau du serveur applicatif. A vous de voir, si vous voulez un duo de serveurs HTTP/applicatif ou seulement un serveur applicatif, mais c’est un autre sujet…
IBM nous fournit des API pour gérer les listes de validation. On retrouve les actions possibles dans Navigator for i…. Et d’autres !
En regardant de plus près ces API, on constate sur la création d’une entrée de la présence d’un attribut permettant ou non de décrypter un mot de passe :
Navigator for i utilisant les valeurs par défaut, lorsqu’on crée une entrée par ce biais, le mot de passe n’est pas décryptable. Par contre, si on crée une entrée par l’API correspondante, avec cet attribut positionné à QSY_VFY_FIND (1), on peut par la suite récupérer le mot de passe via l’API C QsyFindValidationLstEntry() ou son équivalent QSYFDVLE
Prenons des exemples :
Je crée dans une liste de validation, dédié à l’article, DTFORM/DEMOBLOG, un profil MdpnonVIsible avec l’attribut de décryptage à ‘0’, et un profil MdpVisible avec l’attribut de décryptage à ‘1’.
Première remarque : l’appel d’api d’ajout d’une entrée dans une liste de validation renvoie un erreur si la liste n’existe pas. Il faut la créer au préalable par la commande CRTVLDL.
En regardant dans Navigator for i, les deux entrées apparaissent sans distinction :
Lors du décryptage, si on tente un appel de l’API find avec une erreur, mauvais nom de liste, profil inexistant, …, le retour est en erreur, comme pour toutes les API : -1. On peut récupérer le message détaillé de l’erreur, on reste sur de la gestion standard :
Si on lance l’API Find avec pour le profil MdpnonVisible :
L’API renvoie un code retour ok, mais pas de mot de passe, normal, il n’est pas décryptable.
Avec le profil décryptable, on récupère bien le mot de passe initial :
Par cette méthode, vous pouvez donc récupérer des mots de passe stockés dans une liste de validation, à la condition que l’entrée ait été créée avec le top de décryptage à ‘1‘.
Pour compléter la sécurité sur le décryptage des mots de passe, vous pouvez mettre :
Sur la liste de validation
Un profil technique comme propriétaire
Aucun droit sur aucun autre profil .
Avoir un programme dédié au décryptage avec :
Comme propriétaire le même que celui de la liste de validation
Compilé pour faire de l’adoption de droit.
Et si on veut aller plus loin, en cas de debug possible en prod, protéger les sources, du programme de décryptage et ses appelants, par mot de passe.
Bien entendu cette stratégie n’est valable que si la gestion des droits utilisateurs est rigoureuse… Pas de *allobj sur les profils par exemple !
Conclusion :
Vous pouvez utiliser les listes de validation pour stocker des profils/mot de passe, sans les stocker en clair sur la machine. Mais on peut très bien imaginer utiliser ces listes pour stocker toutes les données sensibles permettant les échanges inter-applications ou autre :
URL d’invocation de WS
IP ou nom DNS pour FTP / SFTP
…
Et pour cela de se créer une liste par usage, liste pour URL, liste pour IP/DNS, …, de mettre dans le profil, un code application, et dans le mot de passe la valeur que l’on veut récupérer, avec la limitation de 600 caractères pour le mot de passe, à part pour des URL très spécifique, ça ne devrait pas être limitatif.
Les listes de validation restent des objets très peu connu, mais qui mérite de l’être !
/wp-content/uploads/2017/05/logogaia.png00Damien Trijasson/wp-content/uploads/2017/05/logogaia.pngDamien Trijasson2024-02-05 14:16:002025-03-19 10:40:31Utiliser les listes de validation comme coffre fort de mot de passe
Depuis la V7R1 (SF99701 – DB2 – niveau 23), on peut invoquer des web service via SQL. Les fonctions se trouvent dans SYSTOOLS.
En V7R4 TR5, sont sorties de nouvelles fonctions, elles se trouvent dans QSYS2.
Outre les fonctions HTTP, celles pour encoder / décoder en base64 et pour encoder / décoder L’URL, ont aussi été implémentées dans QSYS2.
Rappel des différences entre ces fonctions
Tout d’abord les performances. Les fonctions de QSYS2 permettent un gain non négligeable, elles sont basé sur les fonctions AXIS en C natif, contrairement à celles de SYSTOOLS qui sont basées sur des classes java.
Les paramètres dans l’entête ou le corps du message sont transmis en JSON pour les fonctions de QSYS2, à la place de XML pour celle de SYSTOOLS.
La gestion des certificats est simplifiée par l’utilisation de DCM, alors qu’avec les fonctions de SYSTOOLS, il fallait pousser le certificat dans le magasin du runtime java utilisé par les fonctions HTTP. En cas de multiple versions de java installées, il fallait s’assurer de laquelle servait pour les fonctions HTTP. L’ajout du certificat, se faisait via des commandes shell.
Les types et tailles des paramètres des fonctions ont été adaptés pour ne plus être des facteurs limitants de l’utilisation des fonctions SQL, voici quelques exemples :
Certaines utilisations ont aussi été simplifiées en automatisant des tâches.
Prenons l’exemple d’un appel à un web service avec une authentification basique. Le couple profil / mot de passe doit être séparé par « : » et l’ensemble encoder en base64. C’est la norme HTTP.
Dans le cas des fonctions de SYSTOOLS, il fallait effectuer l’ensemble des opérations, alors qu’avec les fonctions de QSYS2, il suffit de passer le profil et le mot de passe dans la propriété BasicAuth. La mise en forme et l’encodage étant faits directement par les fonctions AXIS :
Il y a par contre un cas limitatif des fonctions QSYS2, que IBM a rajouté, alors que la norme HTTP autorise ce type d’appel.
Il s’agit d’avoir une authentification basique sur un appel en http.
Ce cas n’est pas trop contraignant, aujourd’hui le https est la norme et le http quasiment disparu…. quasiment ! Nous rencontrons encore chez nos clients des web services « interne » en http. La migration en https n’étant pas vendeur auprès des directions qui n’y voit aucun gain pour le métier. C’est l’éternel problème des changements structurels en IT.
Dans ces cas, la fonction de QSYS2, renverra une erreur, assez claire !
Le premier réflexe est de voir avec le fournisseur du service s’il ne dispose pas d’une version en https.
Maintenant, si vous n’avez pas d’autre choix que d’appeler un web service en http avec authentification basique, il faudra continuer d’utiliser les fonctions de SYSTOOLS. Dans tous les autres cas, aucune hésitation, utilisez les fonctions de QSYS2.
Mais mettons nous d’accord, de l’authentification basique en http, ce n’est pas de la sécurité, c’est une absurdité.
En http, le message passe en clair sur la trame réseau, avec votre profil / mot de passe, encodé en base 64, et non encrypté, donc en clair eux aussi.
Edit :Précision apportée par Gautier Dumas de CFD-innovation. Merci à lui. On peut contourner le problème avec les fonctions de QSYS2. Il ne faut pas utiliser la propriété BASICAUTH, mais construire l’authentification basique comme on le faisait avec celle de SYSTOOLS. VALUES QSYS2.HTTP_GET( ‘http://hostname/wscommon/api/contacts’, ‘{« header »: »Authorization, BASIC dGVzdHVzZXI6dGVzdHB3ZA== »}’); Il n’y a donc vraiment plus de raison de continuer avec les fonctions de SYSTOOLS !
Vous pouvez utiliser le catalogue base de données pour identifier vos informations sensibles
Pour cela vous allez utiliser les vues syscolumns de QSYS2 (norme IBMi) ou sqlcolumns de SYSIBM (norme DB2)
Vous pouvez rechercher toutes les zones qui contiennent (email, mail, RIB, IBAN, ETC..)
Dans notre exemple , on recherchera les zones IBAN dans toutes les tables en analysant : Nom de zone SQL Nom de zone IBMI Entête de colonne Texte de colonne
Sans différentiation de majuscule minuscule
Et on sortira la liste des droits public sur ces objets
— liste des fichiers avec une zone IBAN
— Avec un IBAN
SELECT COLUMN_NAME AS Zone,
IFNULL(COLUMN_HEADING, ' ') AS Entete,
IFNULL(COLUMN_TEXT, ' ') AS Text,
TABLE_SCHEMA AS bibliotheque,
TABLE_NAME AS fichier,
(SELECT OBJECT_AUTHORITY
FROM QSYS2.OBJECT_PRIVILEGES
WHERE SYSTEM_OBJECT_SCHEMA = TABLE_SCHEMA
AND OBJECT_NAME = TABLE_NAME
AND OBJECT_TYPE = '*FILE'
FETCH FIRST ROW ONLY) AS DROIT_public
FROM qsys2.syscolumns
WHERE COLUMN_NAME LIKE ('%IBAN%')
OR SYSTEM_COLUMN_NAME LIKE ('%IBAN%')
OR UCASE(COLUMN_HEADING) LIKE ('%IBAN%')
OR UCASE(COLUMN_TEXT) LIKE ('%IBAN%');
Conclusion :
Ca veut dire que toutes les tables avec *public à *USE sont visualisables par tous les utilisateurs de la machine.
Pour sécuriser vous devez le faire sur les fichiers Soit – Mettre en place des droits sur l’objet, attention l’utilisateur peut avoir droit à ce fichier quand il est dans l’application. Soit – Sécuriser un service d’accès par exemple ici ODBC, pour éviter un accès remote, (Fonctions usage ou programme d’exit sont les meilleurs solutions)
Bien sur si vous créez de nouvelle table vous pouvez crypter ces zones, ce qui la rendrait illisible à un utilisateur qui ne connait pas la clé
Contrôler le nombre de paramètres passés à un programme CL – %PARMS() / CEETSTA
Il arrive parfois d’avoir moins de paramètres passés à un programme CL que le nombre attendu, par exemple si on ajoute un paramètre à ce dernier mais que pour diverses raisons on ne souhaite pas modifier et recompiler tous les programmes qui y font appel.
Il existe deux solutions relativement simples à implémenter pour contrôler le nombre de paramètres transmis afin d’adapter en conséquence le comportement du programme : La fonction intégrée %PARMS et l’API CEETSTA.
%PARMS() – V7R4 et ultérieures
À partir de la V7R4, rien de plus simple, il suffit d’utiliser la fonction intégrée %PARMS(), qui retourne le nombre de paramètres :
PGM PARM(&PARAM1 &PARAM2)
/* Paramètres */
DCL VAR(&PARAM1) TYPE(*CHAR) LEN(10)
DCL VAR(&PARAM2) TYPE(*CHAR) LEN(10)
/* Corps du programme en fonction du passage du paramètre */
IF COND(%PARMS() *EQ 2) THEN(DO)
SNDPGMMSG MSG('Le paramètre &PARAM2 est renseigné')
ENDDO
ELSE CMD(DO)
SNDPGMMSG MSG('Le paramètre &PARAM2 n''est pas renseigné')
ENDDO
ENDPGM
Malheureusement, si on est confrontés à une contrainte de version, %PARMS ne descend pas en dessous de la V7R4 :
CEETSTA – V7R3 et antérieures
Dans ce cas, la solution la plus propre (je ne parlerai donc pas de monitoring sur un CHGVAR) est l’utilisation de l’API CEETSTA. Il suffit de lui passer en paramètre : – Une variable qui contiendra la valeur de retour, 1 si le paramètre est transmis, 0 s’il n’est pas transmis – Une variable indiquant la position du paramètre à contrôler
presence_flag
Sortie
*INT
Variable de retour : 1 ou 0
arg_num
Entrée
*INT
Position de la variable à tester
PGM PARM(&PARAM1 &PARAM2)
/* Paramètres */
DCL VAR(&PARAM1) TYPE(*CHAR) LEN(10)
DCL VAR(&PARAM2) TYPE(*CHAR) LEN(10)
/* Déclaration des variables nécessaires à l'utilisation de l'API */
DCL VAR(&PRESENCE) TYPE(*INT) /* Variable de retour : 1 ou 0 */
DCL VAR(&ARG_NUM) TYPE(*INT) VALUE(2) /* Position de la variable à tester */
/* Appel de l'API */
CALLPRC PRC('CEETSTA') PARM((&PRESENCE) (&ARG_NUM))
/* Corps du programme en fonction du passage du paramètre */
IF COND(&PRESENCE *EQ 1) THEN(DO)
SNDPGMMSG MSG('Le paramètre &PARAM2 est renseigné')
ENDDO
ELSE CMD(DO)
SNDPGMMSG MSG('Le paramètre &PARAM2 n''est pas renseigné')
ENDDO
ENDPGM
Remarques
Le compte des paramètres pour la arg_num commence à 1 La valeur de retour est un *INT pas un *LGL
https://www.gaia.fr/wp-content/uploads/2023/08/Openssh.gif191194Julien/wp-content/uploads/2017/05/logogaia.pngJulien2023-12-24 01:41:132023-12-24 01:41:15Contrôler le nombre de paramètres passés à un programme CL – %PARMS() / CEETSTA