, Retour d’expérience installation IBM i 7.6

En bons élèves, nous profitons de l’été pour faire nos devoirs de vacances. Entre autre, installation de la version 7.6 sur plusieurs de nos partitions.

D’abord une partition de test, bac à sable, puis nos partitions de production i(vous avez peut être vu une interruption de service sur nos sites web).

J’en profite pour faire un petit retour d’expérience sur ces installations.

Et pour finir ce préambule, je remercie l’équipe du support !

Une mise à jour comme les autres ?

Oui, je ne détaille pas ici le processus de mise à jour, c’est classique : téléchargement des images et clés sur ESS, PRUV pour les contrôle etc …

Quelques points d’attention

  • DST/SST
    • Le mot de passe de QSECOFR ne doit pas être celui par défaut (sinon il sera inutilisable)
    • Les profils 11111111 et 22222222 sont supprimés pendant l’installation
    • Bonne pratique : créer au moins un autre profil avec tous les droits pour DST, changer le mot de passe de QSECOFR. Les profils 11111111 et 22222222 ne devraient déjà plus être utilisés depuis longtemps
  • Java 11 64 bit non supporté

Ce qui nous a échappé

Deux sujets qui m’ont mobilisés !

Impossible de saisir le mot de passe de QSECOFR au démarrage

Après l’installation de la 7.6 sur la partition, et fort satisfait, je tentes de me loguer avec QSECOFR : informations d’authentification incorrectes !

Après vérification dans mon gestionnaire de mots de passe, nouvelle tentative : idem.

A la 3ème, profil désactivé …

Heureusement, j’ai toujours un profil clone de QSECOFR pour remédier à ces situations : je change le mot de passe de QSECOFR, et là cela fonctionne !

