Skip to content

Add SSL support and update lambda context file require path #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ custom:
host: 'localhost'
port: 6379
db: 12
endpointAddressSSL: true
keyPath: contrib/secure/tls-key.pem
certPath: contrib/secure/tls-cert.pem
```

### Using with serverless-offline plugin
Expand All @@ -63,6 +66,14 @@ plugins:
- serverless-offline
```

### Setting up a Self Signed Certificate

When using with the AWS IoT Device SDK create a self-signed certificate using OpenSSL.

```$ openssl genrsa -out tls-key.pem 2048
$ openssl req -new -sha256 -key tls-key.pem -out my-csr.pem
$ openssl x509 -req -in my-csr.pem -signkey tls-key.pem -out tls-cert.pem```

## Todo

- Improve support of AWS Iot SQL syntax
Expand Down
59 changes: 52 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,21 @@ const evalInContext = require('./eval')
const createMQTTBroker = require('./broker')
// TODO: send PR to serverless-offline to export this
const functionHelper = require('serverless-offline/src/functionHelper')
const createLambdaContext = require('serverless-offline/src/createLambdaContext')
const LambdaContext = require('serverless-offline/src/LambdaContext');

const VERBOSE = typeof process.env.SLS_DEBUG !== 'undefined'
const defaultOpts = {
host: 'localhost',
location: '.',
port: 1883,
httpPort: 1884,
port: 1883, // HTTP
securePort: 8883, // HTTPS
httpPort: 1884, // WS
httpsPort: 1885, // WSS
noStart: false,
skipCacheInvalidation: false
skipCacheInvalidation: false,
endpointAddressSSL: false,
keyPath: '',
certPath: ''
}

const ascoltatoreOpts = {
Expand Down Expand Up @@ -63,6 +69,10 @@ class ServerlessIotLocal {
usage: 'http port for client connections over WebSockets. Default: 1884',
shortcut: 'h'
},
httpsPort: {
usage: 'https port for client connections over WebSockets. Default: 1885',
shortcut: 's'
},
noStart: {
shortcut: 'n',
usage: 'Do not start local MQTT broker (in case it is already running)',
Expand All @@ -71,6 +81,15 @@ class ServerlessIotLocal {
usage: 'Tells the plugin to skip require cache invalidation. A script reloading tool like Nodemon might then be needed',
shortcut: 'c',
},
endpointAddressSSL: {
usage: 'Instructs this plugin to use the SSL port for the endpoint address'
},
keyPath: {
usage: 'Path to the private key file'
},
certPath: {
usage: 'Path to the certificate file'
},
}
}
}
Expand Down Expand Up @@ -119,6 +138,7 @@ class ServerlessIotLocal {

_createMQTTBroker() {
const { host, port, httpPort } = this.options
const { securePort, httpsPort, keyPath, certPath, endpointAddressSSL } = this.options

const mosca = {
host,
Expand All @@ -130,14 +150,39 @@ class ServerlessIotLocal {
}
}

if (httpsPort) {
_.merge(mosca, {
secure: {
port: securePort
},
https: {
host,
port: httpsPort,
bundle: true
},
onlyHttp: false
})

if(keyPath && certPath) {
_.merge(mosca, {
secure: {
keyPath,
certPath
},
allowNonSecure: true
})
}
}

// For now we'll only support redis backend.
const redisConfigOpts = this.options.redis;

const ascoltatore = _.merge({}, ascoltatoreOpts, redisConfigOpts)

this.mqttBroker = createMQTTBroker(ascoltatore, mosca)

const endpointAddress = `${IP.address()}:${httpPort}`
const endpointPort = (endpointAddressSSL) ? httpsPort : httpPort;
const endpointAddress = `${host}:${endpointPort}`

// prime AWS IotData import
// this is necessary for below mock to work
Expand Down Expand Up @@ -182,7 +227,7 @@ class ServerlessIotLocal {
const fun = this._getFunction(key)
const funName = key
const servicePath = path.join(this.serverless.config.servicePath, location)
const funOptions = functionHelper.getFunctionOptions(fun, key, servicePath)
const funOptions = functionHelper.getFunctionOptions(fun, key, servicePath, runtime)
this.debug(`funOptions ${JSON.stringify(funOptions, null, 2)} `)

if (!fun.environment) {
Expand Down Expand Up @@ -293,7 +338,7 @@ class ServerlessIotLocal {
return
}

const lambdaContext = createLambdaContext(fn)
const lambdaContext = new LambdaContext(fn, {})
try {
handler(event, lambdaContext, lambdaContext.done)
} catch (error) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"aws-sdk-mock": "^1.7.0",
"ip": "^1.1.5",
"lodash": "^4.17.4",
"mosca": "^2.6.0",
"mosca": "^2.8.3",
"mqtt": "^2.13.1",
"mqtt-match": "^1.0.3",
"redis": "^2.8.0"
Expand Down