Mehr Sicherheit in Oracle11g: PL/SQL Netzwerk ACL
Oracle11g wird ja mehr und mehr genutzt. Und eine Erfahrung, die jeder Nutzer von UTL_SMTP, UTL_HTTP und anderen "Netzwerk"-Paketen auf Oracle11g macht ist, dass sie irgendwie nicht mehr funktionieren ... das sieht dann typischerweise so aus:
SQL> select httpuritype('www.oracle.de').getclob() from dual;
ERROR:
ORA-29273: HTTP-Anforderung nicht erfolgreich
ORA-06512: in "SYS.UTL_HTTP", Zeile 1674
ORA-24247: Netzwerkzugriff von Zugriffskontrollliste (ACL) abgelehnt
ORA-06512: in "SYS.HTTPURITYPE", Zeile 34
Am EXECUTE-Privileg liegt es nicht ... das ist vorhanden. Trotzdem gelingt der Netzwerkzugriff nicht. Grund ist ein in Oracle11g neu eingeführtes Sicherheitskonzept: Netzwerkzugriffe, welche durch PL/SQL-Pakete erfolgen, müssen vom DBA separat freigegeben werden.
Auf den ersten Blick macht das mehr Arbeit - genauer betrachtet ist das meiner Meining nach jedoch eins der besten Sicherheitsfeatures in Oracle11g. Man denke nur an einen Hacker, der durch eine SQL Injection-Lücke in die Datenbank eindringt und feststellt, dass er Zugriff auf das UTL_HTTP-Paket hat ... er kann nun neben der Datenbank auch auf das gesamte Netzwerk (welches von der Datenbank erreicht werden kann) zugreifen. Genau aus diesem Grund existiert auch die Empfehlung, das EXECUTE-Privileg auf diese Netzwerkpakete von PUBLIC zu entfernen (REVOKE EXECUTE on UTL_HTTP from PUBLIC) und es nur den Nutzern zu vergeben, die es wirklich brauchen.
In Oracle11g kann, nein muss der Netzwerkzugriff für die einzelnen Ziele separat und feinganular freigegegeben werden. Und das geht mit dem neuen PL/SQL-Paket DBMS_ACL_ADMIN so:
begin
begin
dbms_network_acl_admin.drop_acl(
acl => 'HTTP_OracleDe.xml'
);
exception
when others then null; -- ACL does not exist yet
end;
-- Privilege to connect to a host
dbms_network_acl_admin.create_acl(
acl => 'HTTP_OracleDe.xml',
description => 'HTTP-Connects zu www.oracle.de',
principal => 'CCZARSKI', -- DB Schema (grantee)
is_grant => true,
privilege => 'connect',
start_date => null,
end_date => null
);
-- Privilege to resolve a hostname (DNS lookup)
DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(
acl => 'HTTP_OracleDe.xml',
principal => 'CCZARSKI', -- DB Schema (grantee)
is_grant => true,
privilege => 'resolve'
start_date => null,
end_date => null
);
-- Privilege to connect to www.oracle.de
dbms_network_acl_admin.assign_acl(
acl => 'HTTP_OracleDe.xml',
host => 'www.oracle.de',
lower_port => 80,
upper_port => 80
);
-- Privilege to connect to www.oracle.com (oracle.de is redirected to oracle.com)
dbms_network_acl_admin.assign_acl(
acl => 'HTTP_OracleDe.xml',
host => 'www.oracle.com',
lower_port => 80,
upper_port => 80
);
end;
/
commit
/
Diese Aufrufe schalten die Server www.oracle.de und www.oracle.com auf Port 80 frei. Wie Ihr an den Aufrufen erkennen könnt (Parameter is_grant, start_date und end_date), können Privilegien für bestimmte Zeiträume vergeben werden und neben "positiven" ACL's können auch "negative" Privilegien vergeben werden; á la "Das ganze Subnet "192.168.10.0", aber nicht den Server "192.168.10.88". Als "grantee" können wie immer auch Rollen und auch PUBLIC eingetragen werden. Und so kann man sich auch ein Skript schreiben, welches den "alten" Oracle10g-Zustand wiederherstellt - wobei ich davon für Produktionssysteme dringend abraten möchte; die ACLs sind ein echter Sicherheitsgewinn und es wäre töricht, sie abzuschalten. Auf einer Entwicklermaschine oder für den Übergang kann das folgende Skript aber ganz hilfreich sein:
begin
begin
dbms_network_acl_admin.drop_acl(
acl => 'all-network-PUBLIC.xml'
);
exception
when others then null;
end;
dbms_network_acl_admin.create_acl(
acl => 'all-network-PUBLIC.xml',
description => 'Netzwerk-Connects fuer ALLE',
principal => 'PUBLIC',
is_grant => true,
privilege => 'connect'
);
DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(
acl => 'all-network-PUBLIC.xml',
principal => 'PUBLIC',
is_grant => true,
privilege => 'resolve'
);
dbms_network_acl_admin.assign_acl(
acl => 'all-network-PUBLIC.xml',
host => '*'
);
end;
/
sho err
commit
/
Eine Dictionary View für die ACLs gibt es auch: DBA_NETWORK_ACLS. Ach ja: noch etwas Wichtiges: Wie man an den "Dateinamen" für die ACL erkennen kann, ist hier XML im Spiel. Und tatsächlich: Die ACLs werden als XML in der XMLDB (dem XML DB Repository) gespeichert. Ab Oracle11g gilt also: Wenn man mit den genannten PL/SQL Netzwerk-Paketen arbeiten möchte, muss die XML DB in der Datenbank vorhanden sein.
Mehr Informationen zum Thema findet Ihr in der Oracle-Dokumentation.
1 Kommentar:
Hallo Herr Czarski
prima, danke fuer den Artikel, helpful !
Sokrates
Kommentar veröffentlichen