Le problème est connu et nécessite d’appliquer la PTF SJ05805 (cf https://www.ibm.com/mysupport/s/defect/aCIgJ0000000lGfWAI/dt438834?language=fr). Les mots de passe sont testés en CCSID 37 par le système au lieu du CCSID du travail (émulateur). C’est principalement le caractère « ! » qui pose problème.

Bonne pratique : changer le mot de passe de QSECOFR avant la migration pour un mot de passe simple (quitte à déroger aux règles le temps de l’installation).

Problème de connexion sur tous les serveurs hôtes en TLS

Après installation de la 7.6, impossible de se connecter en telnet sécurisé, ni aux autres services

Et effectivement, le mémo to user (cf https://www.ibm.com/docs/en/ssw_ibm_i_76/pdf/rzaq9.pdf) indique bien :

Dans DCM, allez dans le magasin *SYSTEM, puis gérer « Manage Applications Definitions », sélectionner l’application QIBM_QZBS_SVR_HOSTCNN et associez un certificat (en général le même pour l’ensemble des serveurs hôtes) :

Dès validation la connexion TLS fonctionne, pas besoin d’arrêter/redémarrer des services.

Ce fonctionnement est nécessaire pour la mise en œuvre du MFA, mais impact les services existants.

Tous les systèmes étant sécurisés depuis de nombreuses années, vous devriez être impacté …

En synthèse

A noter que l’ensemble des éléments est bien documenté, y compris les « détails » qui nous ont posés quelques soucis (exception du mot de passe non reconnu).

Une bonne préparation permet de réaliser une migration maitrisée, l’installation elle-même se déroule très bien et rapidement.

, V7R6, la liste des commandes supprimées

APYJRNCHGX Appliquer modifs journal étend
CFGPMAGT Configure PM Agent
CFGPM400 Configure PM Agent
CHGDHCPSVR Change DHCP Server
CHGRTDA Change RouteD Attributes
CPYIGCSRT Copy DBCS Master Sort Table
MRGFORMD Fusionner description imprimé
STRAPF Démarrer APF
STRCGU Start CGU
STRRLU Démarrer Utilit maquette état
STRSDA Démarrer SDA
WRKPMRMTS Work With Remote Systems
WRKPMRPTO Work With Omissions
WRKPMSCH Work With Scheduled Jobs
WRKRTDCFG Work with RouteD Configuration

Remarque :

Sans surprise on retrouve bien SDA et RLU

Routage des travaux interactifs

Je vais essayer de vous expliquer le routage des travaux interactifs.

Un travail interactif est routé vers un sous système par rapport au nom de son unité.

Vous l’indiquez dans la commande ADDWSE
Vous avez 2 paramètres
WRKSTN() nom écran ou nom générique
WRKSTNTYPE type d’écran

l’ordre c’est
nom
nom générique
type

Par contre ce n’est pas dynamique un écran affecté ne sera pas réaffecté dynamiquement, si par exemple votre sous système spécifique est démarré après QINTER.

Il peut être important pour des questions d’administration d’avoir les travaux dans le bon système.

On peut donc ajouter un programme SDA (sélection dynamique à l’arrivée), parce que le critère de nom n’est pas forcément suffisant , ou que suite à un redémarrage, on veut replacer le travail dans le bon sous système, ou tout autre raison.

C’est dans les données de routage qu’il va falloir agir, par défaut PGM(QCMD), mais vous pouvez indiquer un programme à vous.
Ce programme ne reçoit pas de paramètre extérieur et il va par rapport à un algorithme que vous aurez déterminé transférer le travail vers une JOBQ, c’est la commande TFRJOB qui permet de transférer
Le plus souvent on utilise comme critère l’utilisateur ou le nom de l’unité, mais on peut ajouter beaucoup d’autres critéres

Voici un exemple très simple et relativement classique, à mettre sur QINTER qui est souvent le sous système par défaut puisqu’il a une entrée par type

/*------------------------------------------------------------------*/
/*     Ce programme est utilisé dans un sous système interactif     */
/* dans les données de routage il va rerouter une jobq              */
/*  ADDRTGE  ... PGM(MALIB/REROOT)                                  */
/* Ce programme doit être en adoption de droit par rapport QSECOFR  */
/*------------------------------------------------------------------*/
PGM
dcl &user *char 10  /* Utilisateur en cours */
dcl &grp  *char 10  /* Groupe de l'utilisateur */
dcl &unit *char 10  /* nom de l'unité          */
dcl &status *char 2
/* information pour adresse ip */
dcl var(&IPV4ADDR) type(*char) len(15)
DCL    VAR(&JOBI) TYPE(*CHAR) LEN(700) VALUE(' ')
DCL    VAR(&JOBILEN) TYPE(*DEC) LEN(4 0) VALUE(700)
DCL    VAR(&FMTNAME) TYPE(*CHAR) LEN(8) VALUE(JOBI0600)
DCL    VAR(&QUALJN) TYPE(*CHAR) LEN(26) VALUE('*')
DCL    VAR(&INJOB) TYPE(*CHAR) LEN(16) VALUE('                ')
/*-------------------------------------------------*/
/* Extraction des informations de routage          */
/* ici Utilisateur, groupe et nom unité            */
/*-------------------------------------------------*/
             RTVJOBA    USER(&USER) job(&unit)
             RTVUSRPRF  GRPPRF(&GRP)
/* Call QUSRJOBI to retrieve job information */
             CALL       PGM(QSYS/QUSRJOBI) PARM(&JOBI &JOBILEN &FMTNAME +
                        &QUALJN &INJOB)
/* Extract data from the output of QUSRJOBI */
             CHGVAR     VAR(&IPV4ADDR) VALUE(%SST(&JOBI 308 15))
/*-------------------------------------------------*/
/* Règles de routage  sur utilisateur  et groupe   */
/*-------------------------------------------------*/
if cond(&GRP  = 'COMPTA') then(do)
             TFRJOB     JOBQ(COMPTA)
enddo
/*-------------------------------------------------*/
/* Règles de routage  sur unité                    */
/* reroutage de l'unité de secours dans QCTL       */
/* Pour faire des operations en mode restreint     */
/*-------------------------------------------------*/
if cond(&UNIT = 'SECOURS') then(do)
             TFRJOB     JOBQ(QCTL)
enddo
/*-------------------------------------------------*/
/* Règles de routage  sur nom d'ecran              */
/* AAAAAAxxxxx vers JOBQ AAAAAAJOBQ                */
/* AAAAAA racine de l'ecran                        */
/* xxxx   numéro                                   */
/*-------------------------------------------------*/
             chgvar &status 'OK'
             CHKOBJ     OBJ((%SST(&UNIT 1 6) *TCAT 'JOBQ')) +
                          OBJTYPE(*JOBQ)
             monmsg cpf9800 exec(do)
             chgvar &status 'KO'
             enddo
/* si JOBQ existe */
if cond(&status = 'OK') then(do)
             TFRJOB     JOBQ((%SST(&UNIT 1 6) *TCAT 'JOBQ'))
enddo
/*-------------------------------------------------*/
/* Règles de routage  sur adresse ip               */
/* Ici controle adresse ip  avec refus si pas reseau*/
/*  172                                            */
/*-------------------------------------------------*/
if cond(%sst(&IPV4ADDR 1 3) *ne '172') +
then(do)
             SNDMSG     MSG('Tentative de connexion refusée,' *BCAT +
                       &IPV4ADDR *BCAT ', sur adresse IP' *BCAT +
                         &UNIT) TOMSGQ(*HSTLOG)
             ENDJOB     JOB(*)
enddo
/*-------------------------------------------------*/
/* Les autres ne sont pas reroutés                  */
/*-------------------------------------------------*/
endpgm

Dans notre exemple, on a ajouté un contrôle sur l’adresse IP avec un blocage si pas le réseau attendu

Remarques :

La limite c’est votre imagination, vous devez bien réfléchir et cibler votre besoin , vous pouvez par exemple ajouter du paramétrage


Vous pouvez également utiliser le programme d’exit (QIBM_QTG_DEVINIT) , mais plus compliqué à mettre en œuvre

Vous devez vous assurer que le programme utilisé pour SDA ne plante pas

Les unités peuvent être créer automatiquement c’est la valeur système QAUTOVRT

Si vous choisissez de l’utiliser, préférez un nombre (exemple : 500 ) plutôt que *NOMAX et tous les 6 mois faites un coup de ménage sur les unités inutilisées

===> DSPOBJD OBJ(ALL) OBJTYPE(DEVD)

Vous pouvez les identifier facilement :

Par défaut les unités s’appellent QPADEVxxxx , ne pas hésiter à les supprimer 2 fois par an

, , Fonction usage / Exit programme

Vous êtes de plus en plus confronter à la mise en place de sécurité sur des services (ODBC, FTP, etc..)
il existe 2 solutions sur l’ibmi qui vont vous aider dans votre démarche

Les fonctions usage et les exit programmes

Vous avez des interfaces 5250 pour les administrer, mais aussi maintenant Navigator for i
WRKFCNUSG et WRKREGINF
Vous avez également des services SQL
QSYS2.SQL_CHECK_FUNCTION_USAGE(), QSYS2.FUNCTION_USAGE, QSYS2.FUNCTION_INFO
QSYS2.EXIT_POINT_INFO,QSYS2.EXIT_PROGRAM_INFO

Rapidement voici une petite comparaison

D’abord un essai de comparaison entre les principales valeurs

Accès / FonctionnalitéFonction d’usage (Function Usage ID)Programme d’exit (Exit Point)Description / Concerne
Accès base de données (ODBC, JDBC…)QIBM_DB_OPENQIBM_QZDA_INIT, QIBM_QZDA_NDB1Autorise/refuse l’ouverture de base de données (SQL, ODBC, etc.)
SQL Server Mode (QSQSRVR)QIBM_DB_QSQSRVRN/AContrôle l’accès aux jobs QSQSRVR (SQL server mode)
DDM/DRDAQIBM_DB_DDMDRDAQIBM_QDDMDRDASERVER, QIBM_QDDSQLDRDAAccès aux bases via DDM / DRDA
ODBC SpécifiqueN/AQIBM_QZDA_SQL1, QIBM_QZDA_INITAppels SQL via ODBC / DRDA
JDBCN/AQIBM_QZDA_SQL1, QIBM_QZDA_INITJDBC via Toolbox ou Native JDBC
FTPQIBM_FTP_SERVERQIBM_QTMF_SVR_LOGON, QIBM_QTMF_SVR_EXITContrôle l’accès FTP
TelnetQIBM_TELNET_SERVERQIBM_QTV_TELNETContrôle l’accès Telnet
Remote Command (RUNRMTCMD)QIBM_NETWORK_SERVERQIBM_QZRC_RMTExécution de commandes distantes
Client Access (iSeries Access, ACS…)QIBM_ACCESS3270, QIBM_DB_OPENQIBM_QZDA_* (exits ODBC), QIBM_QZRC_RMTAccès via IBM i Access clients (ODBC, FTP, etc.)

Fonctions d’usage (Function Usage) :
Elles permettent d’activer ou de restreindre une fonctionnalité par utilisateur (sans programmation).
Elles ont un mode par défaut ouvert ou fermé
Vous devez ensuite gérer les exceptions à cette règle
C’est en œuvre par défaut sur votre système
C’est dynamique vous pouvez par exemple avoir un scripte qui modifie le paramétrage pour les heures HNO
C’est compliquer pour tracer les refus

Exit Programs (Programmes d’exit) :
Permettent une personnalisation des contrôles d’accès .
Vous pouvez indiquer des critères d’actions, de ressources, de temporalité
exemple, Michel à droit à uniquement le bibliothèque compta en HNO
Vous maitrisez entièrement la logique de contrôle
Vous pouvez auditer ou loguer avant d’interdire par exemple
Vous pouvez impacter les performances de votre système avec un mauvais programme, voir même bloquer sur un plantage
Ce n’est pas en œuvre par défaut sur votre système
Ce n’est pas dynamique vous devrez arrêter le service concerné pour une prise en compte
Simple pour tracer les refus, c’est votre programme

Conclusion
J’espère que ca vous aidera à faire votre choix
dans tous les cas c’est absolument indispensable aujourd’hui de se préoccuper de ces problèmes à minima des accès ODBC

Toujours d’actualité un service qui n’est pas utilisé doit être arrêter

Quand vous passez de FTP à SFTP vous ne bénéficier plus de ces 2 options

, , Conserver des informations avant migration

Vous changez de machine ou de version et les dates de référence de vos objets et vos sources vont être remise à zéro,
grâce aux services SQL , vous pouvez facilement conserver temporairement ces informations

Vous pourrez par exemple avoir besoin de ces informations pour faire une analyse d’impact sur l’utilisation de certain programmes ou de sources

Pour garder une trace de ces informations voici ce que vous pouvez faire

créer une bibliothèque

==> CRTLIB MIGRATION

vous avez intérêt à extraire les informations juste avant la migration

1) Sur les objets

Vous pouvez utiliser la fonction table QSYS2.OBJECT_STATISTICS

exemple :

create table migration.lstobj as(
SELECT * FROM TABLE (
QSYS2.OBJECT_STATISTICS(‘ALL’,’ALL’) ) AS X
) with data

Vous pouvez si vous le voulez choisir ou éliminer des objets ou des bibliothèques.

2) sur les sources

