Skip to content

Commit

Permalink
新增 grpc ssl 安全配置
Browse files Browse the repository at this point in the history
  • Loading branch information
xdxiaodong committed Dec 3, 2019
1 parent d142b52 commit ee585f5
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 17 deletions.
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
## Install

```bash
$ npm i egg-grpc --save
$ npm i egg-grpc-ssl --save
```

```js
// {app_root}/config/plugin.js
exports.grpc = {
enable: true,
package: 'egg-grpc',
package: 'egg-grpc-ssl',
};
```

Expand All @@ -45,6 +45,15 @@ exports.grpc = {
// dir: 'app/proto', // proto files dir, relative path
// property: 'grpc', // default attach to `ctx.grpc.**`
// loadOpts: { convertFieldsToCamelCase: true, }, // message field case: `string user_name` -> `userName`
// clientSsl: {
// enable: false,
// grpc.credentials.createSsl
// rootCerts: 'config/cert/server.crt',
// options: {
// "grpc.ssl_target_name_override": 'example.server',
// "grpc.default_authority": 'example.server'
// }
// }
};
```

Expand Down Expand Up @@ -211,11 +220,11 @@ stream.end(data3);

## Example

see [grpc.tests.js](test/grpc.tests.js).
see [test/grpc.tests.js](test/grpc.tests.js).

## Questions & Suggestions

Please open an issue [here](https://github.com/eggjs/egg/issues).
Please open an issue [here](https://github.com/xdxiaodong/egg-grpc/issues).

## License

Expand Down
17 changes: 13 additions & 4 deletions README.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@
## 安装

```bash
$ npm i egg-grpc --save
$ npm i egg-grpc-ssl --save
```

```js
// {app_root}/config/plugin.js
exports.grpc = {
enable: true,
package: 'egg-grpc',
package: 'egg-grpc-ssl',
};
```

Expand All @@ -45,6 +45,15 @@ exports.grpc = {
// dir: 'app/proto', // proto 文件目录,相对路径
// property: 'grpc', // 默认挂载到 `ctx.grpc.**`
// loadOpts: { convertFieldsToCamelCase: true, }, // message field case: `string user_name` -> `userName`
// clientSsl: {
// enable: false,
// grpc.credentials.createSsl
// rootCerts: 'config/cert/server.crt',
// options: {
// "grpc.ssl_target_name_override": 'example.server',
// "grpc.default_authority": 'example.server'
// }
// }
};
```

Expand Down Expand Up @@ -211,11 +220,11 @@ stream.end(data3);

## 示例

参见 [grpc.tests.js](test/grpc.tests.js).
参见 [test/grpc.tests.js](test/grpc.tests.js).

## 问题反馈

