互联网技术/SSH
SSH 是 Telnet 和 rsh 的安全替代方案。客户端和服务器之间的所有通信都是加密的。要访问大多数 Unix 操作系统中的 SSH 客户端(通常是 OpenSSH),请在终端窗口中键入 ssh [email protected]
。如果您没有指定用户名,则将使用输入命令的用户($USER
)。在 Windows 中,您需要下载第三方实用程序,例如 PuTTY 或 Cygwin。在 ssh(1) 手册页中查找更多信息。在其他操作系统(例如智能手机)上,您需要使用基于 Web 的客户端。Android 上有几个 SSH 应用,包括 ConnectBot、Dropbear、ServerAssistant 和 Telnet / SSH Simple Client。
SSH 实际上不仅仅是一种安全访问远程 shell 的方式。它可以用于许多其他方式来安全地传输信息。
安全 shell 客户端方便地称为 ssh
。它通常用于访问远程主机。ssh
的典型用法是
ssh user@host
这意味着客户端打算以 user
身份登录 host
机器。身份验证成功后,将在客户端和 host
之间建立 SSH 会话。
Rsync 和 SFTP 是两种推荐的文件传输方式,因为 SCP 存在无法修复的缺陷。
SFTP 与 FTP 无关。SFTP 只是像 FTP 一样工作,这意味着您像使用 FTP 一样使用它。使用 SFTP 只需要 SSH 服务器。FTP 服务器与 SFTP 无关。文件默认以二进制方式传输。
sftp user@host
"rsync" 不是 SSH 套件的一部分,但几乎无处不在。它使用 SSH 在传输到或从远程系统时保护连接。
rsync file user@host:/path/
或者
rsync user@host:/path/file .
"rsync" 最好的部分之一是它只传输任何更改,如果目标上有文件的早期版本。这节省了时间和带宽。"rsync" 有很多有用的选项,包括 -a 选项,它将递归复制与保留时间、属性、所有者和组等结合在一起。
SSH 套件仍然包含一个简洁的实用程序 "scp",它代表安全复制,它有一种很棒的方式在机器之间复制文件。在最近的版本中,它是 SFTP 的包装器,但它几乎完全像默认的 unix cp
命令一样工作。scp
还允许您将文件从远程主机复制到远程主机。scp
的示例
scp [email protected]:~/files/ .
,这意味着将文件从 host.com 机器上用户主目录中的 files/
目录(它将复制 files/
目录中的所有文件)复制到 CWD(当前工作目录)。
另一个很好的用途是使用它来加密从一台机器到另一台机器的任何数据的传输。作为一个极端的例子,您可以使用 SSH 将磁盘从一台机器远程移动到另一台机器(类似于 ghost,但安全)。这可能不是 SSH 的最佳用途,也不是通过网络传输数据的最快方式,但它表明 SSH 非常强大。
scp
,即安全复制,就像 rcp
一样工作。
- 复制到远程主机 - 您必须使用冒号。REMOTE_PATH 不是必需的,所有 REMOTE_PATH 都相对于用户的主目录。
scp FILE_PATH user@host:REMOTE_PATH
- 从远程主机复制,
scp user@host:REMOTE_PATH LOCAL_PATH
注意:如果您的文件名包含空格,请按如下方式使用 scp:-
- 文件名是 /media/sda6/Tutorials/Linux Unix/linux_book.pdf,目标目录是 home/narendra/data
$scp user@host:"/media/sda6/Tutorials/Linux\\ Unix/linux_book.pdf" /home/narendra/data
- 文件名是 /home/narendra/linux_book.pdf,目标目录是 /media/Tutorials/Linux Unix/
- $
scp /home/narendra/linux_book.pdf user@host:"/media/Tutorials/Linux\\ Unix/"
- $
注意:如果要复制整个目录,请使用
scp -r user@host:"<syntaxhighlight_dirname>" <destination_dirname>
尽管 SSH 可以与密码一起使用,但不建议这样做,并且许多服务器不允许密码登录。相反,请使用密钥 - 这更安全,也更方便。
要创建 SSH 密钥,
大多数现代 Unix 系统都包含 OpenSSH 客户端。要生成密钥,请运行
$ ssh-keygen
这会将您的私钥存储在$HOME/.ssh/id_rsa,并将您的公钥存储在$HOME/.ssh/id_rsa.pub中。您可以使用不同的文件名,但这些是默认文件名,因此最好不要更改它们。
由于私钥的安全至关重要,因此如果文件权限不安全,SSH 将无法正常工作。SSH 会以适当的权限创建文件和目录,但有时会出错。要解决权限问题,请
$ chmod 600 ~/.ssh/KEY ~/.ssh/KEY.pub $ chmod 700 ~/.ssh
要使用 SSH 密钥登录远程服务器,您需要将公钥放入该服务器的授权密钥列表中。
换句话说,您需要将本地 ~/.ssh/id_rsa.pub
文件的副本追加到远程 ~/.ssh/authorized_keys
文件的末尾。
最简单的方法是使用 ssh-copy-id
。这需要某种替代身份验证形式,通常是密码(因为您在服务器上还没有密钥,所以您还不能使用密钥身份验证)。
ssh-copy-id -i ~/.ssh/KEY [email protected]
传输方法 B:分步操作
[edit | edit source]手动执行上述 ssh-copy-id
命令自动完成的每个步骤,是另一种实现方式。
- 首先,在目标服务器上创建远程
~/.ssh
文件夹(如果它不存在)。
ssh user@host "mkdir ~/.ssh && chmod 700 ~/.ssh"
- 接下来,仅上传您的公钥(而不是私钥)。
cd ~/.ssh
sftp [email protected]:.ssh
put KEY.pub
- 然后,将您的公钥追加到服务器的授权密钥列表。
ssh [email protected]
cat ~/.ssh/KEY.pub >> ~/.ssh/authorized_keys
rm ~/.ssh/KEY.pub
高级 *nix 用户可以使用一行命令完成所有这些步骤。
cat ~/.ssh/id_rsa.pub | ssh [email protected] "cat >> ~/.ssh/authorized_keys"
SSH 个人配置
[edit | edit source]您不需要设置~/.ssh/config文件,但它使身份验证更容易。重要的是指定您的用户名和私钥 - 如果在配置文件中指定了这些信息,则无需在命令行中提供。使用 HostName,您可以将 ssh 命令缩短为
$ ssh servername
示例
[edit | edit source]#Specific configuration applied to one host #This configuration applies specifically to a host which uses Windows Domain login Host Short_Name HostName server1.example.com User domain\username IdentityFile ~/.ssh/KEY # Use this login as default for all hosts in the one domain # It will look for a key with the hostname in the key's file name Host *.example.com User domain\username IdentityFile ~/.ssh/%h_KEY # Generic configuration that applies to my private LAN. # Of note, the options to forward X11 lets you run remote graphical # programs while viewing and interacting with them locally. Host localnetwork 192.168.1.0/24 User USERNAME IdentityFile ~/.ssh/key_37_rsa AddKeysToAgent yes ForwardX11 yes # In a pesky lab environment, add the following to your config # CheckHostIP no # Catch-all settings which apply these settings to all hosts, # if the particular option has not yet already been set. # If there are a lot of keys in the SSH agent, then IdentitiesOnly is needed Host * IdentitiesOnly yes ServerAliveCountMax 2 ServerAliveInterval 20
现在,您只需使用 ssh Short_Name
即可登录到 server1.example.com
。配置选项根据首次匹配原则进行选择,因此将非常具体的规则放在前面,将更一般的规则放在后面。
使用 SSH 代理
[edit | edit source]如今,大多数桌面环境都会自动提供 SSH 代理。因此,如果您想查看详细信息,请查找以下环境变量$SSH_AUTH_SOCK和$SSH_AGENT_PID,尽管只有前者用于连接到它,并且必须在任何需要连接到代理的程序中可用。
可以轻松地手动将密钥添加到代理中,
ssh-add ~/.ssh/KEY
或者,可以通过在客户端配置文件中相应规则集中将 AddKeysToAgent 设置为 "yes",在首次使用时自动添加密钥。
但是,请记住,当代理中的密钥超过六个时,需要采取特殊措施来防止代理以错误的顺序尝试错误的密钥,从而阻止登录。具体来说,应为每个主机将 IdentitiesOnly 设置为 "yes",理想情况下使用客户端配置文件。见下文。
公钥加密
[edit | edit source]SSH 与 Telnet 和 "rsh" 之间最显著的差异在于安全性。SSH 使用 RSA、EcDSA 或 Ed25519 进行 公钥加密.
- 您尝试连接的服务器或域会为客户端生成一对密钥(公钥和私钥)。
- 客户端首次尝试连接时,会获得公钥。相应的私钥是秘密的,并保存在服务器中。
- 客户端通过公钥加密数据包,然后使用存储的相应私钥解密数据。
服务器到客户端的通信也是以相同的方式进行的 - 服务器使用客户端的公钥加密,客户端使用其私钥解密。
使用公钥加密设置 OpenSSH
[edit | edit source]以下假设可以物理访问服务器或某些等效的带外方式。
使用发行版的软件包管理器,在服务器上安装 sshd(或 openssh-server),并在客户端上安装 ssh(或 openssh-client)。它们可能已经安装,因为它们通常是服务器和工作站发行版默认安装的一部分。确保以下内容位于服务器上的 /etc/ssh/sshd_config 中,并且没有被注释掉。也就是说,它们前面没有 #。
PubkeyAuthentication yes PasswordAuthentication no
- 在服务器上,
- 为传入连接在服务器上打开 TCP 端口 22。这取决于您的防火墙。非标准端口。
- 如果服务器位于使用 DHCP 的路由器后面
- 停止使用 DHCP 并为服务器分配静态 IP 地址。如果您不知道如何操作,请查看 Gentoo 手册或 Arch Linux Wiki 以获取说明。
- 在路由器上将外部 TCP 端口 22(或其他端口)转发到服务器上的端口 22。
- 在客户端上,创建并测试客户端密钥对
- 在客户端命令行上,运行
ssh-keygen -f ~/.ssh/server.key
("rsa" 是默认值,不需要显式指定 "rsa")。考虑使用-C
选项对密钥对进行注释。 - 将公钥复制到可移动介质,并将该介质传输到服务器并将其挂载。将公钥复制到服务器,例如复制到 ~/.ssh/server.key。然后将密钥追加到 authorized_keys 文件,
cat ~/.ssh/server.key >> ~/.ssh/authorized_keys
- 返回客户端,测试新密钥是否有效:
ssh -i ~/.ssh/server.key serve.example.com
- 在客户端命令行上,运行
- (重新)启动 sshd 服务。
- 使用密钥再次从客户端登录
提示:如果您在服务器上登录的用户名与您当前在客户端上使用的用户名相同,则无需指定要在服务器上登录的用户名。
SSH 作为代理
[edit | edit source]如果您能够建立 SSH 连接,则可以(很可能)使用该连接作为 SOCKS5 代理,而无需在远程计算机上进行任何额外设置。然后,流量可以通过 SSH 连接安全地进行隧道传输。如果您处于无线连接中,则可以使用此方法有效地保护您的所有流量免受窥探。您还可以使用此方法绕过 IP 限制,因为您将显示为从远程计算机连接。请注意,除非采取特定的措施,否则 DNS 流量不会通过隧道传输。
选择一个较大的端口号(大于 1024,因此您可以以非 root 用户身份使用它)。这里我选择 1080,这是标准的 SOCKS 端口。使用 -D
选项进行动态端口转发。
ssh -D 1080 user@host
就是这样。现在,只要 SSH 连接保持打开状态,您的应用程序就可以使用您自己的计算机(localhost)上端口 1080 上的 SOCKS 代理。例如,在 Linux 上的 Firefox 中
- 转到编辑 -> 首选项 -> 高级 -> 网络 -> 连接 -> 设置...
- 选中 "手动代理配置"
- 确保 "对所有协议使用此代理服务器" 已清除
- 清除 "HTTP 代理"、"SSL 代理"、"FTP 代理" 和 "Gopher 代理" 字段
- 在 "SOCKS 主机" 中输入 "127.0.0.1",并在 "端口" 中输入 "1080"(或您选择的任何端口)。
从您的 Web 浏览器使用 SSH
[edit | edit source]即使您没有安全的 shell 客户端,您也可以在支持 JavaScript 的 Web 浏览器中使用 SSH。为此,您必须在运行 SSH 服务器的系统上安装 AnyTerm、AjaxTerm 或 WebShell,或者使用第三方服务,例如 WebSSH.
SSH 反向隧道
[edit | edit source]反向隧道允许您使用远程机器(例如,位于AWS上)作为您本地机器的入口点。 因此,对远程机器 IP 上特定端口的请求将被转发到您的本地机器,并返回响应。 它被称为反向隧道,因为这并非您的本地机器将数据发送到该端口上的远程机器,而是从远程机器到本地机器。
用例:如果您的计算机位于NAT 后面 - 没有公网 IP 地址(或没有本地静态 IP 地址) - 但您仍然希望让您的本地 HTTP 服务器或某些数据库或其他特定服务对公众可用。
另一个用例:如果进行种子,因为使用公网 IP 地址,更多计算机将能够获取您的合法数据。
这样的命令可以设置一个反向隧道,其中远程机器上的 63368 端口通过 SSH 反向隧道转发回源机器上的 8000 端口,通过 4160 端口连接的 SSH。
ssh -R 63368:localhost:8000 -p 4160 host.example.net
格式为
ssh -R port-incoming:localhost:port-local -p port-for-for-connecting host.example.net
远程机器的/etc/ssh/sshd_config 可以包含以下内容
AllowTcpForwarding yes
AllowAgentForwarding no
AllowStreamLocalForwarding yes
PermitTunnel yes
GatewayPorts yes # optional, for external visibility
进一步阅读
[edit | edit source]- OpenSSH 维基教科书
- https://man.openbsd.org/ssh, https://man.openbsd.org/ssh_config
- LPI Linux 认证/安全 Shell (SSH)
- 构建 Beowulf 集群/安装、配置和管理/共享目录和 SSH
- "Mediawiki: 在 Gerrit 中设置 SSH 密钥" 包含关于设置 SSH 密钥的分步教程。
- ArchWiki: OpenSSH
- Gentoo 手册: SSH
- SSH 反向隧道:从云获取静态 IP
- "Github: 生成 SSH 密钥" 包含另一个关于设置 SSH 密钥的分步教程。
- "如何在 Ubuntu 20.04 上设置 SSH 密钥" 包含类似的关于设置 SSH 密钥的分步教程。
- "Ubuntu: SSH/OpenSSH/Keys" 包含类似的关于设置 SSH 密钥的分步教程。
- "通过 SSH 配置 Git 以一次登录" 描述了如何使用 ssh-agent(在 macOS 和 Linux 系统上)在每次会话中解锁一次密码保护的私钥,而不是在每次使用密钥进行推送或拉取时都解锁。