158. SSH

Secure Shell (SSH) 是一个网络协议,它主要被用来加密客户端和服务端之间的连接。 在客户端和服务端的每一次交互都被加密。

这个教程解释了如何在 Ubuntu 机器上启用 SSH。

启用 SSH 将会允许你远程连接到你的系统,并且执行管理员任务。你将能够通过 scpsftp安全传输文件。

在 Ubuntu 上启用 SSH

默认情况下,当 Ubuntu 最初被安装的时候,通过 SSH 进行远程访问是不被允许的。在 Ubuntu 上启用 SSH 非常的简单直接。

以 root 或者其他 sudo 用户身份执行下面的步骤,在你的 Ubuntu 系统上安装并且启用 SSH。

01.使用Ctrl+Alt+T打开终端,并且安装openssh-server软件包:

1
2
sudo apt update
sudo apt install openssh-server

当被提示时,输入你的密码并且按 Enter,继续安装。

02.一旦安装完成,SSH 服务将会被自动启动。你可以验证 SSH 是否正在运行,输入:

1
sudo systemctl status ssh

输出将会告诉你服务正在运行,并且启用开机启动:

1
2
3
4
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-06-01 12:34:00 CEST; 9h ago
...

q返回命令行。

03.Ubuntu 自带一个配置防火墙配置工具,称为 UFW。如果防火墙在你的系统上被启用,请确保打开了 SSH 端口:

1
sudo ufw allow ssh

就这些。现在你可以从任何远程机器上通过 SSH 连接到你的 Ubuntu 系统。Linux 和 macOS 系统默认都安装了 SSH 客户端。想要从一个 Window 机器上连接,使用一个 SSH 客户端,例如:PUTTY

连接到 SSH 服务器

想要在局域网内连接到你的 Ubuntu 机器,以下面的格式输入 ssh 命令,加上用户名和 IP 地址。

1
ssh username@ip_address
1
确保你将`username`修改成你自己的用户名,`ip_address`修改成你安装了 SSH 的 Ubuntu 机器的 IP 地址。

如果你不知道你的 IP 地址,你可以使用ip命令轻易地找到它:

1
ip a

你可以从输出中看到,系统 IP 地址是10.0.2.15

一旦你找到 IP 地址,通过运行下面的ssh 命令登录远程机器:

1
ssh linuxize@10.0.2.15

当你第一次连接时,你将看到下面的信息:

1
2
3
The authenticity of host '10.0.2.15 (10.0.2.15)' can't be established.
ECDSA key fingerprint is SHA256:Vybt22mVXuNuB5unE++yowF7lgA/9/2bLSiO3qmYWBY.
Are you sure you want to continue connecting (yes/no)?

输入yes并且你将会被提示输入你的密码:

1
2
Warning: Permanently added '10.0.2.15' (ECDSA) to the list of known hosts.
linuxize@10.0.2.15's password:

一旦你输入密码,你将会看到默认的 Ubuntu 消息:

1
2
3
4
5
6
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-26-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
...

现在你可以登录到你的 Ubuntu 机器上。

连接到 NAT 后面的 SSH

想要通过互联网连接到你的 Ubuntu 机器,你需要知道你的公网 IP 地址,并且配置你的路由器接收端口22的数据,并且发送它到正在运行 SSH 的 Ubuntu 机器。

想要获取你尝试通过 SSH 连接的机器的公网 IP,在这个机器上访问 URL 地址:https://api.ipify.org

当设置端口转发时,每一个路由器都有不同的方式来设置端口转发。你应该参考你的路由器文档,关于如何设置端口转发的信息。简单来讲,你应该输入之前设置的 SSH 端口号 22,以及之前服务器的私有 IP 地址。

一旦你找到 IP 地址,配置你的路由器,输入:

1
ssh username@public_ip_address

如果你将你的机器暴露在互联网中,你最好采取一些安全措施。最基础的一个措施就是配置你的路由器接受一个非标准端口的 SSH 流量,并且转发到你运行 SSH 服务的机器的端口22。

你也可以设置 SSH 密钥公钥验证方式,之后你就可以不使用密码就可以连接到你的 Ubuntu 机器上了。

在 Ubuntu 上禁用 SSH

想要在你的 Ubuntu 系统上禁用 SSH 服务器,简单停止 SSH 即可,输入:

1
sudo systemctl disable --now ssh

稍后,你可以重新启用,输入:

1
sudo systemctl enable --now ssh

SSH登录

SSH 无密登录

step1 客户端生成公私钥

本地客户端生成公私钥:(一路回车默认即可)

1
ssh-keygen

生成之后会在用户的根目录生成一个 “.ssh”的文件夹,进入“.ssh”会生成如下几个文件:

1
cd ~/.ssh

下创建两个密钥:

  1. authorized_keys: 存放远程免密登录的公钥,主要通过这个文件记录多台机器的公钥
  2. id_rsa : 生成的私钥文件
  3. id_rsa.pub : 生成的公钥文件
  4. know_hosts : 已知的主机公钥清单

ps

