惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
B
Blog RSS Feed
W
WeLiveSecurity
I
InfoQ
L
Lohrmann on Cybersecurity
Simon Willison's Weblog
Simon Willison's Weblog
腾讯CDC
S
Schneier on Security
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Threat Research - Cisco Blogs
P
Palo Alto Networks Blog
Attack and Defense Labs
Attack and Defense Labs
I
Intezer
Recent Commits to openclaw:main
Recent Commits to openclaw:main
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
WordPress大学
WordPress大学
Cisco Talos Blog
Cisco Talos Blog
T
The Exploit Database - CXSecurity.com
S
Securelist
T
Tailwind CSS Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
美团技术团队
Stack Overflow Blog
Stack Overflow Blog
T
Tor Project blog
博客园 - 叶小钗
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
Project Zero
Project Zero
C
Cybersecurity and Infrastructure Security Agency CISA
Apple Machine Learning Research
Apple Machine Learning Research
V
Visual Studio Blog
Know Your Adversary
Know Your Adversary
T
The Blog of Author Tim Ferriss
N
News and Events Feed by Topic
小众软件
小众软件
G
Google Developers Blog
F
Full Disclosure
O
OpenAI News
The Last Watchdog
The Last Watchdog
G
GRAHAM CLULEY
TaoSecurity Blog
TaoSecurity Blog
U
Unit 42
Jina AI
Jina AI
S
SegmentFault 最新的问题
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
P
Proofpoint News Feed
Y
Y Combinator Blog
N
News and Events Feed by Topic
K
Kaspersky official blog

文章列表 - 她和她的猫

使用小鹤双拼一个月 折腾 Hugo PaperMod 主题 去长鹿旅游休博园 深入 Hyperf:Inject 注解是如何工作的? 译|理解容器镜像层 使用 Rust 实现高性能预写日志(Write Ahead Log) 译|使用 Linux 命名空间隔离系统 深入 Hyperf:HTTP 服务是如何处理请求的? Linux 文件权限学习笔记 译|了解 Bitcask:基于日志结构的 KV 存储引擎 还原 SM2 压缩公钥的几种方法 深入 Hyperf:HTTP 服务启动时发生了什么? 一次 Hyperf 注解失效问题分析 将博客迁移到又拍云 译|PHP 7 新的 Hashtable 实现 排查 ES 查询问题:深入了解 json_encode() 函数 浅析 Redlock 分布式锁实现原理 Yar 源码阅读笔记:RPC 服务端 Yar 源码阅读笔记:客户端的并行调用 Yar 源码阅读笔记:客户端的同步调用 Yar 源码阅读笔记:数据传输模块 Yar 源码阅读笔记:消息编码模块 Yar 源码阅读笔记:RPC 通信协议 Yar 源码阅读笔记:开篇 PHP 8 新特性介绍 基于 OpenSSL 实现国密 SM4 加解密 PHP 源码阅读笔记:编译与调试 PHP 什么是惊群问题 大端模式和小端模式 基于 GitHub Actions 定时推送网址到百度站长平台 聊聊五种 I/O 模型 Workerman 源码分析:文件上传 浅入浅出 HTTP 协议 PHP 网络编程:构建 MySQL 蜜罐获取攻击者微信 ID 使用 Workerman 接入 Bilibili 直播弹幕协议 使用 GitHub Actions 自动部署 Hexo 什么是二进制安全 【转载】PHP 程序员进阶之路 优化 Workerman 检查主进程是否存活的逻辑 基于 Redis 实现分布式锁 《PHP 实现 Base64 编码/解码》笔记 PHP 多进程下载必应壁纸 基于 Redis 实现延迟队列 【转载】PHP 实现 Base64 编码/解码 使用 MySQL FIELD() 函数自定义排序规则 Laravel 的 Facades 实现原理 C语言单链表实现约瑟夫环 数据结构学习笔记:顺序栈和链栈(C语言) 使用 QueryList + Redis 下载壁纸 在 Laravel 登录/注册中使用 mews/captcha 扩展包 使用 mews/captcha 扩展包为 Laravel 应用添加图片验证码 给 YOURLS 短网址系统编写插件《批量生成短网址》 给 YOURLS 短网址系统编写插件《Hello World!》 PHP 7.1 使用 json_encode 函数造成浮点类型数据出现精度问题 Laravel 授权策略(Policy)的基本使用 Ubuntu 系统下 WiFi 频繁掉线解决方法 Laravel 应用部署到 Nginx 服务器上的第一个坑 Ubuntu 16.04 LST 安装 Redis 和 Composer PHP 采集逐浪小说章节列表 Nginx 环境 SSL 强制 HTTP 301 跳转到 HTTPS 【工作&生活】第一周 ServiceStack.Redis 与多线程 Count the number of Duplicates C# Base64 加密及解密 ASP.NET MVC 使用动态类型传递数据 Django 使用 order_by() 对数据进行排序操作 ASP.NET + jQuery + AJAX 实现用户登录 ASP.NET 从客户端中检测到有潜在危险的 Request.Form 值 ASP.NET 使用 FormData 实现 AJAX 上传图片 Python 使用 BeautifulSoup 抓取网页 贪心算法之字符串的完美度 一言不和就造轮子之 CookieHelper ASP.NET 上传图片 DBHelper 类 C# 捕获屏幕源码 用 JavaScript 做一些有趣的事情 第一篇文章 好久不见。 如何防止非法调用 PHP 文件 清明小记。 PHP 生成随机字符串 Z-Blog PHP 程序做 301 跳转 PHP 处理数组常用的几个函数 Sublime Text 3 快捷键总结 PHP 使用 file_get_contents() 函数实现采集网页 使用 C# 编写学生信息管理系统 终于到了。 zblog报错: magic_quotes_gpc 和 safe_mode 世事无常。 如何使用 PHP 上传文件 安卓手机编写和运行 PHP 程序的软件 使用 AJAX 刷新、验证 PHP 图片验证码 PHP 生成图片验证码 PHP 之 session 的使用方法 PHP 之 cookie 的使用方法 PHP 实现分页原理详解 Thinkphp 框架中系统常量在 Js 文件中不解析的解决方法
1Password 自动化登录堡垒机
她和她的猫 · 2025-05-31 · via 文章列表 - 她和她的猫

