草庐IT

mongodb - 在 MongoDB 上设置 SSL 后,https 请求不起作用,但 http 可以

coder 2023-11-01 原文

根据几篇文章、mongodb.org 手册、一些 dba.stackexchange.com 问题和各种教程,我已经在我的 mongo 数据库上设置了自签名证书和 SSL。

因此,我使用以下命令(或配置文件)运行 mongodb 实例:

mongod --sslMode requireSSL --sslPEMKeyFile ./selfsignsec/mongodb.pem --sslCAFile ./selfsignsec/ca.pem 

看起来一切都很好:

[datetime].129-0700 I CONTROL  [initandlisten] MongoDB starting : pid=42188 port=27017 dbpath=/data/db
...
[datetime].129-0700 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.2 22 Jan 2015
...
[datetime].129-0700 I CONTROL  [initandlisten] options: { net: { ssl: { CAFile: "./selfsignsec/dbclient.pem", PEMKeyFile: "./selfsignsec/mongodb.pem", mode: "requireSSL" } } }
...
[datetime].178-0700 I NETWORK  [initandlisten] waiting for connections on port 27017 ssl

然后,我使用以下代码通过客户端证书连接到该实例:

...

var https = require('https'),
    fs = require('fs'); 
...

app.use(methodOverride('X-HTTP-Method-Override')); //ability to use put, etc.
...

// For the moment, allow just about everything for CORS origin, methods, and headers
...

// http://docs.mongodb.org/manual/core/authentication/
var config = {
                mongo: {
                    host: "localhost",
                    port: 27017,
                    db: "test",
                    ssl: true
                   }
                };

var dbstring = "mongodb://" + config.mongo.host + ":" + config.mongo.port +
"/" + config.mongo.db;

var dboptions = {
    server: {
            ssl: true,
            sslCert: fs.readFileSync('./selfsignsec/my-client.crt.pem'),
            sslKey: fs.readFileSync('./selfsignsec/my-client.key.pem')
        }
    };

mongoose.connect(dbstring, dboptions);
mongoose.connection.once('open', function() {

    app.models = require('./models/index');
    var routes = require('./routes');

    _.each(routes, function(controller, route) {
        // declaring controllers & pass in the app & route
        app.use(route, controller(app, route));
    }); 

    console.log('Secure Express server listening on port 27017...');
    app.listen(27017);

});

服务器日志看起来不错:

[datetime].166-0700 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:57591 #1 (1 connection now open)
...

但是,在浏览器中,当我转到 https://localhost:27017/somecollection 时,GET 失败。我没有建立连接 (ERR_CONNECTION_CLOSED)。

当我只使用http时,我得到了json集合!

还有一次,我使用了管理员用户名和密码,得到了:

[datetime].347-0700 I ACCESS   [conn43] Successfully authenticated as principal adminrole on test

但是浏览器的请求和响应是一样的:https 没有响应,http 请求完全收集。

如果mongod和mongo客户端都设置了ssl,http怎么返回结果呢?

长话短说:

顺便说一句,如果我不在客户端代码中传递任何 ssl 值,我会从服务器得到我期望的:

AssertionException handling request, closing client connection: 17189 The server is configured to only allow SSL connections

如果我通过了一个错误的证书,我确实得到了预期:

no SSL certificate provided by peer; connection rejected
end connection 127.0.0.1:55829 (0 connections now open)

隐身请求的结果与上述相同。

netstat -a 结果 | grep 27017:

tcp46      0      0  *.27017                *.*                    LISTEN     
tcp4       0      0  localhost.27017        localhost.56297        ESTABLISHED
tcp4       0      0  localhost.56297        localhost.27017        ESTABLISHED
tcp4       0      0  localhost.27017        localhost.56296        ESTABLISHED
tcp4       0      0  localhost.56296        localhost.27017        ESTABLISHED
tcp4       0      0  localhost.27017        localhost.56295        ESTABLISHED
tcp4       0      0  localhost.56295        localhost.27017        ESTABLISHED
tcp4       0      0  localhost.27017        localhost.56294        ESTABLISHED
tcp4       0      0  localhost.56294        localhost.27017        ESTABLISHED
tcp4       0      0  localhost.27017        localhost.56293        ESTABLISHED
tcp4       0      0  localhost.56293        localhost.27017        ESTABLISHED
tcp4       0      0  *.27017                *.*                    LISTEN     
704e9db9a444912b stream      0      0 704e9db9b79bb6c3                0                0                0 /tmp/mongodb-27017.sock

openssl s_client -connect localhost:27017 -tls1 -servername localhost | 的结果openssl x509 -text -noout:

depth=1 C = US, ST = CA, L = SanFran, O = Local Signing Authority, CN = localhost
verify error:num=19:self signed certificate in certificate chain
read:errno=0
Certificate:
Data:
    Version: 1 (0x0)
    Serial Number: 13550121380367150794 (0xbc0bb39a9435aeca)
