有什么办法可以让 openssl s_client 从 stdin 读取吗?

有什么办法可以让 openssl s_client 从 stdin 读取吗?

我想编写一个脚本来创建 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

另请参阅如何将“echo”导入“openssl”?

答案3

这是为了从 adfs 服务器获取证书:

echo "" | openssl s_client -connect domain-controller-hostname:636 -showcerts 2>/dev/null | openssl x509 -out certfile.txt

相关内容