Security
Unlike in the golden era of BBSing, modern Internet-connected systems are prone to hacking attempts, eavesdropping, etc. While plain-text passwords, insecure data over Plain Old Telephone Service (POTS), and so on was good enough then, modern systems must employ protections against attacks. ENiGMA½ comes with many security features that help keep the system and your users secure — not limited to:
- Passwords are never stored in plain-text, but instead are stored using Password-Based Key Derivation Function 2 (PBKDF2). Even the system operator can never know your password!
- Alternatives to insecure Telnet logins are built in: SSH and secure WebSockets for example.
- A built in web server with TLS support (aka HTTPS).
- Optional SSH public key authentication for passwordless logins over secure transports.
- Optional Two-Factor Authentication (2FA) via One-Time-Password (OTP) for users, supporting Google Authenticator, Time-Based One-Time Password Algorithm (TOTP, RFC-6238), and HMAC-Based One-Time Password Algorithm (HOTP, RFC-4266).
Protecting Sensitive Configuration
Section titled “Protecting Sensitive Configuration”config.hjson may contain secrets — the SSH host key passphrase, email credentials, FTN/BinkP session passwords, and more. To limit exposure:
- Restrict file permissions. The config file should be readable only by the OS user that runs ENiGMA½:
Terminal window chmod 600 /path/to/enigma-bbs/config/config.hjson - Restrict the SSH private key itself in the same way:
Terminal window chmod 600 /path/to/enigma-bbs/config/ssh_private_key.pem - Do not commit
config.hjsonto version control. Add it to.gitignoreif you track your configuration in git. - Limit OS-level read access to backup archives that include the config directory.
Keeping Secrets Out of config.hjson
Section titled “Keeping Secrets Out of config.hjson”For stronger separation — especially in container or GitOps environments — ENiGMA½ supports two directives that let you keep sensitive values out of config.hjson entirely:
@file:/path/to/secret— reads the value from a file at startup (trimming surrounding whitespace). Ideal for Docker/Podman secrets (/run/secrets/…) or any chmod-600 file on disk.@environment:VAR_NAME— reads the value from an environment variable.
These work for any string-valued config key. Examples:
loginServers: { ssh: { privateKeyPass: "@file:/run/secrets/ssh_key_pass" }}
email: { transport: { auth: { user: noreply@yourbbs.net pass: "@environment:SMTP_PASS" } }}
scannerTossers: { ftn_bso: { binkp: { nodes: { "1:218/700": { sessionPassword: "@file:/run/secrets/binkp_pass" } } } }}See Configuration Files — Secret Files for the full reference and a complete list of supported @environment: type coercions.
Two-Factor Authentication via One-Time Password
Section titled “Two-Factor Authentication via One-Time Password”Enabling Two-Factor Authentication via One-Time-Password (2FA/OTP) on an account adds an extra layer of security (“something a user has”) in addition to their password (“something a user knows”). Providing 2FA/OTP to your users has some prerequisites:
- A configured email gateway such that the system can send out emails.
- One or more secure servers enabled such as SSH or secure WebSockets (that is, WebSockets over a secure connection such as TLS).
- The web server enabled and exposed over TLS (HTTPS).
User Registration Flow
Section titled “User Registration Flow”Due to the nature of 2FA/OTP, even if enabled on your system, users must opt-in and enable this feature on their account. Users must also have a valid email address such that a registration link can be sent to them. To opt-in, users must enable the option, which will cause the system to email them a registration link. Following the link provides the following:
- A secret for manual entry into a OTP device.
- If applicable, a scannable QR code for easy device entry (e.g. Google Authenticator)
- A confirmation prompt in which the user must enter a OTP code. If entered correctly, this validates everything is set up properly and 2FA/OTP will be enabled for the account. Backup codes will also be provided at this time. Future logins will now prompt the user for their OTP after they enter their standard password.
Recovery
Section titled “Recovery”In the situation that a user loses their 2FA/OTP device (such as a lost phone with Google Auth), there are some options:
- Utilize one of their backup codes.
- Contact the SysOp.
ACS Checks
Section titled “ACS Checks”Various places throughout the system that implement ACS can make 2FA specific checks:
AR#: Current users required authentication factor.AR2for example means 2FA/OTP is required for this user.AF#: Current users active authentication factor.AF2means the user is authenticated with some sort of 2FA (such as One-Time-Password).
See ACS for more information.
Example
Section titled “Example”The following example illustrates using an AR ACS check to require applicable users to go through an additional 2FA/OTP process during login:
login: { art: USERLOG next: [ { // users with AR2+ must first pass 2FA/OTP acs: AR2 next: loginTwoFactorAuthOTP } { // everyone else skips ahead next: fullLoginSequenceLoginArt } ] // ...}