Si vous avez des fichiers sources QRPGLESRC, QCLSRC etc …

Vous pouvez utiliser la vue QSYS2.SYSPARTITIONSTAT

exemple :

create table migration.lstsrc as(
SELECT *
FROM qsys2.SYSPARTITIONSTAT WHERE
not source_type is null and NUMBER_ROWS > 0
) with data

ici on limite aux membres sources non vide

Si vous avez des fichiers sources dans L’ifs, nodejs, php, python, ou même des développements traditionnels en RPGLE ou CLLE

Vous pouvez utiliser la fonction table QSYS2.IFS_OBJECT_STATISTICS

exemple :

create table migration.lstifs1 as(
SELECT *
FROM TABLE (
qsys2.ifs_object_statistics(
start_path_name => ‘/Votre_repert/’ ,
subtree_directories => ‘YES’
)
)
) with data

Vous devrez limiter à vos repertoires de sources , vous pouvez en faire plusieurs

Ensuite vous devrez envoyer votre bibliothèque sur le systéme cible

Soit par la migration naturelle qui emmènera toutes les bibliothèques ou par une opération spécifique d’envoi de la bibliothèque FTP, SAVRSTLIB etc…

Attention :

Après 6 mois cette bibliothèque devra être supprimée, elle ne servira plus à rien