前阵子刷到涛叔的《自动化登录堡垒机》,用 expect 自动输密码和 OTP。我平时就用 1Password 管理密码和密钥,所以直接用它的 SSH Agent 来存堡垒机的密钥,本地不用留私钥。OTP 一开始也想用 1Password CLI 来获取,但实测太慢了,最后换成了 2fa 工具。

先装 1Password CLI

# macOS
brew install 1password-cli
# 其它系统参考官方文档
# https://developer.1password.com/docs/cli/get-started/#step-1-install-1password-cli

装好后在 1Password 设置里开启「与 1Password CLI 集成」:

启用与 1Password CLI 集成

之后就能在终端用了,常用命令:

op vault list                    # 保险库列表
op item list                     # 项目列表
op item get {id/name}            # 项目信息
op item get {id/name} --reveal   # 包含密码
op item get {id/name} --reveal --format json  # JSON 格式
op item get {id/name} --otp      # 一次性密码

还需要装 jq 来解析 JSON,从 1Password 的项目信息里提取密码和一次性密码:

# macOS
brew install jq
# Debian/Ubuntu
sudo apt-get install jq
# RedHat/CentOS
yum install jq

脚本改动不大,把硬编码的密码和动态口令改成用 op 命令获取就行:

#!/usr/bin/expect

trap {
    set XZ [stty rows   ]
    set YZ [stty columns]
    stty rows $XZ columns $YZ < $spawn_out(slave,name)
} WINCH

set OP_ITEM_ID "Bastion-Host-Login"  # 换成你的项目 ID 或名称

if {[catch {exec op item get ${OP_ITEM_ID} --reveal --format json} data]} {
    puts "错误: 无法获取1Password数据,请确保已登录op CLI"
    exit 1
}

if {[catch {exec echo $data | jq -r {.fields[] | select(.id == "password") | .value}} password]} {
    puts "错误: 无法解析密码"
    exit 1
}

if {[catch {exec echo $data | jq -r {.fields[] | select(.type == "OTP") | .totp}} totp]} {
    puts "错误: 无法解析TOTP"
    exit 1
}

spawn ssh foo@example.zz.ac

expect "Password:"
send "$password\r"

expect "Verification code:"
send "$totp\r"

interact

脚本里的 catch 命令类似 try-catch,失败返回非零值,成功返回 0 并把结果存到变量里。用之前把 OP_ITEM_ID 换成实际值:

