These docs are for v6.1.0. Click to read the latest docs for v7.4.0.

H2Db Service

ESF integrates a Java SQL database named H2. The main features of this SQL Database are:

  • Very fast, open source, JDBC API
  • Embedded and server modes; in-memory databases
  • Browser-based Console application
  • Small footprint

Supported Features

ESF supports the following H2 database features:

  • Persistence modes: The H2 implementation currently supports in-memory and file-based database instances. See the Persistence Modes section for more details.

  • Multiple database instances: It is possible to create and configure multiple database instances from the ESF Administration UI, these instances can be selectively consumed by applications. A default database instance is created automatically.

  • TCP Server: The current implementation allows external processes to access the database instances managed by ESF using TCP. This enables the integration of external applications that can share data with ESF components using the database.

  • Web-based console: It is possible to start the H2 Web console directly from the ESF Administration UI. The console can be used to inspect the database contents and perform arbitrary queries for debug purposes.

  • Basic credential management: The current implementation allows to change the password of the admin DB user from the ESF Administration UI. This allows the access restriction to the existing database instances.

Limitations

  • Private in-memory instances: Only named in-memory instances are supported (e.g. jdbc:h2:mem:<dbname>, where <dbname> is not the empty string), private instances represented by the jdbc:h2:mem: URL are currently not supported.

  • Remote connections: The current implementation only supports embedded database instances. Connecting to remote instances using the jdbc:h2:tcp:* and jdbc:h2:ssl:* connector URLs is not supported.

Changes to Database Related Components

By default, the DataService in ESF uses the H2 database to persist the messages. However, there is no support for migrating an old HSQLDB database to the new H2 instances.

The new H2DbWireRecordFilter and H2DbWireRecordStore Wire components have been added. These components provide the same functionalities offered by the HSQL based DbWireRecordFilter and DbWireRecordStore components but using the H2 database.
The legacy components will continue to be available in order to keep backward compatibility, but are deprecated in this version of ESF and should not be used for new installations.

Usage

Creating a new H2 database instance

To create a new H2 database instance, use the following procedure:

  1. Open the ESF Administrative UI and press the + button in the side menu, under the Services section. A pop-up dialog should appear.
  2. Select org.eclipse.kura.core.db.H2DbService from the Factory drop-down list, enter an arbitrary name for the new instance and click Apply.
1217
  1. An entry for the newly created instance should appear in the side menu under Services, click on it to review its configuration:
1007

It is not possible to create different DB instances that manage the same DB URL. When creating a new instance please make sure that the URL specified in the field db.connector.url is not managed by another instance.

Selecting a Database Instance for Existing ESF Components

A database instance is identified by its Kura service PID. The PID for the default instance is org.eclipse.kura.db.H2DbService while the PID for instances created using the Web UI is the string entered in the Name field at step 2 of the previous section.

The built-in ESF components that use database functionalities allow to specify which instance to use in their configuration. These components are the DataService component of the cloud stack, the H2DbWireRecordFilter and H2DbWireRecordStore wire components.
The configuration of each component contains a property that allows to specify the service PID of the desired instance.

Enabling the TCP Server

❗️

Development-only feature

This feature is intended to be used only for debugging/development purposes. The server created by H2 is not running on a secure protocol. Only enable the server for a limited time and make sure to properly secure the firewall ports on which it is running.

The TCP server can be used by creating a H2DbServer instance:

  1. Open the ESF Web UI and press the + button in the side menu, under the Services section. A pop-up dialog should appear.
  2. Select org.eclipse.kura.core.db.H2DbServer from the Factory drop-down​ list, enter an arbitrary name for the new instance and click Apply.
1218
  1. Clicking on the name of the new server instance on the left side of the Web UI​. The configuration of the server component will appear:
1003
  1. Set the db.server.type field to TCP
  2. Review the server options under db.server.commandline, check the official documentation for more information about the available options.
  3. Set the db.server.enabled to true.

