質問の短いバージョン
関連ファイルが存在すると仮定すると、次のコマンドシーケンスが機能しないのはなぜですか?
socat tcp-listen:10001,fork exec:'/bin/cat' &
socat openssl-listen:10002,fork,reuseaddr,cert=server.pem,cafile=client.crt tcp:localhost:10001 &
socat tcp-listen:10003 openssl-connect:localhost:10002,cert=client.pem,cafile=server.crt &
socat stdout tcp:localhost:10003
質問の長いバージョン
socat
次の資料に記載されているようにwithを使用しようとしています。openssl
状況によっては、Debian 9 で socat バージョン 1.7.2.4+sigfix と OpenSSL バージョン 1.1.0f を実行しています。
openssl
私はそれをさらに試す前に、最初にsocat
完全な確認としてそれ自体を使用しました。 1つのsocat
インスタンスを「エコサーバー」で起動し、2つの中間socat
インスタンス(つまり、2番目と3番目のインスタンス)を使用してトンネルを作成し、4番目のインスタンスを「クライアント」として使用して、トンネルを介して元のプロセスにデータを送信します。 。以下は私が実行したコマンドの例です。
socat tcp-listen:10001,fork exec:'/bin/cat' &
socat tcp-listen:10002,fork tcp:localhost:10001 &
socat tcp-listen:10003,fork tcp:localhost:10002 &
socat stdout tcp:localhost:10003
これは期待どおりに機能します。端末に入力されたテキストがコンソールに表示されます。サンプルセッションは次のとおりです。
user@host:~$ socat tcp-listen:10001,fork exec:'/bin/cat' &
[1] 1001
user@host:~$ socat tcp-listen:10002,fork tcp:localhost:10001 &
[2] 1002
user@host:~$ socat tcp-listen:10003,fork tcp:localhost:10002 &
[3] 1003
user@host:~$ socat stdout tcp:localhost:10003
hey
hey
正当であることを確認した後、証明書と鍵生成プロセスを続行しました。
まず、サーバーキーと自己署名証明書を生成しました。
openssl genrsa -out server.key 2048
openssl req -new -key server.key -x509 -days 3653 -out server.crt
cat server.key server.crt > server.pem
chmod 600 server.key server.pem
その後、クライアントキーと自己署名証明書を生成しました。
openssl genrsa -out client.key 2048
openssl req -new -key client.key -x509 -days 3653 -out client.crt
cat client.key client.crt > client.pem
chmod 600 client.key client.pem
最後に、以前と同じトンネル設定を試しましたが、OpenSSL暗号化を使用しました。
socat tcp-listen:10001,fork exec:'/bin/cat' &
socat openssl-listen:10002,fork,reuseaddr,cert=server.pem,cafile=client.crt tcp:localhost:10001 &
socat tcp-listen:10003 openssl-connect:localhost:10002,cert=client.pem,cafile=server.crt &
socat stdout tcp:localhost:10003
これはうまくいかないようです。最後のコマンドを実行した後、次のエラーが発生します。
YYYY/mm/dd HH:MM:SS socat[pid1] E SSL_connect(): error:14082174:SSL routines:SSL3_CHECK_CERT_AND_ALGORITHM:dh key too small
YYYY/mm/dd HH:MM:SS socat[pid2] E SSL_accept(): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
サンプルセッションは次のとおりです。
user@host:~$ socat tcp-listen:10001,fork exec:'/bin/cat' &
[1] 1001
user@host:~$ socat openssl-listen:10002,fork,reuseaddr,cert=server.pem,cafile=client.crt tcp:localhost:10001 &
[2] 1002
user@host:~$ socat tcp-listen:10003 openssl-connect:localhost:10002,cert=client.pem,cafile=server.crt &
[3] 1003
user@host:~$ socat stdout tcp:localhost:10003
2018/08/22 23:43:30 socat[1005] E SSL_accept(): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
2018/08/22 23:43:30 socat[1003] E SSL_connect(): error:14082174:SSL routines:SSL3_CHECK_CERT_AND_ALGORITHM:dh key too small
[3]+ Exit 1 socat tcp-listen:10003 openssl-connect:localhost:10002,cert=client.pem,cafile=server.crt
ユーザーの提案に従うデイブ・トンプソン_085openssl s_client
次のコマンドを試してみました。
openssl s_client -cipher 'DHE:!EXPORT:!LOW' -connect localhost:10002
これにより、次のエラー出力が生成されました。
socat[pid] E SSL_accept(): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small:../ssl/statem/statem_clnt.c:1460:
答え1
まず、確実ですか?ソカットOpenSSL 1.1.0を使用していますか?アップストリーム(socat.org)1.7.2.4ソース(2014年にリリース)は、APIに大幅な変更が加えられたOpenSSL 1.1.0(2016年リリース)と互換性がありません。確認してくださいldd $(which socat)
。あなたのsocatとOpenSSL(両方)は標準のリポジトリ、他のビルダー/パッケージから来ますか、それともソースからビルドされますか?
とにかく、1.7.2.4(アップストリーム)ソースはデフォルトで512ビットDHパラメータに設定されていますが、「新機能」ではそうは言わず、「sig」パッチが何も変わらないと仮定します。これは実際には小さすぎます。 Logjam以前にも脆弱であることが知られており、1.0.1nまたは1.0.2b以上(両方とも2015-06にリリース)のすべてのlibsslクライアントでは許可されていません。どの1.1.0、2016年8月に初めてリリースされました)。
AFAICSあなたの選択は次のとおりです。
socatを1.7.3.0以上にアップグレードしてください(アップストリームには1024ビットがあります)。 3.1+ 2048ビットが優れています。
少なくとも1024ビットの場所でDHパラメータを生成または取得します。 (あなたのクライアントを含むほとんどのクライアントには2048が優れています。)一部クライアントに問題(古いJavaバージョンなど)が発生し、サーバーファイル
cert
に追加される可能性があります。openssl dhparam $n >file
1024または2048を使用してDHパラメータを生成できます$n
。遅すぎるとあなたはできますに追加してください-dsaparam
。上記と同じですが、パラメータをサーバーで構成されている別々のファイルに入れます。マンページこのオプションは「はい」と言いますが、
dhparams=<file>
コードでは「はい」と言い、dh=
テストによって後者が確認されます。DHEを使用する暗号スイートに同意しないように、サーバー、クライアント、またはその両方の組み合わせを構成します。ここでは、サーバーが間違ったサーバーなので、個人的にサーバーを構成します。再びマニュアルページには次のように表示されますが、
cipher
現実はciphers
。 1.7.2.4には「tmp_ecdh」パラメータセットがなく(AFAICT)1.1.0では動作しないため、ECDHEはサポートされていません。これは、DHEがなければ、接続が完全な転送セキュリティを持つことができないことを意味します。これらの制限を受け入れることができる場合は、,ciphers='DEFAULT:!DHE'
サーバーでそれを使用するのが簡単な解決策です。(1.7.3.0以降では「tmp_ecdh」を設定し、デフォルトでDH-1024以上がなくてもECDHEをサポートしています.使用されず、関係ありません。