Featured image of post SSH: SSH to Windows, SSH Configuration, Passwordless Login, VSCode Remote Development, etc.

SSH: SSH to Windows, SSH Configuration, Passwordless Login, VSCode Remote Development, etc.

SSH related content, including SSH to Windows, SSH configuration, passwordless login, VSCode remote development, etc.

Motivation

SSH (Secure Shell) is a widely used remote login protocol. I have used it extensively, and setting it up is not difficult, with many configurations being one-time setups. However, most of these configurations are only done when changing computers or reinstalling the system, leading to a low usage frequency. As a result, I often have to look up related information each time.

Here, I have compiled commonly used SSH-related content for easy reference in the future.

SSH Installation

First, SSH consists of a client and a server. The client is used to connect to other computers, while the server allows other computers to connect to yours.

Almost all mainstream operating systems (Windows/macOS/Linux) come with an SSH client, so you can usually open a command-line tool on any computer and use the ssh command.

However, the SSH server is different. Most operating systems do not install the SSH server by default, or even if it is installed, it is generally not enabled by default. Therefore, this section mainly discusses how to install and set up the SSH server to start automatically.

Windows

Earlier versions of Windows (before Windows 10 1809) did not come with an SSH server, but starting from Windows 10 1809, Windows includes the OpenSSH server. However, it is not installed by default and needs to be enabled by the user.

  1. Open the “Settings” app and click on “Apps”.
  2. On the “Apps & features” page, click on “Optional features” on the right side.
  3. On the “Optional features” page, click on “Add a feature”.
  4. On the “Add a feature” page, find “OpenSSH Server” and click to install it.
  5. After installation, open the “Services” app (you can search for “Services” in the Start menu), find “OpenSSH SSH Server”, right-click it, and select “Properties”.
  6. In the “Properties” window, set the “Startup type” to “Automatic”, then click the “Start” button to start the service.
  7. Click “Apply” and “OK” to save the settings.

Linux

Most Linux distributions come with an SSH server, but if not, you can install it using the package manager.

  • Ubuntu/Debian systems:
    1
    2
    
    sudo apt update
    sudo apt install openssh-server
    
  • Fedora/RHEL/CentOS systems:
    1
    
    sudo dnf install openssh-server
    
  • Arch Linux:
    1
    
    sudo pacman -S openssh
    
  • openSUSE:
    1
    
    sudo zypper install openssh
    

After installation, you can start the SSH service and set it to start on boot with the following commands:

1
2
sudo systemctl start sshd
sudo systemctl enable sshd

macOS

macOS comes with an SSH server, but it is disabled by default. You can enable it by following these steps:

  1. Open “System Preferences” and click on “Sharing”.
  2. On the “Sharing” page, check the box for “Remote Login”.
  3. This will automatically enable the SSH server and display the SSH connection information.

SSH Passwordless Login

SSH passwordless login is achieved through SSH key pairs, allowing you to connect to a remote server without entering a password.

The principle is to generate a key pair (public and private keys) on your local computer A, then copy the public key to the remote server B. After that, when connecting from computer A to server B, SSH will use the key pair for authentication without requiring a password.

  1. Generate an SSH key pair on your local computer A:

    1
    
    ssh-keygen -t ed25519
    

    Here, -t ed25519 specifies using the ed25519 algorithm to generate the key pair. You can also use -t rsa to generate an RSA key pair.

    Follow the prompts and press Enter to accept the defaults. The private and public keys will be saved in ~/.ssh/id_ed25519 and ~/.ssh/id_ed25519.pub, respectively.

  2. Copy the public key to the remote server B:

    • If your local computer A is Linux or macOS, you can use the following command to copy the public key to the remote server B:

      1
      
      ssh-copy-id user@remote_server
      

      Here, user is the username on the remote server B, and remote_server is the IP address or domain name of the remote server B. You will need to enter the password for the remote server B.

    • If your local computer A is Windows, you can manually copy the public key content to the ~/.ssh/authorized_keys file on the remote server B.

      Specifically, first view the public key content on your local computer A:

      1
      
       Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub
      

      Or open the C:\Users\<YourUsername>\.ssh\id_ed25519.pub file directly with Notepad and copy its content.

      Then, on the remote server B, create or edit the ~/.ssh/authorized_keys file and paste the public key content into it.

      Finally, for security reasons, ensure that the permissions of the ~/.ssh/authorized_keys file are set correctly:

      1
      
      chmod 600 ~/.ssh/authorized_keys
      
  3. Test passwordless login: Now you can try connecting from your local computer A to the remote server B by running:

    1
    
    ssh user@remote_server
    

    If everything is set up correctly, you should be able to log in to the remote server B directly without entering a password.