The server, with the default configuration, will be listening on port 9123.

🚧

Make sure to review the firewall configuration in order to ensure that the server is reachable from an external process.

Enabling the Web Console

❗️

Development-only feature

This feature is intended to be used only for debugging/development purposes. The server created by H2 is not running on a secure protocol. Only enable the server for a limited time and make sure to properly secure the firewall ports on which it is running.

In order to enable the H2 Web console, proceed as follows:

  1. Create a new H2DbServer instance.
  2. Set the db.server.type field to WEB
  3. Enter appropriate parameters for the Web server in the db.server.commandline field. An example of valid settings can be -webPort 9123 -webAllowOthers -ifExists.
  4. Set the db.server.enabled to true.

The server is now listening on the specified port.

🚧

Make sure to review the firewall configuration in order to ensure that the server is reachable from an external process.

Use a browser to access the console. Open the http://: URL, where is the IP address of the ESF device and is the port specified at step 3.

940

Enter the DB URL as specified in the Kura configuration in the JDBC URL field and the credentials. Click on Connect, you should be able to access the console.

3020

Change the Database Password

To change the database password the System Administrator needs to:

  1. Open the configuration of the desired database instance in the ESF Web UI.
  2. Enter the new password in the db.password field.
  3. Click Apply.

🚧

If the H2DbServer instance fails to open a database, it will delete and recreate all database files. This behavior​ is aimed at preventing potential issues caused by incorrect credentials in the configuration snapshots. It is highly recommended to perform a backup of an existing database before trying to open it using a H2DbService instance and before changing the password.

Persistence Modes

The H2 database supports several persistence modes.

In Memory

An in-memory database instance can be created using the following URL structure: jdbc:h2:mem:, where is a non-empty string that represents the database name. This configuration is suggested for database instances that are frequently updated. Examples:

  • jdbc:h2:mem:kuradb
  • jdbc:h2:mem:mydb

The default database instance is in-memory by default and uses the jdbc:h2:mem:kuradb URL.

Most Persistent

A persistent database instance can be created using the jdbc:h2:file:, where is a non-empty string that represents the database path.

If no URL parameters are supplied the database will enable the transaction log by default. The transaction log is used to restore the database to a consistent state after a crash or power failure. This provides good protection against data losses but causes a lot of writes to the storage device, reducing both performance and the lifetime of flash-based storage devices.

This configuration is suggested for database instances that are rarely updated. Examples:

  • jdbc:h2:file:/opt/db/mydb

Make sure to use absolute paths in the DB URL since H2 does not support DB paths relative to the working directory.

❗️

ESF versions with the embedded H2DB (version < 1.4.199) can be affected by database corruption when the database is persisted in the filesystem.

Eurotech suggests the update to ESF 6.1.2 that provides H2DB v.1.4.199.

The database format used by H2DB v.1.4.199 is incompatible with the one used in previous versions of the product. In case of an upgrade of an ESF instance with a persisted database to 6.1.2, the customer has to delete/upgrade the existing persisted database to be compatible with this new version. Please refer to http://www.h2database.com/html/tutorial.html#upgrade_backup_restore

Mostly Persistent

The transaction log can be disabled by appending the LOG=0 parameter to the DB URL. In this way, ​it is possible to reduce the stress on the underlying storage device and increase performance, at the expense of a higher probability of losing data in case of power failure.

In order to reduce the probability of data losses, the H2DbService performs periodic checkpoints on the database. A checkpoint forces all pending modifications to be committed to the storage device. The interval in seconds between two consecutive checkpoints can be configured using the db.checkpoint.interval.seconds property.

This configuration is suggested for database instances with intermediate update rates. Examples:

  • jdbc:h2:file:/opt/db/mydb;LOG=0

❗️

ESF versions with the embedded H2DB (version < 1.4.199) can be affected by database corruption when the database is persisted in the filesystem.

