您的位置:首页 > 数据库 > Mongodb

Go实战--golang使用ssl连接MongoDB(mgo)

2017-08-25 10:54 543 查看
生命不止,继续 go go go!!!

之前写过关于golang如何使用mongodb的文章:

Go实战–golang中使用MongoDB(mgo)

文中主要介绍了Windows下如何安装mongodb,mongodb的简单命令,golang如何操作mongodb,以及使用golang+mongodb创建的微服务。

今天继续深深耕一点。

Windows下mongo使用配置文件

创建一个配置文件,例如命名为mongod.cfg

创建一个日志文件,例如命名为mongodb.log

创建一个存储数据的文件夹

配置文件中键入以下内容:

systemLog:
destination: file
path: "D:\\mongodb_log\\mongodb.log"
logAppend: true
storage:
dbPath: "D:\\mongodb_data\\db"
security:
authorization: enabled


cmd键入以下命令:

mongod --config "d:\Program Files\MongoDB\conf\mongod.cfg"


此时查看mongodb.log内容为:

2017-08-24T02:18:49.250-0700 I CONTROL  [initandlisten] MongoDB starting : pid=3004 port=27017 dbpath=D:\mongodb_data\db 64-bit host=LAPTOP-MNU6522J
2017-08-24T02:18:49.250-0700 I CONTROL  [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2017-08-24T02:18:49.250-0700 I CONTROL  [initandlisten] db version v3.4.6
2017-08-24T02:18:49.250-0700 I CONTROL  [initandlisten] git version: c55eb86ef46ee7aede3b1e2a5d184a7df4bfb5b5
2017-08-24T02:18:49.251-0700 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.1u-fips  22 Sep 2016
2017-08-24T02:18:49.251-0700 I CONTROL  [initandlisten] allocator: tcmalloc
2017-08-24T02:18:49.251-0700 I CONTROL  [initandlisten] modules: none
2017-08-24T02:18:49.251-0700 I CONTROL  [initandlisten] build environment:
2017-08-24T02:18:49.251-0700 I CONTROL  [initandlisten]     distmod: 2008plus-ssl
2017-08-24T02:18:49.252-0700 I CONTROL  [initandlisten]     distarch: x86_64
2017-08-24T02:18:49.252-0700 I CONTROL  [initandlisten]     target_arch: x86_64
2017-08-24T02:18:49.252-0700 I CONTROL  [initandlisten] options: { config: "d:\Program Files\MongoDB\conf\mongod.cfg", security: { authorization: "enabled" }, storage: { dbPath: "D:\mongodb_data\db" }, systemLog: { destination: "file", logAppend: true, path: "D:\mongodb_log\mongodb.log" } }
2017-08-24T02:18:49.253-0700 I -        [initandlisten] Detected data files in D:\mongodb_data\db created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2017-08-24T02:18:49.253-0700 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=3540M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),
2017-08-24T17:18:51.229+0800 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory 'D:/mongodb_data/db/diagnostic.data'
2017-08-24T17:18:51.231+0800 I NETWORK  [thread1] waiting for connections on port 27017


使用tail查看实时日志

此时,你是不是很怀念linux呢,实时查看日志。我们也可以在windows上使用tail命令

下载

http://files.cnblogs.com/hantianwei/tail.zip

解压,添加到环境变量

重启一个cmd,键入:

tail -f D:\mongodb_log\mongodb.log


为mongodb增加证书

生成证书

命令:

openssl req -newkey rsa:2048 -new -x509 -days 365 -nodes -out mongodb-cert.crt -keyout mongodb-cert.key


需要填写一些信息:

λ openssl req -newkey rsa:2048 -new -x509 -days 365 -nodes -out mongodb-cert.crt -keyout mongodb-cert.key
Generating a 2048 bit RSA private key
..........+++
..............................................+++
writing new private key to 'mongodb-cert.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:cn
State or Province Name (full name) [Some-State]:beijing
Locality Name (eg, city) []:beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:superwang
Organizational Unit Name (eg, section) []:wangshubo
Common Name (e.g. server FQDN or YOUR name) []:wangshubo
Email Address []:wangshubo1989@126.com


生成pem

cat mongodb-cert.key mongodb-cert.crt > mongodb.pem


修改配置文件

mongod.cfg文件增加ssl:

systemLog:
destination: file
path: "D:\\mongodb_log\\mongodb.log"
logAppend: true
storage:
dbPath: "D:\\mongodb_data\\db"
security:
authorization: enabled
net:
ssl:
mode: requireSSL
PEMKeyFile: "D:\\Program Files\\MongoDB\\mongodb.pem"


启动mongo服务

mongod --config "d:\Program Files\MongoDB\conf\mongod.cfg"


通过tail查看日志:

