Your data. Anywhere you go.

New Relic for iOS or Android


Download on the App Store    Android App on Google play


New Relic Insights App for iOS


Download on the App Store


Learn more

Close icon

Relic Solution: Using Synthetics to Monitor SSL Expiration

rfb

#21

So here’s what I cobbled together from the other guys posts… url1 and your account details need replacing.

var request = require(‘request’),
assert = require(‘assert’),
Q = require(‘q’);
/*


What is the URL that you want to check?


*/
var urlsToMonitor = [‘https://url1/’, ‘https://url2/’];

var licenseKey = ‘yyyyyyyyyyyyyyyy’;
var accountId = ‘zzzzzz’;

function treatAsUTC(date) {
var result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}

function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return Math.round((treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay);
}

function processSite(urlToMonitor)
{
var deferred = Q.defer();
console.log('Preparing to monitor '+urlToMonitor);
var r = request({
url: urlToMonitor,
method: ‘HEAD’,
gzip: true,
followRedirect: false,
followAllRedirects: false
});

r.on(‘response’,
function(res) {
var certDetails = (res.req.connection.getPeerCertificate());
var currentDate = new Date();
var certExpirationDate = new Date(certDetails.valid_to);
var certificateIssuer = certDetails.issuer.O;
var daysToExpiration = daysBetween(currentDate, certExpirationDate);
var certificateIssuer = certDetails.issuer.O;
console.log('This certificate was issued by '+certificateIssuer, ‘’);
console.log('This SSL certificate will expire on ‘+certExpirationDate, ‘’);
console.log(’**** Date at time of testing: ‘+currentDate);
console.log(’**** Days to expiration: '+daysToExpiration);
console.log("Creating event for: "+urlToMonitor);

  function insertInsightsEvent(urlToMonitor, certificateIssuer, daysToExpiration, expirationMilliseconds){

var options = {
uri: ‘https://insights-collector.newrelic.com/v1/accounts/’+accountId+’/events’,
body: ‘[{“eventType”:“SSLCertificateCheck”,“Url”:"’+urlToMonitor+’",“Issuer”:"’+certificateIssuer+’",“DaysToExpiration”:’+daysToExpiration+’, “ExpirationDate”:’+expirationMilliseconds+’}]’,
headers:{
‘X-Insert-Key’: licenseKey,
‘Content-Type’: ‘application/json’
}
};
console.log("Posting event for: “+urlToMonitor);
request.post(options, function(error,response, body){
console.log(response.statusMessage);
console.log(response.statusCode + " status code”);
assert.ok(response.statusCode == 200, ‘Expected 200 OK response’);
var info = JSON.parse(body);
assert.ok(info.success == true, 'Expected True results in Response Body, result was ’ + info.success);
console.log(“SSL cert check completed successfully”);
});
}
insertInsightsEvent(urlToMonitor, certificateIssuer, daysToExpiration, certExpirationDate.getTime());
deferred.resolve();
}
);

return deferred.promise;
}

for(var i=0; i< urlsToMonitor.length; i++)
{
var urlToMonitor = urlsToMonitor[i];
processSite(urlToMonitor);
}


#22

Thanks Bevan. That works like a charm now!


#23

Thanks for working this out together everyone! You are champs! :trophy:


#24

When I run this I get an error - “TypeError: Cannot read property ‘valid_to’ of null

Why is the script, that works for others, throwing this error for me? Any guidance will be appreciated.

Preparing to monitor https://newrelic.com/
TypeError: Cannot read property ‘valid_to’ of null
at Request.eval [as _callback] (eval at (/opt/runtimes/3.0.0/modules/synthetics-runner/lib/job-resource/index.js:76:19), :63:52)
at Request.self.callback (/opt/runtimes/3.0.0/node_modules/request/request.js:188:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request. (/opt/runtimes/3.0.0/node_modules/request/request.js:1171:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at IncomingMessage. (/opt/runtimes/3.0.0/node_modules/request/request.js:1091:12)
at IncomingMessage.g (events.js:292:16)
at emitNone (events.js:91:20)


#25

Hey there - I’m the original author of this post and I want to help - it seems that the var certDetails = (res.req.connection.getPeerCertificate()); portion of your script is failing. Can you share a link to the synthetic monitor? This way I can take a look and offer any advice. Thanks! Hope to get this resolved soon~


#26

Thanks for your assistance rmusser.

https://synthetics.newrelic.com/accounts/1250955/monitors/a30a2229-c6cc-466c-a408-cd56b5a58a8e/script


#27

Thanks for getting back to us, @pkapoor! Ryan is out on vacation :palm_tree: right now, so we will wait for him to get back to continue the troubleshooting. I wanted to reach out so you didn’t think we had forgotten about you! Hang tight! :blush:


#28

Hey there - I took a look at the script, it seems as though you weren’t actually making the request. I’ve adjusted it, and removed your API key information. Take a look and let me know what you think. Also, have you been in touch with Manny? Let me know, I can make sure you two get connected. Please see below:

var request = require('request'),
  assert = require('assert'),
  Q = require('q');
/*
**************************************************
What is the URL that you want to check?
**************************************************
*/
var urlsToMonitor = ['https://newrelic.com/', 'https://www.pitneybowesepay.com/'];

var licenseKey = 'FOO';
var accountId = 'BAR';

function treatAsUTC(date) {
    var result = new Date(date);
    result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
    return result;
}

function daysBetween(startDate, endDate) {
    var millisecondsPerDay = 24 * 60 * 60 * 1000;
    return Math.round((treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay);
}

function insertInsightsEvent(urlMonitored, certificateIssuer, daysToExpiration, expirationMilliseconds){
  var options = {
    uri: 'https://insights-collector.newrelic.com/v1/accounts/'+accountId+'/events',
    body: '[{"eventType":"SSLCertificateCheck","Url":"'+urlMonitored+'","Issuer":"'+certificateIssuer+'","DaysToExpiration":'+daysToExpiration+', "ExpirationDate":'+expirationMilliseconds+'}]',
		headers:{
			'X-Insert-Key': licenseKey,
			'Content-Type': 'application/json'
		}
  };
  console.log("Posting event for: "+urlMonitored);
  request.post(options, function(error,response, body){
      console.log(response.statusMessage);
      console.log(response.statusCode + " status code");
      assert.ok(response.statusCode == 200, 'Expected 200 OK response');  
      var info = JSON.parse(body);
      assert.ok(info.success == true, 'Expected True results in Response Body, result was ' + info.success);
      console.log("SSL cert check completed successfully");
    });
}

function processSite(urlToMonitor)
{
	//var deferred = Q.defer();
  console.log('Preparing to monitor '+urlToMonitor);

  var theRequestObject = request({
    url: urlToMonitor,
    method: 'HEAD',
    gzip: true,
    followRedirect: false,
    followAllRedirects: false
  });

  theRequestObject.on('response', 
    function(res) { 
      var certDetails = (res.req.connection.getPeerCertificate());
      var currentDate = new Date(); 
      var certExpirationDate = new Date(certDetails.valid_to);
      var certificateIssuer = certDetails.issuer.O; 
      var daysToExpiration = daysBetween(currentDate, certExpirationDate);
      var certificateIssuer = certDetails.issuer.O;
      console.log('This certificate was issued by '+certificateIssuer, '');
      console.log('This SSL certificate will expire on '+certExpirationDate, '');
      console.log('**** Date at time of testing: '+currentDate);
      console.log('**** Days to expiration: '+daysToExpiration);
      console.log("Creating event for: "+urlToMonitor);
      insertInsightsEvent(urlToMonitor, certificateIssuer, daysToExpiration, certExpirationDate.getTime());
    }
  );
}

for(var i=0; i< urlsToMonitor.length; i++)
{
  var urlToMonitor = urlsToMonitor[i];
  processSite(urlToMonitor);
}

SSL is not verified if a URL redirects to another, valid, host
#29

@rmusser After implementing this, Did received “NetworkError: Monitor produced no traffic”. How to resolve this ?


#30

Hi @Shriram.Krishnan - You need to create this as an API synthetic, not a Browser synthetic.


#31

@stefan_garnham Thanks for pointing it out :blush: I need to start finding difference between API Synthetic and Browser Synthetic and also usage for it. Thank you for your support as always.

Similar to this if you have any useful script keep posted, so that I will gain knowledge by crawling your foot steps on NewRelic. :wink:


#32

(post withdrawn by author, will be automatically deleted in 24 hours unless flagged)


#33

I’m trying to check the SSL expiry check for multiple certificates, getting the below assertion error.

Preparing to monitor https://noms.xyz.com/
Preparing to monitor https://service.xvy.xyz.com/
This certificate was issued by Entrust, Inc.
This SSL certificate will expire on Mon Mar 30 2020 11:20:42 GMT+0000 (UTC)
**** Date at time of testing: Mon Jul 02 2018 15:50:49 GMT+0000 (UTC)
**** Days to expiration: 637
Creating event for: https://nomm.xyz.com/
Posting event for: https://nomm.xyz.com/
This certificate was issued by Entrust, Inc.
This SSL certificate will expire on Thu Apr 16 2020 21:41:32 GMT+0000 (UTC)
**** Date at time of testing: Mon Jul 02 2018 15:50:49 GMT+0000 (UTC)
**** Days to expiration: 654
Creating event for: https://service.xvy.xyz.com/
Posting event for: https://service.xvy.xyz.com/
Bad Request
400 status code

AssertionError: Expected 200 OK response
at Request.eval [as _callback] (eval at (/opt/runtimes/2.0.0/modules/synthetics-runner/lib/job-resource/index.js:76:19), :66:8)
at Request.self.callback (/opt/runtimes/2.0.0/node_modules/request/request.js:198:22)
at Request.emit (events.js:110:17)
at Request. (/opt/runtimes/2.0.0/node_modules/request/request.js:1057:14)
at Request.emit (events.js:129:20)
at IncomingMessage. (/opt/runtimes/2.0.0/node_modules/request/request.js:1003:12)
at IncomingMessage.emit (events.js:129:20)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)


#34

Hi @yograj.patel - Verify that you have set the account key for your Insights API correctly and that you have the correct permissions level for using the API.


#35

Hi Stefan, I have set the API key from Insights and I have the admin permission.

Verified the license key and the account ID are correct, but still getting the error.


#36

Without further information on your script, @yograj.patel, I cannot assist. Perhaps @RyanVeitch can assist in the meantime?


#37

var request = require(‘request’),
assert = require(‘assert’),
Q = require(‘q’);
/*


What is the URL that you want to check?


*/
var urlsToMonitor = [‘https://myadmin.business.com/’,‘https://myaccount.business.com/’,'https://nopssupport.corp.com’];

var licenseKey = ‘xxxxxxxxxxxxxxxxxxxxxxxxxxxxx’;
var accountId = ‘xxxx15’;

function treatAsUTC(date) {
var result = new Date(date);
result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
return result;
}

function daysBetween(startDate, endDate) {
var millisecondsPerDay = 24 * 60 * 60 * 1000;
return Math.round((treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay);
}

function insertInsightsEvent(urlMonitored, certificateIssuer, daysToExpiration, expirationMilliseconds){
var options = {
uri: ‘https://insights-collector.newrelic.com/v1/accounts/’+accountId+’/events’,
body: ‘[{“eventType”:“SSLCertificateCheck”,“Url”:"’+urlMonitored+’",“Issuer”:"’+certificateIssuer+’",“DaysToExpiration”:’+daysToExpiration+’, “ExpirationDate”:’+expirationMilliseconds+’}]’,
headers:{
‘X-Insert-Key’: licenseKey,
‘Content-Type’: ‘application/json’
}
};
console.log("Posting event for: “+urlMonitored);
request.post(options, function(error,response, body){
console.log(response.statusMessage);
console.log(response.statusCode + " status code”);
assert.ok(response.statusCode == 200, ‘Expected 200 OK response’);
var info = JSON.parse(body);
assert.ok(info.success == true, 'Expected True results in Response Body, result was ’ + info.success);
console.log(“SSL cert check completed successfully”);
});
}

function processSite(urlToMonitor)
{
//var deferred = Q.defer();
console.log('Preparing to monitor '+urlToMonitor);

var theRequestObject = request({
url: urlToMonitor,
method: ‘HEAD’,
gzip: true,
followRedirect: false,
followAllRedirects: false
});

theRequestObject.on(‘response’,
function(res) {
var certDetails = (res.req.connection.getPeerCertificate());
var currentDate = new Date();
var certExpirationDate = new Date(certDetails.valid_to);
var certificateIssuer = certDetails.issuer.O;
var daysToExpiration = daysBetween(currentDate, certExpirationDate);
var certificateIssuer = certDetails.issuer.O;
console.log('This certificate was issued by '+certificateIssuer, ‘’);
console.log('This SSL certificate will expire on ‘+certExpirationDate, ‘’);
console.log(’**** Date at time of testing: ‘+currentDate);
console.log(’**** Days to expiration: '+daysToExpiration);
console.log("Creating event for: "+urlToMonitor);
insertInsightsEvent(urlToMonitor, certificateIssuer, daysToExpiration, certExpirationDate.getTime());
}
);
}

for(var i=0; i< urlsToMonitor.length; i++)
{
var urlToMonitor = urlsToMonitor[i];
processSite(urlToMonitor);
}


#38

It looks like some of your script is missing as I pasted yours in a new script and there are several errors displayed for undefined objects such as theRequestObject.

I would suggest, as you have removed the promises, that you output the parameters for insertInsightsEvent to the console so you can verify they are being passed correctly.


#39

@stefan_garnham I have used the same query which you have provided in the above chat, updated my api key under license key and updated the account ID ( https://rpm.newrelic.com/accounts/****115/integrations?page=api_keys ) taken from the masked data.

But getting forbidden error.

Preparing to monitor https://newrelic.com/
Preparing to monitor https://google.com/
This certificate was issued by Google Trust Services
This SSL certificate will expire on Tue Aug 28 2018 11:32:00 GMT+0000 (UTC)
**** Date at time of testing: Tue Jul 03 2018 13:57:53 GMT+0000 (UTC)
**** Days to expiration: 56
Creating event for: https://google.com/
Posting event for: https://google.com/
Forbidden
403 status code

AssertionError: Expected 200 OK response
at Request.eval [as _callback] (eval at (/opt/runtimes/2.0.0/modules/synthetics-runner/lib/job-resource/index.js:76:19), :40:14)
at Request.self.callback (/opt/runtimes/2.0.0/node_modules/request/request.js:198:22)
at Request.emit (events.js:110:17)
at Request. (/opt/runtimes/2.0.0/node_modules/request/request.js:1057:14)
at Request.emit (events.js:129:20)
at IncomingMessage. (/opt/runtimes/2.0.0/node_modules/request/request.js:1003:12)
at IncomingMessage.emit (events.js:129:20)
at _stream_readable.js:908:16
at process._tickCallback (node.js:355:11)

Not sure If i’m doing something wrong.

And I dont see the data in Insights as well.


#40

It sounds as though you do not have the correct account and API key, or you just do not have permissions to create the data. It seems as though you will need some support from New Relic staff. @RyanVeitch can assist with that.