SSH Configuration Files

SSH configuration files can be used to simplify SSH connection commands. User-level configurations are generally located in ~/.ssh/ (Linux and macOS) or C:\Users\<YourUsername>\.ssh\ (Windows), while system-level configurations are generally located in /etc/ssh/ (Linux and macOS) or C:\ProgramData\ssh\ (Windows). System-level configuration files affect all users and require administrator or sudo privileges to modify; user-level configuration files only affect the current user.

SSH configuration files are divided into client configuration files and server configuration files.

Client Configuration Files

System-level client configuration files are located at /etc/ssh/ssh_config (Linux and macOS) or C:\ProgramData\ssh\ssh_config (Windows), while user-level client configuration files are located at ~/.ssh/config (Linux and macOS) or C:\Users\<YourUsername>\.ssh\config (Windows). If there are many configurations, you can also split the configuration files into multiple files. System-level configuration files can be placed in the /etc/ssh/ssh_config.d/ directory, and user-level configuration files can be placed in the ~/.ssh/config.d/ directory.

Client configuration files commonly include the following options:

  • Host: Specifies the host alias, which can use the wildcard * to match all hosts.
  • HostName: Specifies the hostname or IP address.
  • User: Specifies the login username.
  • Port: Specifies the SSH connection port, default is 22.
  • IdentityFile: Specifies the private key file path.
  • ForwardAgent: Whether to enable SSH agent forwarding, default is no.
  • ServerAliveInterval: Sets the interval for server alive checks in seconds, default is 0 (no checks).
  • ServerAliveCountMax: Sets the maximum number of server alive checks, default is 3.
  • ControlMaster: Whether to enable SSH connection multiplexing, default is no.
  • ControlPath: Specifies the socket file path for SSH connection multiplexing, default is ~/.ssh/sockets/%r@%h:%p.
  • ControlPersist: Whether to enable persistent SSH connection multiplexing, default is no.

Below is an example of a user-level SSH client configuration file ~/.ssh/config:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Default configuration
Host *
    User your_username
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    ForwardAgent no
    ServerAliveInterval 60
    ServerAliveCountMax 3
# Specific host configuration
Host example
    HostName example.com
    User example_user
    Port 2222
    IdentityFile ~/.ssh/id_ed25519_example
    ForwardAgent yes
    ControlMaster auto
    ControlPath ~/.ssh/sockets/%r@%h:%p
    ControlPersist yes
# Use wildcard to match multiple hosts
Host *.example.com
    User wildcard_user
    IdentityFile ~/.ssh/id_ed25519_wildcard

Server Configuration Files

