SSH (Secure Shell) is a protocol for secure communication between computers over a network. It is widely used for secure logins to remote servers, file transfers, and remote command execution.
This page provides a detailed explanation from the basic mechanics of SSH, to how to generate SSH keys, and finally to a practical application example of linking a local PC with GitHub. By acquiring this knowledge, you will be able to perform more secure and efficient remote operations and version control.
SSH (Secure Shell) is a protocol for securely conducting data communication over a network. It was developed in 1995 by Finnish researcher Tatu Ylönen and became popular as a replacement for insecure protocols that were widely used at the time (such as Telnet, rlogin, and rsh).
Main features of SSH:
Currently, SSH is an indispensable tool in many situations, including server management, cloud services, and version control systems (Git).
SSH primarily uses the following two authentication methods:
Public key authentication is recommended in many situations because it is superior in terms of both security and convenience. In this authentication method, the process is as follows:
~/.ssh/authorized_keys file on the remote server.The main advantages of this method are that there is no need to send a password over the network, and since the private key is stored on the local machine, authentication information will not be leaked even if the server-side database is compromised.
There are several types of SSH keys, depending on the cryptographic algorithm used:
For new systems, using Ed25519 or RSA (4096 bits) is generally recommended. However, you need to check which key types are supported by the destination server or service.
SSH keys are typically generated using the ssh-keygen command.
Here are the methods for generating SSH keys on major platforms:
Open a terminal and execute the following command:
# Generate an Ed25519 key (recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"
# Or, generate an RSA 4096-bit key
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
After executing the command, the following prompts will appear:
~/.ssh/id_ed25519 or ~/.ssh/id_rsa)In a Windows environment, you can use Git Bash or WSL (Windows Subsystem for Linux) to generate SSH keys with the same command as above.
On Windows 10 and later, you can also generate SSH keys in PowerShell with the following command:
# Generate an Ed25519 key
ssh-keygen -t ed25519 -C "your_email@example.com"
# Or, generate an RSA 4096-bit key
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
To confirm that the keys were generated successfully, run the following command:
# List the private and public keys
ls -la ~/.ssh
The generated key files are as follows:
id_ed25519 or id_rsa: Private key (NEVER share this)id_ed25519.pub or id_rsa.pub: Public key (register this on the remote server)Best practices for securely managing SSH keys:
Using an SSH-Agent allows you to enter your passphrase once, and subsequent connections will be authenticated automatically:
# Start the SSH-Agent
eval "$(ssh-agent -s)"
# Add the key
ssh-add ~/.ssh/id_ed25519
On macOS, you can also save the passphrase to the keychain:
# Add the following to the ~/.ssh/config file
Host *
UseKeychain yes
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
To establish an SSH connection, you need to perform the appropriate setup on both the client PC and the remote server. Here, we will explain the procedure for setting up an SSH connection using public key authentication.
Setting up an SSH connection is broadly divided into the following two steps:
The following diagram shows the SSH connection setup process:
First, perform the following steps on the client PC (local machine):
ssh-keygen command.id_ed25519 or id_rsa) is saved in the ~/.ssh/ directory and protected with appropriate permissions (600).id_ed25519.pub or id_rsa.pub) is prepared for transfer to the remote server.Next, register the generated public key on the remote server. There are mainly the following methods for this:
Using the ssh-copy-id command, you can transfer and register the public key in one go:
# Basic usage
ssh-copy-id username@remote-server
# Specifying a particular key file
ssh-copy-id -i ~/.ssh/id_ed25519.pub username@remote-server
This command adds the specified public key to the ~/.ssh/authorized_keys file on the remote server.
Password authentication is required for the initial connection, but once set up, you can connect without a password thereafter.
In environments where ssh-copy-id is not available, you can perform a manual setup with the following steps:
# Display and copy the public key content
cat ~/.ssh/id_ed25519.pub
# SSH into the remote server (with password authentication)
ssh username@remote-server
# Execute the following commands on the remote server
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "copied_public_key_content" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
You can also transfer the public key file using SCP and then configure it on the remote server:
# Transfer the public key to the remote server
scp ~/.ssh/id_ed25519.pub username@remote-server:/tmp/
# SSH into the remote server
ssh username@remote-server
# Execute the following commands on the remote server
mkdir -p ~/.ssh
chmod 700 ~/.ssh
cat /tmp/id_ed25519.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
rm /tmp/id_ed25519.pub
Once the public key registration is complete, verify that you can connect via SSH without a password:
ssh username@remote-server
If you can connect without being prompted for a password, the setup is successful.
If you have trouble connecting, you can use the -v option to see detailed debug information:
ssh -v username@remote-server
When an SSH connection is established, a complex authentication process takes place between the client and the server. Here, we will explain the detailed process of an SSH connection using public key authentication.
The following diagram shows the sequence of SSH authentication:
~/.ssh/known_hosts file. On the first connection, a prompt is displayed to confirm the key's fingerprint.~/.ssh/authorized_keys.Once authentication is successful, all communication between the client and server is encrypted using the established session key. This protects the communication content from eavesdropping or tampering by third parties.
Points to enhance the security of the SSH authentication process:
/etc/ssh/sshd_config file.
The known_hosts file is a crucial file used by the SSH client to verify the identity of remote servers.
Here are some additional information and tips for managing the known_hosts file.
~/.ssh/known_hosts (user-specific) or /etc/ssh/ssh_known_hosts (system-wide).
Commands to efficiently manage the known_hosts file:
# Remove a specific host's key (e.g., if the host's IP or DNS has changed)
ssh-keygen -R hostname
# Pre-add a specific host's key (useful for automation in scripts)
ssh-keyscan -H hostname >> ~/.ssh/known_hosts
# Check the fingerprint of a specific host's key
ssh-keygen -l -F hostname
# Hash the known_hosts file (for improved security)
ssh-keygen -H -f ~/.ssh/known_hosts
Common issues and solutions related to the known_hosts file:
ssh-keygen -R hostname and then reconnect.StrictHostKeyChecking=no in ~/.ssh/config, but this is not recommended in production environments due to security risks.known_hosts file to prepare for accidental deletion.HashKnownHosts yes in ~/.ssh/config to hash hostnames and reduce the risk of information leakage./etc/ssh/ssh_known_hosts so that all users can connect securely.
Settings related to known_hosts in the ~/.ssh/config file:
Host *
# Specify the location of the known_hosts file
UserKnownHostsFile ~/.ssh/known_hosts.d/default
# Enable hashing of hostnames
HashKnownHosts yes
# Set strict host key checking
# yes: do not connect to unknown hosts
# ask: ask before connecting to unknown hosts (default)
# no: connect to unknown hosts without warning (insecure)
StrictHostKeyChecking ask
# Use a different known_hosts file for a specific host
Host example.com
UserKnownHostsFile ~/.ssh/known_hosts.d/example
SCP and SFTP are tools for securely transferring files using the SSH protocol. Both leverage the encryption features of SSH, allowing for secure file transfers over the internet.
SCP (Secure Copy Protocol) is a file transfer protocol based on the SSH protocol, used to securely copy files between a local machine and a remote host, or between two remote hosts. SCP is implemented as a command-line tool and allows for simple and efficient file transfers.
Main features of SCP:
SFTP (SSH File Transfer Protocol) is a file transfer protocol that operates over the SSH protocol, offering more feature-rich file operations than SCP. SFTP has an operational feel similar to FTP, while ensuring security by using the encryption and authentication functions of SSH.
Main features of SFTP:
The main differences are as follows:
Here are the basic syntax and common usage examples of the SCP command.
scp [options] source destination
Source and destination are specified in the following format:
[username@]hostname:filepath
Copying a local file to a remote server:
# Copy a single file to a remote server
scp local_file.txt username@remote_server:/path/to/destination/
# Copy multiple files to a remote server
scp file1.txt file2.txt username@remote_server:/path/to/destination/
# Copy a directory to a remote server (recursively)
scp -r local_directory/ username@remote_server:/path/to/destination/
Copying a file from a remote server to local:
# Copy a remote file to local
scp username@remote_server:/path/to/remote_file.txt local_directory/
# Copy a remote directory to local (recursively)
scp -r username@remote_server:/path/to/remote_directory/ local_directory/
Copying a file between remote servers:
# Copy a file from server1 to server2
scp username1@server1:/path/to/file.txt username2@server2:/path/to/destination/
-r: Recursively copy directories.-p: Preserves modification times, access times, and permissions from the original file.-P port: Specifies the port to connect to on the remote host (default is 22).-C: Enables compression.-l limit: Limits the used bandwidth, specified in Kbit/s.-q: Disables the progress meter (quiet mode).-v: Verbose mode. Prints debugging messages.Transferring a large file with compression enabled:
scp -C large_file.zip username@remote_server:/path/to/destination/
Transferring a file using a non-standard port:
scp -P 2222 file.txt username@remote_server:/path/to/destination/
Transferring a file with a bandwidth limit (to reduce impact on other network traffic):
scp -l 1000 large_file.zip username@remote_server:/path/to/destination/
Here are the basic usage and common commands for SFTP.
# SFTP connect to a remote server
sftp username@remote_server
# SFTP connect using a non-standard port
sftp -P 2222 username@remote_server
Once the connection is established, the SFTP prompt (sftp>) will be displayed,
where you can enter SFTP commands.
File transfer commands:
# Download a file from remote to local
get remote_file.txt [local_file.txt]
# Download multiple files
mget *.txt
# Upload a file from local to remote
put local_file.txt [remote_file.txt]
# Upload multiple files
mput *.txt
# Download a directory recursively
get -r remote_directory/
# Upload a directory recursively
put -r local_directory/
Directory operation commands:
# Show the current remote directory
pwd
# Show the current local directory
lpwd
# List the contents of the remote directory
ls [directory]
# List the contents of the local directory
lls [directory]
# Change the remote directory
cd remote_directory
# Change the local directory
lcd local_directory
# Create a remote directory
mkdir remote_directory
# Create a local directory
lmkdir local_directory
File management commands:
# Rename or move a remote file
rename old_name new_name
# Delete a remote file
rm remote_file
# Delete a remote directory
rmdir remote_directory
# Change permissions of a remote file
chmod 644 remote_file
# Change owner/group of a remote file
chown user:group remote_file
Other commands:
# Show help
help
# Exit the SFTP session
exit or bye or quit
You can also put SFTP commands in a file for batch processing:
# Create a command file
echo "cd /remote/directory
get file1.txt
get file2.txt
put local_file.txt
bye" > sftp_commands.txt
# Execute the command file
sftp -b sftp_commands.txt username@remote_server
In addition to the command-line SFTP, there are many graphical SFTP clients:
Here are the best practices and precautions for using SCP and SFTP securely.
Besides SCP and SFTP, there are other alternatives for secure file transfer:
The developers of OpenSSH are gradually deprecating the use of SCP due to known security issues in the SCP protocol and recommend using SFTP instead. In future OpenSSH versions, the SCP command may be changed to use the SFTP protocol internally.
To set up an SSH connection with GitHub, follow these steps:
# macOS
cat ~/.ssh/id_ed25519.pub | pbcopy
# Windows (PowerShell)
Get-Content ~/.ssh/id_ed25519.pub | Set-Clipboard
# Linux
cat ~/.ssh/id_ed25519.pub | xclip -selection clipboard
ssh -T git@github.com
On the first connection, a message will appear to confirm the server's fingerprint. Type "yes" to continue.
If the connection is successful, a message like the following will be displayed:
Hi username! You've successfully authenticated, but GitHub does not provide shell access.
After setting up the SSH connection, here is how to use SSH for operations with GitHub repositories:
On the GitHub repository page, click the "Code" button, select the "SSH" tab, and copy the URL. Then, clone the repository with the following command:
git clone git@github.com:username/repository.git
To change from HTTPS to SSH, use the following commands:
# Check the current remote URL
git remote -v
# Change the remote URL to SSH
git remote set-url origin git@github.com:username/repository.git
# Verify the change
git remote -v
With the SSH connection configured, you can push and pull with the usual Git commands without entering a password:
# Push changes
git push origin main
# Pull changes
git pull origin main
How to deal with problems when connecting to GitHub via SSH:
If the ssh -T git@github.com command fails:
ssh -vT git@github.com to see detailed information.ssh-add -l.chmod 600 ~/.ssh/id_ed25519).If you see a "Permission denied (publickey)" error:
ssh -i ~/.ssh/id_ed25519 -T git@github.com.ssh-add -l.X11 Forwarding is a feature of SSH that allows you to forward the display of graphical applications running on a remote server to your local machine. This makes it possible to operate GUI applications on a remote server on your local machine's screen.
X11 refers to protocol version 11 of the X Window System, a windowing system widely used in Unix-like systems. This protocol adopts a client-server model to provide a graphical user interface (GUI).
How X11 Forwarding works:
This feature is very convenient when you need to use graphical tools on a remote server, or when developing or debugging applications on a remote machine.
To use X11 forwarding, you need to configure it on both the client and server sides:
Enable X11 forwarding in the SSH server (sshd) configuration file (usually /etc/ssh/sshd_config):
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost yes
After changing the configuration, you need to restart the SSH service:
# For Linux (using systemd)
sudo systemctl restart sshd
# For macOS
sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
sudo launchctl load /System/Library/LaunchDaemons/ssh.plist
Add the following settings to the client-side SSH configuration file (~/.ssh/config):
Host *
ForwardX11 yes
ForwardX11Trusted yes
Alternatively, you can use the -X or -Y option when connecting:
-X: Enables basic X11 forwarding (with security restrictions).-Y: Enables trusted X11 forwarding (with fewer security restrictions).To use X11 forwarding, you need the following software:
Here are examples of running remote applications using X11 forwarding:
Connect via SSH with X11 forwarding enabled:
# Basic X11 forwarding
ssh -X username@remote-server
# Trusted X11 forwarding
ssh -Y username@remote-server
After connecting, launch a graphical application on the remote server:
# Examples of simple graphical applications
xclock
xeyes
firefox
gedit
The application's window will appear on your local machine's screen.
X11 forwarding is convenient, but it can consume a lot of network bandwidth. Tips for improving performance:
ssh -XC username@remote-server (the -C option enables compression).X11 forwarding is convenient, but there are security considerations:
-Y option relaxes security restrictions and should only be used with trusted servers.-X option instead of -Y whenever possible.If X11 forwarding is a security concern, you can consider the following alternatives:
Port forwarding (also called SSH tunneling) is a technique that uses the SSH protocol to transfer data through an encrypted tunnel. This allows for secure access to resources that are normally inaccessible and communication that bypasses firewalls.
Main advantages of Port Forwarding:
Port forwarding is utilized for various purposes, such as database management, remote desktop connections, and private web Browse.
There are mainly the following three types:
Local port forwarding forwards a port on the local machine to a port on the remote server. When you connect to the specified port on the local machine, that connection is forwarded through the SSH tunnel to the specified port on the remote server.
Common syntax:
ssh -L local_port:destination_host:destination_port username@ssh_server
For example, when connecting to a remote database server:
# Connect from local port 3307 to the remote server's MySQL port (3306)
ssh -L 3307:localhost:3306 username@remote-server
After this setup, connecting to localhost:3307 on the local machine will forward the connection to localhost:3306 on the remote server.
Remote port forwarding forwards a port on the remote server to a port on the local machine. This is the reverse of local port forwarding and is used, for example, to access a service on a local machine from the internet.
Common syntax:
ssh -R remote_port:destination_host:destination_port username@ssh_server
For example, to make a web server running locally available from a remote location:
# Connect from remote server's port 8080 to the local web server (port 3000)
ssh -R 8080:localhost:3000 username@remote-server
After this setup, connecting to localhost:8080 on the remote server will forward the connection to localhost:80 on the local machine.
Dynamic port forwarding sets up a SOCKS proxy and forwards traffic to multiple destinations through an SSH tunnel. This is useful for tunneling all traffic from web Browse or other applications.
Common syntax:
ssh -D local_port username@ssh_server
For example, to set up a SOCKS proxy on local port 1080:
# Set up a SOCKS proxy on local port 1080
ssh -D 1080 username@remote-server
After this setup, if you specify localhost:1080 as the SOCKS proxy in your browser or other applications,
all traffic will be sent from the remote server through the SSH tunnel.
Port forwarding is a secure means of communication, but if not properly configured and managed, it can pose security risks:
0.0.0.0 (all interfaces) instead of localhost can allow unintended access.localhost.
Settings in the SSH server (/etc/ssh/sshd_config) to control port forwarding:
# Allow/deny all port forwarding
AllowTcpForwarding yes/no
# Allow only local port forwarding
AllowTcpForwarding local
# Allow/deny remote port forwarding
GatewayPorts yes/no
# Restrictions for specific users or groups
Match User username
AllowTcpForwarding yes
PermitOpen localhost:3306 localhost:5432
After changing these settings, you need to restart the SSH service.
Best practices for using SSH more securely:
Common issues that occur when using SSH and their solutions:
~/.ssh/known_hosts file.ServerAliveInterval and ServerAliveCountMax in ~/.ssh/config.~/.ssh directory and key files (directory should be 700, private key 600).~/.ssh/config file, specify which key to use for each host.-X or -Y option and ensure the necessary packages are installed.