Featured image of post SSH相关: ssh到Windows、ssh配置、免密码登录、VSCode远程开发等

SSH相关: ssh到Windows、ssh配置、免密码登录、VSCode远程开发等

SSH相关的内容,包括ssh到Windows、ssh配置、免密码登录、VSCode远程开发等

缘起

SSH(Secure Shell)是非常常用的远程登录协议,我本身使用得已经非常多了,设置并不难,而且很多都是一劳永逸。但大部分设置基本都是每次换电脑或重装系统时才会搞,使用频率非常低,所以每次都要重新查找相关资料。

这里就把常用的SSH相关内容整理一下,方便以后查找。

SSH安装

首先,SSH分为客户端和服务端。客户端是用来连接其他电脑的,服务端是用来允许其他电脑连接到你的。

目前几乎所有主流操作系统(Windows/macOS/Linux)都自带SSH客户端,所以随便拿到一台电脑,你基本上都可以打开命令行工具,输入ssh命令来使用SSH。

但SSH服务端就不一样了,大部分操作系统默认并不安装SSH服务端,或者即使安装了,也一般不会默认就开启。所以这里主要讲一下如何安装和设置SSH服务端自启动。

Windows

之前的Windows版本(Windows 10 1809之前)没有自带SSH服务端,但从Windows 10 1809开始,Windows就自带了OpenSSH服务端。但默认是没有安装的,需要用户主动启用。

  1. 打开“设置”应用,点击“应用”。
  2. 在“应用和功能”页面,点击右侧的“可选功能”。
  3. 在“可选功能”页面,点击“添加功能”。
  4. 在“添加功能”页面,找到“OpenSSH Server”,点击安装。
  5. 安装完成后,打开“服务”应用(可以在开始菜单搜索“服务”),找到“OpenSSH SSH Server”,右键点击,选择“属性”。
  6. 在“属性”窗口中,将“启动类型”设置为“自动”,然后点击“启动”按钮启动服务。
  7. 点击“应用”和“确定”保存设置。

Linux

大部分Linux发行版都自带SSH服务端,但如果没有,可以通过包管理器安装。

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

安装完成后可以通过以下命令启动SSH服务并设置为开机自启:

1
2
sudo systemctl start sshd
sudo systemctl enable sshd

macOS

macOS自带SSH服务端,但默认是关闭的。可以通过以下步骤启用:

  1. 打开“系统偏好设置”,点击“共享”。
  2. 在“共享”页面,勾选“远程登录”。
  3. 这时会自动启用SSH服务端,并显示SSH连接信息。

SSH免密码登录

SSH免密码登录是通过SSH密钥对实现的,可以让你在连接到远程服务器时不需要输入密码。

其原理是在本地电脑A生成一对密钥(公钥和私钥),然后将公钥复制到远程服务器B上。之后再从电脑A连接到服务器B时,SSH会使用密钥对进行身份验证,而不需要输入密码。

  1. 在本地电脑A上生成SSH密钥对

    1
    
    ssh-keygen -t ed25519
    

    这里的-t ed25519表示使用ed25519算法生成密钥对,你也可以使用-t rsa生成RSA密钥对。

    按照提示一路回车即可,默认会将生成的私钥和公钥分别保存在~/.ssh/id_ed25519~/.ssh/id_ed25519.pub

  2. 将公钥复制到远程服务器B上

    • 如果本地电脑A是Linux或macOS,可以使用以下命令将公钥复制到远程服务器B上:

      1
      
      ssh-copy-id user@remote_server
      

      这里的user是远程服务器B上的用户名,remote_server是远程服务器B的IP地址或域名。这里你需要输入远程服务器B的密码。

    • 如果本地电脑A是Windows,可以手动将公钥内容复制到远程服务器B的~/.ssh/authorized_keys文件中。

      具体来说,首先在本地电脑A上查看公钥内容:

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

      或者直接用记事本打开C:\Users\<YourUsername>\.ssh\id_ed25519.pub文件,将内容复制。

      然后在远程服务器B上创建或编辑~/.ssh/authorized_keys文件,将公钥内容粘贴进去。

      最后为了安全起见,确保~/.ssh/authorized_keys文件的权限设置正确:

      1
      
      chmod 600 ~/.ssh/authorized_keys
      
  3. 测试免密码登录: 现在你可以尝试从本地电脑A连接到远程服务器B,直接运行:

    1
    
    ssh user@remote_server
    

    如果一切设置正确,你应该可以直接登录到远程服务器B,而不需要输入密码。

SSH配置文件

SSH配置文件可以用来简化SSH连接命令,用户级配置一般位于~/.ssh/(Linux和macOS)或C:\Users\<YourUsername>\.ssh\(Windows)中,系统级配置一般位于/etc/ssh/(Linux和macOS)或C:\ProgramData\ssh\(Windows)中。系统级配置文件对所有用户生效,需要管理员或者sudo权限才能修改;用户级配置文件只对当前用户生效。