Remarque :

Vous pouvez également inclure dans cette bibliothèque d’autres éléments qui pourront être utile comme :

La liste des valeurs systèmes , QSYS2.SYSTEM_VALUE_INFO
Le planning des travaux , QSYS2.SCHEDULED_JOB_INFO
les programmes d’exit , QSYS2.EXIT_PROGRAM_INFO
les watchers , QSYS2.WATCH_INFO
les bases de données DRDA , QSYS2.RDB_ENTRY_INFO
les reroutages de travaux , QSYS2.ROUTING_ENTRY_INFO
la table des réponses par défaut , QSYS2.REPLY_LIST_INFO
etc …

, Contrôler la cohérence des services SQL

On utilise de plus en plus les services SQL sur IBMi

Il peut être important de contrôler les services SQL installés sur votre machine

Vous avez 2 programmes qui sont fournis, nous vous proposons un petit habillage pour vous faciliter leurs utilisations
QSQIBMCHK et QSQSYSIBM

La commande

CMD        PROMPT('Contrôles services SQL')               
 PARM       KWD(TYPE) TYPE(*CHAR) LEN(4) RSTD(*YES) +      
              DFT(*CHK) VALUES(*CHK *FIX) PROMPT('Type +   
              de vérification') 

Le programme CLLE

pgm parm(&type)                                                         
dcl &type *char 4                                                       
dclf qsys/QADSPFFD                                                      
/* Récupération du CCSID de la première zone de qadbxref */             
             DSPFFD     FILE(QSYS/QADBXREF) OUTPUT(*OUTFILE) +          
                          OUTFILE(QTEMP/WADSPFFD) /* w */               
             OVRDBF     FILE(QADSPFFD) TOFILE(QTEMP/WADSPFFD) +         
                          LVLCHK(*NO)                                   
             RCVF                                                       
/* Changement du job au bon CCSID                              */       
             chgjob ccsid(&WHCSID)                                      
/* Pour contrôler les objets fournis par IBM qui sont manquants      */ 
if cond(&type = '*CHK') then(do)                                        
CALL QSYS/QSQIBMCHK                                                     
enddo                                                                   
/* Pour corriger                                                     */ 
if cond(&type = '*FIX') then(do)                                        
CALL QSYS/QSQSYSIBM                                                     
enddo                                                                   
             dltovr     FILE(QADSPFFD)  
endpgm    

Pour contrôler

==>CTLSRVSQL *CHK

Vous allez avoir ces messages dans la LOG

QSQXRLF OBJECTS FOUND = 55
QSQXRLF OBJECTS UNKNOWN = 0
QSQXRLF OBJECTS MISSING = 0
QSQSYSIBM OBJECTS FOUND = 716
QSQSYSIBM OBJECTS UNKNOWN = 0
QSQSYSIBM OBJECTS MISSING = 0
SYSTOOLS OBJECTS FOUND = 105
SYSTOOLS OBJECTS UNKNOWN = 0
SYSTOOLS OBJECTS MISSING = 0
TOTAL IBM OBJECTS FOUND = 876
TOTAL IBM OBJECTS UNKNOWN = 0
TOTAL IBM OBJECTS MISSING = 0
QSQIBMCHK – OBJECT VERIFICATION COMPLETE

Si vous avez des erreurs par exemple 1 dans OBJECTS UNKNOWN vous devrez corriger

Pour corriger

==>CTLSRVSQL *FIX

Vous allez avoir ces messages dans la LOG

QSQSYSIBM ASNEEDED PROCESSING SUCCESSFUL FOR 1236 COMPONENTS.

PS :
Vous n’avez pas besoin d’être en mode restreint
Mais vous devez être *SECADM et *ALLOBJ

Pour en savoir plus
https://www.ibm.com/support/pages/qsqibmchk-tool

Merci Jean-Marie pour le thème suggéré

, Ménage dans l’IFS

Vous devez surveiller l’IFS de votre partition et plus particulièrement la partie /home/ ou vous retrouvez les fichiers générés par vos utilisateurs et y faire le ménage régulièrement est une bonne pratique.

Une épuration à 30 jours semble un bon compromis

Voici 2 techniques pour réaliser cette opération

La première est à base d’un script UNIX

Voici un exemple, dans le répertoire /home/maurice/OUT on supprime les fichiers CSV de plus de 10 jours

Exemple :

find /home/maurice/OUT -type f -name « *.CSV » -mtime +10 -exec rm {} \;

Si vous voulez l’automatiser vous pouvez la mettre dans une commande ==>STRQSH

La deuxième est d’utiliser le nouveau service SQL SYSTOOLS.IFS_UNLINK

C’est une fonction, donc vous pourrez l’intégrer dans un select SQL


on prendra le même cas d’usage pour comparer

Exemple

SELECT path_name, SYSTOOLS.IFS_UNLINK(PATH_NAME)
FROM TABLE (QSYS2.IFS_OBJECT_STATISTICS(START_PATH_NAME => ‘/home/maurice/OUT’,
SUBTREE_DIRECTORIES => ‘NO’))
where ucase(Path_name) like(‘%.CSV%’)
and CREATE_TIMESTAMP < (current date – 10 days) ;

On utilise ici la fonction table QSYS2.IFS_OBJECT_STATISTICS qui permet de lister les fichiers d’un répertoire

Si vous voulez l’automatiser vous pouvez la mettre dans une commande ==>STRSQL ou dans dans du SQL embarqué

Conclusion

Il est important de surveiller L’IFS qui a tendance à grossir de manière excessive, et de supprimer les éléments inutiles

Nos solutions sont simples et efficaces vous pouvez facilement paramétrer les requêtes (répertoire, extension et périodicité)

, , Les tentatives de connexion échouées

Si vous avez mis en œuvre le journal vous pouvez et même devez analyser les refus de connexion.
Le plus souvent c’est un mauvais mot de passe mais ca peut être aussi une attaque, ou un comportement douteux

Voici une requête simple qui permet cette analyse rapide

SELECT JOB_NAME, USER_NAME, FUNCTION, MESSAGE_ID, MESSAGE_TIMESTAMP
FROM TABLE(QSYS2.DISPLAY_JOURNAL(‘QSYS’, ‘QAUDJRN’))
WHERE MESSAGE_ID IN (‘CPF2234’, ‘CPF1107’, ‘CPF1393’)
ORDER BY MESSAGE_TIMESTAMP DESC;

Les messages traités ici
CPF2234 Tentative de connexion échouée.
CPF1107 Mot de passe incorrect.
CPF1393 Accès refusé.

Remarque :
Vous pouvez ajouter des filtres (plage horaire, autres messages de refus , etc …)
Vous devrez découper vous même la zone entry data, vous pouvez également utiliser les fonctions table QSYS2.DISPLAY_JOURNALxx spécialisées par TYPE

Plus d’information ici https://www.ibm.com/support/pages/qsys2displayjournal

, Synchronisez votre partition avec QSNTP

On a de plus en plus besoin d’avoir des machines synchronisées, pour la validation des transactions, des informations de sécurité etc…

il existe un protocole qui permet de synchroniser l’horloge de votre partition c’est le protocole SNTP

On va voir ici comment le mettre en œuvre en tant que client, en sachant que vous pourriez également utiliser votre IBMI comme un serveur

Votre serveur peut être interne ou externe il est accédé sur le port 123 , si vous cherchez un serveur :

https://syrte.obspm.fr/spip/services/ref-temps/article/diffusion-de-l-heure-par-internet-ntp-network-time-protocolv

1) Paramétrage du service TCP/IP

Vous devrez bien sur arrêter et redémarrer le service pour que la modification soit prise en compte

2) Mise en œuvre par la valeur système QTIMADJ mettre QIBM_OS400_NTP pour activer

3) Suivi des mises à jour, elles sont stockées dans un répertoire /QIBM/UserData/OS400/TCPIP/NTP

Vous avez des fichiers de log QTOTxxxx , ils sont horodatés

Vous avez également dans le journal d’audit les postes de type SV (modification de valeurs systèmes) qui peuvent être analysé

Vous y retrouverez les modifications de la valeur système QTIME

Pour en savoir plus

https://www.ibm.com/docs/fr/i/7.5?topic=protocol-scenario-synchronizing-clocks-i

N’hésitez pas c’est simple et efficace