Unix ソケットで実行されている ssh サービスがあり、UNIX ソケットのチャネルに向けたいローカル TCP サーバーがあります。
基本的に私がするとき:
$ ssh root@localhost -p 2000
次に、ローカルの TCP サーバーが要求を受け取り、それを Unix ソケットにパイプします。TCP クライアント (この場合は ssh) が Unix ソケットから応答を受け取ります。関連コード:
let running_tunnel debug (tcp_ic, tcp_oc) () =
Lwt_io.with_connection a_unix_addr begin fun (mux_ic, mux_oc) ->
let%lwt _ = some_call with_an_arg
and _ =
(* Some setup code *)
let rec forever () =
Lwt_io.read_line tcp_ic >>= fun opening_message ->
Lwt_io.write_from_string_exactly
mux_oc opening_message 0 (String.length opening_message) >>= fun () ->
Lwt_io.read_line mux_ic >>= fun reply ->
Lwt_io.printl reply >>= fun () ->
Lwt_io.write_line tcp_oc reply >>= fun () ->
forever ()
in
forever ()
in
Lwt.return_unit
end
そして、この種の作品。コマンドラインでsshを呼び出すと「スタック」しますが、反対側のsshヘッダーが正しいため、データを取得していることはわかっていますSSH-2.0-OpenSSH_6.7
. また、最初の ssh ハンドシェイクのより多くの部分を出力するように側に指示します。つまり、次の出力が表示されます。
??^?W\zJ?~??curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group14-sha1ssh-rsa,ssh-dss>aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com>aes128-ctr,aes192-ctr,aes256-ctr,chacha20-poly1305@openssh.com?umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1?umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1none,zlib@openssh.comnone,zlib@openssh.co
など、正しいようです。ハングの理由は私が使用しているためだと考えたLwt_io.read_line
ので、代わりにこれを試しました:
let rec forever () =
Lwt_io.read tcp_ic >>= fun opening_message ->
Lwt_io.write_from_string_exactly
mux_oc opening_message 0 (String.length opening_message) >>= fun () ->
Lwt_io.read mux_ic >>= fun reply ->
Lwt_io.printl reply >>= fun () ->
Lwt_io.write tcp_oc reply >>= fun () ->
forever ()
in
forever ()
これは実際にはさらに悪化し、最初のハンドシェイクさえ出力しませんでした。専用の ... 関数も試しましたが、{write,read}_into
成功は限られていました。strace/dtruce で実行すると、次のような最終結果が表示されます。
read(0x6, "SSH-2.0-OpenSSH_6.9\r\n\0", 0x1000) = 21 0
write(0x1, "SSH-2.0-OpenSSH_6.9\n\0", 0x14) = 20 0
read(0x7, "\0", 0x1000) = -1 Err#35
write(0x7, "SSH-2.0-OpenSSH_6.9\0", 0x13) = 19 0
select(0x9, 0x7FFF5484F880, 0x7FFF5484F800, 0x7FFF5484F780, 0x0) = 1 0
read(0x7, "SSH-2.0-OpenSSH_6.7\r\n\0", 0x1000) = 21 0
write(0x1, "SSH-2.0-OpenSSH_6.7\n\0", 0x14) = 20 0
read(0x6, "\0", 0x1000) = -1 Err#35
write(0x6, "SSH-2.0-OpenSSH_6.7\n\0", 0x14) = 20 0
select(0x9, 0x7FFF5484F880, 0x7FFF5484F800, 0x7FFF5484F780, 0x0) = 1 0
read(0x6, "\0", 0x1000) = 1968 0
read(0x6, "\0", 0x1000) = -1 Err#35
^C
6.9 はローカル マシンの ssh で、6.7 は Unix ソケットの背後にあるリモート マシンです。私にとって奇妙に思えることの 1 つは、 がどのように\r
ドロップされ、これにより読み取り/書き込みカウントが 1 変化するかということです。これが決定的な違いになるかどうかはわかりません。
理想的には、この読み取り可能なチャネル (TCP ソケット) で利用可能なデータがあるときはいつでも、書き込み可能なチャネル (Unix ソケット) に直接書き込む、またはその逆の Lwt からのある種の抽象化が必要です。