Security hardening guide | Tarantool
Tarantool Enterprise Edition Security hardening guide

Security hardening guide

This guide explains how to enhance security in your Tarantool Enterprise Edition’s cluster using built-in features and provides general recommendations on security hardening. If you need to perform a security audit of a Tarantool Enterprise cluster, refer to the security checklist.

Tarantool Enterprise Edition does not provide a dedicated API for security control. All the necessary configurations can be done via an administrative console or initialization code.

Tarantool Enterprise Edition has the following built-in security features:

Tarantool Enterprise Edition supports password-based authentication and allows for two types of connections:

For more information on authentication and connection types, see the Security section of the Tarantool manual.

In addition, Tarantool provides the following functionality:

  • Sessions – states which associate connections with users and make Tarantool API available to them after authentication.
  • Authentication triggers, which execute actions on authentication events.
  • Third-party (external) authentication protocols and services such as LDAP or Active Directory – supported in the web interface, but unavailable on the binary-protocol level.

Tarantool Enterprise Edition provides the means for administrators to prevent unauthorized access to the database and to certain functions.

Tarantool recognizes:

  • different users (guests and administrators)
  • privileges associated with users
  • roles (containers for privileges) granted to users

The following system spaces are used to store users and privileges:

  • The _user space to store usernames and hashed passwords for authentication.
  • The _priv space to store privileges for access control.

For more information, see the Access control section.

Users who create objects (spaces, indexes, users, roles, sequences, and functions) in the database become their owners and automatically acquire privileges for what they create. For more information, see the Owners and privileges section.

Tarantool Enterprise Edition provides the ability to apply additional restrictions for user authentication. For example, you can specify the minimum time between authentication attempts or disable access for guest users.

The following configuration options are available:

auth_delay

Specifies a period of time (in seconds) that a specific user should wait for the next attempt after failed authentication.

With the configuration below, Tarantool refuses the authentication attempt if the previous attempt was less than 5 seconds ago.

box.cfg{ auth_delay = 5 }
Since version: 2.11
Type: number
Default: 0
Environment variable: TT_AUTH_DELAY
Dynamic: yes
disable_guest

If true, disables access over remote connections from unauthenticated or guest access users. This option affects both net.box and replication connections.

Since version: 2.11
Type: boolean
Default: false
Environment variable: TT_DISABLE_GUEST
Dynamic: yes

A password policy allows you to improve database security by enforcing the use of strong passwords, setting up a maximum password age, and so on. When you create a new user with box.schema.user.create or update the password of an existing user with box.schema.user.passwd, the password is checked against the configured password policy settings.

The following configuration options are available:

password_min_length

Specifies the minimum number of characters for a password.

The following example shows how to set the minimum password length to 10.

box.cfg{ password_min_length = 10 }
Since version: 2.11
Type: integer
Default: 0
Environment variable: TT_PASSWORD_MIN_LENGTH
Dynamic: yes
password_enforce_uppercase

If true, a password should contain uppercase letters (A-Z).

Since version: 2.11
Type: boolean
Default: false
Environment variable: TT_PASSWORD_ENFORCE_UPPERCASE
Dynamic: yes
password_enforce_lowercase

If true, a password should contain lowercase letters (a-z).

Since version: 2.11
Type: boolean
Default: false
Environment variable: TT_PASSWORD_ENFORCE_LOWERCASE
Dynamic: yes
password_enforce_digits

If true, a password should contain digits (0-9).

Since version: 2.11
Type: boolean
Default: false
Environment variable: TT_PASSWORD_ENFORCE_DIGITS
Dynamic: yes
password_enforce_specialchars

If true, a password should contain at least one special character (such as &|?!@$).

Since version: 2.11
Type: boolean
Default: false
Environment variable: TT_PASSWORD_ENFORCE_SPECIALCHARS
Dynamic: yes
password_lifetime_days

Specifies the maximum period of time (in days) a user can use the same password. When this period ends, a user gets the “Password expired” error on a login attempt. To restore access for such users, use box.schema.user.passwd.

Note

The default 0 value means that a password never expires.

The example below shows how to set a maximum password age to 365 days.

box.cfg{ password_lifetime_days = 365 }
Since version: 2.11
Type: integer
Default: 0
Environment variable: TT_PASSWORD_LIFETIME_DAYS
Dynamic: yes
password_history_length

Specifies the number of unique new user passwords before an old password can be reused.

