Skip to content

Commit

Permalink
Google Compute Engine OS Login 2FA Enabled (aquasecurity#878)
Browse files Browse the repository at this point in the history
Co-authored-by: dipsubha06 <[email protected]>
  • Loading branch information
mehakseedat63 and dipsubha06 authored Sep 30, 2021
1 parent d4c890c commit 7b4fb9f
Show file tree
Hide file tree
Showing 3 changed files with 198 additions and 0 deletions.
1 change: 1 addition & 0 deletions exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ module.exports = {
'instanceDesiredMachineTypes' : require(__dirname + '/plugins/google/compute/instanceDesiredMachineTypes.js'),
'automaticRestartEnabled' : require(__dirname + '/plugins/google/compute/automaticRestartEnabled.js'),
'instanceTemplateMachineTypes' : require(__dirname + '/plugins/google/compute/instanceTemplateMachineTypes.js'),
'osLogin2FAEnabled' : require(__dirname + '/plugins/google/compute/osLogin2FAEnabled.js'),
'diskAutomaticBackupEnabled' : require(__dirname + '/plugins/google/compute/diskAutomaticBackupEnabled.js'),
'diskOldSnapshots' : require(__dirname + '/plugins/google/compute/diskOldSnapshots.js'),

Expand Down
85 changes: 85 additions & 0 deletions plugins/google/compute/osLogin2FAEnabled.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
var async = require('async');
var helpers = require('../../../helpers/google');

module.exports = {
title: 'OS Login 2FA Enabled',
category: 'Compute',
description: 'Ensure that Virtual Machines instances have OS logic feature enabled and configured with Two-Factor Authentication.',
more_info: 'Enable OS login Two-Factor Authentication (2FA) to add an additional security layer to your VM instances. The risk of your VM instances getting attcked is reduced significantly if 2FA is enabled.',
link: 'https://cloud.google.com/compute/docs/oslogin/setup-two-factor-authentication',
recommended_action: 'Set enable-oslogin-2fa to true in custom metadata for the instance.',
apis: ['instances:compute:list', 'projects:get'],
compliance: {
pci: 'PCI recommends implementing additional security features for ' +
'any required service. This includes using secured technologies ' +
'such as SSH.'
},

run: function(cache, settings, callback) {
var results = [];
var source = {};
var regions = helpers.regions();

let projects = helpers.addSource(cache, source,
['projects', 'get', 'global']);

if (!projects || projects.err || !projects.data || !projects.data.length) {
helpers.addResult(results, 3,
'Unable to query for projects: ' + helpers.addError(projects), 'global', null, null, (projects) ? projects.err : null);
return callback(null, results, source);
}

var project = projects.data[0].name;

async.each(regions.instances.compute, (region, rcb) => {
var zones = regions.zones;
var noInstances = [];
async.each(zones[region], function(zone, zcb) {
var instances = helpers.addSource(cache, source,
['instances', 'compute', 'list', zone]);

if (!instances) return zcb();

if (instances.err || !instances.data) {
helpers.addResult(results, 3, 'Unable to query instances', region, null, null, instances.err);
return zcb();
}

if (!instances.data.length) {
noInstances.push(zone);
return zcb();
}

instances.data.forEach(instance => {
let resource = helpers.createResourceName('instances', instance.name, project, 'zone', zone);
let isEnabled = false;

if (instance.metadata && instance.metadata.items && instance.metadata.items.length) {

if (instance.metadata.items.find(item => (item.key && item.key.toLowerCase() === 'enable-oslogin-2fa' &&
item.value && item.value.toLowerCase() === 'true'))) {
isEnabled = true;
}
}

if (isEnabled) {
helpers.addResult(results, 0,
'OS Login 2FA is enabled for the the instance', region, resource);
} else {
helpers.addResult(results, 2,
'OS Login 2FA is not enabled for the the instance', region, resource);
}

});
zcb();
}, function() {
if (noInstances.length) {
helpers.addResult(results, 0, `No instances found in following zones: ${noInstances.join(', ')}`, region);
}
rcb();
});
}, function() {
callback(null, results, source);
});
}
};
112 changes: 112 additions & 0 deletions plugins/google/compute/osLogin2FAEnabled.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
var expect = require('chai').expect;
var plugin = require('./osLogin2FAEnabled');

const createCache = (instanceData, error) => {
return {
instances: {
compute: {
list: {
'us-central1-a': {
data: instanceData,
err: error
}
}
}
},
projects: {
get: {
'global': {
data: 'testproj'
}
}
}
}
};

describe('osLogin2FAEnabled', function () {
describe('run', function () {

it('should give unknown if an instance error occurs', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0);
expect(results[0].status).to.equal(3);
expect(results[0].message).to.include('Unable to query instances');
expect(results[0].region).to.equal('us-central1');
done()
};

const cache = createCache(
[],
['error']
);

plugin.run(cache, {}, callback);
});

it('should pass no VM Instances', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('No instances found');
expect(results[0].region).to.equal('us-central1');
done()
};

const cache = createCache([]);

plugin.run(cache, {}, callback);
});

it('should fail when OS Login 2FA is not enabled', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0);
expect(results[0].status).to.equal(2);
expect(results[0].message).to.include('OS Login 2FA is not enabled for the the instance');
expect(results[0].region).to.equal('us-central1');
done()
};

const cache = createCache(
[
{
id: "17198672",
name: "testing-instance",
zone: "https://www.googleapis.com/compute/v1/projects/test-dev/zones/us-central1-a",
metadata: { items: [] }
}
]
);

plugin.run(cache, {}, callback);
})

it('should pass when OS Login 2FA is enabled', function (done) {
const callback = (err, results) => {
expect(results.length).to.be.above(0);
expect(results[0].status).to.equal(0);
expect(results[0].message).to.include('OS Login 2FA is enabled for the the instance');
expect(results[0].region).to.equal('us-central1');
done()
};

const cache = createCache(
[
{
id: "321087009587",
name: "testing-instance2",
zone: "https://www.googleapis.com/compute/v1/projects/test-dev/zones/us-central1-a",
metadata: {
items: [
{ key: 'enable-oslogin', value: 'TRUE' },
{ key: 'enable-oslogin-2fa', value: 'TRUE' }
]
}
}
]
);

plugin.run(cache, {}, callback);
})

})
})

0 comments on commit 7b4fb9f

Please sign in to comment.