跳转到内容

互联网技术/SSH

来自维基教科书,自由的教科书,属于一个开放的世界

SSHTelnetrsh 的安全替代品。客户端和服务器之间的所有通信都经过加密。要访问大多数 Unix 操作系统中的 SSH 客户端(通常是 OpenSSH),在终端窗口中键入 ssh [email protected]。如果您没有指定用户名,将使用输入命令的用户($USER)。在 Windows 中,您需要下载第三方实用程序,例如 PuTTY 或 Cygwin。在 ssh(1) 手册页中查找更多信息。在其他操作系统(例如智能手机)上,您必须使用基于 Web 的客户端。Android 上有几个 SSH 应用程序,包括 ConnectBot、Dropbear、ServerAssistant 和 Telnet/SSH 简单客户端。

SSH 实际上远不止一种安全访问远程 shell 的方式。它可以用于许多其他安全传输信息的方式。

使用 SSH

[编辑 | 编辑源代码]

安全 shell 客户端方便地称为 ssh。它通常用于访问远程主机。ssh 的典型用法是

ssh user@host

这意味着客户端打算以 user 用户身份登录 host 机器。身份验证成功后,将在客户端和 host 之间建立 SSH 会话。

Rsync 和 SFTP 是推荐的两种传输文件的方式,因为 SCP 存在无法修复的缺陷。

使用 SFTP

[编辑 | 编辑源代码]

SFTP 与 FTP 没有任何关系。SFTP 只是像 FTP 一样工作,这意味着您可以像使用 FTP 一样使用它。使用 SFTP 只需要 SSH 服务器。FTP 服务器与 SFTP 无关。文件默认以二进制形式传输。

sftp user@host

使用 Rsync

[编辑 | 编辑源代码]

"rsync" 不属于 SSH 套件,但几乎无处不在。它在传输到或从远程系统时使用 SSH 来保护连接。

rsync file user@host:/path/

rsync user@host:/path/file .

"rsync" 最好的部分之一是它只传输任何更改,如果目标上存在文件的早期版本。这节省了时间和带宽。"rsync" 还有许多有用的选项,包括 -a 选项,它将递归复制与保留时间、属性、所有者和组等结合在一起。

使用 SCP

[编辑 | 编辑源代码]

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 可以与密码一起使用,但不建议这样做,而且许多服务器不允许使用密码登录。相反,使用密钥 - 这更安全,也更方便。

要创建 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 文件的末尾。

传输方法 A: ssh-copy-id

[编辑 | 编辑源代码]

最简单的方法是使用 ssh-copy-id。这需要某种其他形式的身份验证,通常是密码(因为您还没有在服务器上获得密钥,所以您还不能使用密钥身份验证)。

ssh-copy-id -i ~/.ssh/KEY [email protected]

传输方法 B: 分步进行

[编辑 | 编辑源代码]

手动执行上述 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”,最好使用客户端配置文件。 请参阅以下内容。

SSH 与 Telnet 和“rsh” 最大的区别在于安全性。 SSH 使用 RSAEcDSAEd25519 用于 公钥加密

  • 你尝试连接到的服务器或域会为客户端生成一对密钥(公钥和私钥)。
  • 客户端第一次尝试连接时,会获得公钥。 相应的私钥是秘密的,保存在服务器上。
  • 客户端通过使用公钥加密数据包,然后使用存储在服务器上的相应私钥解密数据。

服务器到客户端的通信也是以相同的方式进行的 - 服务器使用客户端的公钥加密,客户端使用其私钥解密。

使用公钥加密设置 OpenSSH

[edit | edit source]

以下内容假定可以物理访问服务器或某些带外等效物。

使用你发行版的包管理器,在服务器上安装 sshd(或 openssh-server),在客户端上安装 ssh(或 openssh-client)。 它们很可能已经安装,因为它们通常是服务器和工作站发行版默认安装的一部分。 确保以下内容位于服务器上的 /etc/ssh/sshd_config 中,并且未被注释掉。 也就是说,它们前面没有 #

PubkeyAuthentication yes
PasswordAuthentication no
  1. 在服务器上,
    1. 打开服务器上的 TCP 端口 22 以接收传入连接。 这取决于你的防火墙。 非标准端口。
    2. 如果服务器位于使用 DHCP 的路由器后面
      1. 停止使用 DHCP 并为你的服务器分配一个静态 IP 地址。 如果你不知道如何操作,请参阅 Gentoo 手册或 Arch Linux Wiki 获取说明。
      2. 将路由器上的外部 TCP 端口 22(或另一个端口)转发到服务器上的端口 22。
  2. 在客户端上,创建并测试客户端密钥对
    1. 在客户端命令行中,运行 ssh-keygen -f ~/.ssh/server.key(“rsa” 是默认值,不需要显式指定“rsa”)。 考虑使用 -C 选项对密钥对进行注释。
    2. 将公钥复制到可移动介质中,将该介质传输到服务器并将其挂载。 将公钥复制到服务器,例如复制到那里的 ~/.ssh/server.key 中。 然后将密钥追加到 authorized_keys 文件中,cat ~/.ssh/server.key >> ~/.ssh/authorized_keys
    3. 回到客户端,测试新密钥是否有效:ssh -i ~/.ssh/server.key serve.example.com
  3. (重新)启动 sshd 服务。
  4. 使用密钥从客户端再次登录

提示:如果你在服务器上登录的用户名与你在客户端上当前使用的用户名相同,则不需要在服务器上指定要登录的用户名。

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]
华夏公益教科书