<!-- Source: https://docs.squirro.com/en/latest/technical/admin/configuration/secure-config-guide.html -->
# Secure Configuration Guide

## Overview

This page outlines a number of steps that can be taken in order to configure the Squirro environment in a more secure manner than out of the box. This includes Squirro-specific steps, such as encrypting configuration files or enabling single sign-on (SSO), but also shows how the operating systems and some of the shipped services can be configured in a more restrictive way.

## Pre-Requisites

Linux instance to be setup according to third party standards and protocols.

Familiarity with Squirro services and setup procedures.

## Linux & Networking

### Firewall Settings

#### Squirro Ports

Incoming traffic to Squirro servers are open on a number of TCP ports. The individual ports and the required access level are documented below.

#### Storage Nodes

On Squirro storage nodes all port except the following can be blocked.

|  |  |  |
| --- | --- | --- |
| **TCP Port** | **Usage** | **Open for** |
| 9200 | Elasticsearch access | All storage and Squirro nodes |
| 9300 | Elasticsearch replication | All storage nodes |

#### Squirro Nodes

On Squirro cluster nodes all ports except the following can be blocked.

|  |  |  |
| --- | --- | --- |
| **TCP Port** | **Usage** | **Open for** |
| 443 | Web and API access (SSL-protected) | - All clients (or load balancer) |
| 3306 | MariaDB | - All Squirro nodes |
| 6379 | Redis (storage) | - All Squirro nodes |
| 6380 | Redis (cache) | - All Squirro nodes |

