# SSH Keys Setup Guide ## Security Notice SSH private keys (.ppk, .pem, id_rsa, etc.) should **NEVER** be: - Stored in the application directory - Committed to git repositories - Placed in web-accessible locations ## Recommended Setup ### 1. Create Secure Keys Directory on Server ```bash # On your production server sudo mkdir -p /var/crew-keys sudo chmod 700 /var/crew-keys ``` ### 2. Place Your SSH Key ```bash # Copy your key to the secure location sudo cp /path/to/your/root.ppk /var/crew-keys/ sudo chmod 600 /var/crew-keys/root.ppk sudo chown root:root /var/crew-keys/root.ppk ``` ### 3. Verify Permissions ```bash ls -la /var/crew-keys/ # Should show: drwx------ (700) for directory # Should show: -rw------- (600) for key file ``` ## Docker Configuration The `docker-compose.prod.yml` and `docker-compose.dev.yml` files are configured to mount `/var/crew-keys` as a **read-only** volume: ```yaml volumes: - /var/crew-keys:/var/keys:ro ``` The `:ro` flag ensures the container can only read the keys, not modify them. ## Application Configuration The [config/filesystems.php](config/filesystems.php) references the key at: ```php 'privateKey' => '/var/keys/root.ppk', ``` This path is inside the container and maps to `/var/crew-keys/root.ppk` on the host. ## Testing To verify the SFTP connection works: ```bash docker exec crewsportswear_app_prod php -r " use League\Flysystem\Sftp\SftpAdapter; try { \$adapter = new SftpAdapter([ 'host' => '35.232.234.8', 'port' => 22, 'username' => 'root', 'privateKey' => '/var/keys/root.ppk', 'root' => '/var/www/html/images', 'timeout' => 10, ]); echo 'SFTP connection: SUCCESS'; } catch (Exception \$e) { echo 'SFTP connection failed: ' . \$e->getMessage(); } " ``` ## Troubleshooting ### Permission Denied If you get permission errors: ```bash # Fix directory permissions sudo chmod 700 /var/crew-keys # Fix key file permissions sudo chmod 600 /var/crew-keys/root.ppk ``` ### Key Format Issues PuTTY keys (.ppk) may need conversion for Linux/PHP: ```bash # Convert .ppk to OpenSSH format puttygen root.ppk -O private-openssh -o /var/crew-keys/root.pem chmod 600 /var/crew-keys/root.pem ``` Then update `filesystems.php`: ```php 'privateKey' => '/var/keys/root.pem', ``` --- ## Local Development — Remote DB via SSH Tunnel Use the `ssh-db` profile to connect the local app to a **remote database** through an SSH tunnel, authenticated with a private key. ### 1. Configure `.env.local` ```dotenv # SSH jump host SSH_HOST=your.server.ip.or.hostname SSH_PORT=22 SSH_USER=root SSH_KEY_PATH=~/.ssh/id_rsa # path to your private key on the Mac host # DB endpoint as seen from the SSH server SSH_DB_REMOTE_HOST=127.0.0.1 SSH_DB_REMOTE_PORT=3306 # Tell the app to route through the tunnel container DB_HOST=db-tunnel DB_PORT=3306 DB_DATABASE=your_remote_db_name DB_USERNAME=your_remote_db_user DB_PASSWORD=your_remote_db_password ``` ### 2. Start the stack with the tunnel profile ```bash docker compose -f docker-compose.local.yml --profile ssh-db up --build ``` This starts a `db-tunnel` sidecar container (Alpine + openssh-client) that creates: ``` Mac host → [SSH tunnel] → SSH_HOST → DB (SSH_DB_REMOTE_HOST:SSH_DB_REMOTE_PORT) ``` The app container connects to `db-tunnel:3306`, which forwards all traffic through the encrypted tunnel. ### 3. Key requirements | Requirement | Detail | |---|---| | Key format | OpenSSH (`id_rsa`, `id_ed25519`) — **not** `.ppk` | | Key permissions | `chmod 600 ~/.ssh/id_rsa` | | SSH server | Authorised key must be in `~/.ssh/authorized_keys` on `SSH_HOST` | > **Tip:** If your key is in PuTTY (`.ppk`) format, convert it first: > ```bash > puttygen root.ppk -O private-openssh -o ~/.ssh/id_rsa > chmod 600 ~/.ssh/id_rsa > ``` --- ## Security Best Practices ✅ **DO:** - Store keys outside application directory - Use restrictive permissions (600 for files, 700 for directories) - Mount as read-only in Docker - Keep keys out of version control - Use SSH key authentication instead of passwords - Rotate keys regularly ❌ **DON'T:** - Commit keys to git - Store in web-accessible directories - Use world-readable permissions - Share keys across multiple services - Use password-protected keys without proper passphrase management