Fortinet white logo
Fortinet white logo

User Guide

26.1.0

Secret management framework

Secret management framework

Secrets management is the practice of securely storing and handling sensitive information, including certificates, SSH keys, API keys, credentials, tokens, passwords, and other confidential data.

The Secret Management Framework provides multiple methods for ensuring secure connections when utilizing OnSight Countermeasures. These methods are described below - some are easier to configure but others are more scalable for larger deployments.

Method

Recommendation

Local SSH Key-pair access method

This is most recommended for small scale testing and deployment. Does not scale well for large deployment.

Vault method

This is recommended for scalable, widespread deployment of OnSight Countermeasures.

Note: For the vault method, only Hashicorp vault is supported. Instances of "vault" in this article refers to Hashicorp vault.

Configuration

Directories

The directories listed below reside on the host VM and not within the individual OnSight container.

  • /usr/share/onsight/countermeasures: Directory to put countermeasure plugins
  • /usr/share/onsight/custom-metrics: Directory to put custom metric plugins

  • /usr/share/onsight/secrets: Directory for secrets

  • /usr/share/onsight/ssh-keys: Directory to put ssh private key files

  • /usr/share/onsight/dependencies: Directory to install python packages required to run plugins

  • /var/log/countermeasures: Directory contains:

    • countermeasure.log

    • custom_metric.log

Secret management for password authentication

You can securely store your passwords encrypted in local storage. The stored passwords will be used in execute_ssh_with_secret_password(). If you omit --host, the password is used for a random host. If both a password with host and a password without host exist, the host-specified password is used

Usage: onsight set-secret [OPTIONS]

Set secret for countermeasure and custom plugins in local repo. Password can be set for user or user@host. Password will be removed if --password is missing or empty string.

Options:

--user TEXT [required]

--host TEXT

--password TEXT

--repo TEXT [default: local]

--help Show this message and exit.

You can view the stored passwords with the onsight list-secret command. The passwords will be displayed as encrypted.

SSH key authentication

def execute_ssh(self, cmd, hostname, username, private_key_file, disable_sha2_pubkeys=False)

SSH to a remote server and run a command, returning the command output. private_key_file should be placed under /usr/share/onsight/ssh-keys/ directory in host. public key file must be registerd on the target server

def execute_ssh_with_secret_pkey(self, cmd, hostname, username, repo, key, disable_sha2_pubkeys=False)

private_key will be retrieved from the secret repo (currently, only Hashicorp vault is supported).

SSH Cert authentication

def execute_ssh_with_secret_cert(self, cmd, hostname, username, repo)