Server configuration files are located at /etc/ssh/sshd_config (Linux and macOS) or C:\ProgramData\ssh\sshd_config (Windows). Common options in server configuration files include:

  • Port: Specifies the SSH server port, default is 22.
  • ListenAddress: Specifies the IP address the SSH server listens on, default is all addresses.
  • PermitRootLogin: Whether to allow root user login, default is prohibit-password (disallow password login but allow key-based login).
  • PasswordAuthentication: Whether to allow password login, default is yes.
  • PubkeyAuthentication: Whether to allow public key authentication, default is yes.
  • ChallengeResponseAuthentication: Whether to enable challenge-response authentication, default is no.
  • UsePAM: Whether to enable PAM authentication, default is yes.
  • AllowUsers: Specifies a list of users allowed to log in, can use the wildcard *, default is all users.
  • DenyUsers: Specifies a list of users denied login, can use the wildcard *, default is no denied users.
  • AllowGroups: Specifies a list of groups allowed to log in, can use the wildcard *, default is all groups.
  • DenyGroups: Specifies a list of groups denied login, can use the wildcard *, default is no denied groups.
  • MaxAuthTries: Sets the maximum number of authentication attempts, default is 6.
  • MaxSessions: Sets the maximum number of sessions, default is 10.
  • ClientAliveInterval: Sets the interval for client alive checks in seconds, default is 0 (no checks).
  • ClientAliveCountMax: Sets the maximum number of client alive checks, default is 3.
  • PermitTunnel: Whether to allow SSH tunneling, default is no.
  • X11Forwarding: Whether to allow X11 forwarding, default is no.
  • Subsystem: Specifies the subsystem configuration, default is subsystem sftp /usr/lib/openssh/sftp-server. Below is an example of an SSH server configuration file /etc/ssh/sshd_config:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# SSH server configuration
Port 22
ListenAddress *
PermitRootLogin prohibit-password
PasswordAuthentication yes
PubkeyAuthentication yes
ChallengeResponseAuthentication no
UsePAM yes
AllowUsers user1 user2
DenyUsers user3
AllowGroups group1 group2
DenyGroups group3
MaxAuthTries 3
MaxSessions 10
ClientAliveInterval 60
ClientAliveCountMax 3
PermitTunnel no
X11Forwarding yes
Subsystem sftp /usr/lib/openssh/sftp-server

Some Common SSH Features

Usually, we use SSH to remotely connect to a computer (server) and then use the server’s command-line tools to execute commands. However, SSH has many other features, such as port forwarding, X11 forwarding, etc.

Port Forwarding

SSH can forward local ports to remote server ports or forward remote server ports to local ports. This is very useful for accessing services behind a firewall.

  • Local Port Forwarding:

    1
    
    ssh -L local_port:remote_host:remote_port user@remote_server
    

    With local port forwarding, you can access services on the remote server from your local machine. For example, if there is a web service running on port 8080 on the remote server, you can forward it to your local port 8080 with the following command:

      ```bash
      ssh -L 8080:localhost:8080 user@remote_server
      ```
    
  • Remote Port Forwarding:

    1
    
    ssh -R remote_port:local_host:local_port user@remote_server
    

    With remote port forwarding, you can allow the remote server to access services on your local machine. For example, if you are running a web service locally, you can forward it to port 8080 on the remote server with the following command:

      ```bash
      ssh -R 8080:localhost:8080 user@remote_server
      ```
    
  • Dynamic Port Forwarding (similar to a SOCKS proxy):

    1
    
    ssh -D local_port user@remote_server
    

    With dynamic port forwarding, you can create a SOCKS proxy server on your local machine, allowing other applications to connect to the remote server via SSH. For example, you can create a SOCKS proxy server with the following command:

      ```bash
      ssh -D 1080 user@remote_server
      ```
    

    Then, configure your browser or other applications to use the SOCKS proxy with localhost:1080 as the proxy server address. This way, the traffic from your browser or other applications configured with the SOCKS proxy will go through the remote server’s network. A useful scenario is when your local computer is in country A and the remote server is in country B; you can use SSH’s dynamic port forwarding feature to route your local traffic through the remote server to access resources in country B.

X11 Forwarding

SSH can forward graphical applications from the remote server to your local computer through an SSH tunnel, allowing you to run graphical applications from the remote server on your local machine.

