SSL サーバーをプレーン テキスト モードで起動するには、SSLServer の start_immediately フィールドを false に設定する必要があります。いつでも (つまり、クライアントから STARTTLS コマンドを受け取ったとき)、SSLSocket の accept メソッドを呼び出して SSL/TLS ハンドシェイクを開始できます。もちろん、クライアントはプロトコルに同意する必要があります:)
これをテストするために私が書いたサンプルサーバーを次に示します。
#!/usr/bin/ruby
require 'socket';
require 'openssl';
certfile = 'mycert.pem';
port = 9002;
server = TCPServer.new( port );
# Establish an SSL context
sslContext = OpenSSL::SSL::SSLContext.new
sslContext.cert = OpenSSL::X509::Certificate.new( File.open( certfile ) );
sslContext.key = OpenSSL::PKey::RSA.new( File.open( certfile ) );
# Create SSL server
sslServer = OpenSSL::SSL::SSLServer.new( server, sslContext );
# Don't expect an immidate SSL handshake upon connection.
sslServer.start_immediately = false;
sslSocket = sslServer.accept;
sslSocket.puts( "Toast.." );
# Server loop
while line = sslSocket.gets
line.chomp!;
if "STARTTLS" == line
# Starting TLS
sslSocket.accept;
end
sslSocket.puts( "Got '#{line}'" );
end
sslSocket.close;
元の投稿者は STARTTLS をテストする方法を知っていると確信していますが、残りの人はこのリマインダーが必要になるかもしれません。実際、私は通常、GNUTLS パッケージ (debian/ubuntu の gnutls-bin) のユーティリティを使用して starttls をテストしています。これにより、いつでもハンドシェイクを開始できるからです。
$ gnutls-cli --starttls --port 9002 --insecure localhost
これは、プレーン テキストの TCP ソケット モードで接続します。いくつかの行を入力して、それらをエコーします。このトラフィックは暗号化されていません。を送信するSTARTTLS
と、sslSocket.accept
が呼び出され、サーバーは SSL ハンドシェイクを待機します。ctrl-d (EOF) を押して gnutls クライアントからハンドシェイクを開始し、暗号化された SSL 接続が確立されるのを確認します。後続の行も同様にエコーされますが、トラフィックは暗号化されています。