SSH cert will be retrieved from the secret repo (currently, only Hashicorp vault is supported.

Secret Management for Hashicorp Vault

You can add SSH keys directly to your OnSight VM in the directory outlined above, but a more scalable solution exists in the form of secret management vaults. Currently, FortiMonitor supports HashiCorp Vault.

You will need to utilize the Vault URL, token, path, mount point, and version as shown in the example below.

Secret repository configuration

  • Create a repository directory under /usr/share/onsight/countermeasures/secrets and insert the config.json file in it (use the repository name for the directory name).

Hashicorp Vault Key-Value engine example:

  • Sample config.json (/usr/share/onsight/secrets/vault-kv/config.json)

{
"type": "hashicorp.vault.kv",
"url": "Your-Vault-URL,
"token": "Your-Vault-Token",
"path": "Your-Vault-Path",
"mount_point": "Your-Vault-MountPoint/Top-Level-Directory",
"kv_version": "v1"
}

Hashicorp Vault SSH engine example:

  • Sample config.json (/usr/share/onsight/secrets/vault-ssh/config.json)

{
"type": "hashicorp.vault.ssh",
"url": "Your-Vault-URL,
"token": "Your-Vault-Token",
"path": "Your-Vault-Path",
"mount_point": "Your-Vault-MountPoint/Top-Level-Directory",
"api_version": "v1"
}
  • The CA public key must be added to target host’s SSH configuration. Add the public key to all target host's SSH configuration.

    • Download the CA public key.
      curl -o /etc/ssh/trusted-user-ca-keys.pem http://URL:PORT/v1/ssh-client-signer/public_key

    • Edit SSH configuration.

      # /etc/ssh/sshd_config
      # ...
      TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem
    • Restart the SSH service to pick up the changes.

Secret management helper functions for CounterMeasure plugins

The following functions have been pre-defined to assist in developing custom CounterMeasures.

def get_secret(self, repo, key=None, **kwargs):
"""
GET secret from Secret management framework
"""
def get_ssh_certificate(self, repo, username, **kwargs):
"""
GET ssh certificate from Secret management framework
"""
 
def execute_ssh_with_secret_pkey(self, cmd, hostname, username, repo, key):
"""
Use Spur/Paramiko to ssh to a remote server and run a command.
Get private key value in secret repo with a given key
Returns a tuple of (return code, stdout, stderr)
"""
 
def execute_ssh_with_secret_cert(self, cmd, hostname, username, repo):
"""
Use Spur/Paramiko to ssh to a remote server and run a command.
Get ssh cert file from secret repo
Returns a tuple of (return code, stdout, stderr)
"""

SSH access scenarios

Signed SSH certificate

The instructions below include details for each aspect of this setup.

  • Configure the Vault

    • Set up Hashicorp Vault server and create SSH engine.

  • On the remote host

    • Add the public key to all target host's SSH configuration.

    • Download CA public key.
      curl -o /etc/ssh/trusted-user-ca-keys.pem http://URL:PORT/v1/ssh-client-signer/public_key

    • Edit ssh configuration
      # /etc/ssh/sshd_config
      # ...
      TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem

    • Restart the SSH service to pick up the changes.

  • On the OnSight

    • Create config.json under /secrets/vault-ssh

      {

      "type": "hashicorp.vault.ssh",

      "url": "Your-Vault-URL,

      "token": "Your-Vault-Token",

      "role": "ssh-client-signer/sign/my-role",

      "api_version": "v1"

      }

  • Within the CounterMeasure plugin

    • Use execute_ssh_with_secret_cert() method to execute command on a remote host

      class VaultDemoCountermeasure(CountermeasurePlugin):

      name = "Vault demo countermeasure"

      textkey = "testing.vault"

      def run(self):

      server = self.metadata.get('server')

      hostname = server.get('fqdn')

      return_code, output, _ = self.execute_ssh_with_secret_cert("pwd", hostname, "vadmin", 'vault-ssh')

      self.save_output(output)

SSH key-pair access

  • Store SSH private key in Vault KV engine and access remote Host with private key.

  • Configure the Vault.

    • Set up Hashicorp Vault server and create KV engine.

    • Save private key in KV engine

      • For example: key=”mykey”, value=”-----BEGIN RSA PRIVATE KEY-----…”

  • On the remote host

    • Copy the public key to the remote host.

  • On the OnSight

    • Create config.json under /secrets/vault-kv.

      {

      "type": "hashicorp.vault.kv",

      "url": "YOUR-VAULT-URL:PORT",

      "token": "YOUR-VAULT-TOKEN",

      "kv_version": "v1",

      "mount_point": "Your-Vault-MountPoint/Top-Level-Directory",

      "path": "Your-Vault-Path",

      }

  • Within the CounterMeasure plugin

    • Use execute_ssh_with_secret_pkey() method to execute command on the remote host.

      class VaultDemoCountermeasure(CountermeasurePlugin):

      name = "Vault demo countermeasure"

      textkey = "testing.vault"

      def run(self):

      server = self.metadata.get('server')

      hostname = server.get('fqdn')

      return_code, output, _ = self.execute_ssh_with_secret_pkey("pwd", hostname, "myuser", 'vault-kv', 'mykey')

      self.save_output(output)

    • Sse get_secret() method to get private key, if you want to use your own code to access to a remote host.

      class VaultDemoCountermeasure(CountermeasurePlugin):

      name = "Vault demo countermeasure"

      textkey = "testing.vault"

      def run(self):

      server = self.metadata.get('server')

      hostname = server.get('fqdn')

      pkey = self.get_key('vault-kv', 'mykey')

      # access to a remote host with pkey

Secret management framework

Secret management framework

Secrets management is the practice of securely storing and handling sensitive information, including certificates, SSH keys, API keys, credentials, tokens, passwords, and other confidential data.

The Secret Management Framework provides multiple methods for ensuring secure connections when utilizing OnSight Countermeasures. These methods are described below - some are easier to configure but others are more scalable for larger deployments.

Method

Recommendation

Local SSH Key-pair access method

This is most recommended for small scale testing and deployment. Does not scale well for large deployment.

Vault method

This is recommended for scalable, widespread deployment of OnSight Countermeasures.

Note: For the vault method, only Hashicorp vault is supported. Instances of "vault" in this article refers to Hashicorp vault.

Configuration

Directories

The directories listed below reside on the host VM and not within the individual OnSight container.

  • /usr/share/onsight/countermeasures: Directory to put countermeasure plugins
  • /usr/share/onsight/custom-metrics: Directory to put custom metric plugins

  • /usr/share/onsight/secrets: Directory for secrets

  • /usr/share/onsight/ssh-keys: Directory to put ssh private key files

  • /usr/share/onsight/dependencies: Directory to install python packages required to run plugins

  • /var/log/countermeasures: Directory contains:

    • countermeasure.log

    • custom_metric.log

Secret management for password authentication

You can securely store your passwords encrypted in local storage. The stored passwords will be used in execute_ssh_with_secret_password(). If you omit --host, the password is used for a random host. If both a password with host and a password without host exist, the host-specified password is used

Usage: onsight set-secret [OPTIONS]

Set secret for countermeasure and custom plugins in local repo. Password can be set for user or user@host. Password will be removed if --password is missing or empty string.

Options:

--user TEXT [required]

--host TEXT

--password TEXT

--repo TEXT [default: local]

--help Show this message and exit.

You can view the stored passwords with the onsight list-secret command. The passwords will be displayed as encrypted.

SSH key authentication

def execute_ssh(self, cmd, hostname, username, private_key_file, disable_sha2_pubkeys=False)

SSH to a remote server and run a command, returning the command output. private_key_file should be placed under /usr/share/onsight/ssh-keys/ directory in host. public key file must be registerd on the target server

def execute_ssh_with_secret_pkey(self, cmd, hostname, username, repo, key, disable_sha2_pubkeys=False)

private_key will be retrieved from the secret repo (currently, only Hashicorp vault is supported).

SSH Cert authentication

def execute_ssh_with_secret_cert(self, cmd, hostname, username, repo)

SSH cert will be retrieved from the secret repo (currently, only Hashicorp vault is supported.

Secret Management for Hashicorp Vault

You can add SSH keys directly to your OnSight VM in the directory outlined above, but a more scalable solution exists in the form of secret management vaults. Currently, FortiMonitor supports HashiCorp Vault.

You will need to utilize the Vault URL, token, path, mount point, and version as shown in the example below.

Secret repository configuration

  • Create a repository directory under /usr/share/onsight/countermeasures/secrets and insert the config.json file in it (use the repository name for the directory name).

Hashicorp Vault Key-Value engine example:

  • Sample config.json (/usr/share/onsight/secrets/vault-kv/config.json)

{
"type": "hashicorp.vault.kv",
"url": "Your-Vault-URL,
"token": "Your-Vault-Token",
"path": "Your-Vault-Path",
"mount_point": "Your-Vault-MountPoint/Top-Level-Directory",
"kv_version": "v1"
}

Hashicorp Vault SSH engine example:

  • Sample config.json (/usr/share/onsight/secrets/vault-ssh/config.json)

{
"type": "hashicorp.vault.ssh",
"url": "Your-Vault-URL,
"token": "Your-Vault-Token",
"path": "Your-Vault-Path",
"mount_point": "Your-Vault-MountPoint/Top-Level-Directory",
"api_version": "v1"
}
  • The CA public key must be added to target host’s SSH configuration. Add the public key to all target host's SSH configuration.

    • Download the CA public key.
      curl -o /etc/ssh/trusted-user-ca-keys.pem http://URL:PORT/v1/ssh-client-signer/public_key

    • Edit SSH configuration.

      # /etc/ssh/sshd_config
      # ...
      TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem
    • Restart the SSH service to pick up the changes.

Secret management helper functions for CounterMeasure plugins

The following functions have been pre-defined to assist in developing custom CounterMeasures.

def get_secret(self, repo, key=None, **kwargs):
"""
GET secret from Secret management framework
"""
def get_ssh_certificate(self, repo, username, **kwargs):
"""
GET ssh certificate from Secret management framework
"""
 
def execute_ssh_with_secret_pkey(self, cmd, hostname, username, repo, key):
"""
Use Spur/Paramiko to ssh to a remote server and run a command.
Get private key value in secret repo with a given key
Returns a tuple of (return code, stdout, stderr)
"""
 
def execute_ssh_with_secret_cert(self, cmd, hostname, username, repo):
"""
Use Spur/Paramiko to ssh to a remote server and run a command.
Get ssh cert file from secret repo
Returns a tuple of (return code, stdout, stderr)
"""

SSH access scenarios

Signed SSH certificate

The instructions below include details for each aspect of this setup.

  • Configure the Vault

    • Set up Hashicorp Vault server and create SSH engine.

  • On the remote host

    • Add the public key to all target host's SSH configuration.

    • Download CA public key.
      curl -o /etc/ssh/trusted-user-ca-keys.pem http://URL:PORT/v1/ssh-client-signer/public_key

    • Edit ssh configuration
      # /etc/ssh/sshd_config
      # ...
      TrustedUserCAKeys /etc/ssh/trusted-user-ca-keys.pem

    • Restart the SSH service to pick up the changes.

  • On the OnSight

    • Create config.json under /secrets/vault-ssh

      {

      "type": "hashicorp.vault.ssh",

      "url": "Your-Vault-URL,

      "token": "Your-Vault-Token",

      "role": "ssh-client-signer/sign/my-role",

      "api_version": "v1"

      }

  • Within the CounterMeasure plugin

    • Use execute_ssh_with_secret_cert() method to execute command on a remote host

      class VaultDemoCountermeasure(CountermeasurePlugin):

      name = "Vault demo countermeasure"

      textkey = "testing.vault"

      def run(self):

      server = self.metadata.get('server')

      hostname = server.get('fqdn')

      return_code, output, _ = self.execute_ssh_with_secret_cert("pwd", hostname, "vadmin", 'vault-ssh')

      self.save_output(output)

SSH key-pair access

  • Store SSH private key in Vault KV engine and access remote Host with private key.

  • Configure the Vault.

    • Set up Hashicorp Vault server and create KV engine.

    • Save private key in KV engine

      • For example: key=”mykey”, value=”-----BEGIN RSA PRIVATE KEY-----…”

  • On the remote host

    • Copy the public key to the remote host.

  • On the OnSight

    • Create config.json under /secrets/vault-kv.

      {

      "type": "hashicorp.vault.kv",

      "url": "YOUR-VAULT-URL:PORT",

      "token": "YOUR-VAULT-TOKEN",

      "kv_version": "v1",

      "mount_point": "Your-Vault-MountPoint/Top-Level-Directory",

      "path": "Your-Vault-Path",

      }

  • Within the CounterMeasure plugin

    • Use execute_ssh_with_secret_pkey() method to execute command on the remote host.

      class VaultDemoCountermeasure(CountermeasurePlugin):

      name = "Vault demo countermeasure"

      textkey = "testing.vault"

      def run(self):

      server = self.metadata.get('server')

      hostname = server.get('fqdn')

      return_code, output, _ = self.execute_ssh_with_secret_pkey("pwd", hostname, "myuser", 'vault-kv', 'mykey')

      self.save_output(output)

    • Sse get_secret() method to get private key, if you want to use your own code to access to a remote host.

      class VaultDemoCountermeasure(CountermeasurePlugin):

      name = "Vault demo countermeasure"

      textkey = "testing.vault"

      def run(self):

      server = self.metadata.get('server')

      hostname = server.get('fqdn')

      pkey = self.get_key('vault-kv', 'mykey')

      # access to a remote host with pkey