SSH配置文件分为客户端配置文件和服务端配置文件。

客户端配置文件

系统级客户端配置文件是/etc/ssh/ssh_config(Linux和macOS)或C:\ProgramData\ssh\ssh_config(Windows),用户级客户端配置文件是~/.ssh/config(Linux和macOS)或C:\Users\<YourUsername>\.ssh\config(Windows)。如果配置比较多,也可以将配置文件拆开成多个文件,系统级配置文件可以放在/etc/ssh/ssh_config.d/目录下,用户级配置文件可以放在~/.ssh/config.d/目录下。

客户端配置文件的常用配置项包括:

  • Host:指定主机别名,可以使用通配符*,表示匹配所有主机。
  • HostName:指定主机名或IP地址。
  • User:指定登录用户名。
  • Port:指定SSH连接端口,默认是22。
  • IdentityFile:指定私钥文件路径。
  • ForwardAgent:是否启用SSH代理转发,默认是no
  • ServerAliveInterval:设置服务器存活检测的时间间隔,单位是秒,默认是0(不检测)。
  • ServerAliveCountMax:设置服务器存活检测的最大次数,默认是3。
  • ControlMaster:是否启用SSH连接复用,默认是no
  • ControlPath:指定SSH连接复用的Socket文件路径,默认是~/.ssh/sockets/%r@%h:%p
  • ControlPersist:是否启用SSH连接复用的持久化,默认是no

下面是一个示例的用户级SSH客户端配置文件~/.ssh/config

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 默认配置
Host *
    User your_username
    Port 22
    IdentityFile ~/.ssh/id_ed25519
    ForwardAgent no
    ServerAliveInterval 60
    ServerAliveCountMax 3
# 特定主机配置
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
# 使用通配符匹配多个主机
Host *.example.com
    User wildcard_user
    IdentityFile ~/.ssh/id_ed25519_wildcard

服务端配置文件

服务端配置文件是/etc/ssh/sshd_config(Linux和macOS)或C:\ProgramData\ssh\sshd_config(Windows)。服务端配置文件的常用配置项包括:

  • Port:指定SSH服务端口,默认是22。
  • ListenAddress:指定SSH服务监听的IP地址,默认是所有地址。
  • PermitRootLogin:是否允许root用户登录,默认是prohibit-password(禁止密码登录,但允许密钥登录)。
  • PasswordAuthentication:是否允许密码登录,默认是yes
  • PubkeyAuthentication:是否允许公钥认证,默认是yes
  • ChallengeResponseAuthentication:是否启用挑战响应认证,默认是no
  • UsePAM:是否启用PAM认证,默认是yes
  • AllowUsers:指定允许登录的用户列表,可以使用通配符*,默认是所有用户。
  • DenyUsers:指定禁止登录的用户列表,可以使用通配符*,默认是没有禁止用户。
  • AllowGroups:指定允许登录的用户组列表,可以使用通配符*,默认是所有用户组。
  • DenyGroups:指定禁止登录的用户组列表,可以使用通配符*,默认是没有禁止用户组。
  • MaxAuthTries:设置最大认证尝试次数,默认是6。
  • MaxSessions:设置最大会话数,默认是10。
  • ClientAliveInterval:设置客户端存活检测的时间间隔,单位是秒,默认是0(不检测)。
  • ClientAliveCountMax:设置客户端存活检测的最大次数,默认是3。
  • PermitTunnel:是否允许SSH隧道,默认是no
  • X11Forwarding:是否允许X11转发,默认是no
  • Subsystem:指定子系统配置,默认是subsystem sftp /usr/lib/openssh/sftp-server

下面是一个示例的SSH服务端配置文件/etc/ssh/sshd_config:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# SSH服务端配置
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

SSH一些常用的功能

通常我们使用SSH都是远程连接到一台电脑(服务器),然后使用服务器的命令行工具来执行命令。但SSH还有很多其他的功能,比如端口转发、X11转发等。

端口转发

SSH可以将本地端口转发到远程服务器的端口,或者将远程服务器的端口转发到本地端口。这对于访问防火墙后面的服务非常有用。

  • 本地端口转发:

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

    通过本地端口转发,你可以在本地访问远程服务器上的服务。例如,如果远程服务器上有一个Web服务运行在8080端口,你可以使用以下命令将其转发到本地的8080端口:

      ```bash
      ssh -L 8080:localhost:8080 user@remote_server
      ```
    
  • 远程端口转发:

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

    通过远程端口转发,你可以让远程服务器访问本地的服务。例如,如果你在本地运行了一个Web服务,你可以使用以下命令将其转发到远程服务器的8080端口:

      ```bash
      ssh -R 8080:localhost:8080 user@remote_server
      ```
    
  • 动态端口转发(类似于SOCKS代理):

    1
    
    ssh -D local_port user@remote_server
    

    通过动态端口转发,你可以在本地创建一个SOCKS代理服务器,允许其他应用程序通过SSH连接到远程服务器。例如,你可以使用以下命令创建一个SOCKS代理服务器:

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

    然后在浏览器或其他应用程序中配置SOCKS代理,使用localhost:1080作为代理服务器地址。这样,你的浏览器或者配置了SOCKS代理的其他应用程序的流量就会走远程服务器的网络。一个有用的使用场景是,比如本地电脑在A国,远程服务器在B国,你可以通过SSH的动态端口转发功能,将本地的流量通过远程服务器转发到B国,这样就可以访问B国的网络资源。

