ssh 和 的原理是什么, 怎么样运用了 tunnel

ssh 和 tls 的关系是啥

  • ssh 是 应用层 的 protocol
  • TLS 是 传输层 的 protocol
  • ssh 自己就是个安全的协议 (ssh is secure by default)
  • ssh 和 tls 都是使用了 public key pair 这一套来完成钥匙协商的
    • ssh 没有用 tls 这样的 handshake (tls handshake 的目的是啥? 钥匙协商吗? 那为什么 ssh 不用握手都可以实现钥匙协商呢?)
    • ssh is self-contained, 不依赖 ssl cert, 也就不依赖 CA 这些第三方

Note

本质上 ssh 和 tls 没啥关系, 唯一的联系是, 两者都是用了 public key pair 来实现 cryptography 的 network protocol

ssh 使用

账号密码登录

 Systems which require access for many users from many varying locations often permit password auth simply to reduce the administrative burden and to maximize access.

Note

ssh 用账号密码登录的时候, 是不要求客户端有自己的 public / private key pair 的.

public key 登录

password authentication:

  • pros: easy to set up
  • cons: allows brute-force password guessing; password must be entered every time; user might have the same password for different system, if one leaks, others are at risk … To counteract the shortcomings of password authentication, ssh supports public key access.
  • An Illustrated Guide to SSH Agent Forwarding

前期准备

  • client 生成 private / public key pair
  • client 把自己的 public key 拷贝到 $HOME/.ssh/authorized_keys 里 ^copy-key
    • ssh-copy-id user@server 首次使用的时候, 是要已经知道 server 的账号密码才可以的复制过去, 复制的地址就是 authorized_keys
    • 或者直接用 scp 来 copy
    • 不 copy 的话, 每次都要账号密码登录

流程

分成两个阶段:

  1. 协商密钥
  2. 相互验证

协商密钥

建立连接

  • client (OpenSSH, Putty) 发起 TCP 连接, 请求发到服务端的 port 22
  • 建立三次握手, 确立网络连接 版本协商
  • 服务器返回:
  • 客户端检查服务器公钥是否在 known_hosts 文件中
  • 首次连接时,需要用户手动确认服务器身份; 手动确认之后会放到 known_hosts 里 加密密钥协商
  • 使用 Diffie-Hellman (DH) 或椭圆曲线 Diffie-Hellman (ECDH) 算法 DH explanation
  • 后续所有通信都使用协商的密钥加密

验证客户端

服务端验证客户端身份

  • 客户端发送自己的 公钥 id (不是公钥, 公钥要提前拷贝到server ^copy-key)
  • 服务器检查客户端的公钥是否在 authorized_keys 文件中
  • 如果公钥不存在,有两种可能:
    1. 要求使用用户名和密码登录
    2. 如果服务器禁止密码登录,则拒绝连接
  • 服务端生成随机数, 用客户端的公钥加密 (random challenge)
  • 客户端解密, 结合 随机数 和 share session key, 生成 MD5 hash value
  • 客户端发送这个 MD5 hash value 给服务端
  • 服务端自己也会计算这个 MD5 hash value, 比较自己计算的和客户端计算的 验证成功, 开始 ssh session

other reference:

图解

ssh-flow.excalidraw

⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠ You can decompress Drawing data with the command palette: ‘Decompress current Excalidraw file’. For more info check in plugin settings under ‘Saving’

Excalidraw Data

Text Elements

client

server

TCP handshake SYN ACK all that good stuff

SSH version server pub key

check known_hosts

is server’s pub key in known_hosts?

proceed

ask if user wants to trust

save to known_hosts

abort

yes

no

yes

no

proceed

DH key negotiation

client pub key id

check authorized_keys

Key negotiation stage

check if client key id in authorized_keys

proceed

if password auth is allowed

prompting client for username and password

abort

yes

no

yes

no

proceed

generates random number, encrypted with client pub key

random challenge

decrypts challenges, MD5 hash(session_key, random_num)

MD5 hash value

calculates its own MD5 hash(session_key, random_num)

compare 2 hash values, decides whether auth passed

Client authentication stage [everything is encrypted here]

Link to original

others

fingerprint
  • 客户端验证服务端 的时候, 如果服务端的 pub key 不在 客户端的 known_hosts 里, 会有这个提示:
$ ssh [email protected]
The authenticity of host '192.168.0.4 (192.168.0.4)' can't be established.
ED25519 key fingerprint is SHA256:5lkC61T+vQ7mR4INcwBktQaolmAswQx9bws/cT+A/Kc.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? 
  • 里面的 fingerprint 是什么?
    • “a short version of server’s public key” 是个 public key 的 hash value - Public key fingerprint
    • 目的是: pub key 很长, 也不 human friendly; 通过 hash function 生成个短的 fingerprint, 用 hexadecimal 展示出来, 便于 human inspection

“This process produces a short fingerprint which can be used to authenticate a much larger public key. For example, whereas a typical RSA public key will be 2048 bits in length or longer, typical MD5 or SHA-1 fingerprints are only 128 or 160 bits in length.”

pub/pri key pair 在这里是什么作用?

用了 DH 是不是就不需要 pub/pri key pair 了?

问题:

  • 在上面这个过程里, 好像没有用到 客户端 和 服务端 的 pub/pri key pair?
  • 每次对话的 key pair 都是随机生成的, 为什么还需要 persistent 的 key pair 呢?
    因为需要验证 服务器的身份
  • 临时的密钥只是用来建立一个安全的加密通道的 (钥匙协商), 并不能验证服务器的身份
  • 所以还是要有 pub/pri pair 来确定客户端连接的服务器是 真正的服务器
Link to original

  • 在 ssh 里, 客户端 会把 服务端的 pub key 储存在 $HOME/.ssh/known_hosts
    • 服务端的 pub key 是长期不变的, 不是用于钥匙协商的 ephemeral key
  • 在 key exchange 过后, 服务端的 私钥 会参与签名
    1. 通过 DH 交换的密钥生成个 hash value
      • H = hash(KEX_INIT_MSG, SERVER_PUBLIC_HOST_KEY, DH_SHARED_SECRET_K, SESSION_ID)
        • H → 计算的哈希值,包含
        • KEX_INIT_MSG(密钥交换的初始化消息)
        • SERVER_PUBLIC_HOST_KEY(服务器的公钥)
        • DH_SHARED_SECRET_K(Diffie-Hellman 计算出的共享密钥)
        • SESSION_ID(用于防止重放攻击)
    2. server 用自己的 private key 再给上面生成的 hash value 加密一次
      • 签名的本质是 server 的 private key 对 由信息生成的 hash value 进行处理的过程
      • Signature = sign(Host_Private_Key, H)
    3. server 把 Server_Public_Key, Signature 一起发给 client
    4. client 查看 server pub key 是否在 known_hosts
      • 不在的话会问 用户, 是否要相信这个 pub key

ssh agent forwarding

ssh agent

It’s a program that runs in the background and keeps your key loaded into memory, so that you don’t need to enter your passphrase every time you need to use the key. The nifty thing is, you can choose to let servers access your local ssh-agent as if they were already running on the server.

SSH agent forwarding can be used to make deploying to a server simple. It allows you to use your local SSH keys instead of leaving keys (without passphrases!) sitting on your server.

todo

ssh 是第几层的 tunneling? ssh 一定用到了 tunneling 吗?

ssh 工作流程: 建立连接 密钥交换 身份验证 通信

  • client 尝试建立连接
  • server 发送公钥给 sender
  • 类似于 TLS 的交换钥匙

ssh 和 https 不同的是, ssh 是双向认证的, 两对 public-private key; https 一般只是 client 验证 server.

啥叫 port forwarding

ssh 的密码和 keys 分别是怎么工作的

  • 已经连接过的 client 的 public key 会被 server 存到 ~/.ssh/authorized_keys 里, 以后再连接的时候, client 会和 server 进行一次 加密挑战, 就不需要账号密码登录了

ssh 里的 fingerprint 是啥 ssh 第一次连接的流程是啥? 以后连接的流程是啥? 为什么我要提前下载 eos 的 private key?

sign 和 encryption 的区别

  • The purpose of signing is authentication and integrity verification, not confidentiality
  • Encrypting transforms data to make it unreadable to anyone without the proper key, the purpose is confidentiality