美文网首页
SSH协议详解 2021-08-24

SSH协议详解 2021-08-24

作者: 9_SooHyun | 来源:发表于2021-08-24 22:51 被阅读0次
    • SSH authentication with SSH keys

      Abstract:
      The idea is to have a cryptographic key pair - public key and private key - and configure the public key on a server to authorize access and grant anyone who has a copy of the private key access to the server.
      Host keys authenticate hosts. Authorized keys and identity keys authenticate users.

    使用ssh key实现远程免密登录涉及以下步骤:

    • 公私钥生成与公钥部署ssh client 生成公私钥,生成公私钥使用ssh-keygen,例如ssh-keygen -t rsa -C "costumed_comment(such as your email address)"
      然后把公钥的内容追加到 ssh server指定用户的~/.ssh/authorized_keys。
      The public key can then be installed as an authorized key on a server using the ssh-copy-id
      如将公钥内容追加到root用户的/root/.ssh/authorized_keys,表示该公钥已被root用户认证可信
    • ssh client配置~/.ssh/config文件(可选,推荐)。配置~/.ssh/config可以针对不同的remote目标机器设置不同的登录配置,如配置hostname(真实地址)、IP、端口、指定登录方式(密码\ssh key\etc)和私钥文件等
      eg.配置如下config
    # Read more about SSH config files: https://linux.die.net/man/5/ssh_config
    Host devmachine
        HostName 9.9.9.9
        Port 99999
        User root
        PreferredAuthentications publickey  
        IdentityFile /Users/dev/.ssh/id_rsa_devmachine  # 指定私钥文件
    

    配置完成后,ssh root@devmachine甚至直接ssh devmachine就能够登录上9.9.9.9。因为这个命令依据devmachine这个Host读取config内的管理配置,无需再声明IP、端口、私钥和登录用户等参数
    ssh的config文件可以存在多个,vscode安装了remote-ssh插件后可以加载ssh的config文件,实现ssh到开发机做远程开发

    如果不配置~/.ssh/config,也可以通过指定ssh参数的形式实现登录

    指定IP、端口和私钥可以登录:
    ssh -i /Users/dev/.ssh/id_rsa_devmachine root@9.9.9.9 -p 99999
    通过输入密码登录:
    ssh root@9.134.165.116 -p 36000

    一点踩坑记录:
    部分软件(如weterm、某些版本的vscode)的ssh功能在使用本地私钥时可能会报
    Error: Error while signing data with privateKey: error:06000066:public key routines:OPENSSL_internal:DECODE_ERROR
    解决方式-网上的办法是转格式
    To fix this error, we can convert the private key file from OpenSSH private key format to PEM format.
    ssh-keygen -p -m PEM -f target_id_rsa

    配置github等代码托管平台使用ssh key免密登录,具体可以参考https://docs.github.com/en/authentication/connecting-to-github-with-ssh


    ssh协议认证过程

    参考:https://xdev.in/posts/understanding-of-ssh/
    简单来说概括为以下两步:

    • ssh client验证 ssh server身份ssh client通过ssh命令发起连接请求, ssh server收到后返回自己的公钥指纹(RSA key fingerprint)。如果ssh clientssh server是首次建立连接,ssh client会收到提示如:
      The authenticity of host 'ssh-server.example.com (12.18.429.21)' can't be established.
      RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
      Are you sure you want to continue connecting (yes/no)?
      
      ssh client选择是否信任 ssh server,如果信任则会将 ssh server的公钥rsa-key写入本地的~/.ssh/known_hosts。后续ssh client再与 ssh server进行连接,则会对比连接时 ssh server发来的公钥与known_hosts中的是否一致。此时,服务端拥有客户端的公钥和本机的私钥,客户端拥有服务端的公钥和本机的私钥
    • ssh server验证 ssh client身份ssh server利用ssh client连接时指定的公钥加密一个随机数并协商会话密钥sessionkey,如果ssh client用私钥顺利解出随机数并发回ssh server,那么ssh server验证 ssh client身份完毕
    • 双向认证完毕,避免中间人(man-in-the-middle attack)攻击。双方使用sessionkey对data进行对称加密后传输

    如果配置好公私钥后,用户仍然需要使用账号密码登录,检查

      1. 检查ssh server端的/etc/ssh/sshd_config是否允许公私钥登录

      RSAAuthentication yes
      PubkeyAuthentication yes
      AuthorizedKeysFile .ssh/authorized_keys

    然后重启sshd服务
    service sshd restart

      1. 检查ssh server端的用户家目录下~.ssh是否可读写

      ls -l ~/.ssh/
      total 20
      -rw-rw-r-- 1 xiu xiu 576 Oct 18 19:25 authorized_keys
      -rw------- 1 xiu xiu 90 Oct 18 18:07 config
      -rw------- 1 xiu xiu 1675 Oct 18 18:07 id_rsa
      -rw-r--r-- 1 xiu xiu 404 Oct 18 18:07 id_rsa.pub
      -rw-r--r-- 1 xiu xiu 409 Oct 18 19:15 known_hosts

      1. 开启sshd调试模式进行进一步调试可以参考:
        https://blog.51cto.com/zouqingyun/1874410
    • 关于ssh client的配置信息

      The ssh program on a host receives its configuration from either the command line or from configuration files ~/.ssh/config and /etc/ssh/ssh_config.

      Command-line options take precedence over configuration files. The user-specific configuration file ~/.ssh/config is used next. Finally, the global /etc/ssh/ssh_config file is used. The first obtained value for each configuration parameter will be used.

    • SSH tunneling(also called SSH port forwarding,中文【端口转发】)

      包含3种端口转发,分别是Local Forwarding、Remote Forwarding和Dynamic Forwarding

      • Local Forwarding(本地端口转发到远端端口)

        In OpenSSH, local port forwarding is configured using the -L option:

        ssh -L local-port:target-host:target-port tunnel-host
        

        Eg. 设定localhost与gateway.example.com连通;而intra.example.com部署在gateway.example.com后的内网,与localhost不能互通

        ssh -L 80:intra.example.com:80 gateway.example.com
        

        This example opens a connection to the gateway.example.com jump server, and forwards any connection to port 80 on the local machine to port 80 on intra.example.com.

        上面的命令让本地的ssh client监听本地80端口,任何发往本地80端口的请求都会redirect到ssh client,然后发往ssh server即gateway.example.com,随后server将直接deliver数据到自己的80端口,完成响应后原路返回

        最终的效果是,请求http://localhost:80实际上是请求被gateway.example.com隔离的内网机器intra.example.com上部署的http://intra.example.com:80服务。这样一来,原本intra.example.com不能直接被localhost访问,但localhost通过ssh端口转发,把自己的80端口请求通过ssh连接转发到gateway.example.com:22然后再转发给intra.example.com,实现了外网对内网资源的访问

      • Remote Forwarding(远端端口转发到本地端口)

        In OpenSSH, remote SSH port forwardings are specified using the -R option. For example:

        ssh -R remote-port:target-host:target-port -N remotehost
        

        Eg.

        ssh -R 8080:localhost:80 public.example.com
        

        This allows anyone on the remote server to connect to TCP port 8080 on the remote server. The connection will then be tunneled back to the client host, and the client then makes a TCP connection to port 80 on localhost. Any other host name or IP address could be used instead of localhost to specify the host to connect to.

        与local forwarding相反,建立本地计算机到远程计算机的 SSH 隧道以后,本地转发是通过本地计算机访问远程计算机,而远程转发则是通过远程计算机访问本地计算机

        上面的命令建立了远端public.example.com到本地的ssh隧道,访问远程主机public.example.com:8080的请求,会被public.example.com经过ssh端口转发到本机,然后再转发到localhost:80

      • Dynamic Forwarding(动态端口转发)

        动态转发把本地端口绑定到 SSH 服务器就到此为止。至于 SSH 服务器要去访问哪一个网站,完全是动态的,取决于原始通信

        ssh -D local-port tunnel-host -N
        

        注意,这种转发采用了 SOCKS5 协议。访问外部网站时,需要把 HTTP 请求转成 SOCKS5 协议,才能把本地端口的请求转发出去

        SOCKS(SOCKet Secure),是一种会话层协议,主要用于客户端与外网服务器之间通讯的中间传递。当防火墙后的客户端要访问外部的服务器时,就跟SOCKS代理服务器连接。这个代理服务器控制客户端访问外网的资格,允许的话,就将客户端的请求发往外部的服务器

      note: SSH端口转发完全基于基本的SSH连接,因此,凡是可以切断SSH连接的方式都可以终止端口转发,包括但不限于通过在远程终端上执行exit命令、暴力关闭本地终端窗口、远程主机关机、本地主机关机等


    更多可以参考 https://github.com/wangdoc/ssh-tutorial

    相关文章

      网友评论

          本文标题:SSH协议详解 2021-08-24

          本文链接:https://www.haomeiwen.com/subject/exvjiltx.html