Skip to content
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

added: SSL support for API/monitor interface #294

Open
wants to merge 1 commit 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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@ url: 'http://myDomain.com'

Node that Uptime works great behind a proxy - it uses the `http_proxy` environment variable transparently.

SSL
---

By default, Uptime uses regular HTTP on the API and monitor server, but it's possible to enable SSL for encrypting the connection to your monitor instance. The settings for this are located in the `config/default.yaml` file:

```yaml
ssl:
enabled: true
certificate: uptime.crt # path to certificate file
key: uptime.key # path to key file
selfSigned: false
```

You must specify `true` for the `selfSigned` option when using a self-signed certificate, otherwise Node.js will throw an "UNABLE_TO_VERIFY_LEAF_NODE" error and will not poll.

Architecture
------------

Expand Down
19 changes: 17 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

var http = require('http');
var https = require('https');
var url = require('url');
var express = require('express');
var config = require('config');
Expand All @@ -26,7 +27,21 @@ a.start();
// web front

var app = module.exports = express();
var server = http.createServer(app);
if (config.ssl && config.ssl.enabled === true) {
if (typeof(config.ssl.certificate) === 'undefined') {
throw new Error("Must specify certificate to enable SSL!");
}
if (typeof(config.ssl.key) === 'undefined') {
throw new Error("Must specify key file to enable SSL!");
}
var options = {
cert: fs.readFileSync(config.ssl.certificate),
key: fs.readFileSync(config.ssl.key)
};
var server = https.createServer(options, app);
} else {
var server = http.createServer(app);
}

app.configure(function(){
app.use(app.router);
Expand Down Expand Up @@ -149,7 +164,7 @@ if (!module.parent) {
} else {
port = serverUrl.port;
if (port === null) {
port = 80;
port = config.ssl && config.ssl.enabled ? 443 : 80;
}
}
var port = process.env.PORT || port;
Expand Down
6 changes: 6 additions & 0 deletions config/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ monitor:
timeout: 5000 # five seconds
userAgent: NodeUptime/3.0 (https://github.com/fzaninotto/uptime)

ssl:
enabled: false
certificate: uptime.crt # certificate file
key: uptime.key # key file
selfSigned: false

analyzer:
updateInterval: 60000 # one minute
qosAggregationInterval: 600000 # ten minutes
Expand Down
13 changes: 10 additions & 3 deletions lib/monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Module dependencies.
*/
var http = require('http');
var https = require('https');
var url = require('url');
var EventEmitter = require('events').EventEmitter;
var PollerCollection = require('./pollers/pollerCollection');
Expand All @@ -26,6 +27,9 @@ function Monitor(config) {
config.timeout = config.timeout || 5 * 1000;
this.config = config;
this.pollerCollection = new PollerCollection();
this.selfSigned = config.selfSigned;
this.ssl = url.parse(config.apiUrl).protocol.indexOf('https') > -1 ? true : false;
this.connection = this.ssl === true ? https : http;
this.apiHttpOptions = {};
}

Expand Down Expand Up @@ -87,7 +91,8 @@ Monitor.prototype.findChecksNeedingPoll = function(callback) {
var options = url.parse(this.config.apiUrl + '/checks/needingPoll');
this.applyApiHttpOptions(options);
var self = this;
http.get(options, function(res) {
if (self.selfSigned === true) options.rejectUnauthorized = false;
this.connection.get(options, function(res) {
if (res.statusCode != 200) {
return callback(new Error(self.config.apiUrl + '/checks/needingPoll resource responded with error code: ' + res.statusCode));
}
Expand Down Expand Up @@ -151,7 +156,8 @@ Monitor.prototype.declarePoll = function(check, callback) {
options.method = 'PUT';
this.applyApiHttpOptions(options);
var self = this;
var req = http.request(options, function(res) {
if (self.selfSigned === true) options.rejectUnauthorized = false;
var req = this.connection.request(options, function(res) {
if (res.statusCode != 200) {
return callback(new Error(self.config.apiUrl + '/check/:id/test resource responded with error code: ' + res.statusCode));
}
Expand Down Expand Up @@ -187,7 +193,8 @@ Monitor.prototype.createPing = function(error, check, timestamp, time, details,
};
this.applyApiHttpOptions(options);
var self = this;
var req = http.request(options, function(res) {
if (self.selfSigned === true) options.rejectUnauthorized = false;
var req = this.connection.request(options, function(res) {
if (res.statusCode != 200) {
return callback(new Error(self.config.apiUrl + '/pings resource responded with error code: ' + res.statusCode));
}
Expand Down
3 changes: 2 additions & 1 deletion monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ var config = require('config');
var Monitor = require('./lib/monitor');

// start the monitor
config.monitor.selfSigned = config.ssl && config.ssl.selfSigned ? true : false;
monitor = Monitor.createMonitor(config.monitor);

// load plugins
Expand All @@ -18,4 +19,4 @@ config.plugins.forEach(function(pluginName) {

monitor.start();

module.exports = monitor;
module.exports = monitor;