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:
- Via an administrative console.
- Over a binary port for read and write operations and procedure invocation.
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.11Type: numberDefault: 0Environment variable: TT_AUTH_DELAYDynamic: 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.11Type: booleanDefault: falseEnvironment variable: TT_DISABLE_GUESTDynamic: 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
- password_enforce_uppercase
- password_enforce_lowercase
- password_enforce_digits
- password_enforce_specialchars
- password_lifetime_days
- password_history_length
-
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.11Type: integerDefault: 0Environment variable: TT_PASSWORD_MIN_LENGTHDynamic: yes
-
password_enforce_uppercase
¶ If true, a password should contain uppercase letters (A-Z).
Since version: 2.11Type: booleanDefault: falseEnvironment variable: TT_PASSWORD_ENFORCE_UPPERCASEDynamic: yes
-
password_enforce_lowercase
¶ If true, a password should contain lowercase letters (a-z).
Since version: 2.11Type: booleanDefault: falseEnvironment variable: TT_PASSWORD_ENFORCE_LOWERCASEDynamic: yes
-
password_enforce_digits
¶ If true, a password should contain digits (0-9).
Since version: 2.11Type: booleanDefault: falseEnvironment variable: TT_PASSWORD_ENFORCE_DIGITSDynamic: yes
-
password_enforce_specialchars
¶ If true, a password should contain at least one special character (such as
&|?!@$
).Since version: 2.11Type: booleanDefault: falseEnvironment variable: TT_PASSWORD_ENFORCE_SPECIALCHARSDynamic: 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.11Type: integerDefault: 0Environment variable: TT_PASSWORD_LIFETIME_DAYSDynamic: 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.11Type: integerDefault: 0Environment variable: TT_PASSWORD_HISTORY_LENGTHDynamic: yesNote
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' }
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:
- the Logs section
- the Logging section in the configuration reference
- the Tarantool audit module topic
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:
- box.cfg.listen – on the server side.
- box.cfg.replication–on the client side.
- net_box_object.connect()–on the client side.
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 tossl
. The default value isplain
, 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 thetransport = '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 thessl_ca_file
parameter is set for a server; otherwise, optional. If the private key is encrypted, provide a password for it in thessl_password
orssl_password_file
parameter.ssl_cert_file
– a path to an SSL certificate file. Mandatory for a server. For a client, it’s mandatory if thessl_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 inssl_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 inssl_password
.Tarantool applies the
ssl_password
andssl_password_file
parameters in the following order:- If
ssl_password
is provided, Tarantool tries to decrypt the private key with it. - If
ssl_password
is incorrect or isn’t provided, Tarantool tries all passwords fromssl_password_file
one by one in the order they are written. - If
ssl_password
and all passwords fromssl_password_file
are incorrect, or none of them is provided, Tarantool treats the private key as unencrypted.
- If
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
andssl_cert_file
. - Optional URI parameters:
ssl_ca_file
,ssl_ciphers
,ssl_password
, andssl_password_file
.
Client side
- Is configured via the
box.cfg.replication
option (see details) ornet_box_object.connect()
.
Parameters:
- If the server side has only the
transport
,ssl_key_file
andssl_cert_file
parameters set, on the client side, you need to specify onlytransport = 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 specifytransport
,ssl_key_file
andssl_cert_file
as the mandatory parameters. Other parameters –ssl_ca_file
,ssl_ciphers
,ssl_password
, andssl_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.
- 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 }
- 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.