For more information on configuring ports, see [Installing Squirro on Linux](../../../getting/install/linux.md#install-linux).

## Nginx

Squirro ships with an Nginx web server which terminates web connections and then forwards them internally on the machine to the services.

### SSL certificate

For the HTTPS connection to the Squirro cluster node, a self-signed SSL certificate is generated by default. That certificate will trigger warnings for users and is not trusted by the Squirro Toolbox either. For security reasons, an SSL certificate should be issued by the respective body.

For more information on configuring SSL certificates, see [SSL Certificates](ssl-certificates.md#admin-ssl).

### Limit TLS protocols

As a compromise to security and compatibility, Squirro’s default configuration of Nginx allows TLS 1.0, 1.1 and 1.2. This can be reduced to only allow TLS 1.2 if the environment (users and clients connecting) allows that restriction.

To change, edit `/etc/nginx/conf.d/ssl.inc`. Look for the `ssl_protocols` and change it to:

```nginx
ssl_protocols TLSv1.2;
```

### Remove non-secure ports

The default configuration listens on port 80 and 81 for HTTP and 443 for HTTPS. The ports 80 and 81 can be removed to avoid these connections (requiring further changes in the Squirro configuration below).

Edit `/etc/nginx/conf.d/00-default.conf` and remove the following two lines:

```nginx
listen 80;
listen 81;
```

### Enable secure flag of cookies

The secure flag in cookies can get enabled to make HTTPS connections more secure. This prevents for cookie to get transmitted in clear-text if the user visits any HTTP URLs within the scope of the cookie.

Edit `/etc/squirro/frontend.ini` and add the following line in the section `[flask_app]`:

```ini
session_cookie_secure = true
```

## MariaDB

### SSL certificate

MariaDB can be configured to encrypt connections with TLS. For this, an SSL certificate needs to be provided at `/etc/my.cnf.d/certificates/`. To create self-signed certificates, the official documentation for [Certificate Creation with OpenSSL](https://mariadb.com/kb/en/certificate-creation-with-openssl/) can be followed.

The files can then be provided to MariaDB by putting the following configuration into `/etc/my.cnf.d/security.cnf`:

```ini
[server]
ssl_cert = /etc/my.cnf.d/certificates/server-cert.pem
ssl_key = /etc/my.cnf.d/certificates/server-key.pem
ssl_ca = /etc/my.cnf.d/certificates/ca.pem
```

### Enabling SSL

You must edit `/etc/squirro/common.ini` and add the line `ssl=true` in the `db` section as follow:

```ini
[db]
mysql_transaction_isolation=READ COMMITTED
ssl=true
ssl_ca=<PATH_TO_SSL_CERTIFICATE>
```

### Changing User Passwords

Each Squirro service with a database has a dedicated MariaDB user. Squirro recommends the default passwords of these users are changed. This can be achieved using the following commands per service:

```shell-session
$ mysql -u root -p
USE mysql;
UPDATE user SET password=PASSWORD('YourPasswordHere') WHERE User='<service_user_name>';
FLUSH PRIVILEGES;
```

The service database users for which to do this are:

- configuration
- cluster (will only exist on multi-node installations)
- datasource
- emailsender
- filtering
- machinelearning
- plumber
- scheduler
- topic
- user

The password can be different for each user.

## Redis

There are two Redis instances, one for queueing and more persistent metadata, and one for caching. Their respective configuration files are:

- Storage: `/etc/redis/redis.conf`
- Cache: `/etc/redis/cache.conf`

### SSL certificate

The Redis version shipped with Squirro does not currently allow SSL encryption. Later in 2020 Squirro aims to include Redis 6, which provides TLS encryption.

### Changing Redis Passwords

Squirro recommends the default passwords of the Redis instances be changed. In both configuration files, the password can be set on the lines:

```text
masterauth <password>
…
requirepass <password>
```

The password for the two Redis instances should be the same.

## Elasticsearch

> **Note**
>
> Starting from Release 3.7.4, Squirro storage nodes use fully secured Elasticsearch out-of-the-box with a SSL and a default password.
> For that reason, there is no need to perform manual configuration.

### SSL certificate

Elasticsearch allows the encryption of communication with TLS.

For this the certificate files can be put into `/etc/elasticsearch/certs` as:

- `servername.key`
- `servername.crt`
- `ca.crt`

They are then referenced in `/etc/elasticsearch/elasticsearch.yml` by adding the following lines:

```yaml
xpack.ssl.key: certs/servername.key
xpack.ssl.certificate: certs/servername.crt
xpack.ssl.certificate_authorities: certs/ca.crt

xpack.security.transport.ssl.enabled: true
xpack.security.http.ssl.enabled: true
```

Full documentation is available in the Elasticsearch manual at [Encrypting Communications](https://www.elastic.co/guide/en/elasticsearch/reference/current/encrypting-communications.html).

### Password

A password can be defined to access Elasticsearch. For this the following line needs to be added to `/etc/elasticsearch/elasticsearch.yml`:

```yaml
xpack.security.enabled: true
```

The password can then be defined by calling the command:

```bash
/usr/share/elasticsearch/bin/elasticsearch-setup-passwords interactive
```

After you set your password, you are required to add this parameter to squirro, you must edit `/etc/squirro/common.ini` and add the following lines (under [index]):

```ini
es_auth_user = elastic # or the user you selected
es_auth_password = YOUR_PASSWORD
```

NB: you can also generate a random password by calling:

```bash
/usr/share/elasticsearch/bin/bin/elasticsearch-setup-passwords auto -b
```

Important: On ES version < 7.7.1 you must first install x-pack and then the commands change as follow:

```bash
/usr/share/elasticsearch/bin/bin/x-pack/elasticsearch-setup-passwords auto -b
/usr/share/elasticsearch/bin/x-pack/setup-passwords interactive
```

See [Cluster References](https://www.elastic.co/guide/en/elasticsearch/reference/7.8/configuring-tls.html#tls-transport) for more information.

### Accessing Elasticsearch

Edit `/etc/squirro/common.ini` and ensure the following lines point to your relevant Elasticsearch host(s):

```bash
[index]
es_index_servers = https://localhost:9200
```

If your Elasticsearch is on a remote host, the correct setting is as follows:

```bash
[index]
es_index_servers = https://hostname.yourdomain.tld:9200
```

If you use multiple hosts, the correct setting is as follows:

```bash
[index]
es_index_servers = https://hostname1.yourdomain.tld:9200, https://hostname2.yourdomain.tld:9200,  https://hostname3.yourdomain.tld:9200
```

If you use self-signed certificates that the operating system cannot trust, you can provide your custom certificates as follows:

```bash
[index]
es_index_servers = https://hostname.yourdomain.tld:9200
es_pem_path = /path/to/your/ca.pem
```

Note: Ensure that the `ca` file is readable by the squirro group (gid).

While not recommended in production, you can disable the SSL certificate verification as follows:

```bash
[index]
es_verify_certs = False
```

#### Example

The following is a combined reference for example purposes:

```bash
[index]
auto_refresh = False
es_index_servers = https://hostname1.yourdomain.tld:9200, https://hostname2.yourdomain.tld:9200,  https://hostname3.yourdomain.tld:9200
es_auth_user = elastic
es_auth_password = your-password
es_pem_path = /path/to/your/ca.pem
es_verify_certs = True
```

> **Caution**
>
> If you make any changes to `/etc/squirro/common.ini`, you must restart the Squirro services for the changes to take effect using the command `squirro_restart`.

## Squirro

### SSO

Squirro supports the use of Single Sign-On with multiple SAML protocols. Squirro recommends that is enabled for secure server setups.

For user guides on how to enable Single Sign-On for various providers, see [SAML SSO for Squirro](../external-authentication/saml-sso.md#admin-saml-sso).

### Change Session Secret

To ensure the session cookies are hashed uniquely, you should add a custom secret key to the configuration file.

This must be set to the same value on all servers of a cluster.

See [Session Secret Key](config-files/frontend-ini.md#frontend-ini-session-secret) for how to set this value.

### Reducing Session Lifetime

> **Note**
>
> The following section describes the behavior of a new sessions mode introduced with Squirro Release 3.8.6 LTS. This needs to be enabled in the [Configuration Service](config-service.md#admin-config-service) with the `security.expiring-sessions` settings.

Squirro user sessions expire based on the following two separate timeouts:

- **Session timeout**, which logs a user out if they have not been active during that time window.
- **Maximum session duration**, which can never be exceeded, independent of user activity.

These two default values are 12 hours and 7 days respectively. (This means a user’s session can be valid for up to 7 days, as long as they are active at least once every 12 hours.)

Depending on your security considerations, these values can be adjusted. To do so, edit `/etc/squirro/frontend.ini` and add the following settings:

```ini
[frontend]
# Session timeout. This is calculated on every request and the cookie is
# extended correspondingly. (default: 12 hours)
session_timeout_seconds = 43200
# Maximum session lifetime that can not be exceeded. If the user is active in
# every `session_timeout_seconds` window between the session being created and
# `session_max_duration_seconds` the session will still be closed. (default: 7 days)
session_max_duration_seconds = 604800
```

Reference: For different recommendations for these values, refer to [Session Expiration](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#session-expiration) in the [OWASP Session Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html) or [NIST 800-63B](https://pages.nist.gov/800-63-3/sp800-63b.html#sec7).

#### Restoring Permanent Sessions

> **Caution**
>
> Previous versions of this guide had recommended switching to session cookies. This is no longer recommended as some browsers, most notably Google Chrome, tend to persist session cookies indefinitely.

If you have followed previous versions of the guide, ensure that the corresponding setting is turned back on:

```ini
[frontend]
session_permanent = true
```

Restart the frontend service to activate both of these configuration file changes:

```bash
systemctl restart sqfrontendd
```

### Changing database passwords

The changed Redis and MariaDB passwords need to be updated in the configuration files. Where a Vault is used (see “Encrypting Configuration Files” section), the passwords can instead be set in the corresponding values there.

|  |  |  |  |
| --- | --- | --- | --- |
| **Filename** | **INI file section** | **INI file key** | **Value** |
| Redis |  |  |  |
| `/etc/squirro/common.ini` | redis | password | Redis password |
| `/etc/squirro/common.ini` | redis_content | password | Redis password |
| `/etc/squirro/common.ini` | redis_cache | password | Redis password |
| `/etc/squirro/common.ini` | redis_http_cache | password | Redis password |
| `/etc/squirro/common.ini` | redis_provider_deduplication | password | Redis password |
| `/etc/squirro/common.ini` | redis_bloom | password | Redis password |
| `/etc/squirro/common.ini` | redis_studio | password | Redis password |
| `/etc/squirro/common.ini` | redis_studio_cache | password | Redis password |
| `/etc/squirro/datasource.ini` | queues_local | redis_password | Redis password |
| `/etc/squirro/datasource.ini` | redis_key_value_cache_provider | redis_password | Redis password |
| `/etc/squirro/datasource.ini` | redis_key_value_store_provider | redis_password | Redis password |
| `/etc/squirro/filtering.ini` | redis_email_history | password | Redis password |
| `/etc/squirro/filtering.ini` | redis_item_batching | password | Redis password |
| `/etc/squirro/frontend.ini` | redis_studio | password | Redis password |
| `/etc/squirro/frontend.ini` | redis_studio_cache | password | Redis password |
| `/etc/squirro/machinelearning.ini` | queues_local | redis_password | Redis password |
| MariaDB |  |  |  |
| `/etc/squirro/configuration.ini` | configuration | db | MariaDB password for user `configuration` |
| `/etc/squirro/datasource.ini` | datasource | db | MariaDB password for user `datasource` |
| `/etc/squirro/emailsender.ini` | emailsender | db | MariaDB password for user `emailsender` |
| `/etc/squirro/filtering.ini` | filtering | db | MariaDB password for user `filtering` |
| `/etc/squirro/machinelearning.ini` | machinelearning | db | MariaDB password for user `machinelearning` |
| `/etc/squirro/plumber.ini` | plumber | db | MariaDB password for user `plumber` |
| `/etc/squirro/scheduler.ini` | scheduler | db | MariaDB password for user `scheduler` |
| `/etc/squirro/topic.ini` | topic | db | MariaDB password for user `topic` |
| `/etc/squirro/topicproxy.ini` | topicproxy | db | MariaDB password for user `topic` |
| `/etc/squirro/user.ini` | user | db | MariaDB password for user `user` |
| `/etc/squirro/userproxy.ini` | userproxy | db | MariaDB password for user `user` |

### Changing Endpoints for APIs

If the HTTP ports have been disabled, Squirro needs to be changed to use the HTTPS endpoints. For this, edit `/etc/squirro/common.ini` and change any occurrence of `http://127.0.0.1:81/` to `https://127.0.0.1/.`

This can be achieved with the following command:

```bash
sed -i'' -e 's@http://127.0.0.1:81@https://127.0.0.1@' /etc/squirro/common.ini
```

### Changing MariaDB connection to TLS

SSL can be enabled for MariaDB connections by setting the following configuration value in `/etc/squirro/common.ini`:

```ini
[db]
ssl=true
```

The `[db]` section will already exist in the config file, thus the full section will then look something like this:

```ini
[db]
mysql_transaction_isolation=READ COMMITTED
ssl=true
```

### Changing Default Session Passwords

Squirro recommends that the below session passwords stored in `/etc/squirro/frontend.ini` be changed from the default values:

```ini
[frontend]
# key used to create secure HMAC tokens from passwords
password_key = …

[flask_app]
secret_key = …
```

Random values can be generated for these.

### Encrypting Configuration Files

By default passwords (e.g. the passwords for Redis or MariaDB) are configured in plain text in the configuration files. However, Squirro can provide a mechanism so that this sensitive information is encrypted. There are three different ways to encrypt Squirro configuration files:

- Encryption key in a Unix environment variable
- Encryption key stored in a file
- A custom command for encrypting and decrypting

For more information on the different types of encryption, see [Securing Configuration Files](securing-config-files.md#admin-securing-config-files).

Should there be some form of the vault where credentials are stored, Squirro can provide the necessary decryption tools in order to decrypt values.

### PDF Viewer License Key

The built-in PDF viewer requires a valid license key to operate. Without a license key, PDF documents render with a watermark.

To configure the license key, edit `/etc/squirro/frontend.ini` and add the following setting:

```ini
[nutrient_pdf_viewer]
license_key = YOUR_LICENSE_KEY
```

If you do not have a license key, visit the [Squirro Support website](https://go.squirro.com/support) and submit a technical support request. For full guidance on obtaining and applying the license key, including Ansible-managed deployments, see the [PDF Viewer](pdf-viewer.md#pdf-viewer-introduction) page.

> **Note**
>
> The PDF viewer also requires specific Content Security Policy directives to load correctly. For details, see the [Recommended Minimal Policy](#admin-csp-minimal-policy) section.

### Content Security Policy (CSP)

Squirro supports setting a CSP header on all frontend responses. Enabling CSP is recommended for production deployments, especially those exposed to the internet or subject to security audits.

#### Setting the CSP Header

The CSP header is controlled by the `security.content-security-policy` server configuration key.

**Via the Configuration Service UI:**

Navigate to the **Server** space, open **Configuration**, and search for `security.content-security-policy`. Set the value to the desired policy string.

> **Note**
>
> Configuration changes are subject to caching and are not applied instantaneously. See [Configuration Service](config-service.md#admin-config-service) for details.

#### Recommended Minimal Policy

The minimal recommended CSP value for Squirro depends on the `frontend.userapp.csp-safe-templates` server setting (default: `false`). It controls the `script-src` directive; the rest of the policy is the same either way.

With the default (`csp-safe-templates` off), `script-src` needs `'unsafe-eval'`:

```text
style-src 'self' 'unsafe-inline'; worker-src blob:; img-src 'self' data: blob:; script-src 'self' 'unsafe-eval';
```

With `csp-safe-templates` on, it can be tightened to `'wasm-unsafe-eval'`:

```text
style-src 'self' 'unsafe-inline'; worker-src blob:; img-src 'self' data: blob:; script-src 'self' 'wasm-unsafe-eval';
```

See [Backwards Compatibility Settings](#admin-csp-compat) for how to enable `csp-safe-templates`.

`'unsafe-inline'` in `style-src` covers Squirro’s inline theming and widget styles. `worker-src blob:` and `img-src blob:` are required by the built-in PDF viewer (since version 3.15.4), whose WebAssembly module also needs `'wasm-unsafe-eval'` (already permitted by the broader `'unsafe-eval'` in the default policy).

For deployments that load external resources (e.g., images from items or custom fonts), a more comprehensive policy can be used:

| Directive | Example Value | Purpose |
| --- | --- | --- |
| `default-src` | `'self'` | Fallback for all resource types |
| `style-src` | `'self' 'unsafe-inline'` | Allow Squirro’s inline styles |
| `img-src` | `'self' data: https:` | Allow images from items/external sources |
| `frame-ancestors` | `'self'` | Prevent click-jacking via iframes |

> **Caution**
>
> `script-src 'unsafe-eval'` weakens much of CSP’s protection. A default install requires it for dashboard query templates; enable `frontend.userapp.csp-safe-templates` (see [Backwards Compatibility Settings](#admin-csp-compat)) to remove it and tighten `script-src` to `'wasm-unsafe-eval'`.

#### Backwards Compatibility Settings

Squirro includes several features that historically relied on JavaScript patterns incompatible with strict CSP (specifically `eval()` and `new Function()`). These have been replaced with CSP-safe alternatives. The original behavior is preserved behind backwards-compatibility flags for deployments that have not yet migrated.

**CSP-Safe Dashboard Templates**

Dashboard query templates (the `<%= ... %>` expressions in widget query configurations) are normally evaluated using Underscore’s `_.template()`, which internally calls `new Function()` and requires `script-src 'unsafe-eval'`.

The `frontend.userapp.csp-safe-templates` server configuration key (boolean, default: `false`) switches to an AST-based parser that does not require `eval`.

Enable this when deploying CSP without `'unsafe-eval'`. Set it via the Configuration Service UI.

> **Note**
>
> The AST evaluator supports a subset of JavaScript. If you have custom dashboard query templates using advanced expressions beyond simple variable interpolation and conditionals, test them after enabling this flag.

**Studio Plugin Templates**

Studio plugins historically used `_.template()` for rendering, which requires `'unsafe-eval'`. Plugins can set the `USE_LIT_HTML_TEMPLATE: true` flag in their `config.js` to use lit-html instead, which is CSP-safe.

Squirro’s built-in studio plugins are already migrated. If your deployment includes **custom studio plugins**, check whether they set `USE_LIT_HTML_TEMPLATE: true` in their `config.js`. Plugins that have not been migrated will fail to render under strict CSP. Contact the plugin developer to migrate the template to lit-html.

**Insecure Widgets**

The `no_insecure_widgets` setting in the `[security]` section of `/etc/squirro/common.ini` hides widgets from the dashboard editor that allow arbitrary HTML injection (e.g., the **Text** widget). These widgets are an XSS vector when unrestricted HTML input is allowed.

```ini
[security]
no_insecure_widgets = true
```

For Docker deployments, set the environment variable `SQ_SECURITY_NO_INSECURE_WIDGETS=true`.

> **Note**
>
> This setting hides the widgets from the editor but does not remove them from existing dashboards. Dashboards that already use these widgets will continue to render them.

#### Verifying CSP is Working

**Check the HTTP response header:**

```bash
curl -sI https://your-squirro-server/ | grep -i content-security-policy
```

Expected output:

```text
Content-Security-Policy: style-src 'self' 'unsafe-inline';
```

**Browser Developer Tools:**

Open the Network tab, select any request to the Squirro server, and inspect the Response Headers for `Content-Security-Policy`.

**Check for CSP violations:**

Open the browser Console. Any resource blocked by CSP produces a log entry such as `Refused to execute inline script because it violates the following Content Security Policy directive: ...`

#### Common Issues

- **External images not loading** – Add the image source domains to the `img-src` directive (e.g., `img-src 'self' https://cdn.example.com`).
- **Dashboard query templates failing** – Enable `frontend.userapp.csp-safe-templates` in the Configuration Service (see above).
- **Custom studio plugins not rendering** – The plugin has not been migrated to lit-html. Check for `USE_LIT_HTML_TEMPLATE: true` in the plugin’s `config.js`.
- **Embedded Squirro dashboards blocked** – If Squirro is embedded in an iframe on another site, add the embedding site’s origin to `frame-ancestors`.

**Relevant Links:**

- [Mozilla Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP)
- [CSP Evaluator](https://csp-evaluator.withgoogle.com/)
- [Configuration Service](config-service.md#admin-config-service) – Configuration Service documentation