X11转发

SSH可以将远程服务器的图形界面应用程序通过SSH隧道转发到本地电脑上,这样你就可以在本地运行远程服务器上的图形界面应用程序。

注意:这里有一对容易混淆的概念:X服务端X客户端。在X11协议中,X服务端是指有图形界面可以作为显示的电脑,而X客户端是指想要运行一个图形程序的电脑。通常情况下,我们在本地电脑上运行X服务端(比如Xming或VcXsrv),而在远程服务器上运行X客户端(图形界面应用程序),这样我们可以将远程服务器上运行的程序显示到本地电脑上。这跟SSH的服务端和客户端概念是相反的。

要启用X11转发,你需要在SSH客户端和服务端都进行配置。

  • 在SSH服务端上

    确保sshd_config文件中有以下配置:

    1
    2
    
    X11Forwarding yes
    X11DisplayOffset 10
    
  • 在SSH客户端上

    1. 前置要求

      1. 确保本地电脑上安装了X11服务器软件。Linux通常自带了X11服务器,但在Windows和macOS上需要安装额外的软件。比如Windows上的Xming或VcXsrv,以及macOS上的XQuartz。

      2. 确保SSH客户端支持X11转发。大部分Linux和macOS的SSH客户端都支持X11转发,但在Windows上的OpenSSH需要是8.0或更高版本(见GitHub上的PowerShell Issue #1515)。可以运行ssh -V命令来查看当前版本。

      3. 确保本地电脑上设置了DISPLAY环境变量。

        • Windows:

          如果用PowerShell,可以运行以下命令:

          1
          
          $env:DISPLAY = "localhost:0.0"
          

          如果用cmd,可以运行以下命令:

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

          在Linux和macOS上,通常不需要手动设置DISPLAY环境变量,因为SSH客户端会自动设置。

          但是如果需要手动设置,可以在终端中运行以下命令:

          1
          
          export DISPLAY=localhost:0.0
          
    2. 连接远程服务器

      在SSH客户端连接远程服务器时,需要使用-X-Y选项启用X11转发:

      1
      
      ssh -X user@remote_server
      

      或者

      1
      
      ssh -Y user@remote_server
      

      -X选项启用安全的X11转发,而-Y选项启用不安全的X11转发(允许更高权限的操作)。

    3. 测试X11转发

      启用X11转发后,你可以在远程服务器上运行图形界面应用程序,它们的窗口会显示在本地电脑上。例如,你可以在远程服务器上运行xclock命令来测试X11转发:

      1
      
      xclock
      

      如果一切设置正确,你应该可以在本地电脑上看到一个时钟窗口。

VSCode远程开发

VS Code刚发布时只是众多编辑器中的一个,跟文本编辑器比,不比NotePad++、Sublime Text之流强到哪里;跟IDE比,也不如专业的Visual Studio、IntelliJ IDEA等。其流行起来主要是因为两个杀手锏:一是插件,二是远程开发。

我在VS Code刚发布时还同时使用Sublime Text、Visual Studio Community版、PyCharm等编辑器和IDE,但在VS Code支持远程开发后,我就彻底放弃了其他编辑器和IDE,完全转向了VS Code。虽然后来在学习Java Web开发时又用了一段时间的IntelliJ IDEA,但大部分情况下VS Code已经完全够用了。

扯远了,但总之在我看来,VS Code最具革命性和吸引力的就是其原生支持远程开发,而且十分方便易用。

VS Code安装后就自带了远程开发插件(Remote Development Extension Pack),其使用也非常简单:

  1. 在本地电脑上打开VS Code,点击左侧活动栏中的“远程资源管理器”图标(一个电脑和一个箭头的图标)。
  2. 点击左上角的“连接到主机…”按钮,输入远程服务器的SSH连接信息(格式为user@remote_server),然后按回车键。
  3. 如果是第一次连接,会提示你选择SSH配置文件,选择默认的用户级配置文件即可(~/.ssh/configC:\Users\<YourUsername>\.ssh\config)。这个配置文件跟前面提到的SSH客户端配置文件是一样的,前面的配置同样会适用到这里。
  4. 连接成功后,VS Code会在远程服务器上安装一个VS Code服务器端组件,然后你就可以像在本地一样使用VS Code来编辑远程服务器上的文件了。

鸣谢

本文封面图来自IPXO

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计