Aufruf einer HTTPS Webseite mit UTL_HTTP

Ziel

In diesem Blogeintrag wird gezeigt, wie man mithilfe des UTL_HTTP Packages eine mit SSL verschlüsselete Webseite aufrufen kann und die häufig auftretenen Felhermeldungen ORA-29024 und ORA-24247 beheben kann. Als Beispiel wird die Webseite des Fedora Projekts https://fedoraproject.org/de/ aufgerufen.

Systemumgebung

Grundlage für diese Anleitung ist die folgende Systemumgebung. 

Betriebssystem

CentOS release 5.9 (Final)

Oracle Version

BANNER 
-------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production 
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0      
Production TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

Konfiguration

Wallet anlegen

Um auf eine SSL verschlüsselte Seite zugreifen zu können muss ein Oracle Wallet verwendet werden. In diesem Wallet werden die SSL Zertifikate der aufzurufenden Webseite hinterlegt. 

Ein Wallet kann auf mehrere Art und Weisen angelegt werden. Zum einen über den Wallet Manager, der eine grafische Benutzeroberfläche bietet und zum anderen über die Kommandozeilenwerkzeuge orapki und mkstore. Ich werde in diesem Tutorial ausschließlich orapki verwenden.

Im ersten Schritt muss das Zielverzeichnis für das Wallet angelegt werden. Der Speicherort kann frei gewählt werden. Lediglich der Oracle Home Besitzer muss Zugriff auf dieses Verzeichnis haben. Anschließend kann das Wallet erstellt werden.

$> mkdir /u01/app/oracle/wallet 
$> orapki wallet create -wallet /u01/app/oracle/wallet -pwd Welcome1 -auto_login

Hinweis: Das gewählte Passwort muss den Komplexitätsanforderungen der Datenbank entsprechen. Wird ein zu schwaches Passwort verwendet, wird die folgende, wenig aussagende, Fehlermeldung ausgegeben.

Unable to save wallet at /u01/app/oracle/wallet

SSL Zertifikate herunterladen und zum Wallet hinzufügen

Im nächsten Schritt müssen die SSL Zertifikate der Zielwebseite https://fedoraproject.org/de/ heruntergeladen und zum Wallet hinzugefügt werden. Für das Speichern der Zertifikate verwende ich Google Chrome

Wenn man eine HTTPS Webseite mit Google Chrome aufruft, erscheint neben der URL ein kleines Schloss Symbol. Über dieses Symbol gelangt man zu den Zertifikatsinformationen.

Zertifikatsinformationen
Informationen über das SSL-Zertifikat anzeigen

Klingt man auf den Link Zertifikatinformationen öffnet sich ein neues Fenster. Im Reiter Zertifizierungspfad sieht man die Hierarchie der Zertfikate. Hinter jeder Stufe verbirgt sich ein Zertifikat, das heruntergeladen werden muss. Standardmäßig ist das letzte Zertifikat in der Liste selektiert.

Zertifizierungspfad
Zertifizierungspfad

Im Reiter Details besteht die Möglichkeit über die Schaltfläche In Datei kopieren.. das Zertifikat zu exportieren.

Zertifikatdetails
Details zum SSL-Zertifikat

Der Zertifikatexport-Assistent startet. Ich werde nur auf die wichtigen Fenster eingehen.

Das Zertifikat sollte base-64-codiert gespeichert werden.

Zertifikatexport-Assistent
Auswahl des Base-64 Formates

Als Namen für die Datei verwende ich gerne den Namen des Zertifikats, soweit möglich.

Zertifikatexport-Assistent
Speicherpfad für den SSL-Zertifikat Export festlegen

Die oben aufgeführten Schritte müssen für alle Ebenen des Zertifizierungspfad wiederholt werden. Dafür muss man die Ebene selektieren und auf die Schaltfläche Zertifikat anzeigen drücken. Danach sind die Schritte wieder identisch.

Mein Endergebnis sieht so aus:

- fedoraproject.org.cer - GeoTrust SSL CA.cer - GeoTrust Global CA.cer

Diese drei Dateien kopiere ich auf den Datenbank Server in das Verzeichnis /tmp.

Nun müssen die drei Zertifikate dem Wallet hinzugefügt werden.

$> orapki wallet add -wallet /u01/app/oracle/wallet -trusted_cert \
   -cert "/tmp/fedoraproject.org.cer" -pwd Welcome1
$> orapki wallet add -wallet /u01/app/oracle/wallet -trusted_cert \
   -cert "/tmp/GeoTrust Global CA.cer" -pwd Welcome1 