Eurotech suggests the update to ESF 6.1.2 that provides H2DB v.1.4.199.

The database format used by H2DB v.1.4.199 is incompatible with the one used in previous versions of the product. In case of an upgrade of an ESF instance with a persisted database to 6.1.2, the customer has to delete/upgrade the existing persisted database to be compatible with this new version. Please refer to http://www.h2database.com/html/tutorial.html#upgrade_backup_restore

Filesystem tuning

The H2 database might become corrupted in case of power failure.
In case of file-backed database (e.g. mostly or most persistent), the following database mount options can improve database reliability, reducing the database corruption probability at the expense of reduced performance and lifetime of the flash storage devices:

  • data=journal: From EXT4(5) Linux MAN Page:

    All data is committed into the journal prior to being written into the main filesystem.

    This setting only applies to ext3/ext4 filesystems.

  • sync: From mount(8) Linux MAN Page:

    All I/O to the filesystem should be done synchronously. In case of media with limited number of write cycles (e.g. some flash drives) "sync" may cause life-cycle shortening.

After some long running tests, it appears that the data=journal option alone is enough to reduce corruption probability (no corruption observed during the test).

In order to apply the options above, perform the following steps:

1 - Edit the /etc/fstab row for the filesystem containing the database file, appending the desired options to the fourth column, using comma as separator.

For example, an /etc/fstab file with data=journal enabled will look like the following:

proc            /proc           proc    defaults          0       0
PARTUUID=3920f25c-01  /boot           vfat    defaults          0       2
PARTUUID=3920f25c-02  /               ext4    defaults,noatime,data=journal  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that

2 - If the database resides on the root filesystem, the data=journal option must be specified in the kernel command line as well, by appending rootflags=data=journal

On some systems, this can be done by editing the /boot/cmdline.txt file:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=3920f25c-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait rootflags=data=journal

Enhance H2 security

The H2 version used in ESF (v.1.4.199) is currently affected by CVE-2021-23463 and CVE-2021-42392. Out of the box, the ESF framework and ESF bundles are not affected by these vulnerabilities. However, custom-made bundles/applications might use some advanced H2 features that could expose the application to the following vulnerabilities:

CVE-2021-23463

This vulnerability allows for a XML External Entity (XXE) Injection via the org.h2.jdbc.JdbcSQLXML class object, when it receives parsed string data from org.h2.jdbc.JdbcResultSet.getSQLXML() method. If it executes the getSource() method when the parameter is DOMSource.class it will trigger the vulnerability.

By default, ESF and Eurotech add-ons do not use or expose such class and methods. A third party application may use such classes and it should be checked to verify that it properly verify the content provided to such class.

CVE-2021-42392

The org.h2.util.JdbcUtils.getConnection method of the H2 database takes as parameters the class name of the driver and URL of the database. An attacker may pass a JNDI driver name and a URL leading to a LDAP or RMI servers, causing remote code execution. This can be exploited through various attack vectors, most notably through the H2 Console which leads to unauthenticated remote code execution.

As stated above, the H2 console is a feature intended for development purposes only and should never be enabled in production mode.

Vulnerabilities mitigation

This mitigation disables the usage of classes that do not belong to packages com.h2 and org.h2. This is quite restrictive, so exceptions can be added, like Java triggers or function aliases, database event listeners, table engines, or JAVA_OBJECT data type.

Modify the /opt/eurotech/esf/bin/start_kura_backgroud.sh file while ESF is up and running by adding the following property:

-Dh2.allowedClasses=com.h2.*,org.h2.* \

If in development mode, nothing else has to be done. If in production mode, then reload the fingerprint of the startup command line and reboot (Security -> Security Policies -> click on Startup command line -> Reload fingerprint). If you want to revert the changes because some bug happened or else, then remove the previously added line and reload the startup command line fingerprint while ESF is running.