op item list                     # 列出所有项目
op item list | grep "堡垒机"     # 搜索特定名称

1Password CLI 的性能问题

用起来才发现,这个脚本慢得离谱。登录一次要 3-10 秒,跟手动输入差不多,自动化了个寂寞 ¯\(ツ)

问题出在 op 命令获取密码太慢。试过指定保险库、减少字段,都没用。Google 搜了一下,发现这是老问题了,一直没解决。

官方说 macOS 有缓存优化,加 --debug 确实显示缓存命中了,但速度还是很慢:

op item get xxxx --reveal --debug
23:19PM | DEBUG | Session delegation enabled
23:19PM | DEBUG | NM request: NmRequestAccounts
23:19PM | DEBUG | NM response: Success
23:19PM | DEBUG | NM request: NmRequestAccounts
23:19PM | DEBUG | NM response: Success
23:19PM | DEBUG | InitDefaultCache: successfully initialized cache
23:19PM | DEBUG | EncryptedKeysets: Cache hit on keyset
23:19PM | DEBUG | AllVaults: cache hit on vault xxxxxxxxxxxxxxxxx
23:19PM | DEBUG | AllVaults: cache hit on vault xxxxxxxxxxxxxxxxx
23:19PM | DEBUG | AllVaults: cache hit on vault xxxxxxxxxxxxxxxxx
23:19PM | DEBUG | VaultItems: cache hit on vault items of vault xxxxxxxxxxxxxxxxx
23:19PM | DEBUG | VaultItems: cache hit on vault items of vault xxxxxxxxxxxxxxxxx
23:19PM | DEBUG | VaultItems: cache hit on vault items of vault xxxxxxxxxxxxxxxxx
23:19PM | DEBUG | VaultItems: cache hit on vault items of vault xxxxxxxxxxxxxxxxx
23:19PM | DEBUG | Item: VaultItems cache hit for vault xxxxxxxxxxxxxxxxx - validating staleness using item version
23:19PM | DEBUG | Item: cache hit on item xxxxxxxxxxxxxxxxx of vault xxxxxxxxxxxxxxxxx

折腾半天,既然 CLI 的性能解决不了,就换个思路:SSH 密钥管认证,独立的 2FA 工具管 OTP。

方案二:SSH 密钥 + 2FA

1Password 还有个 SSH Agent 功能,可以把密钥存到云端。每次用的时候弹窗确认一下,哪个客户端在请求用哪个密钥,一目了然。

1Password SSH 认证请求

好处是本地不用存私钥,而且能跨设备同步。

需要在 1Password 设置里开启「使用 SSH Agent」。

配置 SSH Agent

在 1Password 里创建 SSH 密钥项目,可以导入现有密钥或者生成新的。

创建 SSH Key

然后把公钥保存到 ~/.ssh/bastion.pub,避免密钥太多触发 Too many authentication failures

下载公钥

接着在 ~/.ssh/config 里加:

Host bastion
    HostName example.zz.ac  # 堡垒机地址
    Port 22                 # 堡垒机端口
    IdentitiesOnly yes
    IdentityFile ~/.ssh/bastion.pub
    IdentityAgent "~/.1password/agent.sock"

这样 ssh bastion 就能免密登录了,但还差 OTP。

配置 2FA

装个 2fa 工具:

go install rsc.io/2fa@latest
2fa -add bastion           # 添加密钥
2fa key for bastion: 
2fa bastion                # 获取验证码
211762

我对脚本做了优化,加了超时处理:

#!/usr/bin/expect

trap {
    set XZ [stty rows   ]
    set YZ [stty columns]
    stty rows $XZ columns $YZ < $spawn_out(slave,name)
} WINCH

spawn 2fa bastion
expect -re "(.*)\n"
set totp $expect_out(1,string)

spawn ssh example.zz.ac

expect {
    "Verification code:" {
        send "$totp\r"
    }
    timeout {
        puts "超时: 未收到 OTP 提示"
        exit 1
    }
}

expect {
    "*$" { }
    "*#" { }
    "*>" { }
    timeout {
        puts "登录超时"
        exit 1
    }
}

# send "ls -l\r"  # 登录后可以执行命令

interact

实测登录只要 1 秒左右,比之前快多了,稳定性也更好。