
Some checks failed
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Security Audit (push) Has been cancelled
CI/CD Pipeline / Build Docker Image (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Performance Benchmarks (push) Has been cancelled
CI/CD Pipeline / Cleanup (push) Has been cancelled
498 lines
14 KiB
Bash
Executable File
498 lines
14 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# Configuration Encryption Setup Script
|
||
# This script helps set up the encryption system for configuration values
|
||
|
||
set -e
|
||
|
||
# Colors for output
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Default values
|
||
ROOT_PATH="."
|
||
CONFIG_FILE=""
|
||
INTERACTIVE=false
|
||
FORCE=false
|
||
BACKUP=true
|
||
ENVIRONMENT="production"
|
||
|
||
# Function to print colored output
|
||
print_color() {
|
||
printf "${1}${2}${NC}\n"
|
||
}
|
||
|
||
print_success() {
|
||
print_color "$GREEN" "✓ $1"
|
||
}
|
||
|
||
print_error() {
|
||
print_color "$RED" "✗ $1"
|
||
}
|
||
|
||
print_warning() {
|
||
print_color "$YELLOW" "⚠ $1"
|
||
}
|
||
|
||
print_info() {
|
||
print_color "$BLUE" "ℹ $1"
|
||
}
|
||
|
||
# Function to show help
|
||
show_help() {
|
||
cat << EOF
|
||
Configuration Encryption Setup Script
|
||
|
||
This script helps you set up and manage the configuration encryption system
|
||
for securing sensitive configuration values.
|
||
|
||
Usage: $0 [OPTIONS]
|
||
|
||
Options:
|
||
-h, --help Show this help message
|
||
-r, --root-path PATH Set root path for encryption key (default: .)
|
||
-c, --config FILE Configuration file to encrypt values in
|
||
-i, --interactive Run in interactive mode
|
||
-f, --force Force overwrite existing encryption key
|
||
-e, --environment ENV Environment (dev, staging, prod) (default: production)
|
||
--no-backup Don't create backups when modifying files
|
||
--verify-only Only verify existing encryption setup
|
||
|
||
Examples:
|
||
$0 # Basic setup with interactive prompts
|
||
$0 -i # Full interactive setup
|
||
$0 -c config.prod.toml # Encrypt values in specific config file
|
||
$0 -r /app --environment prod # Setup for production in /app directory
|
||
$0 --verify-only # Just verify current setup
|
||
|
||
The script will:
|
||
1. Generate encryption key if it doesn't exist
|
||
2. Help you encrypt sensitive configuration values
|
||
3. Update configuration files with encrypted values
|
||
4. Verify the encryption setup works correctly
|
||
|
||
Security Notes:
|
||
- Never commit the .k file to version control
|
||
- Use different keys for different environments
|
||
- Backup encryption keys securely
|
||
- Rotate keys regularly in production
|
||
EOF
|
||
}
|
||
|
||
# Parse command line arguments
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
-h|--help)
|
||
show_help
|
||
exit 0
|
||
;;
|
||
-r|--root-path)
|
||
ROOT_PATH="$2"
|
||
shift 2
|
||
;;
|
||
-c|--config)
|
||
CONFIG_FILE="$2"
|
||
shift 2
|
||
;;
|
||
-i|--interactive)
|
||
INTERACTIVE=true
|
||
shift
|
||
;;
|
||
-f|--force)
|
||
FORCE=true
|
||
shift
|
||
;;
|
||
-e|--environment)
|
||
ENVIRONMENT="$2"
|
||
shift 2
|
||
;;
|
||
--no-backup)
|
||
BACKUP=false
|
||
shift
|
||
;;
|
||
--verify-only)
|
||
VERIFY_ONLY=true
|
||
shift
|
||
;;
|
||
*)
|
||
print_error "Unknown option: $1"
|
||
show_help
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# Check if we're in a Rust project
|
||
if [ ! -f "Cargo.toml" ]; then
|
||
print_error "This script must be run from the root of a Rust project"
|
||
exit 1
|
||
fi
|
||
|
||
# Check if the crypto tool is available
|
||
if ! cargo bin --list | grep -q "config_crypto_tool"; then
|
||
print_error "config_crypto_tool binary not found. Please ensure it's built:"
|
||
print_info "cargo build --bin config_crypto_tool"
|
||
exit 1
|
||
fi
|
||
|
||
# Function to check if encryption key exists
|
||
check_encryption_key() {
|
||
if [ -f "$ROOT_PATH/.k" ]; then
|
||
return 0
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Function to generate encryption key
|
||
generate_encryption_key() {
|
||
print_info "Generating encryption key..."
|
||
|
||
if check_encryption_key && [ "$FORCE" = false ]; then
|
||
print_warning "Encryption key already exists at $ROOT_PATH/.k"
|
||
read -p "Do you want to overwrite it? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||
print_info "Keeping existing encryption key"
|
||
return 0
|
||
fi
|
||
fi
|
||
|
||
local force_flag=""
|
||
if [ "$FORCE" = true ]; then
|
||
force_flag="--force"
|
||
fi
|
||
|
||
if cargo run --bin config_crypto_tool -- --root-path "$ROOT_PATH" generate-key $force_flag; then
|
||
print_success "Encryption key generated at $ROOT_PATH/.k"
|
||
|
||
# Set proper permissions
|
||
chmod 600 "$ROOT_PATH/.k"
|
||
print_success "Set secure permissions on encryption key file"
|
||
|
||
# Verify the key works
|
||
if cargo run --bin config_crypto_tool -- --root-path "$ROOT_PATH" verify; then
|
||
print_success "Encryption key verification successful"
|
||
else
|
||
print_error "Encryption key verification failed"
|
||
return 1
|
||
fi
|
||
else
|
||
print_error "Failed to generate encryption key"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Function to encrypt a value
|
||
encrypt_value() {
|
||
local value="$1"
|
||
local description="$2"
|
||
|
||
print_info "Encrypting $description..."
|
||
|
||
if encrypted_value=$(cargo run --bin config_crypto_tool -- --root-path "$ROOT_PATH" encrypt "$value" 2>/dev/null); then
|
||
echo "$encrypted_value"
|
||
return 0
|
||
else
|
||
print_error "Failed to encrypt $description"
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# Function to show common values to encrypt
|
||
show_common_values() {
|
||
cat << EOF
|
||
|
||
Common configuration values that should be encrypted:
|
||
- Database passwords
|
||
- Session secrets
|
||
- API keys (SendGrid, OAuth providers, etc.)
|
||
- SMTP passwords
|
||
- Redis URLs with credentials
|
||
- JWT secrets
|
||
- Third-party service credentials
|
||
|
||
EOF
|
||
}
|
||
|
||
# Function to encrypt values in configuration file
|
||
encrypt_config_values() {
|
||
local config_file="$1"
|
||
|
||
if [ ! -f "$config_file" ]; then
|
||
print_error "Configuration file not found: $config_file"
|
||
return 1
|
||
fi
|
||
|
||
print_info "Analyzing configuration file: $config_file"
|
||
|
||
# Create backup if requested
|
||
if [ "$BACKUP" = true ]; then
|
||
local backup_file="${config_file}.backup.$(date +%Y%m%d_%H%M%S)"
|
||
cp "$config_file" "$backup_file"
|
||
print_success "Created backup: $backup_file"
|
||
fi
|
||
|
||
# Common sensitive keys that should be encrypted
|
||
local sensitive_keys=(
|
||
"session.secret"
|
||
"database.url"
|
||
"oauth.google.client_secret"
|
||
"oauth.github.client_secret"
|
||
"email.smtp_password"
|
||
"email.sendgrid_api_key"
|
||
"redis.url"
|
||
)
|
||
|
||
print_info "Checking for sensitive values to encrypt..."
|
||
|
||
for key in "${sensitive_keys[@]}"; do
|
||
# Check if this key exists in the config and is not already encrypted
|
||
if grep -q "^${key//./\\.}" "$config_file" 2>/dev/null; then
|
||
# Extract the current value
|
||
local current_value=$(grep "^${key//./\\.}" "$config_file" | cut -d'"' -f2)
|
||
|
||
if [[ "$current_value" =~ ^\$\{.*\}$ ]]; then
|
||
print_info "Skipping $key (uses environment variable)"
|
||
continue
|
||
elif [[ "$current_value" == @* ]]; then
|
||
print_info "Skipping $key (already encrypted)"
|
||
continue
|
||
elif [ -n "$current_value" ] && [ "$current_value" != "your-secret-here" ]; then
|
||
print_warning "Found potentially sensitive value for $key"
|
||
|
||
if [ "$INTERACTIVE" = true ]; then
|
||
read -p "Encrypt this value? (y/N): " -n 1 -r
|
||
echo
|
||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||
if encrypted_value=$(encrypt_value "$current_value" "$key"); then
|
||
# Update the configuration file
|
||
sed -i.tmp "s|^${key//./\\.}.*|${key} = \"$encrypted_value\"|" "$config_file"
|
||
rm -f "$config_file.tmp"
|
||
print_success "Encrypted $key"
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
fi
|
||
done
|
||
}
|
||
|
||
# Function to verify encryption setup
|
||
verify_encryption_setup() {
|
||
print_info "Verifying encryption setup..."
|
||
|
||
# Check if key exists
|
||
if ! check_encryption_key; then
|
||
print_error "Encryption key not found at $ROOT_PATH/.k"
|
||
return 1
|
||
fi
|
||
|
||
# Check key permissions
|
||
if [ "$(stat -c %a "$ROOT_PATH/.k" 2>/dev/null)" != "600" ]; then
|
||
print_warning "Encryption key file permissions are not secure"
|
||
print_info "Setting secure permissions..."
|
||
chmod 600 "$ROOT_PATH/.k"
|
||
fi
|
||
|
||
# Verify key works
|
||
if cargo run --bin config_crypto_tool -- --root-path "$ROOT_PATH" verify; then
|
||
print_success "Encryption key verification successful"
|
||
else
|
||
print_error "Encryption key verification failed"
|
||
return 1
|
||
fi
|
||
|
||
# Check if .k is in .gitignore
|
||
if [ -f ".gitignore" ]; then
|
||
if grep -q "^\.k$" ".gitignore" || grep -q "^\.k " ".gitignore"; then
|
||
print_success "Encryption key is properly ignored in .gitignore"
|
||
else
|
||
print_error "Encryption key is NOT in .gitignore - this is a security risk!"
|
||
read -p "Add .k to .gitignore? (Y/n): " -n 1 -r
|
||
echo
|
||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||
echo ".k" >> .gitignore
|
||
print_success "Added .k to .gitignore"
|
||
fi
|
||
fi
|
||
else
|
||
print_warning ".gitignore file not found"
|
||
fi
|
||
|
||
return 0
|
||
}
|
||
|
||
# Function to run interactive setup
|
||
run_interactive_setup() {
|
||
print_info "Starting interactive encryption setup..."
|
||
echo
|
||
|
||
# Step 1: Generate or verify encryption key
|
||
if check_encryption_key; then
|
||
print_success "Encryption key already exists"
|
||
read -p "Do you want to verify it? (Y/n): " -n 1 -r
|
||
echo
|
||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||
verify_encryption_setup
|
||
fi
|
||
else
|
||
print_info "No encryption key found"
|
||
read -p "Generate new encryption key? (Y/n): " -n 1 -r
|
||
echo
|
||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||
generate_encryption_key
|
||
fi
|
||
fi
|
||
|
||
echo
|
||
|
||
# Step 2: Encrypt individual values
|
||
print_info "You can now encrypt individual values:"
|
||
while true; do
|
||
read -p "Enter a value to encrypt (or 'skip' to continue): " value
|
||
if [ "$value" = "skip" ] || [ -z "$value" ]; then
|
||
break
|
||
fi
|
||
|
||
if encrypted_value=$(encrypt_value "$value" "custom value"); then
|
||
print_success "Encrypted value: $encrypted_value"
|
||
echo "Use this in your configuration file:"
|
||
echo "some_key = \"$encrypted_value\""
|
||
fi
|
||
echo
|
||
done
|
||
|
||
# Step 3: Encrypt configuration file values
|
||
if [ -n "$CONFIG_FILE" ]; then
|
||
print_info "Encrypting values in configuration file: $CONFIG_FILE"
|
||
encrypt_config_values "$CONFIG_FILE"
|
||
else
|
||
echo
|
||
print_info "Available configuration files:"
|
||
for file in config*.toml; do
|
||
if [ -f "$file" ]; then
|
||
echo " - $file"
|
||
fi
|
||
done
|
||
|
||
read -p "Enter configuration file to encrypt values in (or 'skip'): " config_file
|
||
if [ "$config_file" != "skip" ] && [ -n "$config_file" ]; then
|
||
encrypt_config_values "$config_file"
|
||
fi
|
||
fi
|
||
|
||
echo
|
||
print_success "Interactive setup completed!"
|
||
}
|
||
|
||
# Function to show security recommendations
|
||
show_security_recommendations() {
|
||
cat << EOF
|
||
|
||
${GREEN}Security Recommendations:${NC}
|
||
|
||
1. ${YELLOW}Never commit the .k file to version control${NC}
|
||
- The .k file contains your encryption key
|
||
- Add it to .gitignore immediately
|
||
- Use different keys for different environments
|
||
|
||
2. ${YELLOW}Backup your encryption keys securely${NC}
|
||
- Store backups in a secure, separate location
|
||
- Consider using encrypted backup storage
|
||
- Document your backup procedures
|
||
|
||
3. ${YELLOW}Use proper file permissions${NC}
|
||
- Key files should be readable only by the application user
|
||
- Use chmod 600 for the .k file
|
||
- Monitor file access regularly
|
||
|
||
4. ${YELLOW}Rotate keys regularly${NC}
|
||
- Consider quarterly or yearly key rotation
|
||
- Have a key rotation procedure documented
|
||
- Test key rotation in staging first
|
||
|
||
5. ${YELLOW}Monitor and audit${NC}
|
||
- Log encryption/decryption operations
|
||
- Monitor key file access
|
||
- Regular security audits
|
||
|
||
6. ${YELLOW}Environment separation${NC}
|
||
- Use different encryption keys for dev/staging/prod
|
||
- Never use production keys in development
|
||
- Secure key distribution procedures
|
||
|
||
EOF
|
||
}
|
||
|
||
# Main execution
|
||
main() {
|
||
echo
|
||
print_info "Configuration Encryption Setup Script"
|
||
print_info "Environment: $ENVIRONMENT"
|
||
print_info "Root Path: $ROOT_PATH"
|
||
echo
|
||
|
||
# Change to root path
|
||
cd "$ROOT_PATH"
|
||
|
||
# Verify-only mode
|
||
if [ "$VERIFY_ONLY" = true ]; then
|
||
verify_encryption_setup
|
||
exit $?
|
||
fi
|
||
|
||
# Interactive mode
|
||
if [ "$INTERACTIVE" = true ]; then
|
||
run_interactive_setup
|
||
echo
|
||
show_security_recommendations
|
||
exit 0
|
||
fi
|
||
|
||
# Non-interactive mode
|
||
print_info "Running automated setup..."
|
||
|
||
# Generate encryption key if it doesn't exist
|
||
if ! check_encryption_key; then
|
||
generate_encryption_key
|
||
else
|
||
print_success "Encryption key already exists"
|
||
verify_encryption_setup
|
||
fi
|
||
|
||
# Encrypt configuration file if specified
|
||
if [ -n "$CONFIG_FILE" ]; then
|
||
encrypt_config_values "$CONFIG_FILE"
|
||
fi
|
||
|
||
echo
|
||
print_success "Encryption setup completed!"
|
||
|
||
# Show next steps
|
||
cat << EOF
|
||
|
||
${GREEN}Next Steps:${NC}
|
||
1. Test your configuration: cargo run --bin config_crypto_tool verify
|
||
2. Encrypt sensitive values: cargo run --bin config_crypto_tool encrypt "your-secret"
|
||
3. Update your configuration files with encrypted values
|
||
4. Ensure .k file is in .gitignore
|
||
5. Backup your encryption key securely
|
||
|
||
${BLUE}Useful Commands:${NC}
|
||
- Encrypt value: cargo run --bin config_crypto_tool encrypt "value"
|
||
- Decrypt value: cargo run --bin config_crypto_tool decrypt "@encrypted"
|
||
- Find encrypted values: cargo run --bin config_crypto_tool find-encrypted -c config.toml
|
||
- Interactive mode: cargo run --bin config_crypto_tool interactive
|
||
|
||
EOF
|
||
|
||
show_security_recommendations
|
||
}
|
||
|
||
# Run main function
|
||
main "$@"
|