美文网首页
面向开发工程师的 ssh 技巧

面向开发工程师的 ssh 技巧

作者: whyreal | 来源:发表于2021-06-01 13:48 被阅读0次

    你不需要一个图形化的ssh客户端

    这篇不是 ssh 入门教程,我不会告诉你 ssh 怎么装,配置文件在哪,而且讲解也不会特别细致。
    如果你对教程内容感兴趣,可以自己去 baidu 相关内容,哦不,不要用baidu,还是用 bing 吧。

    作为一个开发工程师,在你的职业生涯里无论如何避免不了和服务器打交道,尤其是 Linux。你无论如何都需要一个好用的 ssh 客户端。

    你是否曾经苦苦寻觅一个好用的图形 ssh 客户端,但是你找到了吗?我估计没有,因为市面上根本就没有一个好用的图形化的 ssh 客户端。不管是商业产品,还是开源产品,一个能打的都没有。需求不复杂的情况,还勉强可以用用,一旦有个稍微高级的需求就抓瞎了。

    但是,我们真的需要一个图形化的 ssh 客户端吗?不,不需要。那,不用 xshell ,不用 putty,那用啥?我建议你试试命令行版本的 ssh。也许你只是不大喜欢那些黑漆漆,丑哈哈的窗口,没关系,当你真正体会到命令行的强大,你也许就不会在意他的外表了。

    我们来设计一个简单的场景,看看 ssh 能帮我们做什么。

    假设,你在 aliyun 上有两台服务器,一台 app,一台 db,但是只有一个公网ip,现在你要连db 服务器,通常会怎么做?先 ssh 到 app server,然后再 ssh 到 db server。中间你可能会输入两次密码。如果密码比较复杂,你可能要切换到一个编辑器,从你的密码文件中复制一下密码。

    如果你要拷贝一个文件到 db server,也需要先拷到 app server 上,然后 登上 app server,再把文件拷贝到 db server。

    很烦对不对,我们看看这些流程中有什么痛点:

    1. 每次连接都要输入密码,重开一个 session 也需要输入密码。烦。
    2. 每次连接 db server 都要先连接 app server,然后再ssh 到 db server。烦。
    3. mysql 命令行太难用。烦。要是能用本机的mysql 开发工具直接连数据库就好了。

    下面我们看看如何解决这些问题。

    免密登录

    输密码?不存在的,ssh 支持免密登录。你不需要每次都到密码文件里复制粘贴。

    你需要使用 ssh-genkey 生成一组 key,然后使用 ssh-copy-id 将公钥传到目标服务器上。配置好之后再连接服务器就不需要输入密码了。 ssh 的时候,你可以使用 -i 参数指定私钥的位置,也可以通过配置文件进行设置:

    host app-server
        hostname 47.28.xx.xx
        IdentityFile ~/.ssh/key
    

    说明

    • host: ip,hostname,或者自定义的名称

      if(配置中没有 hostname 设置){
          使用 host 的值作为 ip 或 主机名进行连接
      } else {
          使用 hostname 的值作为 ip 或 主机名进行连接
          此时,host 只是一个逻辑名称,用来区分不同主机的配置
      }
      
    • hostname: 设定真实的 ip 或 主机名

    • ProxyJump:设置 ssh 中转服务器

    • IdentityFile:设置 key 路径

    • Port:设置连接端口

    连接复用

    有些时候,即便配置了免密登录,连服务器还是很慢,怎么办?除了优化 ssh server 的配置,你还可以使用ssh 的连接复用功能。

    ssh 支持连接复用,也就是说,只要你连上服务器,想再开一个 session 的时候,可以复用之前的连接,而不用创建一个新的连接,这样新开 session 基本可以秒开。但是这时候用命令行参数就比较麻烦了,最好是在 ssh 的配置文件里进行设置。例如:

    ControlMaster auto
    ControlPersist yes
    ControlPath /tmp/ssh.%h:%p.%r
    

    ControlPath 用来设置复用连接的 socket 文件的路径。都是临时文件,连接断掉这些文件会自动删除。放到一个你觉得合适的路径即可。

    JUMP!JUMP!JUMP!

    目标服务器无法直接连接,这种情况非常常见。这时候我们需要通过其他服务器进行中转,这些用来中转的服务器通常被称作“跳板机”。 ssh 本身就支持通过跳板机连接服务器。

    ssh -J Jump-Server1 Target-Server
    

    你不需要手动一个一个的登录服务器。我们的场景中你可以这样登录db server:

    ssh -J app-server db-server
    

    如果需要通过多个跳板机连接服务器也不是问题,使用多个 -J 即可,但是要注意先后顺序

    ssh -J Jump-Server1 -J Jump-Server2 -J Jump-Server... Target-Server
    

    而且,只要沿途的服务器上都有你的key,一条命令就可以让你直达目标服务器。哪个图形化的客户端能实现这样的功能?即便能,会比一条命令更加优雅吗?

    同样,JUMP 也可以在配置文件中进行设置:

    host jump-server1
        hostname 47.28.xx.xx
        ...
    host jump-server2
        hostname 192.168.xx.xx
        ProxyJump jump-server1
        ...
    host db-server
        hostname 172.30.xx.xx
        ProxyJump jump-server2
        ...
    

    然后就可以通过 ssh db-server 直接连接了

    隧道-端口映射

    隧道很难理解对吧,那“端口映射”听上去是不是熟悉一些?我们可以通过 ssh 把服务器上的任意端口映射到自己的机器上,比如:mysql。端口映射好之后,随便你用什么工具连数据库都可以。命令的格式是这样的:

    ssh -NfL [本地IP:]本地端口:服务ip:服务端口 server
    

    举个例子:我要把远程的 mysql 映射到本机:

    ssh -NfL 6666:127.0.0.1:3306 db-server
    

    这里的 127.0.0.1 是指服务器上的 127 而不是你机器上那个 127

    这里有一个技巧,要映射的端口不必在目标服务器上,只要目标服务器能访问到就可以映射。上面这条命令可以等价的改写成:

    ssh -NfL 6666:172.30.xx.xx:3306 jump-server2

    看到两条命令的不同了吗?

    除了可以把服务器上的端口映射到本机,也可以把本机的端口映射到服务器上!!不常用,这里就不介绍了

    隧道-socks

    除了做端口映射,ssh 还可以用来创建 socks 代理。socks 代理能干啥?通常是配置在浏览器里,让你的浏览器可以访问服务器上的 web 服务。

    ssh -NfD 本地端口 目标服务器
    

    例如:

    ssh -NfD 10000 app-server
    

    然后,你可以在浏览器上使用 127.0.0.1:10000 作为 socks 代理,就可以访问 app server 上的web 服务了。

    文件传输

    scp 和 sftp 这两个工具,都是用来传输文件的。而且会随着 ssh 一起被安装。虽然两者的操作方式不太相同,但我认为最大的不同可能是 sftp 支持断点续传。

    scp 和 sftp 都受益于上面介绍的免密、连接复用、jump、隧道等技术,可以实现免密,免中转,直接与目标服务器进行文件交换。

    脚本化

    命令好长,记不住啊!是的,的确是记不住,但是也不需要记啊。绝大多数的命令行参数都可以写在配置文件里,如果懒到连ip也不想输(跟我一样)。。。

    你写代码的时候遇到一大段需要复用的代码通常会怎么办?当然,复制粘贴是可以的,但是正常人通常会写个类写个函数啥的,把它封装一下对吧?

    那。。。当然是把复杂的命令写成脚本啦。

    不会写脚本咋办?不难的,你可以把每一个命令及其参数的组合看成是一个 API,脚本也无非是调用几个API 而已。不是不会,只是不熟而已。

    你可以把前面的 ssh 命令放在一个叫做 dbserver.sh 的脚本中(随便什么名字),然后加个可执行权限,再把脚本放在 $PATH 路径上。你就可以在任何目录里很方便的登录服务器,或者创建隧道了。不需要记 ip,不需要查密码。

    可编程

    ssh 除了可以让你交互式的操作服务器以外,还可以进行非交互式操作。例如,你想看下服务器上的时间,你不需要登录到服务器:

    # ssh 目标服务器 命令
    ssh db-server date
    

    命令行真正强大的地方是可编程。如果你想让 xshell 执行一些批量操作,怎么弄?没法弄!但是命令行可以。

    jenkins 都用过吧,如果你只是要完成一些简单的部署任务,你不需要搭一个jenkins 。几行脚本就能搞定

    #!/bin/bash
    
    cd 工程目录
    
    # 打包
    mvn package 或者 yarn ...
    # 部署
    scp package remote-server:/path/to/projects
    # 重启服务
    ssh remote-server restart service
    

    看见了?我们的 jenkins 不也就干了这点儿事吗?无非有个 web 界面,大家可以一起用而已。

    如何获得 ssh

    • win10 已经自带了 openssh,但是默认可能没有安装
    • 如果希望获得更加完整的 Unix like 使用体验,win10 用户可以考虑 WSL2
    • 如果你不喜欢 WSL2,又或者是一个顽固的 Win7 支持者,可以考虑 cmder、ConEmu 等第三方的终端模拟器
    • 甚至是 git-bash 也是可以的。

    不同方式安装的 ssh,其配置文件的路径可能不大一样。

    总结

    图形化的软件可以让你相对容易上手,如果只是简单用用,是非常好的选择。

    但是这些软件同时也限制了你的想象力。高级的事情做不了,自动化的事情做不了。你现在用 xshell,明天不能用了怎么办,或者又出了个更牛的 xxxxshell,你是不是要重新学习一下呢?但是命令行不一样,除非你有一天不需要和服务器打交道了,我保证在你有限的生命里,ssh 命令会一直在那里,他的行为不会改变,配置方式不会改变,你也不需要重新学习。

    附录

    最后,给一个相对完整的配置文件示例:

    # 全局配置
    Host *
        ControlPath /tmp/ssh.%h:%p.%r
        ControlMaster auto
        ControlPersist yes
    
        UserKnownHostsFile /dev/null
        GlobalKnownHostsFile /dev/null
    
        StrictHostKeyChecking no
        AddKeysToAgent yes
        PubkeyAcceptedKeyTypes +ssh-dss
        ForwardAgent yes
    
        # 保持连接
        TCPKeepAlive yes
        #ServerAliveCountMax 300
        ServerAliveInterval 30
    
        ForwardX11 yes
        ForwardX11Trusted yes
    
        CheckHostIP no
        Compression yes
        IPQos lowdelay
        LogLevel QUIET
    
    # server group 1
    Host sg1.*
        IdentityFile ~/.ssh/zkzy
        user root
    
    Host sg1.172.16.103.11
        port 5811
        hostname 192.168.80.100
    Host sg1.172.16.103.* !sg1.172.16.103.11
        ProxyJump sg1.172.16.103.11
    
    Host sg1.172.16.103.12
        Hostname 172.16.103.12
    Host sg1.172.16.103.13
        Hostname 172.16.103.13
    

    相关文章

      网友评论

          本文标题:面向开发工程师的 ssh 技巧

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