Skip to content

For a platform the catalogue does not cover, you write the script yourselves and upload it as a custom agent. It runs only on the target server, never on the appliance, and it cannot call an API from the appliance.

Only an Owner can turn on custom agents and upload them.

  1. Package agent.yml and the script (.sh, .ps1 or .py) as a zip file. Start from the example for Linux. For Windows servers, see Windows servers.

  2. Open Agents › Catalogue and turn on Allow custom agents under Custom agents.

  3. Choose the file under Zip file with the agent and click Upload and approve.

  4. Allow custom agents on the server (script policy).

  5. Use the agent in a rule. In the rule’s Summary step, click Add agent under Agent chain for …, choose your agent under Eligible agents, and choose the action. Which service to choose on the server is described in Servers sslbrain does not know.

The licence decides the number of custom agents: Free 1, Basic 3, Professional and Enterprise unlimited. A later version of an agent does not take another slot.

If you turn off Allow custom agents, no more can be uploaded. The approved ones keep running.

The service agent does not run custom agents until its script policy is 31. The default is 15. The appliance cannot change this. Set the value on the Windows server in one of two ways:

  • At installation, with the MSI property SCRIPTPOLICY=31 (MSI properties).
  • With Group Policy: ScriptPolicy (REG_DWORD, 31) under HKLM\SOFTWARE\Policies\sslbrain. It takes precedence over the value from the installation. Restart the sslbrainagent service if it should apply at once.

The value is the sum of what the agent may run:

ValueMay run
1FairSSL packages that read
2FairSSL packages that write
4Community packages that read
8Community packages that write
16Custom agents

The values 4 and 8 exist in the script policy, but the catalogue has no community packages today. Every package in the catalogue is written, reviewed and signed by FairSSL. A suggestion from a user becomes a package only after FairSSL has reviewed it, locked the code and released it under FairSSL’s signature.

The Policy and audit › Script policy page on the appliance does not decide what the agents run (policy).

The appliance refuses the agent if any of these fields is missing or wrong:

FieldValue
agent.nameA name no package from FairSSL and no built-in package uses
agent.tiercustom
agent.channelpush-ssh. The name is the one the appliance requires
actions.<name>The action, for example deploy
scriptA .sh, .ps1 or .py file in the zip file
runtime.locationtarget
runtime.interpreterbash
runtime.delivery.modestdin or scp-tmp
categorywrite for an action that changes something, read for one that only reads
timeoutSeconds the action may run
cert_formatpem or pfx_base64 (variables)
parametersYour own fields, filled in on the rule

The zip file may be at most 1 MB, with 64 files, 512 KB per file and 4 MB unpacked. The allowed file types are yml, yaml, sh, ps1, py, json, md and txt. Hidden files, symbolic links, binary files, absolute paths and .. are refused.

On Windows servers, sslbrain installs certificates only through the service agent. The direct connection from the appliance to Windows is used only to find servers and install the service agent, not for certificates. That is why the manual shows no PowerShell script of your own for certificates.

Use the signed Windows agents in the catalogue instead, which the service agent runs, for example IIS, Exchange, SQL Server and installation in the Windows certificate store (Integrations). For a Windows service no package knows, use the template Custom Windows Certificate Deployment from the catalogue. It puts the certificate in the Windows certificate store or in a file. How to install the service agent: Windows servers.

The example writes the certificate and key to files and reloads a service.

agent.yml:

agent:
name: intranet-app-linux
display_name: "Intranet-app"
version: "1.0.0"
tier: custom
description: "Installs the certificate for the intranet app"
channel: push-ssh
actions:
deploy:
description: "Write the certificate and key, and reload the service"
script: deploy.sh
runtime:
location: target
interpreter: bash
delivery:
mode: stdin
category: write
timeout: 120
cert_format: pem

deploy.sh:

#!/usr/bin/env bash
set -euo pipefail
trap 'echo "{\"status\":\"error\",\"message\":\"deploy failed\"}"; exit 1' ERR
SUDO=""
[ "${SSLBRAIN_ELEVATE:-}" = "sudo" ] && SUDO="sudo -n"
umask 077
$SUDO mkdir -p /etc/intranet-app/tls
printf '%s\n' "$CERT_PEM" | $SUDO tee /etc/intranet-app/tls/cert.pem >/dev/null
printf '%s\n' "$KEY_PEM" | $SUDO tee /etc/intranet-app/tls/key.pem >/dev/null
$SUDO systemctl reload intranet-app
echo '{"status":"success"}'

In bash the values are environment variables. In PowerShell they are session variables, for example $PFX_BASE64.

The certificate is delivered in the form the action’s cert_format names. Without cert_format, an action that declares CERT_PEM, KEY_PEM or CHAIN_PEM gets the certificate as PEM.

cert_formatVariables
pemCERT_PEM, KEY_PEM, and CHAIN_PEM when the chain is delivered separately
pfx_base64PFX_BASE64, PFX_PASSWORD, PFX_ENCRYPTION and CERT_PEM

The script always gets:

VariablesContent
HOSTNAME, HOST, SERVER_IP, SERVER_OS_TYPEThe server
CREDENTIAL_USER, CREDENTIAL_SECRETThe credential on the server, when it has one
SSLBRAIN_ELEVATEsudo, when the credential has Elevate via sudo turned on
CERTIFICATE_CN, CERTIFICATE_SERIAL, CERTIFICATE_FINGERPRINT_SHA256, CERTIFICATE_NOT_AFTER, CERTIFICATE_ISSUER, NEW_THUMBPRINT, NEW_FRIENDLY_NAMEThe certificate being installed
OLD_THUMBPRINT, OLD_FRIENDLY_NAME, OLD_FINGERPRINT_SHA256, OLD_CERTIFICATE_SERIALThe certificate being replaced
ENDPOINT_NAME, ENDPOINT_AGENT_TYPE, DEPLOYMENT_MODEThe service in the rule
CERT_PATH, KEY_PATH, CHAIN_PATH, RELOAD_COMMAND, INIT_SYSTEM, SOFTWARE_VERSIONWhat discovery found on the service

A parameter with source: certificate.pem, certificate.key, certificate.chain, certificate.pfx_base64, certificate.pfx_password, certificate.thumbprint, certificate.previous_thumbprint or certificate.fingerprint_sha256 gets the value under the parameter’s own name. In PowerShell it is also bound to param() by name.

Result: the script always writes a JSON object with status set to success or error, and optionally message. The last object with a status counts. The action fails on error, even if the exit code is 0, and on an exit code other than 0.

The appliance signs a custom agent with its own key when it is uploaded. The service agents get the key when they register, and run only custom agents signed with it.

Packages from FairSSL have a manifest with the SHA-384 of each file, signed with ECDSA P-384 on a hardware key at FairSSL. The appliance trusts only FairSSL’s fixed production keys.

Agents › Catalogue shows for each version Verified, Invalid or Unsigned.