$> orapki wallet add -wallet /u01/app/oracle/wallet -trusted_cert \
   -cert "/tmp/GeoTrust SSL CA.cer" -pwd Welcome1

Wird versucht auf eine SSL verschlüsselte Webseite zuzugreifen ohne die entsprechenden SSL Zertifikate zu besitzen, werden die folgenden Fehler gemeldet.

ORA-29273: HTTP-Anforderung nicht erfolgreich 
ORA-06512: in "SYS.UTL_HTTP", Zeile 1130 
ORA-29024: Zertifikatvalidierung nicht erfolgreich

ACLs konfigurieren

Oracle führte mit der Version 11g die Netzwerk ACLs ein, die den Zugriff auf externe Resourcen kontrollieren. Standardmäßig ist jedem nicht DBA Benutzer das Aufrufen von externen Resourcen nicht erlaubt. Wird zum Beispiel versucht unsere Zielwebseite aufzurufen, werden die folgenden Fehler gemeldet.

ORA-29273: HTTP-Anforderung nicht erfolgreich
ORA-06512: in "SYS.UTL_HTTP", Zeile 1130
ORA-24247: Netzwerkzugriff von Access Control-Liste (ACL) abgelehnt

Damit nun ein Benutzer externe Resourcen aufrufen kann, müssen entsprechende ACLs konfiguriert werden.

SQL> BEGIN      
   -- Neue ACL anlegen. Der Name kann frei gewählt werden. Über den Parameter 
   -- principal wird festgelegt, welcher Benutzer, in diesem Fall der Benutzer TEST 
   -- für den Zugriff freigeschaltet werden soll. Das Privileg CONNECT erlaubt 
   -- das Auflösen und Verbinden der externen Resource.
   DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (
      acl => 'utl_http.xml',
      description => 'UTL_HTTP Zugriff',
      principal => 'TEST',
      is_grant => TRUE,
      privilege => 'connect',
      start_date => null,
      end_date => null
   );

   -- Nun wird die Zielresource definiert und der ACL zugewiesen. Als Host muss die
   -- Domain angegeben werden.
   DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (
      acl => 'utl_http.xml',
      host => 'fedoraproject.org',
      lower_port => null,
      upper_port => null
   );

   COMMIT;
END;
/

Test

Nachdem alle Vorbereitungen getroffen sind, kann nun versucht werden, die Zielwebseite aufzurufen.

SQL> DECLARE
   v_request        UTL_HTTP.REQ;
   v_response       UTL_HTTP.RESP;
   -- Ziel URL
   v_url            VARCHAR2(32767) := 'https://fedoraproject.org/de/';
   -- Variable zum Zwischenspeichern der Antwort
   v_data           VARCHAR2(32767); 
BEGIN
   -- Setzen des Wallets.
   UTL_HTTP.SET_WALLET('file:/u01/app/oracle/wallet2', 'Welcome1');

   -- Starten der Anfrage
   v_request := UTL_HTTP.BEGIN_REQUEST(v_url);

   -- Antwort zwischenspeichern
   v_response := UTL_HTTP.GET_RESPONSE(v_request);
   <<SHOW_RESPONSE>>
   BEGIN
      -- Anzeige der Antwort.
      LOOP
         UTL_HTTP.read_text(v_response, v_data, 32767);
         DBMS_OUTPUT.PUT_LINE(v_data);
      END LOOP;
   EXCEPTION
      WHEN UTL_HTTP.end_of_body THEN
         DBMS_OUTPUT.PUT_LINE('Ende erreicht');
   END SHOW_RESPONSE;

   -- Status Code ausgeben. Status Code 200 bedeutet, dass die Anfrage
   -- erfolgreich verarbeitet werden konnte.
   DBMS_OUTPUT.PUT_LINE('Status Code: ' || v_response.status_code);

   -- Schließen der Antwort.
   UTL_HTTP.END_RESPONSE(v_response);
END;
/

Ausgabe:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
   <head>
      ... Inhalt entfernt
      <title>Fedora-Projekt Startseite</title>
   </head>
   <body id="fedoraproject-org" class="lang-de">
      ... Inhalt entfernt
   </body>
</html>

Ende erreicht Status Code: 200

PL/SQL-Prozedur erfolgreich abgeschlossen.

Wie man sieht war der Test erfolgreich. Der komplette Quelltext der Fedora Webseite wird angezeigt.

Leave a Reply

Your email address will not be published. Required fields are marked *