2017-08-24T17:35:24.671+0800 I CONTROL  [main] ***** SERVER RESTARTED *****
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten] MongoDB starting : pid=9880 port=27017 dbpath=D:\mongodb_data\db 64-bit host=LAPTOP-MNU6522J
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten] db version v3.4.6
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten] git version: c55eb86ef46ee7aede3b1e2a5d184a7df4bfb5b5
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.1u-fips  22 Sep 2016
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten] allocator: tcmalloc
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten] modules: none
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten] build environment:
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten]     distmod: 2008plus-ssl
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten]     distarch: x86_64
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten]     target_arch: x86_64
2017-08-24T17:35:25.831+0800 I CONTROL  [initandlisten] options: { config: "d:\Program Files\MongoDB\conf\mongod.cfg", net: { ssl: { PEMKeyFile: "D:\Program Files\MongoDB\mongodb.pem", mode: "requireSSL" } }, security: { authorization: "enabled" }, storage: { dbPath: "D:\mongodb_data\db" }, systemLog: { destination: "file", logAppend: true, path: "D:\mongodb_log\mongodb.log" } }
2017-08-24T17:35:25.833+0800 I -        [initandlisten] Detected data files in D:\mongodb_data\db created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2017-08-24T17:35:25.833+0800 I STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=3540M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),
2017-08-24T17:35:26.762+0800 I CONTROL  [initandlisten]
2017-08-24T17:35:26.762+0800 I CONTROL  [initandlisten] ** WARNING: No SSL certificate validation can be performed since no CA file has been provided
2017-08-24T17:35:26.762+0800 I CONTROL  [initandlisten] **          Please specify an sslCAFile parameter.
2017-08-24T17:35:27.090+0800 I FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory 'D:/mongodb_data/db/diagnostic.data'
2017-08-24T17:35:27.092+0800 I NETWORK  [thread1] waiting for connections on port 27017 ssl


启动mongodb客户端

cmd输入命令:

mongo


如下:

MongoDB shell version v3.4.6
connecting to: mongodb://127.0.0.1:27017
2017-08-24T17:38:05.507+0800 I NETWORK  [thread1] Socket recv() 远程主机强迫关闭了一个现有的连接。 127.0.0.1:27017
2017-08-24T17:38:05.552+0800 I NETWORK  [thread1] SocketException: remote: (NONE):0 error: 9001 socket exception [RECV_ERROR] server [127.0.0.1:27017]
2017-08-24T17:38:05.595+0800 E QUERY    [thread1] Error: network error while attempting to run command 'isMaster' on host '127.0.0.1:27017'  :
connect@src/mongo/shell/mongo.js:237:13
@(connect):1:6
exception: connect failed


没有证书的原因

通过ssl启动mongodb客户端

cmd键入命令:

mongo --ssl --sslPEMKeyFile "D:\Program Files\MongoDB\mongodb.pem" --sslAllowInvalidCertificates


如下:

MongoDB shell version v3.4.6
connecting to: mongodb://127.0.0.1:27017
2017-08-24T17:47:06.597+0800 W NETWORK  [thread1] SSL peer certificate validation failed: self signed certificate
2017-08-24T17:47:06.597+0800 W NETWORK  [thread1] The server certificate does not match the host name. Hostname: 127.0.0.1 does not match CN: wangshubo
MongoDB server version: 3.4.6


这里需要提醒的是,千万不要忘记
--sslAllowInvalidCertificates
,因为这是我们自制的证书。

解决not authorized on admin to execute command的问题

1.不带ssl启动mongod

mongod.exe --dbpath d:\mongodb_data\db


2.客户端端连接

mongo


3.切换到admin

use admin


4.创建role

> db.createRole({role:'sysadmin',roles:[],privileges:[{resource:{anyResource:true},actions:['anyAction']}]})
{
"role" : "sysadmin",
"roles" : [ ],
"privileges" : [
{
"resource" : {
"anyResource" : true
},
"actions" : [
"anyAction"
]
}
]
}


5.切换到test,创建用户

> use test
switched to db test
> db.createUser({user:'wangshubo',pwd:'dabaojian',roles:[{role:'sysadmin',db:'admin'}]})
Successfully added user: {
"user" : "wangshubo",
"roles" : [
{
"role" : "sysadmin",
"db" : "admin"
}
]
}


6.重新启动mongodb服务端,使用认证

mongod --config "d:\Program Files\MongoDB\conf\mongod.cfg"


7.使用ssl连接

mongo --ssl --sslPEMKeyFile "D:\Program Files\MongoDB\mongodb.pem" --sslAllowInvalidCertificates --sslAllowInvalidHostnames


8.使用

使用test

use test


查看数据库

> show dbs
2017-08-25T10:36:48.550+0800 E QUERY    [thread1] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }",
"code" : 13,
"codeName" : "Unauthorized"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:769:19
shellHelper@src/mongo/shell/utils.js:659:15
@(shellhelp2):1:1


9.不要灰心,操作前先认证就好了

> db.auth("wangshubo","dabaojian")
1
> show dbs
admin  0.000GB
local  0.000GB
store  0.000GB
test   0.000GB


