Three genuinely common Ubuntu server administration tasks — copying files at the command line, adding an SSH key for Git authentication, and restricting SSH access to specific IP addresses — come up often enough as a set to be worth covering together.
Copying a file with cp
cp source.txt destination.txt
cp source.txt /var/www/html/
Copying a directory recursively
cp -r source_directory/ destination_directory/
The -r (recursive) flag is required for copying a directory and its full contents — attempting cp on a directory without it fails with an "omitting directory" error, since cp alone only operates on individual files.
Copying while preserving file permissions and timestamps
cp -a source_directory/ destination_directory/
-a (archive mode) preserves ownership, permissions, and timestamps during the copy — genuinely important when copying application files where the original permissions (like a web server's expected file ownership) need to be maintained exactly, not reset to the copying user's defaults.
Copying a file to a remote server with scp
scp local_file.txt user@remote-server:/path/to/destination/
Generating an SSH key pair
ssh-keygen -t ed25519 -C "your_email@example.com"
ed25519 is the modern recommended key type — genuinely stronger and faster than the older RSA default for most practical purposes, though RSA remains supported for compatibility with older systems that don't yet support ed25519.
Adding the public key to GitHub or Bitbucket
cat ~/.ssh/id_ed25519.pub
The output of this command — the public key, never the private one — is what gets pasted into GitHub's or Bitbucket's SSH key settings, authorizing this specific machine to authenticate over SSH for Git operations without a password prompt each time.
Testing the SSH connection to Git hosting
ssh -T git@github.com
Restricting SSH access to specific IP addresses with ufw
sudo ufw allow from 203.0.113.50 to any port 22
sudo ufw deny 22
Allowing SSH explicitly from a known, trusted IP address first, then denying the general port, is the correct order — reversing it (denying first) can lock out the very connection being used to configure the firewall in the first place, before the allow rule takes effect.
Why restricting rather than fully disabling SSH is the safer approach
Restricting SSH to specific known IP addresses (rather than disabling it outright) genuinely reduces the attack surface from random internet-wide scanning while preserving the ability to remotely administer the server when something needs fixing — a server with SSH fully disabled and no other remote access method can become unreachable entirely if a problem arises.
Checking current firewall rules
sudo ufw status numbered
Reviewing the current rule set before adding new ones helps avoid accidentally creating a conflicting or redundant rule — the numbered format also makes it easy to reference a specific rule for deletion later with ufw delete [number].