尝试通过SSL创建一个简单的Ruby服务器
我正在尝试用Ruby创建一个简单的SSL客户端和服务器。但是我收到了一条神秘的错误信息,文档也没有帮助 这是我的服务器代码:尝试通过SSL创建一个简单的Ruby服务器,ruby,openssl,client-server,Ruby,Openssl,Client Server,我正在尝试用Ruby创建一个简单的SSL客户端和服务器。但是我收到了一条神秘的错误信息,文档也没有帮助 这是我的服务器代码: #!/usr/bin/ruby require "gserver" require "openssl" listeningPort = Integer(ARGV[0]) class Server < GServer def initialize(listeningPort) @sslContext = OpenSSL::SSL::SSLContex
#!/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
当我连接时,我在服务器和客户端上都会出现以下错误:
in `connect': SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A: unknown protocol (OpenSSL::SSL::SSLError)
问题可能是它不信任证书(自签名)。我不知道如何告诉客户信任该证书。上面,我已经将服务器的证书放在上下文中,但这只是一个偶然的机会。我甚至不确定我的证书是否为可接受的格式(它是base64格式,文件中有证书和私钥)。文档非常少,在这个领域的网络上似乎也没有太多
有什么想法吗?多亏了链接到一些像样的文档,我才想出了办法 首先,SSLSocket.connect()只能在客户端上调用 但主要的问题是,我正在尝试使用GServer套接字并将其升级到SSL。相反,我应该使用OpenSSL::SSL::SSLServer 另外,我将我的证书和私钥分为两个文件 以下是工作服务器:
#!/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
如果需要提供中间证书,请使用它们设置sslContext.extra\u chain\u cert 如果使用letsencrypt证书,请将fullchain.pem用于sslContext.cert,privkey.pem用于sslContext.key,将[“chain.pem”]用于sslContext.extra_chain_cert。这样,您还可以通过全链验证从浏览器测试与服务器的连接
注意:这是对作者答案的补充,但被user@joe拒绝了,因为他知道这不是对问题的补充。如果你同意他的观点,试着用这个答案来解决这个问题 啊,这很有帮助:您可以发布生成cert.pem和priv.pem的命令吗?
openssl req-x509-newkey rsa:4096-keyout priv.pem-out cert.pem-days 365-nodes#remove-nodes向其中添加pw代码>用于生成它们客户端实现在我看来是错误的。该解决方案只是测试服务器和客户端共享是否具有预共享证书。认证不是这样运作的。客户端有一个存储并验证服务器提供的证书链。检查(主要说明)。我不知道您是否只会获得有效的ssl\u套接字
。注意ssl的上下文。验证ssl模式并挖掘其含义。
#!/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
#!/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