ssh公钥生效需满足至少下面两个条件:

  • .ssh 目录的权限必须是700
  • .ssh/authorized_keys 文件权限必须是600

step2 上传公钥到服务器

这里测试用的服务器地址为:192.168.32.32

用户为:root

方法1

1
ssh-copy-id -i ~/.ssh/id_rsa.pub <remote_ip>

上面这条命令是写到服务器上的ssh目录下去了

1
2
cd ~/.ssh
vim authorized_keys

可以看到客户端写入到服务器的 id_rsa.pub (公钥)内容。

方法2

使用命令ssh-copy-id <remote_ip>

1
ssh-copy-id root@192.168.32.32

方法3

通过scp将内容写到对方的authorized_keys文件中

1
scp -p ~/.ssh/id_rsa.pub root@<remote_ip>:/root/.ssh/authorized_keys

step3 测试免密登录

客户端通过ssh连接远程服务器,就可以免密登录了。

1
ssh root@192.168.32.32

设置指定用户

step1 配置SSH服务器

编辑SSH服务器配置文件(通常位于/etc/ssh/sshd_config)。

1
$ sudo vim /etc/ssh/sshd_config

确保以下行未注释(没有#):

1
2
PubkeyAuthentication yes
PasswordAuthentication yes

这允许使用SSH密钥和密码进行身份验证。

step2 设置Match

在配置文件的末尾添加Match块,限制只允许用户user1, user2, user3使用密钥登录。您可以这样做:

1
2
Match User user1,user2,user3
PasswordAuthentication no

1
2
3
4
5
6
7
8
Match User user1
PasswordAuthentication no

Match User user2
PasswordAuthentication no

Match User user3
PasswordAuthentication no

这将禁用user1,user2,user3用户的密码登录。其他用户将按照默认设置进行身份验证,允许密码登录。

多个用户也可以单独

step3 重启SSH服务

保存配置文件并重启SSH服务,以使更改生效:

1
$ sudo systemctl restart ssh

现在,user1,user2,user3用户只能使用其SSH密钥进行身份验证,而其他用户仍然可以使用密码进行身份验证。

请确保在执行此操作之前,您已经测试过SSH密钥对的工作方式,并且确保您至少有一种方法可以访问服务器,以防止自身被锁定。

SSH设置环境变量

方法1

~/.ssh/config 中设置如下内容:

1
2
Host *
SetEnv TERM=xterm-256color

它的作用是为所有主机(Host * 表示匹配所有主机)设置一个环境变量 TERM, 其值为 xterm-256color, 具体含义如下:

  • Host *: 这是一个通配符规则,表示该配置适用于所有远程主机。 如果你只想针对特定主机应用配置,可以将 * 替换为主机名或 IP 地址。
  • SetEnv TERM=xterm-256color : SetEnv 是 SSH 配置指令, 用于在连接到远程主机时传递环境变量. TERM=xterm-256color 设置了终端类型为 xterm-256color, 这是一种支持 256 色的终端模拟器类型。这对于需要彩色输出的程序(如 vim、tmux 等)非常重要。

TERM=xterm-256color 的是为了解决远程连接用户时, 键入字符错乱的问题

方法2

ssh 连接时, 使用命令行 -o 选项设置环境变量: ssh -o SetEnv="TERM=xterm-256color" user@hostname

SSH 上传下载

上传

上传本地文件到服务器

格式:scp 要上传的文件路径 用户名@服务器地址:服务器保存路径

例如:把本机 /home/test.txt 文件上传到 192.168.0.101 这台服务器上的 /data/ 目录中

1
scp /home/test.txt root@192.168.0.101:/data/

上传目录到服务器

格式:scp -r 要上传的目录 用户名@服务器地址:服务器的保存目录

例如:把 /home 目录上传到服务器的 /data/ 目录

1
scp -r /home root@192.168.0.101:/data/

下载

从服务器上下载文件

格式:scp 用户名@服务器地址:要下载的文件路径 保存文件的文件夹路径

例如:把 192.168.0.101 上的 /data/test.txt 的文件下载到 /home(本地目录)

1
scp root@192.168.0.101:/data/test.txt /home

从服务器下载整个目录

格式:scp -r 用户名@服务器地址:要下载的服务器目录 保存下载的目录

例如:把 192.168.0.101 上的 /data 目录下载到 /home(本地目录)

1
scp -r root@192.168.0.101:/data  /home/

注:目标服务器要开启写入权限。

访问服务器的 127.0.0.1:port

假设目标服务器的 ip 地址为: 192.168.32.32, port 为 8080

则在本地的浏览器地址栏输入: <ip>:<port>, 这里输入: 192.168.32.32:8080

设置特定用户的sshd_config

1
2
Match User <用户名>
PasswordAuthentication yes

FAQ

ssh 连接 remote host identification has changed

找到.ssh目录,下面有一个known_hosts文件,删除 ~/.ssh/known_hosts 文件,或者如果你可以判断出known_hosts中原ssh服务器的公钥,删去那部分,

Double and random letters when typing on a SSH MacOS -> Ubuntu connection

这里, 设置远程机器的 TERM 变量为 xterm-256color.