互联网技术/SSH
SSH 是 Telnet 和 rsh 的安全替代品。客户端和服务器之间的所有通信都经过加密。要访问大多数 Unix 操作系统中的 SSH 客户端(通常是 OpenSSH),在终端窗口中键入 ssh [email protected]
。如果您没有指定用户名,将使用输入命令的用户($USER
)。在 Windows 中,您需要下载第三方实用程序,例如 PuTTY 或 Cygwin。在 ssh(1) 手册页中查找更多信息。在其他操作系统(例如智能手机)上,您必须使用基于 Web 的客户端。Android 上有几个 SSH 应用程序,包括 ConnectBot、Dropbear、ServerAssistant 和 Telnet/SSH 简单客户端。
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]
手动执行上述 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”(或你选择的任何端口)。
从你的网络浏览器中使用 SSH
[edit | edit source]即使你没有安全的 shell 客户端,你也可以使用支持 javascript 的网络浏览器从网络浏览器中使用 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 密钥的分步教程。
- "配置 Git 通过 SSH 登录一次" 描述了如何在 macOS 和 Linux 系统上使用 ssh-agent,在每个会话中解锁一次受密码保护的私钥,而不是每次使用该密钥进行推送或拉取时都解锁一次。