JDBC Zugriff auf Oracle-Datenbank scheitert mit I/O-Fehler: Connection reset

Warum komme ich plötzlich nicht mehr an die Datenbank?

Mit einer unserer Java-Anwendungen hatten wir plötzlich ein unerklärliches Zugriffs-Problem auf die darunter liegende Oracle Datenbank. Nach der Installation der Anwendung auf einer neuen Virtuellen Maschine scheiterte jeder JDBC-Zugriff auf die Datenbank mit dem Fehler:

java.sql.SQLRecoverableException: I/O-Fehler: Connection reset

obwohl der Datenbank Server selbst nicht verändert wurde. Wir konnten den Fehler mit einer einfachen Test Klasse repoduzieren und es wurde schnell klar, es liegt weder an der Anwendung, noch am Datenbank-Server.

Ursache für den Connection reset

Der Oracle JDBC Treiber verschlüsselt die Verbindung zum Datenbank-Server und nutzt für die Verschlüsselung u.a. die Klasse SecureRandom. Diese Klasse liefert Zufallszahlen basierend auf der Entropie des Systems (1) (2). Die Entropie wird in der Regel über Hardware gebildet, z.B. Maus-Bewegungen und Tastaur-Eingaben oder auch durch spezielle “randomness generators”. Der Zugriff erfolgt über spezielle Devices: /dev/random oder /dev/urandom, wobei /dev/random der Default ist. Das Besondere an /dev/random ist, dass der Zugriff blockiert, wenn die Entropie des Systems nicht groß genug ist. Dies führt dann zu der Exception „SQLRecoverableException: I/O-Fehler: Connection reset“ beim JDBC Zugriff auf die Datenbank.

Was ist bei der Installation auf der neuen VM passiert?

Bei der neuen Virtuellen Maschine handelt es sich um ein Serversystem ohne große Maus-Bewegungen oder Tastaur-Eingaben und eine anderweitige Entropiequelle ist nicht eingerichtet. D.h. nach Installation und Start der Anwendung ist die Entropie des Systems zu klein für einen nicht blockierenden Zugriff auf /dev/random.

Die Lösung

Als Alternative zu /dev/random kann auch /dev/urandom benutzt werden. Der Zugriff auf /dev/urandom blockiert nicht, wenn zu wenig Entropie vorhanden ist – das wollen wir gerade erreichen. Allerdings ist in diesem Fall die Verschlüsselung nicht so gut und kann theoretisch geknackt werden. In der Anwendung haben wir uns trotzdem für diesen Weg entschieden, weil es sich bei der Datenbank-Verbindung um eine für Dritte unzugängliche Verbindung handelt. Die Benutzung von /dev/urandom wird über eine System Property konfiguriert:

-Djava.security.egd=file:///dev/urandom

Dieses Problem existiert im Prinzip bei allen verschlüsselten Verbindungen. Durch das Setzten der System Property java.security.egd ist natürlich nicht nur der Oracle JDBC Treiber betroffen, sondern auch andere Benutzungen von SecureRandom. Auch in anderen Umgebungen gibt es ein ähnliches Problem, siehe Apache HTTP Webserver SSLRandomSeed Direktive.

Michael Bouschen
Michael Watzek

Quellen:
(1) Oracle JDBC intermittent Connection Issue
(2) ORACLE IO exception – Connection reset or Timeout reached – 30s – for process

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s