Signature Algorithm: sha256WithRSAEncryption
    Issuer: C=US, ST=CA, L=SanFran, O=Local Signing Authority, CN=localhost
    Validity
        Not Before: May 21 19:42:47 2015 GMT
        Not After : Oct  2 19:42:47 2016 GMT
    Subject: C=US, ST=CA, L=SanFran, O=Local Signing Authority, CN=127.0.0.1
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
            Public-Key: (2048 bit)
            Modulus:
                00:ba:0e:a4:0d:23:6c:a7:01:a9:e7:92:0e:9e:15:
                1c:83:5d:91:32:7a:fb:6e:6f:da:ad:70:24:ef:a0:
                4d:83:24:a1:f0:d0:6a:40:81:12:aa:f9:40:6d:53:
                b3:d6:c1:24:b4:c9:07:a2:e9:5a:80:7a:51:30:71:
                9c:e2:ee:fc:ce:d7:b1:2c:e2:91:40:94:9d:43:50:
                08:33:67:cb:58:66:0d:c7:13:cc:45:20:e7:ef:70:
                c4:8a:26:64:b5:af:4e:f8:c4:70:d8:7e:17:21:40:
                4f:12:5b:35:71:b0:51:87:6f:12:4e:06:99:12:ac:
                0e:4e:8e:7d:9c:6e:41:6f:d8:ca:93:77:9a:ee:60:
                7e:9d:86:c1:6d:df:7c:a6:3a:71:cd:73:d8:8e:d1:
                d8:61:f9:48:e5:02:44:10:31:94:58:1a:d2:75:a7:
                14:83:b5:ad:b9:2e:ae:7a:65:af:8d:5d:31:65:fd:
                c5:1f:e1:4f:f2:fb:80:df:08:25:64:5b:a6:c2:9d:
                aa:10:8b:25:2e:fc:75:65:82:ea:4f:5c:18:68:21:
                2b:0e:00:b8:57:e9:fb:14:67:18:14:ae:e0:c5:e6:
                d9:5d:a1:df:6e:9d:27:0b:72:bd:33:e2:e8:a6:b3:
                e8:a1:94:cc:ec:78:15:1b:37:b2:23:57:7c:d6:65:
                c8:71
            Exponent: 65537 (0x10001)
Signature Algorithm: sha256WithRSAEncryption
     56:f6:ca:05:be:4a:ab:8d:94:8b:4e:7a:51:e2:8c:ed:d3:0e:
     16:ac:68:61:eb:5b:d0:c3:e5:96:f2:50:12:f3:a8:10:14:c8:
     9f:63:cc:f3:d3:b9:c2:71:8b:ac:7a:9c:9e:61:8d:09:26:4c:
     6f:0d:30:2d:87:e2:e8:aa:77:f0:33:25:51:cb:67:d9:99:a5:
     3c:cf:3a:3d:27:63:cd:3e:42:50:da:d6:68:a0:0a:c4:78:ad:
     aa:a5:b1:93:8f:01:d0:70:72:5e:c0:19:5a:43:94:ba:65:35:
     aa:0d:8b:da:b5:16:50:f5:bc:8f:cf:80:c9:f9:53:67:eb:68:
     a2:0b:60:11:a0:c0:04:ef:47:5c:8b:e6:28:09:37:b9:43:bb:
     0f:8f:1d:28:2a:d7:aa:46:6e:7d:32:64:44:70:74:c0:84:bd:
     3e:82:87:85:68:51:c1:ba:44:d1:b3:29:bd:78:d8:80:63:59:
     40:a5:dd:97:a1:a5:35:7c:5d:cb:11:1d:39:63:08:15:f5:00:
     7c:6f:85:a8:df:9b:26:aa:66:a4:8a:81:f9:7a:ea:65:f5:03:
     89:0b:ef:49:67:60:79:c5:82:39:eb:b3:88:9e:7b:b9:f9:6e:
     c1:2c:30:19:23:d5:c8:3a:4e:c6:2a:33:c0:5a:5f:74:04:90:
     91:07:b3:f2

最佳答案

你有两个问题。首先是自签名服务器证书;其次是 CN 中的 DNS 名称。您有第三个相关问题,一旦您解决了前两个问题,该问题就会消失。

第一个问题,自签名证书,见How do you sign Certificate Signing Request with your Certification Authority? .浏览器已积极反对自签名证书。

第二个问题,CN中的DNS名称,参见How to create a self-signed certificate with openssl? .这是另一个浏览器要求。 DNS 名称必须放在主题备用名称 (SAN) 中,而不是通用名称 (CN) .


But, in the browser, when I go to https://localhost:27017/somecollection, the GET fails.

一个相关的问题是主题的 CN 是 CN=127.0.0.1127.0.0.1 不是 localhost,所以浏览器认为它是不同的来源。对于这个,甚至其他用户代理(非浏览器)也会失败。非浏览器包括 cURL 和 GNU 的 Wget。

一旦将所有 DNS 名称放入 SAN 中,此问题就会消失。 DNS 名称包括 127.0.0.1localhostjohn-dev-machinejohn-dev-machine.example.com


您可以查看服务器是否真的通过 HTTPS 提供服务:

echo -e "GET /somecollection HTTP/1.1\r\nHost:localhost\r\n\r\n" | \
  openssl s_client -connect localhost:27017 -tls1 -servername localhost -ign_eof

您应该会看到返回的原始 HTML。然后您可以按 CTRL+C 退出。

OpenSSL 不执行主机名检查(程序员必须手动执行)或强制执行 DNS 名称策略(在 CN 或 SAN 中)。因此,如果服务器通过 HTTPS 在该端口上提供页面,它将起作用。

关于mongodb - 在 MongoDB 上设置 SSL 后,https 请求不起作用,但 http 可以,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30354647/

有关mongodb - 在 MongoDB 上设置 SSL 后,https 请求不起作用,但 http 可以的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  3. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  4. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  5. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  6. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  7. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  8. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  9. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  10. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

随机推荐