The Go Programming Language
› http://golang.org/
› Go Playground
Go Projects
› Revel Web Framework
vimiix

写了一个 ssh 客户端,欢迎体验

  •  
  •   vimiix ·
    vimiix · Dec 15, 2023 · 5846 views
    This topic created in 1059 days ago, the information mentioned may be changed or developed.

    需求来源

    对于一个后端程序员来说,在工作中免不了要和繁杂的服务器打交道,ssh 是不可或缺的开发工具。但每次登录都需要输入密码的行为,对于认为一切皆可自动化的程序员来说,肯定是有点繁琐的(如果您是使用图形化界面的用户可忽略)。

    所以我在前段时间考虑,我应该自己实现一个 ssh 客户端,它不需要拥有许多复杂的功能,只需要满足我以下这几个需求即可满足日常使用:

    • 和 ssh 保持差不多的使用习惯
    • 仅在第一次登录时询问我密码,后续使用无需再提供密码
    • 可以给服务器它任意的标签,这样我就可以自由地通过 IP 或者标签来登录

    于是乎,近期我在业余时间就设计并编写了 ssx 这个轻量级的具有记忆的 ssh 客户端。它完美的实现了上面我所需要的功能,也已经被我愉快的应用到了日常的开发中。

    项目源码地址:https://github.com/vimiix/ssx

    使用方式

    下面就简单介绍一下 ssx 的使用方式。

    ssx 是通过 golang 开发的一个独立的二进制文件,安装方式就是从 release 页面下载对应平台的软件包,解压后把 ssx 二进制放到系统的任意目录下,这里我习惯放到 /usr/local/bin 目录下,如果你选择其他目录下,需要确保存放的目录添加到 $PATH 环境变量中,这样后续使用我们就不用再添加路径前缀,直接通过 ssx 命令就可以运行了。

    登录服务器

    使用 ssx 登录服务器的时候,基本和 ssh 使用习惯一致,下面是基本命令模式:

    ssx [-s] [USER@]HOST[:PORT] [-k IDENTITY_FILE]
    

    在这个命令中,USER 是可以省略的,如果省略则是系统当前用户名;PORT 是可以省略的,默认是 22 ,-k IDENTITY_FILE 代表如果是使用私钥登录,则通过 -k 来指定私钥的路径,也是可以省略的,默认是 ~/.ssh/id_rsa,当然了,前提是这个文件存在。所以最精简的登录命令就是:ssx <ip>

    当首次登录,不存在可用私钥时,会通过交互方式来让用户输入密码,一旦登录成功,这个密码就会被 ssx 保存到本地的数据文件中 (默认为 ~/.ssx/db, 可通过环境变量 SSX_DB_PATH 进行自定义),下次登录时,仍然执行 ssx <ip> 即可自动登录。

    注意,登录过的服务器,再次登录时,我嫌输入全部 IP 比较麻烦,所以 ssx 支持输入 IP 中的部分字符,自动搜索匹配进行登录。

    为服务器打标签

    当我们成功登录过一次服务器后,就可以通过 ssx list 命令来查看目前 ssx 存储的所有服务器列表。下面是一个列表示例:

    # output example
    # Entries (stored in ssx)
    #  ID |       Address        |          Tags
    #-----+----------------------+--------------------------
    #  1  | [email protected]:22  | centos
    

    ssx 会给每个服务器分配一个唯一的 ID ,我们在打标签时就需要通过 ID 来指定服务器条目。

    当然,既然服务器有唯一 ID ,ssx 也支持通过 ID 来进行登录:ssx -i <ID>

    打标签需要通过 ssx 的子命令 tag 来完成,下面是 tag 命令的模式:

    ssx tag -i <ENTRY_ID> [-t TAG1 [-t TAG2 ...]] [-d TAG3 [-d TAG4 ...]]
    
    • -i 指定 list 命令输出的要操作的服务器对应的 ID 字段
    • -t 指定要添加的标签名,可以多次指定就可以同时添加多个标签
    • -d 指定要删除的标签名,同样也可以多次指定

    当我们完成对服务器的打标签后,比如上面示例中的服务器,我增加了一个 centos 的标签,那么我此时就可以通过标签来进行登录了:

    // -t 可省略
    ssx [-t] centos
    

    删除服务器记录

    ssx 也支持删除服务器记录,命令如下:

    ssx delete -i <ID>
    

    一旦删除,ssx 不会保留该服务器的任何信息,所以下次登录时会等同于新的服务器来对待,ID 也会重新生成。

    目前支持的环境变量

    除了上面提到的 SSX_DB_PATH 可以指定存储数据的文件外,ssx 还支持:

    • SSX_CONNECT_TIMEOUT:SSH 连接超时时间,默认为 10s
    • SSX_IMPORT_SSH_CONFIG:是否引用用户 ssh 配置,默认为空

    这里我解释一下 SSX_IMPORT_SSH_CONFIG 的作用,这个环境变量不设置时,ssx 默认是不会读取用户的 ~/.ssh/config 文件的,ssx 只使用自己存储文件进行检索。如果将这个环境变量设置为非空(任意字符串),ssx 就会在初始化的时候加载用户 ssh 配置文件中存在的服务器条目,但 ssx 仅读取用于检索和登录,并不会将这些条目持久化到 ssx 的存储文件中,所以,如果 ssx IP 登录时,这个 IP 是 ~/.ssh/config 文件中已经配置过登录验证方式的服务器,ssx 匹配到就直接登录了。但 ssx list 查看时,该服务器会被显示到 found in ssh config 的表格中,这个表格中的条目是不具有 ID 属性的,以下是一个示例:

    export SSX_IMPORT_SSH_CONFIG=true
    ssx list
    # output example
    # Entries (stored in ssx)
    #  ID |       Address        |          Tags
    #-----+----------------------+--------------------------
    #  1  | [email protected]:22  | centos
    #
    # Entries (found in ssh config)
    #               Address              |           Tags
    # -----------------------------------+----------------------------
    #   [email protected]:22            | github.com
    

    操作演示

    最后通过一个演示动画来感受一下这个小可爱的功能吧。

    demo

    37 replies  •  2024-01-26 14:39:54 +08:00
    Inn0Vat10n
    Inn0Vat10n
    Dec 15, 2023❤️1
    1
    为什么不用 sshkey 呢,把集群 authorized_keys 刷一遍,所有机器登录都不用密码了
    vimiix
    vimiix
    OP
    Dec 15, 2023
    2
    @Inn0Vat10n 大部分机器不是属于我的,不方便直接放公钥上去
    march1993
    march1993
    Dec 15, 2023
    3
    ~/.ssh/config 够日常使用了吧。。而且可以复制到不同机器或者同事
    vimiix
    vimiix
    OP
    Dec 15, 2023
    4
    @march1993 嗯,但 ssh/config 里得配置明文,或者刷私钥,我平时用的测试机可能涉及几十台,所以简单写了个工具玩玩 :P
    ( ssx 的数据文件是二进制文件,也可以直接拷贝共享
    LonnyWong
    LonnyWong
    Dec 15, 2023
    5
    我写的这个 https://github.com/trzsz/trzsz-ssh ,在 V2 发过很多次了,OP 没看到?
    不过,自己写一次也很好,能学到不少东西。
    LonnyWong
    LonnyWong
    Dec 15, 2023❤️2
    6
    提个小建议,放出来给大家用的,最好别用 `ssh.InsecureIgnoreHostKey()`:

    https://github.com/vimiix/ssx/blob/ee6c0166ed0c447aa398f4c0c11b7c9f69770e18/ssx/entry/entry.go#L65

    ```go
    func (e *Entry) GenSSHConfig() *ssh.ClientConfig {
    cfg := &ssh.ClientConfig{
    User: e.User,
    Auth: e.AuthMethods(),
    HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    Timeout: getConnectTimeout(),
    }
    cfg.SetDefaults()
    return cfg
    }
    ```
    JounQin
    JounQin
    Dec 15, 2023 via iPhone
    7
    如果要传输密码信息那相信存储的时候也没法做非对称加密,那么用类似 base64 或者加盐的方式做编解码,其实安全性并不高?如果我判断有误,抱歉。
    LonnyWong
    LonnyWong
    Dec 15, 2023
    8
    @JounQin #7 是的,最好是用公私钥,然后私钥要设置复杂密码,开机时将私钥 ssh-add 到 ssh agent 中,这样用起来也很方便。更好的是,使用私钥要刷指纹的那种 ssh agent 。
    vimiix
    vimiix
    OP
    Dec 15, 2023
    9
    @LonnyWong 👍,之前没注意到,谢谢你的建议,确实应该考虑
    98842674
    98842674
    Dec 15, 2023
    10
    之前看到有人在 V2 上发类似的工具,但是很能理解楼主自己重新写一个,因为其实我自己也用 Python 写过一个类似的 : )
    很多人的初衷就是为了实现一个自己顺手的工具,而每个人的诉求又不尽相同,所以还是写一个专门为自己打造的用起来更方便,而且可以随时根据自己的诉求添加新的功能。

    看看大家写的工具,也挺有趣的,觉得不错的点子,也可以在自己的工具里改进一下。
    LonnyWong
    LonnyWong
    Dec 15, 2023 via iPhone❤️1
    11
    @vimiix #9 另外说一下,go 标准库中的 known_hosts 有两个小坑:
    https://github.com/golang/go/issues/29286
    https://github.com/golang/go/issues/53463

    有个第三方库解决了,我也为它贡献过几行代码:
    https://github.com/skeema/knownhosts
    vimiix
    vimiix
    OP
    Dec 15, 2023
    12
    @98842674 嗯,第一诉求是满足自己的需求
    vimiix
    vimiix
    OP
    Dec 15, 2023
    13
    @LonnyWong 好的,我学习一下,再次感谢
    QKgf555H87Fp0cth
    QKgf555H87Fp0cth
    Dec 15, 2023
    14
    都是大佬
    wkong
    wkong
    Dec 15, 2023
    15
    666 支持
    hytirrb
    hytirrb
    Dec 15, 2023
    16
    牛蛙,哥你是参加了哪些教程写的,感觉挺牛的,适合初学者学习
    vimiix
    vimiix
    OP
    Dec 15, 2023
    17
    @hytirrb 没有参加,go 是我平时的主力开发语言
    ljlljl0
    ljlljl0
    Dec 15, 2023
    18
    UP 演示动图是用什么录制的呀,还挺清晰的
    adoal
    adoal
    Dec 15, 2023
    19
    @vimiix “大部分机器不是属于我的,不方便直接放公钥上去”……这个不是放到用户自己家目录里就行了吗,就跟在家目录里放个吴梦梦潘甜甜小电影一样,还需要啥机器主人权限?
    adoal
    adoal
    Dec 15, 2023
    20
    2. 可以配置用 ControlMaster 来复用 ssh 连接,一次认证连上去,后续的会话都用同一个连接开新 shell
    adoal
    adoal
    Dec 15, 2023
    21
    不是否定 OP 针对自己个性化需求的开发。只是想说,openssh 演化了这么多年,其实功能非常强大,在最基本的日常用法之外有很多花样。当然,纯程序员可能更喜欢通过写代码来实现自己需求,而我主要是运维的身份,更喜欢尽量发掘现有成熟工具的潜力,没有谁高谁低的臧否。
    vimiix
    vimiix
    OP
    Dec 15, 2023❤️1
    22
    @ljlljl0 asciinema + svg-term
    vimiix
    vimiix
    OP
    Dec 15, 2023
    23
    @adoal 嗯嗯,赞同您的说法,ssh 肯定是成熟的工具,其肯定更适用于运维和生产环境。我写这个小工具主要目的是一个是解决我日常开发的一些显而易见的问题(也可能可以通过各种 ssh 的配置方式解决,但我比较懒,不想手动去配置,希望用朴素的方式连接后工具就可以自动帮我记下来,这个从安全的角度来说,不是个好的实践方案),另一方面也是想业余时间写点产品化的东西,这样有助于我建立产品思维。在生产上,我肯定是优先考虑用成熟的产品,但在个人工作流自动化方面,更愿意折腾自己写点东西的。:)
    trzzzz
    trzzzz
    Dec 15, 2023
    24
    https://github.com/T-TRz879/scpw 。这是我之前写过一个 scp 的客户端,个人工作需要经常传包,每次 server 和包都比较固定,懒得敲那么多。OP 的 ssx 很不错
    lstz
    lstz
    Dec 15, 2023 via iPhone
    25
    不敢苟同以上部分同学的观点,难道有了 A 工具就不能再写个 B 工具吗?
    我认为百家争鸣是最好也是最健康的状态,楼主加油,支持一个
    LonnyWong
    LonnyWong
    Dec 15, 2023
    26
    @lstz #25 有人反对楼主自己写吗?
    lstz
    lstz
    Dec 15, 2023 via iPhone
    27
    @LonnyWong 无需问我
    lstz
    lstz
    Dec 15, 2023 via iPhone
    28
    看来是误会,我收回前面的话
    YaD2x
    YaD2x
    Dec 15, 2023
    29
    貌似在 windows 终端登录后,不支持上下翻动历史命令,终端的高亮颜色显示也有变化。
    vimiix
    vimiix
    OP
    Dec 17, 2023
    30
    @trzzzz 过奖,后面有规划在 ssx 里加上 scp 的能力,在设计中
    vimiix
    vimiix
    OP
    Dec 17, 2023
    31
    @lstz #25 感谢支持
    vimiix
    vimiix
    OP
    Dec 17, 2023
    32
    @YaD2x #29 我这边测试了下,windows 上颜色正常,上下左右键确实失效了。我下周排查下看能否解决,感谢提醒
    vimiix
    vimiix
    OP
    Dec 17, 2023
    33
    @YaD2x #29 windows 中方向键失效的问题已在 v0.0.4 版本修复
    Songine
    Songine
    Jan 6, 2024 via Android
    34
    不错诶,安卓 APP 上也可以直接跑,但是搞不懂怎样才可以附加命令给连接的主机呢?
    类似 ssh user@ip cmd 好像不行..
    vimiix
    vimiix
    OP
    Jan 9, 2024
    35
    @Songine #34 直接执行一条命令然后就返回,这个意思吗?如果是的话,这个后面版本会增加
    Songine
    Songine
    Jan 12, 2024 via Android
    36
    @vimiix 对的,就是执行单条命令返回,后续会有这个功能的话那就太好了(◦˙▽˙◦)
    vimiix
    vimiix
    OP
    Jan 26, 2024❤️1
    37
    @Songine 执行单条命令的功能已经在 v0.0.6 版本中支持
    https://github.com/vimiix/ssx/releases/tag/v0.0.6
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1610 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 55ms · UTC 08:08 · PVG 16:08 · LAX 00:08 · JFK 03:08
    ♥ Do have faith in what you're doing.