Note: There is a pair of easily confused concepts here: X server and X client. In the X11 protocol, the X server refers to the computer with a graphical interface that can serve as a display, while the X client refers to the computer that wants to run a graphical program. Typically, we run the X server on our local computer (such as Xming or VcXsrv on Windows, and XQuartz on macOS), while running the X client (graphical applications) on the remote server. This allows us to display programs running on the remote server on our local machine. This is opposite to the SSH server and client concepts.

To enable X11 forwarding, you need to configure both the SSH client and server.

  • On the SSH server

    Ensure that the sshd_config file has the following configuration:

    1
    2
    
    X11Forwarding yes
    X11DisplayOffset 10
    
  • On the SSH client

    1. Prerequisites:

      1. Ensure that you have X11 server software installed on your local computer. Linux usually comes with an X11 server, but on Windows and macOS, you need to install additional software, such as Xming or VcXsrv on Windows, and XQuartz on macOS.

      2. Ensure that your SSH client supports X11 forwarding. Most SSH clients on Linux and macOS support X11 forwarding, but on Windows, OpenSSH needs to be version 8.0 or higher (see PowerShell Issue #1515 on GitHub). You can run the ssh -V command to check the current version.

      3. Ensure that the DISPLAY environment variable is set on your local computer.

        • Windows:

          If using PowerShell, you can run the following command:

          1
          
          $env:DISPLAY = "localhost:0.0"
          

          If using cmd, you can run the following command:

          1
          
          set DISPLAY=localhost:0.0
          
        • Linux/macOS:

          On Linux and macOS, you usually do not need to manually set the DISPLAY environment variable, as the SSH client will automatically set it.

          However, if you need to set it manually, you can run the following command in the terminal:

          1
          
          export DISPLAY=localhost:0.0
          
    2. Connect to the remote server:

      When connecting to the remote server with the SSH client, use the -X or -Y option to enable X11 forwarding:

      1
      
      ssh -X user@remote_server
      

      or

      1
      
      ssh -Y user@remote_server
      

      The -X option enables secure X11 forwarding, while the -Y option enables insecure X11 forwarding (allowing higher privilege operations).

    3. Test X11 forwarding:

      After enabling X11 forwarding, you can run graphical applications on the remote server, and their windows will be displayed on your local computer. For example, you can run the xclock command on the remote server to test X11 forwarding:

      1
      
      xclock
      

      If everything is set up correctly, you should see a clock window on your local computer.

Remote Development with VSCode

When VS Code was first released, it was just one of many editors. Compared to text editors like Notepad++ and Sublime Text, it wasn’t significantly better; compared to IDEs like Visual Studio and IntelliJ IDEA, it wasn’t as powerful. Its popularity mainly stemmed from two killer features: extensions and remote development.

When VS Code was first released, I was also using Sublime Text, Visual Studio Community Edition, PyCharm, and other editors and IDEs. However, after VS Code supported remote development, I completely abandoned other editors and IDEs and fully switched to VS Code. Although I used IntelliJ IDEA for a while when learning Java Web development, in most cases, VS Code has been sufficient.

I digress, but in my opinion, the most revolutionary and attractive feature of VS Code is its native support for remote development, which is also very convenient and easy to use.

VS Code comes with the Remote Development Extension Pack pre-installed. Using it is also very simple:

  1. Open VS Code on your local computer and click the “Remote Explorer” icon (a computer with an arrow) in the left activity bar.
  2. Click the “Connect to Host…” button in the upper left corner, enter the SSH connection information for the remote server (in the format user@remote_server), and press Enter.
  3. If it’s your first time connecting, you will be prompted to choose an SSH configuration file. Select the default user-level configuration file (either ~/.ssh/config or C:\Users\<YourUsername>\.ssh\config). This configuration file is the same as the SSH client configuration file mentioned earlier, and the previous configurations will also apply here.
  4. After a successful connection, VS Code will install a VS Code server component on the remote server, and then you can use VS Code to edit files on the remote server just like you would locally.

Acknowledgments

This article’s cover image is from IPXO.

comments powered by Disqus