In the example below, a new password should differ from the last three passwords.

box.cfg{ password_history_length = 3 }
Since version: 2.11
Type: integer
Default: 0
Environment variable: TT_PASSWORD_HISTORY_LENGTH
Dynamic: yes

Note

Tarantool uses the auth_history field in the box.space._user system space to store user passwords.

By default, Tarantool uses the CHAP protocol to authenticate users and applies SHA-1 hashing to passwords. Note that CHAP stores password hashes in the _user space unsalted. If an attacker gains access to the database, they may crack a password, for example, using a rainbow table.

In the Enterprise Edition, you can enable PAP authentication with the SHA256 hashing algorithm. For PAP, a password is salted with a user-unique salt before saving it in the database, which keeps the database protected from cracking using a rainbow table.

To enable PAP, specify the box.cfg.auth_type option as follows:

box.cfg{ auth_type = 'pap-sha256' }
Since version: 2.11
Type: string
Default value: ‘chap-sha1’
Possible values: ‘chap-sha1’, ‘pap-sha256’
Environment variable: TT_AUTH_TYPE
Dynamic: yes

For new users, the box.schema.user.create method will generate authentication data using PAP-SHA256. For existing users, you need to reset a password using box.schema.user.passwd to use the new authentication protocol.

Warning

Given that PAP transmits a password as plain text, Tarantool requires configuring SSL/TLS for a connection.

The examples below show how to specify the authentication protocol on the client side:

  • For net.box, you can specify the authentication protocol using the auth_type URI parameter or the corresponding connection option:

    -- URI parameters
    conn = require('net.box').connect(
        'username:password@localhost:3301?auth_type=pap-sha256')
    
    -- URI parameters table
    conn = require('net.box').connect({
        uri = 'username:password@localhost:3301',
        params = {auth_type = 'pap-sha256'},
    })
    
    -- Connection options
    conn = require('net.box').connect('localhost:3301', {
        user = 'username',
        password = 'password',
        auth_type = 'pap-sha256',
    })
    
  • For replication configuration, the authentication protocol can be specified in URI parameters:

    -- URI parameters
    box.cfg{
        replication = {
            'replicator:password@localhost:3301?auth_type=pap-sha256',
        },
    }
    
    -- URI parameters table
    box.cfg{
        replication = {
            {
                uri = 'replicator:password@localhost:3301',
                params = {auth_type = 'pap-sha256'},
            },
        },
    }
    

If the authentication protocol isn’t specified explicitly on the client side, the client uses the protocol configured on the server via box.cfg.auth_type.

Tarantool Enterprise Edition has a built-in audit log that records events such as:

  • authentication successes and failures
  • connection closures
  • creation, removal, enabling, and disabling of users
  • changes of passwords, privileges, and roles
  • denials of access to database objects

The audit log contains:

  • timestamps
  • usernames of users who performed actions
  • event types (e.g. user_create, user_enable, disconnect, etc)
  • descriptions

You can configure the following audit log parameters:

  • audit_log = <PATH_TO_FILE> which is similar to the log parameter. This parameter tells Tarantool to record audit events to a specific file.
  • audit_nonblock which is similar to the log_nonblock parameter.

For more information on logging, see the following:

Access permissions to audit log files can be set up as to any other Unix file system object – via chmod.

Since version 2.10.0, Tarantool Enterprise Edition has the built-in support for using SSL to encrypt the client-server communications over binary connections, that is, between Tarantool instances in a cluster or connecting to an instance via connectors using net.box.

Tarantool uses the OpenSSL library that is included in the delivery package. Please note that SSL connections use only TLSv1.2.

To configure traffic encryption, you need to set the special URI parameters for a particular connection. The parameters can be set for the following box.cfg options and nex.box method:

Below is the list of the parameters. In the next section, you can find details and examples on what should be configured on both the server side and the client side.

  • transport – enables SSL encryption for a connection if set to ssl. The default value is plain, which means the encryption is off. If the parameter is not set, the encryption is off too. Other encryption-related parameters can be used only if the transport = 'ssl' is set.

    Example:

    c = require('net.box').connect({
        uri = 'localhost:3301',
        params = {transport = 'ssl'}
    })
    
  • ssl_key_file – a path to a private SSL key file. Mandatory for a server. For a client, it’s mandatory if the ssl_ca_file parameter is set for a server; otherwise, optional. If the private key is encrypted, provide a password for it in the ssl_password or ssl_password_file parameter.

  • ssl_cert_file – a path to an SSL certificate file. Mandatory for a server. For a client, it’s mandatory if the ssl_ca_file parameter is set for a server; otherwise, optional.

  • ssl_ca_file – a path to a trusted certificate authorities (CA) file. Optional. If not set, the peer won’t be checked for authenticity.

    Both a server and a client can use the ssl_ca_file parameter:

    • If it’s on the server side, the server verifies the client.
    • If it’s on the client side, the client verifies the server.
    • If both sides have the CA files, the sever and the client verify each other.
  • ssl_ciphers – a colon-separated (:) list of SSL cipher suites the connection can use. See the Supported ciphers section for details. Optional. Note that the list is not validated: if a cipher suite is unknown, Tarantool just ignores it, doesn’t establish the connection and writes to the log that no shared cipher found.

  • ssl_password – a password for an encrypted private SSL key. Optional. Alternatively, the password can be provided in ssl_password_file.

  • ssl_password_file – a text file with one or more passwords for encrypted private SSL keys (each on a separate line). Optional. Alternatively, the password can be provided in ssl_password.

    Tarantool applies the ssl_password and ssl_password_file parameters in the following order:

    1. If ssl_password is provided, Tarantool tries to decrypt the private key with it.
    2. If ssl_password is incorrect or isn’t provided, Tarantool tries all passwords from ssl_password_file one by one in the order they are written.
    3. If ssl_password and all passwords from ssl_password_file are incorrect, or none of them is provided, Tarantool treats the private key as unencrypted.

Configuration example:

box.cfg{ listen = {
    uri = 'localhost:3301',
    params = {
        transport = 'ssl',
        ssl_key_file = '/path_to_key_file',
        ssl_cert_file = '/path_to_cert_file',
        ssl_ciphers = 'HIGH:!aNULL',
        ssl_password = 'topsecret'
    }
}}

Tarantool Enterprise supports the following cipher suites:

  • ECDHE-ECDSA-AES256-GCM-SHA384
  • ECDHE-RSA-AES256-GCM-SHA384
  • DHE-RSA-AES256-GCM-SHA384
  • ECDHE-ECDSA-CHACHA20-POLY1305
  • ECDHE-RSA-CHACHA20-POLY1305
  • DHE-RSA-CHACHA20-POLY1305
  • ECDHE-ECDSA-AES128-GCM-SHA256
  • ECDHE-RSA-AES128-GCM-SHA256
  • DHE-RSA-AES128-GCM-SHA256
  • ECDHE-ECDSA-AES256-SHA384
  • ECDHE-RSA-AES256-SHA384
  • DHE-RSA-AES256-SHA256
  • ECDHE-ECDSA-AES128-SHA256
  • ECDHE-RSA-AES128-SHA256
  • DHE-RSA-AES128-SHA256
  • ECDHE-ECDSA-AES256-SHA
  • ECDHE-RSA-AES256-SHA
  • DHE-RSA-AES256-SHA
  • ECDHE-ECDSA-AES128-SHA
  • ECDHE-RSA-AES128-SHA
  • DHE-RSA-AES128-SHA
  • AES256-GCM-SHA384
  • AES128-GCM-SHA256
  • AES256-SHA256
  • AES128-SHA256
  • AES256-SHA
  • AES128-SHA
  • GOST2012-GOST8912-GOST8912
  • GOST2001-GOST89-GOST89

Tarantool Enterprise static build has the embeded engine to support the GOST cryptographic algorithms. If you use these algorithms for traffic encryption, specify the corresponding cipher suite in the ssl_ciphers parameter, for example:

box.cfg{ listen = {
    uri = 'localhost:3301',
    params = {
        transport = 'ssl',
        ssl_key_file = '/path_to_key_file',
        ssl_cert_file = '/path_to_cert_file',
        ssl_ciphers = 'GOST2012-GOST8912-GOST8912'
    }
}}

For detailed information on SSL ciphers and their syntax, refer to OpenSSL documentation.

The URI parameters for traffic encryption can also be set via environment variables. For example:

export TT_LISTEN="localhost:3301?transport=ssl&ssl_cert_file=/path_to_cert_file&ssl_key_file=/path_to_key_file"

For details, refer to the Tarantool configuration reference.

When configuring the traffic encryption, you need to specify the necessary parameters on both the server side and the client side. Below you can find the summary on the options and parameters to be used and examples of configuration.