访问并发起 [issue](https://github.com/eggjs/egg/issues).
访问并发起 [issue](https://github.com/xdxiaodong/egg-grpc/issues).

## License

Expand Down
24 changes: 24 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
'use strict';

const loader = require('./lib/grpc_loader');
const fs = require('fs');
const path = require('path');


module.exports = app => {
// grpc.setLogger(app.coreLogger);
const GrpcLoader = app.loader.GrpcLoader = loader(app);
new GrpcLoader({}).load();
// grpc ssl
if (app.config.grpc.clientSsl.enable) {
if (app.config.grpc.clientSsl.rootCerts.trim() !== '') {
const rootCerts = path.join(app.baseDir, app.config.grpc.clientSsl.rootCerts)
if (fs.existsSync(rootCerts)) {
app.grpc.clientSsl.rootCerts = fs.readFileSync(rootCerts);
}
}
if (app.config.grpc.clientSsl.privateKey.trim() != '') {
const privateKey = path.join(app.baseDir, app.config.grpc.clientSsl.privateKey)
if (fs.existsSync(privateKey)) {
app.grpc.clientSsl.privateKey = fs.readFileSync(privateKey);
}
}
if (app.config.grpc.clientSsl.certChain.trim() != '') {
const certChain = path.join(app.baseDir, app.config.grpc.clientSsl.certChain)
if (fs.existsSync(certChain)) {
app.grpc.clientSsl.certChain = fs.readFileSync(certChain);
}
}
}
};
8 changes: 8 additions & 0 deletions app/extend/application.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

const GrpcBaseClass = require('../../lib/base_grpc');
const GRPC = Symbol('Application#grpc');

module.exports = {

Expand Down Expand Up @@ -36,4 +37,11 @@ module.exports = {
get GrpcBaseClass() {
return GrpcBaseClass;
},
get grpc() {
// this 就是 app 对象,在其中可以调用 app 上的其他方法,或访问属性
if (!this[GRPC]) {
this[GRPC] = { clientSsl: { rootCerts: null, privateKey: null, certChain: null } }
}
return this[GRPC];
}
};
23 changes: 23 additions & 0 deletions config/config.default.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
* @property {Object} clientOpts - options pass to `new Client(host, credentials, opts)`
* @property {String} endpoint - default andress to connect, for debug or showcase purpose
* @property {Number} timeout - default 5000ms
* @property {Boolean} clientSsl.enable - enable client ssl
* @property {Buffer} clientSsl.rootCerts - The root certificate data file path,作为grpc client时仅提供该项作为证书即可
* @property {Buffer} clientSsl.privateKey - The client certificate private key file path, if applicable
* @property {Buffer} clientSsl.certChain - The client certificate cert chain file path, if applicable
* @property {Object} clientSsl.verifyOptions - Additional peer verification options, if desired
* @property {Object} clientSsl.options - 主要用于grpc.ssl_target_name_override和grpc.default_authority的配置
*/
exports.grpc = {
dir: 'app/proto',
Expand All @@ -20,4 +26,21 @@ exports.grpc = {
clientOpts: {},
endpoint: 'localhost:50051',
timeout: 5000,
/**
* 2019-12-03 by 张晓东
* 通过扩展原有配置的形式,使其支持tls/ssl安全
*/
clientSsl: {
enable: false,
// grpc.credentials.createSsl
// config/grpc/cert.server.crt
rootCerts: '', //
privateKey: '', // 作为grpc client时无需填写
certChain: '', // 作为grpc client时无需填写
verifyOptions: {},
options: {
"grpc.ssl_target_name_override": 'example.server',
"grpc.default_authority": 'example.server'
}
}
};
12 changes: 9 additions & 3 deletions lib/base_grpc.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module.exports = class BaseGrpc {

// delegate client rpc to this
for (const key of Object.keys(this.ProtoClass.service)) {
this[key] = function(...args) {
this[key] = function (...args) {
return this._invokeRPC(key, ...args);
};
}
Expand All @@ -40,7 +40,13 @@ module.exports = class BaseGrpc {
if (!this[CLIENT]) {
// options should NOT reuse, otherwise the user-agent will oom you!
// https://github.com/grpc/grpc/blob/master/src/node/src/client.js#L464
this[CLIENT] = new this.ProtoClass(this.config.endpoint, grpc.credentials.createInsecure(), Object.assign({}, this.config.clientOpts));
if (!this.config.clientSsl.enable) {
this[CLIENT] = new this.ProtoClass(this.config.endpoint, grpc.credentials.createInsecure(), Object.assign({}, this.config.clientOpts));
} else {
// TODO: 多个grpc实例
const ssl_creds = grpc.credentials.createSsl(this.app.grpc.clientSsl.rootCerts, this.app.grpc.clientSsl.privateKey, this.app.grpc.clientSsl.certChain, this.config.clientSsl.verifyOptions)
this[CLIENT] = new this.ProtoClass(this.config.endpoint, ssl_creds, Object.assign({}, this.config.clientOpts, this.config.clientSsl.options));
}
}
// TODO: config.ssl
return this[CLIENT];
Expand Down Expand Up @@ -83,7 +89,7 @@ module.exports = class BaseGrpc {
metadata = args[0];
options = undefined;
} else {
[ metadata, options, callback ] = args;
[metadata, options, callback] = args;
}
const invokeArgs = this._beforeRequest({ client, rpc, metadata, options, attrs, callback });
return this._invokeClientStreamRequest(invokeArgs);
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "egg-grpc",
"version": "1.0.3",
"name": "egg-grpc-ssl",
"version": "1.0.4",
"description": "grpc plugin for egg",
"eggPlugin": {
"name": "grpc"
Expand Down Expand Up @@ -50,12 +50,12 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/eggjs/egg-grpc.git"
"url": "git+https://github.com/xdxiaodong/egg-grpc.git"
},
"bugs": {
"url": "https://github.com/eggjs/egg/issues"
"url": "https://github.com/xdxiaodong/egg-grpc/issues"
},
"homepage": "https://github.com/eggjs/egg-grpc#readme",
"author": "TZ <atian25@qq.com>",
"homepage": "https://github.com/xdxiaodong/egg-grpc#readme",
"author": "xiaodong <yunfei_vip@qq.com>",
"license": "MIT"
}

0 comments on commit ee585f5

Please sign in to comment.