File Permissions & SSH

Difficulty: Intermediate

Question

Explain Linux file permissions. How does SSH work, and how do you set up SSH key-based authentication?

Answer

Linux file permissions control who can read, write, and execute files. Every file has three permission groups: owner (u), group (g), and others (o). Each group can have read (r=4), write (w=2), and execute (x=1) permissions.

The numeric notation adds up: 755 means owner has rwx (7), group has r-x (5), others have r-x (5). Common permissions: 644 for files (owner reads/writes, others read), 755 for directories and scripts (owner full, others read/execute), 600 for private keys (owner only).

SSH (Secure Shell) provides encrypted communication between machines. Key-based authentication uses a public/private key pair instead of passwords. The private key stays on your machine (never shared), and the public key goes on the server. When you connect, the server challenges you with the public key, and your client proves identity using the private key.

SSH keys are essential for: Git operations over SSH, connecting to servers, and CI/CD pipeline authentication. Always protect private keys with proper permissions (chmod 600) and optionally a passphrase.

Code examples

File Permissions

# View permissions
ls -la
# drwxr-xr-x  5 john staff  160 Jan 15 10:00 src/
# -rw-r--r--  1 john staff  524 Jan 15 10:00 package.json
# -rwx------  1 john staff  128 Jan 15 10:00 deploy.sh

# Permission breakdown: -rwxr-xr-x
# -     = file type (- file, d directory, l symlink)
# rwx   = owner (read, write, execute)
# r-x   = group (read, execute)
# r-x   = others (read, execute)

# Numeric: r=4, w=2, x=1
# rwx = 4+2+1 = 7
# r-x = 4+0+1 = 5
# r-- = 4+0+0 = 4

# Change permissions
chmod 755 deploy.sh            # rwxr-xr-x
chmod 644 config.json          # rw-r--r--
chmod 600 ~/.ssh/id_ed25519    # rw------- (private key)
chmod +x script.sh             # add execute for all
chmod u+w,g-w file.txt         # add owner write, remove group write

# Change ownership
chown john:staff file.txt      # change owner and group
chown -R www-data:www-data /var/www/  # recursive

# Special permissions
chmod 1777 /tmp                # sticky bit (only owner can delete)
chmod 4755 /usr/bin/passwd     # setuid (runs as file owner)

Memorize common permissions: 644 (files), 755 (directories/scripts), 600 (private keys). Wrong permissions on SSH keys cause authentication failures.

SSH Key Setup

# Generate an SSH key pair (Ed25519 recommended)
ssh-keygen -t ed25519 -C "john@example.com"
# Enter file: ~/.ssh/id_ed25519
# Enter passphrase: (optional but recommended)
# Creates: ~/.ssh/id_ed25519 (private) and ~/.ssh/id_ed25519.pub (public)

# View the public key
cat ~/.ssh/id_ed25519.pub
# ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... john@example.com

# Copy public key to a server
ssh-copy-id user@server.com
# Or manually:
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys

# Add key to GitHub
gh ssh-key add ~/.ssh/id_ed25519.pub --title "Work Laptop"
# Or paste into GitHub Settings > SSH Keys

# Test SSH connection to GitHub
ssh -T git@github.com
# Hi john! You've successfully authenticated.

# SSH agent (avoid typing passphrase repeatedly)
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# Fix permission errors
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 644 ~/.ssh/authorized_keys

Ed25519 keys are more secure and faster than RSA. The SSH agent caches your passphrase so you only enter it once per session. Correct permissions are mandatory.

SSH Config and Remote Access

# SSH config file (~/.ssh/config)
# Saves connection details for quick access

Host production
  HostName 203.0.113.50
  User deploy
  Port 22
  IdentityFile ~/.ssh/id_ed25519
  ForwardAgent yes

Host staging
  HostName staging.example.com
  User deploy
  IdentityFile ~/.ssh/id_staging

Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_github

# Now connect with just:
ssh production
# Instead of: ssh -i ~/.ssh/id_ed25519 deploy@203.0.113.50

# SSH tunneling (port forwarding)
ssh -L 5432:localhost:5432 production
# Access production DB at localhost:5432

# Copy files with SCP
scp file.txt production:/home/deploy/
scp -r ./dist/ production:/var/www/app/

# Rsync (better than scp for syncing)
rsync -avz --progress ./dist/ production:/var/www/app/
# -a = archive (preserves permissions)
# -v = verbose, -z = compress, --progress = show progress

SSH config eliminates remembering IP addresses and key paths. SSH tunneling lets you access remote services securely. Rsync is preferred over SCP for deployments.

Key points

Concepts covered

File Permissions, chmod, chown, SSH, SSH Keys, SSH Config