尝试通过SSL创建一个简单的Ruby服务器 [英] Trying to create a simple Ruby server over SSL

查看:102
本文介绍了尝试通过SSL创建一个简单的Ruby服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Ruby中创建一个简单的SSL客户端和服务器。

I am trying to create a simple SSL client and server in Ruby. But I'm getting a cryptic error message and the documentation is of no help.

这是我的服务器代码:

#!/usr/bin/ruby

require "gserver"
require "openssl"

listeningPort = Integer(ARGV[0])

class Server < GServer
  def initialize(listeningPort)
    @sslContext = OpenSSL::SSL::SSLContext.new
    @sslContext.cert = OpenSSL::X509::Certificate.new(File.open("MyCert.pem"))
    super(listeningPort, "0.0.0.0")
  end
  def serve(io)
    begin
      ssl = OpenSSL::SSL::SSLSocket.new(io, @sslContext)
      ssl.sync_close = true
      ssl.connect
      while (lineIn = ssl.gets)
        lineIn = lineIn.chomp
        $stdout.puts "=> " + lineIn
        lineOut = "You said: " + lineIn
        $stdout.puts "<= " + lineOut
        ssl.puts lineOut
      end
    rescue
      $stderr.puts $!
    end
  end
end

server = Server.new(listeningPort)
server.start
server.join

客户代码类似:

#!/usr/bin/ruby

require "socket"
require "thread"
require "openssl"

host = ARGV[0]
port = Integer(ARGV[1])

socket = TCPSocket.new(host, port)
sslContext = OpenSSL::SSL::SSLContext.new
sslContext.cert = OpenSSL::X509::Certificate.new(File.open("MyCert.pem"))
ssl = OpenSSL::SSL::SSLSocket.new(socket, sslContext)
ssl.sync_close = true
ssl.connect
puts ssl.peer_cert   # this is nil

Thread.new {
  begin
    while lineIn = ssl.gets
      lineIn = lineIn.chomp
      $stdout.puts lineIn
    end
  rescue
    $stderr.puts "Error in input loop: " + $!
  end
}

while (lineOut = $stdin.gets)
  lineOut = lineOut.chomp
  ssl.puts lineOut
end

当我连接时,我在服务器和客户端都遇到这个错误:

When I connect, I get this error on both the server and the client:

in `connect': SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol (OpenSSL::SSL::SSLError)

问题可能是它不信任证书(自签名)。我不知道如何告诉客户端信任该证书。上面,我把服务器的证书放在上下文中,但这只是在黑暗中的一枪。我甚至不确定我的证书是一个可接受的格式(它是在base64与证书和文件中的私钥)。文档很少,在这一领域似乎没有太多的网络。

The problem could be that it doesn't trust the certificate (self-signed). I'm not sure how to tell the client to trust that certificate. Above, I have put the server's cert in the context, but that was just a shot in the dark. I'm not even sure my certificate is in an acceptable format (it is in base64 with the cert and the private key in the file). The documentation is very scant and there doesn't seem to be much on the web in this area either.

任何想法?

推荐答案

一方面,SSLSocket.connect()只能在客户端上调用。

For one thing, SSLSocket.connect() is only meant to be called on the client.

但是主要的问题是,我试图采取GServer套接字并将其升级到SSL。相反,我应该使用OpenSSL :: SSL :: SSLServer。

But the main problem is that I'm trying to take a GServer socket and upgrade it to SSL. Instead, I should use OpenSSL::SSL::SSLServer.

此外,我将我的证书和私钥分成两个文件。

Also, I separated my certificate and private key into two files.

这是正在工作的服务器:

Here is the working server:

#!/usr/bin/ruby

require "socket"
require "openssl"
require "thread"

listeningPort = Integer(ARGV[0])

server = TCPServer.new(listeningPort)
sslContext = OpenSSL::SSL::SSLContext.new
sslContext.cert = OpenSSL::X509::Certificate.new(File.open("cert.pem"))
sslContext.key = OpenSSL::PKey::RSA.new(File.open("priv.pem"))
sslServer = OpenSSL::SSL::SSLServer.new(server, sslContext)

puts "Listening on port #{listeningPort}"

loop do
  connection = sslServer.accept
  Thread.new {
    begin
      while (lineIn = connection.gets)
        lineIn = lineIn.chomp
        $stdout.puts "=> " + lineIn
        lineOut = "You said: " + lineIn
        $stdout.puts "<= " + lineOut
        connection.puts lineOut
      end
    rescue
      $stderr.puts $!
    end
  }
end

>

And client:

#!/usr/bin/ruby

require "socket"
require "thread"
require "openssl"

host = ARGV[0]
port = Integer(ARGV[1])

socket = TCPSocket.new(host, port)
expectedCert = OpenSSL::X509::Certificate.new(File.open("cert.pem"))
ssl = OpenSSL::SSL::SSLSocket.new(socket)
ssl.sync_close = true
ssl.connect
if ssl.peer_cert.to_s != expectedCert.to_s
  stderrr.puts "Unexpected certificate"
  exit(1)
end

Thread.new {
  begin
    while lineIn = ssl.gets
      lineIn = lineIn.chomp
      $stdout.puts lineIn
    end
  rescue
    $stderr.puts "Error in input loop: " + $!
  end
}

while (lineOut = $stdin.gets)
  lineOut = lineOut.chomp
  ssl.puts lineOut
end

这篇关于尝试通过SSL创建一个简单的Ruby服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