golang通过ssl连接mongodb

还记得吗,昨天写了一篇日志:

Go实战–golang中使用HTTPS以及TSL(.crt、.key、.pem区别以及crypto/tls包介绍)

所以,关于golang中介绍不再过多赘述,直接可以上代码了。为了方便起见,我直接把证书内容写到了程序里面。

package main

import (
"crypto/tls"
"crypto/x509"
"fmt"
"log"
"net"

"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)

const rootPEM = `-----BEGIN CERTIFICATE-----
MIID+zCCAuOgAwIBAgIJAKi7rDeJTJPeMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD
VQQGEwJjbjEQMA4GA1UECAwHYmVpamluZzEQMA4GA1UEBwwHYmVpamluZzESMBAG
A1UECgwJc3VwZXJ3YW5nMRIwEAYDVQQLDAl3YW5nc2h1Ym8xEjAQBgNVBAMMCXdh
bmdzaHVibzEkMCIGCSqGSIb3DQEJARYVd2FuZ3NodWJvMTk4OUAxMjYuY29tMB4X
DTE3MDgyNDA5MjU1NFoXDTE4MDgyNDA5MjU1NFowgZMxCzAJBgNVBAYTAmNuMRAw
DgYDVQQIDAdiZWlqaW5nMRAwDgYDVQQHDAdiZWlqaW5nMRIwEAYDVQQKDAlzdXBl
cndhbmcxEjAQBgNVBAsMCXdhbmdzaHVibzESMBAGA1UEAwwJd2FuZ3NodWJvMSQw
IgYJKoZIhvcNAQkBFhV3YW5nc2h1Ym8xOTg5QDEyNi5jb20wggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDldV1M4lMT630NgMGTXcrcusCuzb/JMN3lMb7w
umlGwBo0XrSLbYRHzWdkx1yH9P0VZFalji34ELDTbD951sL/+/Hg4HC3qguVcduv
7wCiKpIm71NWYaYnfOyjCVi8OoGp6eMuImh+jpTGTPTwwwZzG1vc08f+rwtvfDzU
X+1FOvtPmsimmlDssd/edRWvbKkMCNmrVoLJ+zZQ0BfnovcN38+nEcXYakgZHM09
6hC2ASn8zIipoXo7nGaOwLhHnem0aLkdtcnwSvDgibe+eKA36dvZHnGIPj1sgAXl
6ZQvDNbVV5ITPCECf/ivGu1hiN6U0dJMUHeyT1wkuB+TWrPJAgMBAAGjUDBOMB0G
A1UdDgQWBBSjWxZXdtAN2ojdepVSHL5qAxzH8zAfBgNVHSMEGDAWgBSjWxZXdtAN
2ojdepVSHL5qAxzH8zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAI
F7f3md5ffJtpBv4wqfWLiIMi18btXz3hkX8VuCTBvmoxCSeIqnSrLa2pFUlGFpoh
/xkkUcHP5hUA44NTJAYGu5N5PxdLuCe0DrSfqLZWiJzED19Fq1TwI0DU4hNfDWlk
W7idVPVJWEXNuy5BVXmvpUEn+nAV9Qo/SZ816kdPyZMksVId+W7twz4s+t+VCTaY
hQk+bbDw48ciQIDmBn44PoNhL1KCxvJf4QRQwIEaQfIK70HjmhVzDoAGdSM3A1v7
LqQG1bOeAFxY3PPAxfuZOQNtfXhX7JbupvC8c3o5X4hOqLMMr198D+ANsq8effwR
T2fbAPEzzPNDZjydwk2P
-----END CERTIFICATE-----
`

type Person struct {
Name  string
Phone string
}

func main() {

roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM([]byte(rootPEM))
if !ok {
panic("failed to parse root certificate")
}

tlsConfig := &tls.Config{
RootCAs:            roots,
InsecureSkipVerify: true,
}

dialInfo, err := mgo.ParseURL("mongodb://wangshubo:dabaojian@localhost:27017/test")
if err != nil {
log.Println(err)
panic(err)
}

dialInfo.DialServer = func(addr *mgo.ServerAddr) (net.Conn, error) {
conn, err := tls.Dial("tcp", addr.String(), tlsConfig)
if err != nil {
log.Println(err)
}
return conn, err
}

session, err := mgo.DialWithInfo(dialInfo)
if err != nil {
log.Println(err)
panic(err)
}

defer session.Close()

session.SetMode(mgo.Monotonic, true)

c := session.DB("test").C("people")
err = c.Insert(&Person{"superWang", "13478808311"},
&Person{"David", "15040268074"})
if err != nil {
log.Fatal(err)
}

result := Person{}
err = c.Find(bson.M{"name": "superWang"}).One(&result)
if err != nil {
log.Fatal(err)
}

fmt.Println("Name:", result.Name)
fmt.Println("Phone:", result.Phone)
}


输出:

Name: superWang

Phone: 13478808311

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: