diff --git a/ldvspec/connection/__init__.py b/ldvspec/connection/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/ldvspec/connection/config.py b/ldvspec/connection/config.py
new file mode 100644
index 0000000000000000000000000000000000000000..947d8c96042c4254fad4177bf46b4952903fbe7d
--- /dev/null
+++ b/ldvspec/connection/config.py
@@ -0,0 +1,21 @@
+from configparser import ConfigParser
+
+
+def read_config(section, filename='database.cfg'):
+    parser = ConfigParser()
+    try:
+        parser.read(filename)
+    except FileNotFoundError as exc:
+        raise FileNotFoundError(
+            "Configuration file with filename {0} not found".format(filename)
+        ) from exc
+
+    db_settings = {}
+    if parser.has_section(section):
+        params = parser.items(section)
+        for param in params:
+            db_settings[param[0]] = param[1]
+    else:
+        raise Exception('Section {0} not found in the {1} file'.format(section, filename))
+
+    return db_settings
diff --git a/ldvspec/connection/database.cfg b/ldvspec/connection/database.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..05df7ee81622d5db71a04bf57c38b2016bbc0e36
--- /dev/null
+++ b/ldvspec/connection/database.cfg
@@ -0,0 +1,15 @@
+[postgresql-local]
+host=localhost
+port=5433
+database=ldv-spec-db
+user=postgres
+password=secret
+
+[postgresql-ldv]
+tunnelhost=dop821.astron.nl
+tunnelusername=sdco
+host=sdc-db.astron.nl
+port=5432
+database=ldvadmin
+user=ldvrbow
+password=Wehn5CTYj1RcbstMSGls
\ No newline at end of file
diff --git a/ldvspec/connection/retrieve_db_connection.py b/ldvspec/connection/retrieve_db_connection.py
new file mode 100644
index 0000000000000000000000000000000000000000..af8659de67ab2ac9f68ae86aa2b84a4e5521c789
--- /dev/null
+++ b/ldvspec/connection/retrieve_db_connection.py
@@ -0,0 +1,95 @@
+import sys
+
+import psycopg2
+from config import read_config
+import logging
+import argparse
+from sshtunnel import SSHTunnelForwarder
+import os
+
+
+def connect_postgresql(section):
+    """ Connect to the PostgreSQL database server """
+    conn = None
+    tunnel = None
+    try:
+        # read connection parameters
+        configuration = read_config(section=section)
+
+        logging.info('Connecting PostgreSQL database %s', configuration.get('database', 'no database name given'))
+
+        host = configuration.get('host', 'no host given')
+        if host != 'localhost':
+            tunnel = open_tunnel(configuration)
+            conn = psycopg2.connect(host='localhost',
+                                    port=tunnel.local_bind_port,
+                                    database=configuration.get('database'),
+                                    user=configuration.get('user'),
+                                    password=configuration.get('password'))
+        else:
+            conn = psycopg2.connect(**configuration)
+
+        cur = conn.cursor()
+        cur.execute('SELECT version()')
+        db_version = cur.fetchone()
+        logging.info('Database version: ' + db_version[0])
+
+    except (Exception, psycopg2.DatabaseError) as error:
+        logging.error(error)
+        if tunnel is not None:
+            tunnel.stop()
+
+    return conn, tunnel
+
+
+def open_tunnel(configuration_params):
+    tunnel_host = configuration_params.get('tunnelhost', "no tunnel host given")
+    tunnel_username = configuration_params.get('tunnelusername', "no username for the tunnel given")
+    host = configuration_params.get('host', "no host given")
+    port = int(configuration_params.get('port', "no port given"))
+
+    try:
+        ssh_config_file = os.path.expanduser("~/.ssh/config")
+    except FileNotFoundError as exc:
+        raise FileNotFoundError(
+            "Ssh config file not found on standard path '~/.ssh/config'. This is mandatory for opening the ssh tunnel"
+        ) from exc
+
+    logging.info("Creating ssh tunnel for %s and port %s with tunnel host %s and username %s", repr(host), port,
+                 repr(tunnel_host), repr(tunnel_username))
+    ssh_tunnel = SSHTunnelForwarder(
+        ssh_address_or_host=tunnel_host,
+        ssh_username=tunnel_username,
+        ssh_config_file=ssh_config_file,
+        remote_bind_address=(host, port)
+    )
+    ssh_tunnel.start()
+    return ssh_tunnel
+
+
+def main():
+    """
+    Opens a database connection from configuration file database.cfg
+    """
+    logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=logging.DEBUG)
+
+    # Check the invocation arguments
+    parser = argparse.ArgumentParser()
+    parser.add_argument("-s", "--section", help="Add the configuration's section from the database.cfg.")
+    args = parser.parse_args()
+
+    if not args.section:
+        logging.critical("Error: no configuration section given. Try --help")
+        sys.exit(-1)
+
+    return connect_postgresql(args.section)
+
+
+if __name__ == '__main__':
+    connection, server = main()
+    if connection is not None:
+        connection.close()
+        logging.info('Database connection closed.')
+    if server is not None:
+        server.stop()
+        logging.info('Tunneled server stopped.')
diff --git a/ldvspec/connection/test.py b/ldvspec/connection/test.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/ldvspec/requirements/base.txt b/ldvspec/requirements/base.txt
index 45954f46e55c36134e02bec5a7006d63434827a9..b0d8418bd30fe83d55dec70a510771eeef51bf61 100644
--- a/ldvspec/requirements/base.txt
+++ b/ldvspec/requirements/base.txt
@@ -10,4 +10,5 @@ whitenoise==5.0.1
 six==1.15.0
 fontawesome-free==5.15.2
 pyyaml==6.0
-uritemplate==4.1.1
\ No newline at end of file
+uritemplate==4.1.1
+sshtunnel==0.4.0
\ No newline at end of file