Pour répondre à beaucoup de questions, je vais toucher un mot du listener et des connexions à une base de données. Ce qui suit n'est qu'une rapide introduction et je vous renvoie au "Net Service Guide - Oracle 10.2", disponible dans la documentation Oracle à la page suivante : http://www.oracle.com/pls/db102/portal.portal_db?selected=4. Metalink est également une très bonne source d'information à ce sujet.
Adressage et connexions
Pour vous connecter à une base de données Oracle (Il s'agit d'un abus de langage), il vous faut d'abord une adresse... Ceci que vous y accédiez via un serveur d'applications, du Cobol, du .Net ou même SQL*Plus. Pour faire tout de suite compliqué, il faut dire qu'Oracle accepte de nombreuses formes d'adressage, par exemple :
- "Rien" est une forme d'adressage ! Dans le cas où vous ne tapez rien comme adresse, la couche cliente va considérer que vous vous connectez à l'instance par défaut et va chercher un certain nombre de variables pour résoudre votre connexion. La plus généralement utilisée est ORACLE_SID. Si cette variable est positionnée, votre couche client va vous connecter à l'instance locale dont le nom est défini par la valeur de la variable. Cette méthode est peu souple puisque vous devez être sur le serveur de base de données. Elle ne nécessite pas que vous utilisiez un agent de connexion, comme un Listener et est donc souvent utilisée par les DBA. Par exemple, dans une Console Windows, vous taperez quelque chose comme :
set ORACLE_SID=orcl
sqlplus scott/tiger
Sous réserve que votre instance Oracle s'appelle "orcl", qu'elle tourne sur la machine locale et que vous ayez un utilisateur "scott" activé dans la base de données dont le mot de passe est "tiger". Le script utlsampl.sql dans le répertoire ORACLE_HOME/rdbms/admin permet de créer l'utilisateur scott. - "Rien" peut être une autre forme d'adressage si les variables TWO_TASK (Unix & Linux) ou que la clé de registre LOCAL (Windows) sont positionnées. Cette méthode est moins utilisée. Toutefois elle permet de stocker une chaîne d'adressage réseau et que l'utilisateur n'ait rien à taper pour se connecter
- Avec 10g, une connexion "EZConnect" peut être utilisée (prononcez "Easy Connect" ou si vous ne parlez pas anglais, ce dont je doute : "Izi connecte"). Cette chaîne d'adressage a la forme suivante : "//machine
:port Sous réserve que votre instance Oracle s'appelle "XE", qu'elle tourne sur la machine locale , qu'un Listener soit démarré sur la machine locale sur le port 1521 et que vous ayez un utilisateur "scott" activé dans la base de données dont le mot de passe est "tiger"./service" . Elle ne marche qu'avec les clients 10g et nécessite que le client connaisse l'alias de la machine et le port sur laquelle le listener (voir section suivante) est démarré ainsi que le nom de service utilisé pour la connexion. Elle est cependant très simple à utiliser et surtout ne nécessite aucune configuration sur le client. Cette méthode étant nouvelle n'est pas très répandue mais elle est très simple et évite donc plein d'erreurs. Par exemple, vous pouvez taper (en 10g) :
sqlplus scott/tiger@//localhost:1521/XE - Le type d'adressage le plus répandu utilise un alias "TNS" stocké dans un fichier local. Ce fichier de configuration a forcément le nom "tnsnames.ora". Par défaut, il est stocké dans le répertoire ORACLE_HOME/network/admin mais peut être déplacé en positionnant une variable ou clé de registre TNS_ADMIN. Dans ce cas, vous tapez par exemple :
sqlplus scott/tiger@gark
Et le fichier tnsnames.ora contient une ligne comme celle-ci :
gark=(description=(address=(protocol=tcp)(host=localhost)(port=1521))
(connect_data=(service_name=orcl)))
Sous réserve que votre instance Oracle s'appelle "orcl", qu'elle tourne sur la machine locale qu'un Listener soit démarré sur la machine locale sur le port 1521 et que vous ayez un utilisateur "scott" activé dans la base de données dont le mot de passe est "tiger".
Cette méthode est sans doute la plus répandue de toutes : c'est la méthode historique ! Elle nécessite un paramétrage du client et en cas de modification de l'adressage, il faut modifier le fichier de tnsnames.ora. C'est la méthode la plus riche puisqu'elle permet d'exprimer toutes les options de paramétrages de la couche réseau. - Avec le client Oracle8i est apparut la possibilité de stocker l'alias TNS dans Oracle Internet Directory (i.e. un annuaire pour tous les clients). L'intérêt est d'offrir la richesse d'expression de l'adresse de connexion à une base de données dans un endroit central, compatible avec les régles de sécurité de l'entreprise et facile à sécuriser, via une réplication LDAP par exemple. Cette méthode est relativement répandue et surtout évite de repasser sur un client en cas de changement de paramétrage. L'utilisation d'OID à cet effet n'est pas soumis à license (cf "Oracle 10.2 - Licencing Guide"). A mon avis, si vous avez plus 30 ou 50 clients Oracle, c'est LA méthode à utiliser ! A moins que ça vous amuse de changer ou de faire changer vos adresses de connexions sur plusieurs 10x de machines.
- Si vous utilisez un driver JDBC Thin (Type-4) , il existe des notations particulières pour se connecter à une base de données. Cela tient au fait que (1) le driver JDBC-Thin étant écrit complètement en Java, il n'a pas les mêmes fonctionnalités que les autres drivers et (2) Le drivers JDBC Thin pouvant être utilisés dans des applications légères comme des Applets, il faut pouvoir se connecter à distance sans fichiers de configuration.
- La méthode la plus connue consiste à utiliser une syntaxe du type jdbc:oracle:thin:@machine:port:sid où vous remplacez les valeurs "machine" par le nom de machine sur laquelle le listener est démarré. "port" par le port d'écoute du Listener et "sid" par le nom de l'instance à laquelle vous voulez vous connecter. Cette méthode est très simple et assez pauvre. Elle est très répandue
- En 10g, vous pouvez utiliser la syntaxe EZConnect décrite précédemment. Cela est aussi simple et offre de meilleures possibilités, comme la possibilité de se connecter à des instances sur des machines distinctes de la machine sur laquelle le listener est démarré ou celle d'utiliser une adresse IP virtuelle. Quand c'est possible, il faut donc préférer ce type de description de l'adressage. Dans ce cas, la chaîne de connexion ressemble à ceci : jdbc:oracle:thin:@//machine:port/service.
- C'est moins connu mais assez utilisé, en particulier avec des configurations RAC, il est possible d'utiliser certaines syntaxes TNS avec un driver JDBC thin. Pour cela on utilise une chaîne de connexion qui ressemble à celle-ci : jdbc:oracle:thin:@(description=(address=(protocol=tcp)(host=localhost)
(port=1521))(connect_data=(service_name=orcl))) - Il existe de nombreuses autres méthodes pour résoudre une adresse : DNS, Active Directory, CDS, NIS... Ces méthodes sont moins répandues mais peuvent être utiles si vous utilisez déjà des composants Réseau, Microsoft, Novell ou Unix et que vous voulez déléguer la gestion de l'adressage Oracle à ces services
- La méthode ONS (Oracle Names Server) est une méthode qui permet comme pour OID de centraliser les alias TNS dans un serveur. Elle s'appuie sur le protocole SQL*Net au lieu de LDAP et ne permet pas de sécuriser simplement le référentiel. En 10g elle est totalement abandonnée au profit d'OID !
Pour modifier les fichiers de profils (sqlnet.ora) et de paramétrage réseau (tnsnames.ora), vous pouvez éditer les fichiers manuellement. Pour avoir déjà laissé trainer un caractère dans ces fichiers et avoir mis des heures pour touver mon erreur... Pour ne pas connaître toutes les syntaxes par coeur et mettre des minutes pour déboguer, je vous conseille d'utiliser les outils suivants :
- Oracle Configuration Assistant : netca, l'outil le plus simple et le moins riche
- Oracle Network Manager : netmgr, mon outil préféré car le plus riche... Il permet par exemple de créer les alias dans OID
- Oracle Enterprise Manager (Database Control ou Grid Control) : peut-être maintenant plus riche que netmgr... A condition de l'avoir installé
- vi ou notepad : dans certains cas vous ne pouvez pas faire autrement... mais si c'est le cas, c'est que vous le méritez !
Avant de parler du Listener plus en détail, il faut faire une remarque sur le rôle SYSDBA et sur l'utilisation d'un fichier de mot de passe. Pour certaines opérations, se connecter avec un utilisateur "classique", même DBA, de base de données ne suffit pas ! Par exemple, si vous voulez démarrer l'instance qui permet d'accéder à la base de données, il parait assez évident que vous ne pouvez pas utiliser un utilisateur de base de données puisque celle-ci est inaccessible.
En général, on s'appuie sur la sécurité locale du système d'exploitation. Sous Unix ou Linux, par exemple, un utilisateur de l'OS qui appartient au groupe "dba" ou son équivalent si vous avez choisi de l'appeler autrement lors de l'installation peut se connecter et ainsi démarrer l'instance. Pour se connecter, il faut être sur la machine et taper :
- sqlplus "/ as sysdba" (en 9i et 10g)
- ou plus simplement sqlplus / as sysdba (en 10g)
De manière générale seuls les utilisateurs SYSDBA ont certains droits comme celui de se connecter quand la base de données est en mode restreint. Il est possible que vous ayez envie de vous connecter SYSDBA sans vous connecter à l'OS et ainsi, par exemple, démarrer ou arrêter une base de données à distance, sans passer par un agent qui s'exécute sur la machine locale. Ces utilisateurs particuliers doivent alors pouvoir être identifiés, même si la base est arrêtée. Leur identité est gérée dans la base de données ET dans un fichier de mot de passe (le password file). Pour créer ou recréer un password file, il faut utiliser l'interface en ligne de commande "orapwd". Le fichier a un nom et un emplacement bien particulier qui dépend du système d'exploitation. Par exemple sous Unix et Linux, il s'agit de ORACLE_HOME/dbs et le nom est orapwSID où SID est le nom de l'instance. Pour dire qu'on utilise ce fichier, il faut mettre le paramètre d'initialisation "remote_login_passwordfile" à la valeur "exclusive" (ou "shared", si vous voulez utiliser le même fichier pour plusieurs instances) dans le fichier de paramètre de l'instance, pfile ou spfile selon votre choix.
Le listener
Pour se connecter à distance à une base de données, il faut établir une connexion avec un process qui gère la relation entre votre client et l'instance : dans le cas le plus général, cette connexion est établie avec un process serveur dédié. Ce process est un processus sous Unix et un thread sous Windows. Il est possible d'utiliser un process partagé pour gérer le dialogue avec l'instance, mais cela sort du scope de cette explication.
Pour arriver à établir la connexion, il faut le demander à quelqu'un. Le listener peut être ce vecteur: il sert d'agent de connexion. Tout serait trop simple, s'il n'existait pas d'autres agents de connection comme Oracle Connection Manager (CMAN) dans certaines configurations plus évoluées. L'un des rôles du listener est donc de créer **sous Unix et Linux, on dit spawner**, le process serveur qui va dialoguer avec votre client et de vous mettre en relation avec ce process. Pour cela, il se met à l'écoute sur une adresse réseau sur un port particulier et répond à toutes les demandes de connexions. Le nom du processus listener est tnslsnr ou tnslsnr.exe.
Pour configurer le listener, il faut créer un fichier listener.ora dans le répertoire pointé par les variables ORACLE_HOME/network/admin ou TNS_ADMIN si cette variable existe. Il est à noter que si ce fichier n'existe pas, vous pouvez démarrer malgré tout un listener en 10g. Dans ce cas, il se mettra en écoute sur le port 1521 sur le réseau de votre machine. Pour créer un fichier listener.ora, le moyen le plus simple est d'utiliser un des outils de configuration du réseau : network configuration assistant (netca), network manager (netmgr) ou Enterprise Manager 10g.
- Pour démarrer le listener, tapez : lsnrctl start listener où listener est le nom de votre listener.
- Pour vérifier l'état de votre listener (les adresses et les ports sur lesquelles il écoute), tapez : lsnrctl status listener
- L'enregistrement dynamique est désormais la méthode conseillée. Dans ce cas, l'instance se déclare, elle et les services qu'elle sert, auprès du listener. Par défaut, l'instance se déclare auprès d'un listener qui écoute sur le port 1521 sur la machine local (elle utilise la fonction "hostname"). Si vous désirez changer cet enregistrement vers un autre listener, il faut créer un alias TNS dans le fichier tnsnames.ora qui pointe vers le listener. Par exemple :
mon_listener= (description=(address=(protocol=tcp)(host=localhost)(port=1526))
et positionner le paramètre d'initialisation local_listener avec le nom de l'alias. Pour cela, vous pouvez taper les commandes :
SQL> alter system set local_listener='mon_listener' scope=both;
SQL> alter system register; <<-- Cette ligne force l'instance à s'enregistrer à nouveau La base de données enregistre alors son nom ainsi que l'ensemble des noms de services qu'elle sert dans le listener. Pour ajouter ou supprimer des services à la base de données, il suffit de modifier le paramètre d'initialisation service_names ou, en 10g, d'utiliser le package DBMS_SERVICES. Par exemple : SQL> alter system set service_names='service1, service2, service3' scope=both;
SQL> alter system register; - L'enregistrement statique est l'ancienne méthode... Du temps en 8.0 où la base de données ne s'enregistrait pas dans le listener. Dans ce cas, il faut enregistrer le nom de l'instance dans le fichier de paramétrage du listener (le fichier listener.ora dans le répertoire TNS_ADMIN ou ORACLE_HOME/network/admin). Pour cela la méthode la plus simple est sans doute d'utiliser Oracle Network Manager (netmgr). En général on n'utilise plus cette méthode sauf si vous voulez vous connecter à distance sous le compte SYSDBA alors que l'instance n'est pas ouverte. En effet comme dans ce cas, la base de données ne s'est pas encore enregistrer dans le listener (puisqu'elle est arrêtée), le seul moyen de permettre un accès distant est d'enregistrer l'instance de manière statique dans la configuration du listener.
Listener distant ou "remote"
Le listener auquel vous vous adressez pour établir une connexion n'est pas forcément sur la machine qui exécute l'instance. L'intérêt d'utiliser un listener "distant" est multiple :
- Si vous déplacez une instance, vous n'avez pas à changer la configuration du client... puisque le listener lui ne bouge pas
- Si vous voulez répartir les connexions sur plusieurs serveurs (avec RAC, par exemple), le fait d'utiliser un listener distant permet de faire du loadbalancing
- On crée un alias TNS dans le fichier tnsnames.ora de la base de données. Cet alias contient la liste des adresses des listeners distants avec une syntaxe comme celle-ci :
alias=(description=(address_list=
(address=(protocol=tcp)(host=machine1)(port=1521))
(address=(protocol=tcp)(host=machine2)(port=1521))
(address=(protocol=tcp)(host=machine3)(port=1521))
)) - Il faut ensuite déclarer cet alias dans le paramètre d'initialisation de l'instance remote_listener avec une commande comme celle-ci :
SQL> alter system set remote_listener='alias' scope=both;
SQL> alter system register;
Autres considérations :
Il y a de nombreuses choses à dire sur la manière de paramétrer et sécuriser le réseau Oracle. Si vous avez des questions, n'hésitez pas à les poster dans les commentaires de ce thread. Je vais déjà répondre à une question : "Pourquoi il faut sécuriser votre listener avec un mot de passe ?".
Imaginons que vous ayez un listener sans mot de passe positionné sur un serveur. Si, sur un client qui accéde à ce serveur par le réseau TCP/IP, vous créez un alias TNS, par exemple :
alias=(description=(address=(protocol=tcp)(host=machine)(port=1521)))
Alors, vous pouvez effectuer plusieurs opérations à distance comme arrêter le listener avec une commande du type:
lsnrctl stop alias
Les clients ne peuvent plus alors se connecter. Vous pouvez également effectuer d'autres opération comme activer des traces qui pourraient saturer l'espace de certains systèmes de fichiers de votre serveur. Ce type d'attaque sont dites "Denial of Service", et même si elles sont limitées au réseau des bases de données... Mieux éviter de tenter le diable. Mettre un mot de passe sur les listeners est facile et une bonne pratique.
Déboguer votre configuration réseau
Le message d'erreur d'une connexion est généralement explicite et on peut en déduire la raison d'un échec de connexion. Si jamais vous aviez du mal, vous trouverez ci-dessous un ensemble d'étapes qui vous permettent de valider votre connexion à une base de données. Si les symptômes persistent, ouvrez une SR sur Metalink :
- Valider que vous arrivez à vous connecter à l'instance sans passer par le réseau
set ORACLE_SID=orcl
sqlplus "/ as sysdba" - Vérifiez que votre instance est ouverte :
set ORACLE_SID=orcl
sqlplus "/ as sysdba"
SQL> select status from v$instance; - Vérifiez que votre nom d'utilisateur et mot de passe sont corrects
set ORACLE_SID=orcl
sqlplus scott/tiger - Vérifiez que votre listener est bien démarré
lsnrctl status listener (où listener est le nom de votre listener)
et qu'il est bien à l'écoute sur la bonne adresse IP et le bon port :
netstat -a (y compris sous Windows) - Vérifiez que la base de données s'est bien enregistrée dans le listener
lsnrctl services listener (où listener est le nom de votre listener)
Si ce n'est pas le cas, forcer l'enregistrement avec la commande :
set ORACLE_SID=orcl
sqlplus "/ as sysdba"
SQL> alter system register;
Si l'instance ne s'enregistre pas dans le listener, vous pouvez effectuer les tests 6-7-8 et 9 en considérant que le client est la base de données et donc également le serveur. L'alias que vous testerez est la chaîne de caractère contenue dans le paramètre d'initialisation local_listener. Si ce paramètre est vide, cela signifie que la base de données tente de s'enregistrer dans un listener en écoute sur le port 1521 et sur l'adresse servie par la fonction hostname. - Vérifiez que vous arrivez à accéder à la machine sur laquelle le listener est démarré :
ping machine_serveur (depuis le client) - Vérifiez que vous pouvez atteindre la machine cliente depuis votre serveur
ping ip_client (depuis le serveur) - Lancez l'assistant de création/modification des fichiers de configuration (netmgr) sur le client pour vérifier qu'il n'y a pas de problème de formattage dans le fichier tnsnames.ora. Retrouvez et visualisez dans cet assistant votre alias de connexion.
- Tentez d'atteindre le listener distant via l'alias TNS grâce à la commande "tnsping" qui permet de tester la présence du listener sans résoudre le service ou l'instance. Utilisez la commande :
tnsping alias (ou alias est le nom de l'alias TNS que vous testez) - Tentez de vous connecter avec sqlplus :
sqlplus scott/tiger@alias (ou alias est le nom de l'alias TNS que vous testez)
Encore une chose, parce qu'on tombe tous un jour ou l'autre dans ce piège : Si vous utilisez le paramètre NAMES.DEFAULT_DOMAIN dans le fichier de profil SQL (sqlnet.ora), alors un suffixe est ajouté de manière transparente à chaque fois que vous tapez un alias.
Par exemple :
- Si vous avez la valeur NAMES.DEFAULT_DOMAIN=world dans le fichier sqlnet.ora
- Si vous avez un alias "gark=(description=..." dans le fichier tnsnames.ora
- Si vous tentez de vous connecter avec sqlplus user/password@gark
GarK!