Server side

  • Is configured via the box.cfg.listen option.
  • Mandatory URI parameters: transport, ssl_key_file and ssl_cert_file.
  • Optional URI parameters: ssl_ca_file, ssl_ciphers, ssl_password, and ssl_password_file.

Client side

  • Is configured via the box.cfg.replication option (see details) or net_box_object.connect().

Parameters:

  • If the server side has only the transport, ssl_key_file and ssl_cert_file parameters set, on the client side, you need to specify only transport = ssl as the mandatory parameter. All other URI parameters are optional.
  • If the server side also has the ssl_ca_file parameter set, on the client side, you need to specify transport, ssl_key_file and ssl_cert_file as the mandatory parameters. Other parameters – ssl_ca_file, ssl_ciphers, ssl_password, and ssl_password_file – are optional.

Suppose, there is a master-replica set with two Tarantool instances:

  • 127.0.0.1:3301 – master (server)
  • 127.0.0.1:3302 – replica (client).

Examples below show the configuration related to connection encryption for two cases: when the trusted certificate authorities (CA) file is not set on the server side and when it does. Only mandatory URI parameters are mentioned in these examples.

  1. Without CA
  • 127.0.0.1:3301 – master (server)

    box.cfg{
        listen = {
            uri = '127.0.0.1:3301',
            params = {
                transport = 'ssl',
                ssl_key_file = '/path_to_key_file',
                ssl_cert_file = '/path_to_cert_file'
            }
        }
    }
    
  • 127.0.0.1:3302 – replica (client)

    box.cfg{
        listen = {
            uri = '127.0.0.1:3302',
            params = {transport = 'ssl'}
        },
        replication = {
            uri = 'username:password@127.0.0.1:3301',
            params = {transport = 'ssl'}
        },
        read_only = true
    }
    
  1. With CA
  • 127.0.0.1:3301 – master (server)

    box.cfg{
        listen = {
            uri = '127.0.0.1:3301',
            params = {
                transport = 'ssl',
                ssl_key_file = '/path_to_key_file',
                ssl_cert_file = '/path_to_cert_file',
                ssl_ca_file = '/path_to_ca_file'
            }
        }
    }
    
  • 127.0.0.1:3302 – replica (client)

    box.cfg{
        listen = {
            uri = '127.0.0.1:3302',
            params = {
                transport = 'ssl',
                ssl_key_file = '/path_to_key_file',
                ssl_cert_file = '/path_to_cert_file'
            }
        },
        replication = {
            uri = 'username:password@127.0.0.1:3301',
            params = {
                transport = 'ssl',
                ssl_key_file = '/path_to_key_file',
                ssl_cert_file = '/path_to_cert_file'
            }
        },
        read_only = true
    }
    

This section lists recommendations that can help you harden the cluster’s security.

Since version 2.10.0, Tarantool Enterprise Edition has built-in support for using SSL to encrypt the client-server communications over binary connections, that is, between Tarantool instances in a cluster. For details on enabling SSL encryption, see the Traffic encryption section of this guide.

In case the built-in encryption is not set for particular connections, consider the following security recommendations:

  • setting up connection tunneling, or
  • encrypting the actual data stored in the database.

For more information on data encryption, see the crypto module reference.

The HTTP server module provided by rocks does not support the HTTPS protocol. To set up a secure connection for a client (e.g., REST service), consider hiding the Tarantool instance (router if it is a cluster of instances) behind an Nginx server and setting up an SSL certificate for it.

To make sure that no information can be intercepted ‘from the wild’, run nginx on the same physical server as the instance and set up their communication over a Unix socket. For more information, see the socket module reference.

To protect the cluster from any unwanted network activity ‘from the wild’, configure the firewall on each server to allow traffic on ports listed in Network requirements.

If you are using static IP addresses, whitelist them, again, on each server as the cluster has a full mesh network topology. Consider blacklisting all the other addresses on all servers except the router (running behind the Nginx server).

Tarantool Enterprise does not provide defense against DoS or DDoS attacks. Consider using third-party software instead.

Tarantool Enterprise Edition does not keep checksums or provide the means to control data integrity. However, it ensures data persistence using a write-ahead log, regularly snapshots the entire data set to disk, and checks the data format whenever it reads the data back from the disk. For more information, see the Data persistence section.

Found what you were looking for?
Feedback