![有什么办法可以让 openssl s_client 从 stdin 读取吗?](https://linux22.com/image/771102/%E6%9C%89%E4%BB%80%E4%B9%88%E5%8A%9E%E6%B3%95%E5%8F%AF%E4%BB%A5%E8%AE%A9%20openssl%20s_client%20%E4%BB%8E%20stdin%20%E8%AF%BB%E5%8F%96%E5%90%97%EF%BC%9F.png)
我想编写一个脚本来创建 Gmail 帐户中退回的电子邮件列表。我知道我可以使用以下方式进行连接:
openssl s_client -crlf -connect imap.gmail.com:993
我最初尝试过类似的事情:
openssl s_client -crlf -connect imap.gmail.com:993 <<!
a login [email protected] Apa55w0rd
a select INBOX
a search on 4-oct-2021
!
但是,我得到的只是连接到服务器的初始响应,没有命令的任何内容;它显然没有读取 stdin。有没有办法让 s_client 从文件(最好是 stdin)读取命令?
编辑
我已经尝试了 Gerald Schneider 链接的帖子中的建议(https://stackoverflow.com/questions/13707092/openssl-pass-first-few-lines-from-script-then-read-from-stdin),但它似乎不起作用——至少它没有产生我想要的输出:
db1 root : cat <<! | openssl s_client -crlf -connect imap.gmail.com:993
a login [email protected] Apa55w0rd
a select INBOX
a search on 4-oct-2021
!
CONNECTED(00000003)
depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1
verify return:1
depth=1 C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
verify return:1
depth=0 CN = imap.gmail.com
verify return:1
---
Certificate chain
0 s:/CN=imap.gmail.com
i:/C=US/O=Google Trust Services LLC/CN=GTS CA 1C3
1 s:/C=US/O=Google Trust Services LLC/CN=GTS CA 1C3
i:/C=US/O=Google Trust Services LLC/CN=GTS Root R1
2 s:/C=US/O=Google Trust Services LLC/CN=GTS Root R1
i:/C=BE/O=GlobalSign nv-sa/OU=Root CA/CN=GlobalSign Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFUzCCBDugAwIBAgIRANYAB4MRC2TJCgAAAAD/Y6YwDQYJKoZIhvcNAQELBQAw
RjELMAkGA1UEBhMCVVMxIjAgBgNVBAoTGUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBM
TEMxEzARBgNVBAMTCkdUUyBDQSAxQzMwHhcNMjEwOTEzMDMxMTI3WhcNMjExMTIw
MDMxMTI2WjAZMRcwFQYDVQQDEw5pbWFwLmdtYWlsLmNvbTCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBALRQpfQvddKjDkAtx0dNu8ifeLqzo8Lv6892Ij8O
KZBsAGcP39G9elE5UGklMH4Jzo88scMmSq+gTNW+Zss/DJ64RMfh/hBXSemdlfnF
Ro/HywsuPZ4YqHOVBvgW+7/K7YspqhfKn/oSZl5jCXz/J6qcxX7O9+phWD7nWwGS
ksrNkuwBT2fg/mA64q0sGgz+cE0k8LGwWoJSZ+B3Nosl07IKv9Jwddxu85d5cAcQ
djoEHiGTF4bluMlkHKlzQhNLh8bEiAkMV/pu/79D1HD+05z6I2EXt+f7O0Dgc8HC
hYHYGw2x2T4ZHAEH+0vG+2CTQMcNoTJ4jfITe4/OUaDm39ECAwEAAaOCAmcwggJj
MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8E
AjAAMB0GA1UdDgQWBBQGYvnDmgImhQkT2mNBuYvWoMf2wTAfBgNVHSMEGDAWgBSK
dH+vhc3ulc09nNDiRhTzcTUdJzBqBggrBgEFBQcBAQReMFwwJwYIKwYBBQUHMAGG
G2h0dHA6Ly9vY3NwLnBraS5nb29nL2d0czFjMzAxBggrBgEFBQcwAoYlaHR0cDov
L3BraS5nb29nL3JlcG8vY2VydHMvZ3RzMWMzLmRlcjAZBgNVHREEEjAQgg5pbWFw
LmdtYWlsLmNvbTAhBgNVHSAEGjAYMAgGBmeBDAECATAMBgorBgEEAdZ5AgUDMDwG
A1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmxzLnBraS5nb29nL2d0czFjMy9mVkp4
YlYtS3Rtay5jcmwwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdQDuwJXujXJkD5Lj
w7kbxxKjaWoJe0tqGhQ45keyy+3F+QAAAXvdWlDzAAAEAwBGMEQCICZIv+JvLRvF
G192uY3wdMdxa7F1Cjkf4Ts++Nj+VBcTAiBTVo0coasZSSvLhfhpFFgVaYjALw1d
kjNEGOhKDfNX4gB3APZclC/RdzAiFFQYCDCUVo7jTRMZM7/fDC8gC8xO8WTjAAAB
e91aUA0AAAQDAEgwRgIhAJZ/m/XmVsCx5iuxrdiHmKWq04qmdutaRSqyG2X6wFED
AiEAwvkkC+8egz7BfGcAcsdx04FzMrDYfReDn6elgMCsBBAwDQYJKoZIhvcNAQEL
BQADggEBAD+0liFWMdNxq5xWOLiTCw1mWatA3ZdrDqi51cYN4thboxRa+iNfYUn/
AvSel4sJ+5HhdUmgSpXc98x/OFybrYyLXg/Tk3R1hgZmRsgUTrGMP6H6bkrA1du9
qt23JMScvB2P5pmGMoXdKh1dGaigaIEErixhjlALztEvrWUVSzmpg6A4yx0O/9lw
iHgXY0XNcjtZJ/2tta0nizTMKn2NJbjAW2Pdi0GDZUV9DRcicdvhB9uFd/RFEU2o
muPY4eRc/P4n6NE7TH2S3aEGxD74hwZSmb1Jo/g7L8Ta1caomqHIEFBBU4G+8x0h
8XQpI2zZhTJ82wPjEz7GrVdJt/KDwy0=
-----END CERTIFICATE-----
subject=/CN=imap.gmail.com
issuer=/C=US/O=Google Trust Services LLC/CN=GTS CA 1C3
---
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 4870 bytes and written 261 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-CHACHA20-POLY1305
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-CHACHA20-POLY1305
Session-ID: FA01523E2366640CFAA49BFA681D23F7118556474A67072E09F188D42B4FCDAB
Session-ID-ctx:
Master-Key: F26BDF82C66AE5B7D08847C29D786E382212B8017292EEE7A826D2085FC6F73877441EDC72EDFF2A66342EDE147EB2EE
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 100800 (seconds)
TLS session ticket:
0000 - 01 d9 8f a9 94 2e 5a 89-e0 93 18 8f 99 fc 66 63 ......Z.......fc
0010 - c3 b5 cb 58 7b ba ae 67-d4 4d c6 6b e9 56 f5 48 ...X{..g.M.k.V.H
0020 - b3 c7 21 b6 39 84 c5 f0-77 3b 74 95 c3 84 9a 1e ..!.9...w;t.....
0030 - 6a 18 f9 a0 73 41 99 f4-b4 fb c8 4f 32 64 bc 4e j...sA.....O2d.N
0040 - 70 64 b8 de 50 27 7d 34-b1 c9 a0 e1 9c c4 8d e6 pd..P'}4........
0050 - cb cf 09 92 a3 5c 9e 09-75 27 e0 f4 d0 fc 75 06 .....\..u'....u.
0060 - f0 7e 1b 37 f7 6d 74 b3-d9 cb 24 32 a9 fd d0 aa .~.7.mt...$2....
0070 - a2 9e 7d e0 58 1d 70 83-e8 a3 f0 5c 1c eb ce 09 ..}.X.p....\....
0080 - 08 92 d0 de 28 84 6e 14-51 3a 99 a7 20 f3 5c b5 ....(.n.Q:.. .\.
0090 - 98 9e b5 6a 62 d4 da 45-42 52 70 2b 21 49 46 0e ...jb..EBRp+!IF.
00a0 - 87 ca b3 90 a2 d8 5a b8-1d c4 8a 55 e2 57 88 20 ......Z....U.W.
00b0 - 5f a1 3d 7e d0 84 53 51-d0 a7 c4 e1 f3 30 69 2c _.=~..SQ.....0i,
00c0 - 68 16 18 3f 29 28 d5 42-fa cd d2 11 da 2d b2 c2 h..?)(.B.....-..
00d0 - 9e e3 ef 50 b9 dc b6 97-fa 66 4e 71 6d 02 6a 6e ...P.....fNqm.jn
00e0 - 91 3b .;
Start Time: 1633347887
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: yes
---
DONE
答案1
查看源代码似乎 s_client 仅从控制台或 TTY 设备读取,而不是从任何 stdin 读取。
您可以通过插入一个将(伪)TTY 包装在命令周围的程序来解决这个问题。
screen
可以做到这一点,但这有点困难,我有时使用ssh
诡计。
另外,还有用于交互式控制台程序的 goto(预期):https://linux.die.net/man/1/expect,但从来没尝试过。
使用 SSH
echo -e 'GET / HTTP/1.0\nHost: www.example.com\n\n' | ssh -tt user@localhost 'openssl s_client -crlf -servername www.example.com -brief -connect www.example.com:443'
如果检测到管道,-tt 将强制分配 TTY,而 ssh 默认不会这样做。
缺点是您必须将此环回 SSH 连接设置为自动登录才能在脚本中使用它。
这不是二进制安全的。对于简单的 ASCII 来说,它可以。
带屏幕
有点困难,但是减少了登录的麻烦。
准备一个query
包含行的文件以供服务器输入。
例如:
GET / HTTP/1.0
Host: www.example.com
制作一个带名称的独立屏幕myscreen
并将输出保存到./out.log
screen -d -m -S myscreen -L -Logfile ./out.log
发送 openssl 连接命令 (-X 东西)到第一个窗口(-p 0) 屏幕名为myscreen
(-S 我的屏幕),然后立即发送文件中的数据./query
。请注意,$(cat..) 进程替换将删除文件中任何尾随的换行符./query
,并且对于 HTTP 协议,openssl 命令必须具有 -crlf。查询数据必须在打开连接后不久发送,否则 s_client 将超时。
screen -S myscreen -p 0 -X stuff "openssl s_client -crlf -servername www.example.com -brief -connect www.example.com:443^M";screen -S myscreen -p 0 -X stuff "$(cat ./query)^M^M"
最后退出屏幕,删除myscreen
会话(假设前面的查询使服务器已经断开连接并且 s_client 自行退出):
screen -S myscreen -p 0 -X stuff "exit^M"
输出包括查询和退出以及 s_client 输出现在位于./out.log
如果 s_client 在查询后没有退出,您可以首先发送中断信号。
screen -S myscreen -p 0 -X stuff "^C"
答案2
s_client
确实从 读取stdin
,但默认情况下一旦stdin
关闭就会关闭,请尝试使用-ign_eof
。
答案3
这是为了从 adfs 服务器获取证书:
echo "" | openssl s_client -connect domain-controller-hostname:636 -showcerts 2>/dev/null | openssl x509 -out certfile.txt