Added new authalgo support for SNMPv3 (#11966)

* Added new authalgo support for SNMPv3

* Update 2020_07_27_00522_alter_authalgo_column.php

Fixed case

* Update addhost.inc.php

Fixed case

* Update snmp.inc.php

Fixed case

* Update db_schema.yaml

Fixed case

* Fixed SHA-* order to ascending

* Update 2020_07_27_00522_alter_authalgo_column.php

Fixed space

* Update db_schema.yaml

Fixed line to be of type string

* Update config_definitions.json

Fixed sorting

* Fixed test file case sensitivity

* Fixed rollback function

* SourceDoctor code for checks

* Fixed indentation issues on Travis test

* Update to re-trigger testing stuck on CLA step

* Added crypto-algo updates

* Incorporated suggestions from Jellyfrog

* Added documentation entry

* Fixed travis spacing error

* Fixed validations

* Delete snmpv3_version_compare.patch

Sorry, this one was not supposed to be there.

* Added poller evaluation

* Added poller comparison

* Fixed merge-conflicts

* Fixed typo in test unit

* code refinements
only can check on webui that it supports the algorithms, hopefully, the eventlog is enough to notify users of distributed pollers.

* style fixes and remove openssl setting

* fix device access

* fix missing migration column

Co-authored-by: Tony Murray <murraytony@gmail.com>
This commit is contained in:
Hans Erasmus
2020-10-29 20:02:26 +02:00
committed by GitHub
parent 7239d4fc5f
commit 6c4596d1b9
9 changed files with 98 additions and 12 deletions

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AlterDevicesSnmpAlgoColumns extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('devices', function (Blueprint $table) {
$table->string('authalgo', 10)->nullable()->change();
$table->string('cryptoalgo', 10)->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
}
}

View File

@@ -42,6 +42,7 @@ path: blob/master/doc/
- [My alert templates stopped working](#my-alert-templates-stopped-working)
- [How do I use trend prediction in graphs](#how-do-i-use-trend-prediction-in-graphs)
- [How do I move only the DB to another server](#move-db-to-another-server)
- [What are the "optional requirements message" when I add SNMPv3 devices](#optional-requirements-for-snmpv3-sha2-auth)
# Developing
@@ -604,3 +605,5 @@ exit;
- Edit your `config.php` file to point the install to the new database server location.
- **Very important**: On your LibreNMS server, inside your install directory is a `.env` file, in it you need to edit the `DBHOST` paramater to point to your new server location.
- After all this is done, enable all the cron entries again and start apache.
## <a name='optional-requirements-for-snmpv3-sha2-auth'>What are the "optional requirements message" when I add SNMPv3 devices?</a>
When you add a device via the WebUI you may see a little message stating "Optional requirements are not met so some options are disabled". Do not panic. This simply means your system does not contain **openssl >= 1.1** and **net-snmp >= 5.8**, which are the minimum specifications needed to be able to use AES-192,AES-256 as crypto algorithms and SHA-224|256|384|512 as auth algorithms.

View File

@@ -17,11 +17,13 @@
*/
use LibreNMS\Config;
use LibreNMS\Enum\Alert;
use LibreNMS\Exceptions\InvalidIpException;
use LibreNMS\Util\Git;
use LibreNMS\Util\IP;
use LibreNMS\Util\Laravel;
use LibreNMS\Util\OS;
use Symfony\Component\Process\Process;
function generate_priority_label($priority)
{
@@ -87,7 +89,9 @@ function external_exec($command)
{
global $debug, $vdebug;
$proc = new \Symfony\Component\Process\Process($command);
$device = DeviceCache::getPrimary();
$proc = new Process($command);
$proc->setTimeout(Config::get('snmp.exec_timeout', 1200));
if ($debug && ! $vdebug) {
@@ -121,6 +125,12 @@ function external_exec($command)
$proc->run();
$output = $proc->getOutput();
if ($proc->getExitCode()) {
Log::event('Unsupported SNMP Algorithm - ' . $proc->getExitCode(), optional($device)->device_id, 'poller', Alert::ERROR);
d_echo('Exitcode: ' . $proc->getExitCode());
d_echo($proc->getErrorOutput());
}
if ($debug && ! $vdebug) {
$ip_regex = '/(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/';
$debug_output = preg_replace($ip_regex, '*', $output);
@@ -832,6 +842,18 @@ function version_info($remote = false)
return $output;
}//end version_info()
/**
* checks if System is SNMPv3 SHA2 Capable for Auth Algorithms (SHA-224,SHA-256,SHA-384,SHA-512)
* @return bool
*/
function snmpv3_sha2_capable()
{
$process = new Process([Config::get('snmpget', 'snmpget'), '--help']);
$process->run();
return Str::contains($process->getErrorOutput(), 'SHA-512');
}
/**
* Convert a MySQL binary v4 (4-byte) or v6 (16-byte) IP address to a printable string.
* @param string $ip A binary string containing an IP address, as returned from MySQL's INET6_ATON function

View File

@@ -189,6 +189,8 @@ foreach (get_port_assoc_modes() as $mode) {
echo " <option value=\"$mode\" $selected>$mode</option>\n";
}
$snmpv3_sha2_capable = snmpv3_sha2_capable();
?>
</select>
</div>
@@ -240,7 +242,14 @@ foreach (get_port_assoc_modes() as $mode) {
<select name="authalgo" id="authalgo" class="form-control input-sm">
<option value="MD5" selected>MD5</option>
<option value="SHA">SHA</option>
<option value="SHA-224"<?= $snmpv3_sha2_capable ?: ' disabled'?>>SHA-224</option>
<option value="SHA-256"<?= $snmpv3_sha2_capable ?: ' disabled'?>>SHA-256</option>
<option value="SHA-384"<?= $snmpv3_sha2_capable ?: ' disabled'?>>SHA-384</option>
<option value="SHA-512"<?= $snmpv3_sha2_capable ?: ' disabled'?>>SHA-512</option>
</select>
<?php if (! $snmpv3_sha2_capable) {?>
<label class="text-left"><small>Optional requirements not resolved so some options are disabled</small></label>
<?php } ?>
</div>
</div>
<div class="form-group">
@@ -254,8 +263,13 @@ foreach (get_port_assoc_modes() as $mode) {
<div class="col-sm-9">
<select name="cryptoalgo" id="cryptoalgo" class="form-control input-sm">
<option value="AES" selected>AES</option>
<option value="AES-192"<?= $snmpv3_sha2_capable ?: ' disabled'?>>AES-192</option>
<option value="AES-256"<?= $snmpv3_sha2_capable ?: ' disabled'?>>AES-256</option>
<option value="DES">DES</option>
</select>
<?php if (! $snmpv3_sha2_capable) {?>
<label class="text-left"><small>Optional requirements not resolved so some options are disabled</small></label>
<?php } ?>
</div>
</div>
</div>

View File

@@ -301,6 +301,7 @@ foreach (get_port_assoc_modes() as $pam_id => $pam) {
echo ">$pam</option>\n";
}
$snmpv3_sha2_capable = snmpv3_sha2_capable();
echo " </select>
</div>
</div>
@@ -359,7 +360,16 @@ echo " </select>
<select id='authalgo' name='authalgo' class='form-control'>
<option value='MD5'>MD5</option>
<option value='SHA' " . ($device['authalgo'] === 'SHA' ? 'selected' : '') . ">SHA</option>
<option value='SHA-224' " . ($device['authalgo'] === 'SHA-224' ? 'selected' : '') . ($snmpv3_sha2_capable ?: ' disabled') . ">SHA-224</option>
<option value='SHA-256' " . ($device['authalgo'] === 'SHA-256' ? 'selected' : '') . ($snmpv3_sha2_capable ?: ' disabled') . ">SHA-256</option>
<option value='SHA-384' " . ($device['authalgo'] === 'SHA-384' ? 'selected' : '') . ($snmpv3_sha2_capable ?: ' disabled') . ">SHA-384</option>
<option value='SHA-512' " . ($device['authalgo'] === 'SHA-512' ? 'selected' : '') . ($snmpv3_sha2_capable ?: ' disabled') . '>SHA-512</option>
</select>
';
if (! $snmpv3_sha2_capable) {
echo '<label class="text-left"><small>Optional requirements not resolved so some options are disabled</small></label>';
}
echo "
</div>
</div>
<div class='form-group'>
@@ -372,13 +382,19 @@ echo " </select>
<label for='cryptoalgo' class='col-sm-2 control-label'>Crypto Algorithm</label>
<div class='col-sm-4'>
<select id='cryptoalgo' name='cryptoalgo' class='form-control'>
<option value='AES'>AES</option>
<option value='DES' " . ($device['cryptoalgo'] === 'DES' ? 'selected' : '') . '>DES</option>
<option value='AES' " . ($device['cryptoalgo'] === 'AES' ? 'selected' : '') . ">AES</option>
<option value='AES-192' " . ($device['cryptoalgo'] === 'AES-192' ? 'selected' : '') . ($snmpv3_sha2_capable ?: ' disabled') . ">AES-192</option>
<option value='AES-256' " . ($device['cryptoalgo'] === 'AES-256' ? 'selected' : '') . ($snmpv3_sha2_capable ?: ' disabled') . ">AES-256</option>
<option value='DES'>DES</option>
</select>
";
if (! $snmpv3_sha2_capable) {
echo '<label class="text-left"><small>Optional requirements not resolved so some options are disabled</small></label>';
}
echo '
</div>
</div>
</div>';
?>
</div>

View File

@@ -4989,7 +4989,8 @@
}
],
"validate": {
"value.*.authalgo": "in:MD5,SHA"
"value.*.authalgo": "in:MD5,SHA,SHA-224,SHA-256,SHA-384,SHA-512",
"value.*.cryptoalgo": "in:AES,AES-192,AES-256,DES"
}
},
"snmp.version": {

View File

@@ -499,9 +499,9 @@ devices:
- { Field: authlevel, Type: 'enum(''noAuthNoPriv'',''authNoPriv'',''authPriv'')', 'Null': true, Extra: '' }
- { Field: authname, Type: varchar(64), 'Null': true, Extra: '' }
- { Field: authpass, Type: varchar(64), 'Null': true, Extra: '' }
- { Field: authalgo, Type: 'enum(''MD5'',''SHA'')', 'Null': true, Extra: '' }
- { Field: authalgo, Type: varchar(10), 'Null': true, Extra: '' }
- { Field: cryptopass, Type: varchar(64), 'Null': true, Extra: '' }
- { Field: cryptoalgo, Type: 'enum(''AES'',''DES'','''')', 'Null': true, Extra: '' }
- { Field: cryptoalgo, Type: varchar(10), 'Null': true, Extra: '' }
- { Field: snmpver, Type: varchar(4), 'Null': false, Extra: '', Default: v2c }
- { Field: port, Type: 'smallint unsigned', 'Null': false, Extra: '', Default: '161' }
- { Field: transport, Type: varchar(16), 'Null': false, Extra: '', Default: udp }

View File

@@ -100,8 +100,7 @@ class AddHostCliTest extends DBTestCase
public function testSnmpV3AuthProtocol()
{
// $modes = array('md5', 'sha', 'sha-512', 'sha-384', 'sha-256', 'sha-224');
$modes = ['md5', 'sha'];
$modes = ['MD5', 'SHA', 'SHA-224', 'SHA-256', 'SHA-384', 'SHA-512'];
foreach ($modes as $mode) {
$host = 'hostName' . $mode;
$result = \Artisan::call('device:add ' . $host . ' -force -a ' . $mode . ' --v3');
@@ -109,13 +108,13 @@ class AddHostCliTest extends DBTestCase
$device = Device::findByHostname($host);
$this->assertNotNull($device);
$this->assertEquals(strtoupper($mode), $device->authalgo, 'Wrong snmp v3 password algoritme');
$this->assertEquals(strtoupper($mode), $device->authalgo, 'Wrong snmp v3 password algorithm');
}
}
public function testSnmpV3PrivacyProtocol()
{
$modes = ['des', 'aes'];
$modes = ['DES', 'AES', 'AES-192', 'AES-256'];
foreach ($modes as $mode) {
$host = 'hostName' . $mode;
$result = \Artisan::call('device:add ' . $host . ' -force -x ' . $mode . ' --v3');
@@ -123,7 +122,7 @@ class AddHostCliTest extends DBTestCase
$device = Device::findByHostname($host);
$this->assertNotNull($device);
$this->assertEquals(strtoupper($mode), $device->cryptoalgo, 'Wrong snmp v3 crypt algoritme');
$this->assertEquals(strtoupper($mode), $device->cryptoalgo, 'Wrong snmp v3 crypt algorithm');
}
}

View File

@@ -158,6 +158,7 @@ Python | ${versions['python_ver']}
MySQL | ${versions['mysql_ver']}
RRDTool | ${versions['rrdtool_ver']}
SNMP | ${versions['netsnmp_ver']}
OpenSSL | ${versions['openssl_ver']}
====================================
$output