Skip to content

Security Guide

This guide covers secure authentication methods for fnb, moving beyond plain-text password storage in .env files.

Overview

By default, fnb supports SSH password authentication via .env files, but this approach stores passwords in plain text. This guide presents more secure alternatives and best practices.

1. SSH Key Authentication (Most Secure)

SSH key authentication eliminates the need for password storage entirely.

Setup SSH Keys

# Generate SSH key pair (creates private/public key files)
ssh-keygen -t ed25519 -f ~/.ssh/fnb_key

# Copy public key to remote server (adds to ~/.ssh/authorized_keys)
ssh-copy-id -i ~/.ssh/fnb_key.pub user@server.com

# Configure SSH to use the key
echo "Host server.com
  IdentityFile ~/.ssh/fnb_key
  IdentitiesOnly yes" >> ~/.ssh/config

Command Explanations:

  • ssh-keygen: Creates a new SSH key pair (private key + public key)
    • -t ed25519: Uses modern Ed25519 algorithm (recommended)
    • -f ~/.ssh/fnb_key: Specifies output file path (default: id_ed25519 and id_ed25519.pub )
  • ssh-copy-id: Copies your public key to the remote server
    • -i ~/.ssh/fnb_key.pub: Specifies which public key to copy (default to ~/.ssh/id_ed25519.pub)
    • Automatically adds the key to ~/.ssh/authorized_keys on remote server

Benefits

  • No password storage - Most secure option
  • Automatic authentication - No manual intervention needed
  • Key rotation - Easy to revoke and replace keys
  • Standard practice - Widely adopted security standard

Configuration

When using SSH keys, remove password entries from your .env file:

# Remove these lines from .env
# FNB_PASSWORD_USER_SERVER_COM=mypassword
# FNB_PASSWORD_DEFAULT=defaultpassword

2. macOS Keychain Integration

Store passwords securely in macOS Keychain instead of plain-text files.

Setup Keychain Storage

# Store password in keychain
security add-generic-password \
  -s "fnb-ssh" \
  -a "user@server.com" \
  -w "your-password"

# Retrieve password from keychain
security find-generic-password \
  -s "fnb-ssh" \
  -a "user@server.com" \
  -w

Command Explanations:

  • security add-generic-password: Stores a password in macOS Keychain
    • -s "fnb-ssh": Service name (identifier for this password entry)
    • -a "user@server.com": Account name (usually the SSH connection string)
    • -w "your-password": Password to store (can also prompt interactively without this option)
  • security find-generic-password: Retrieves a password from Keychain
    • -s "fnb-ssh": Service name to search for
    • -a "user@server.com": Account name to match
    • -w: Output only the password (without this, shows all metadata)

Implementation Notes

This method requires extending fnb's env.py module to support keychain integration. The current implementation only supports .env files.

3. dotenvx Encryption

Use dotenvx to encrypt .env files while maintaining compatibility with existing fnb workflows.

Setup dotenvx

# Install dotenvx
npm install -g @dotenvx/dotenvx

# Or using other package managers
brew install dotenvx/brew/dotenvx
curl -fsS https://dotenvx.sh/install.sh | sh

Encrypt Existing .env File

# Encrypt your existing .env file
dotenvx encrypt

# This encrypts the .env file in-place and creates .env.keys
# The original .env content is now encrypted

File Structure After Encryption

.env           # Encrypted file (safe to commit)
.env.keys      # Decryption keys (DO NOT commit)

Usage with fnb

# Run fnb with encrypted environment
dotenvx run -- fnb fetch backup-server

# Or set the decryption key in environment
export DOTENV_KEY="dotenv://:key_1234...@dotenvx.com/vault/.env.vault?environment=production"
fnb fetch backup-server

# Decrypt for manual inspection (reference only)
dotenvx decrypt

Benefits

  • Backward compatible - Works with existing fnb implementation
  • Encrypted storage - Passwords encrypted at rest
  • Environment separation - Different keys for dev/staging/production
  • Version control safe - Encrypted .env can be safely committed

Git Configuration

# Add to .gitignore
echo ".env.keys" >> .gitignore

# Encrypted .env CAN be committed (it's encrypted)
git add .env

4. GPG Encryption

Encrypt password files using GPG for an additional security layer.

Setup GPG Encryption

# Create encrypted password file
echo "mypassword" | gpg --symmetric --armor > ~/.config/fnb/password.gpg

# Set restrictive permissions
chmod 600 ~/.config/fnb/password.gpg

# Decrypt when needed
gpg --decrypt ~/.config/fnb/password.gpg

Command Explanations:

  • gpg --symmetric --armor: Encrypts data using symmetric encryption
    • --symmetric: Uses passphrase-based encryption (no public/private keys needed)
    • --armor: Creates ASCII-armored output (text format, easier to handle)
    • Output is encrypted with a passphrase you provide interactively
  • gpg --decrypt: Decrypts GPG-encrypted files
    • Prompts for the passphrase used during encryption
    • --quiet: Can be added to suppress status messages
    • --batch: Can be added for non-interactive mode (requires passphrase via other means)

Integration with fnb

This method requires extending the current implementation to decrypt passwords at runtime.

5. Interactive Password Input

fnb automatically falls back to interactive password input when no stored passwords are found.

Current Behavior

When no password is found in environment variables or other sources, fnb automatically falls back to interactive password input:

  1. fnb attempts to retrieve password from configured sources
  2. If no password is found (ssh_password = None)
  3. rsync executes without password automation
  4. SSH prompts user for password in terminal
  5. User enters password interactively

Benefits

  • No configuration required - Works out of the box
  • Highest security - No stored passwords
  • Standard SSH behavior - Familiar user experience
  • Fallback mechanism - Always available when other methods fail

Usage Example

# No .env file or password configuration
fnb fetch backup-server

# Output:
# Fetching backup-server from user@server:~/data/ to ./backup/
# user@server's password: [user types password]
# Fetch completed successfully: backup-server

When This Mode Activates

  • No .env file exists
  • Environment variables FNB_PASSWORD_* are not set
  • Other password sources (keychain, GPG) are not configured or fail
  • SSH key authentication is not set up

Current .env File Security

If you must continue using .env files, follow these security practices:

File Permissions

# Set restrictive permissions
chmod 600 .env
chmod 600 ~/.config/fnb/.env

# Verify permissions
ls -la .env
# Should show: -rw------- (600)

Environment Variable Format

# Host-specific passwords (recommended)
FNB_PASSWORD_USER_EXAMPLE_COM=hostspecificpassword

# Default password (less secure)
FNB_PASSWORD_DEFAULT=defaultpassword

Git Security

# Ensure .env is in .gitignore
echo ".env" >> .gitignore
echo "*.env" >> .gitignore

# Remove .env from git history if accidentally committed
git rm --cached .env
git commit -m "Remove .env from version control"

Security Best Practices

1. Principle of Least Privilege

  • Use SSH keys with specific access scopes
  • Avoid shared or default passwords
  • Regularly rotate credentials

2. Environment Isolation

  • Use separate SSH keys for different environments
  • Maintain environment-specific .env files with restricted access
  • Never commit .env files to version control

3. Monitoring and Auditing

  • Monitor SSH key usage through server logs
  • Regular security audits of stored credentials
  • Document all authentication methods used

4. Backup Security

  • Encrypt backup destinations when possible
  • Secure backup storage locations
  • Regular backup integrity verification

Migration from Plain-text Passwords

Step 1: Audit Current Setup

# Check current .env files
ls -la .env ~/.config/fnb/.env

# Review configured hosts
fnb status

Step 2: Implement SSH Keys

# For each host in your configuration
ssh-keygen -t ed25519 -f ~/.ssh/fnb_key_hostname
ssh-copy-id -i ~/.ssh/fnb_key_hostname.pub user@hostname

Step 3: Update SSH Configuration

# Add to ~/.ssh/config
Host hostname1
  IdentityFile ~/.ssh/fnb_key_hostname1
  IdentitiesOnly yes

Host hostname2
  IdentityFile ~/.ssh/fnb_key_hostname2
  IdentitiesOnly yes

Step 4: Test and Cleanup

# Test connections
ssh user@hostname1
ssh user@hostname2

# Remove passwords from .env files
# Keep files for other environment variables if needed

Troubleshooting

SSH Key Issues

# Check SSH agent
ssh-add -l

# Add key to agent if needed
ssh-add ~/.ssh/fnb_key

# Test connection
ssh -v user@server.com

Permission Issues

# Fix SSH directory permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/fnb_key*
chmod 644 ~/.ssh/fnb_key*.pub

Keychain Issues (macOS)

# List stored passwords
security dump-keychain | grep fnb-ssh

# Update stored password
security delete-generic-password -s "fnb-ssh" -a "user@server.com"
security add-generic-password -s "fnb-ssh" -a "user@server.com" -w "newpassword"

See Also