SNMP Capabilities (#13289)

* SNMP Capabilities
Allow all available auth algorithms to be set in global settings
cleanup other usages

* fix style
This commit is contained in:
Tony Murray 2021-09-28 18:35:59 -05:00 committed by GitHub
parent add06be809
commit 66dddbaa66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 200 additions and 73 deletions

View File

@ -0,0 +1,105 @@
<?php
/*
* SNMP.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2021 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS;
use Illuminate\Support\Str;
use Symfony\Component\Process\Process;
class SNMPCapabilities
{
/**
* @var bool
*/
private static $sha2;
/**
* @var bool
*/
private static $aes256;
public static function supportsSHA2(): bool
{
if (self::$sha2 === null) {
self::detectCapabilities();
}
return self::$sha2;
}
public static function supportsAES256(): bool
{
if (self::$aes256 === null) {
self::detectCapabilities();
}
return self::$aes256;
}
public static function supportedAuthAlgorithms(): array
{
return array_keys(array_filter(self::authAlgorithms()));
}
public static function supportedCryptoAlgorithms(): array
{
return array_keys(array_filter(self::cryptoAlgoritms()));
}
public static function authAlgorithms(): array
{
$sha2 = self::supportsSHA2();
return [
'SHA' => true,
'SHA-224' => $sha2,
'SHA-256' => $sha2,
'SHA-384' => $sha2,
'SHA-512' => $sha2,
'MD5' => true,
];
}
public static function cryptoAlgoritms(): array
{
$aes256 = self::supportsAES256();
return [
'AES' => true,
'AES-192' => $aes256,
'AES-256' => $aes256,
'AES-256-C' => $aes256,
'DES' => true,
];
}
private static function detectCapabilities(): void
{
$process = new Process([Config::get('snmpget', 'snmpget'), '--help']);
$process->run();
self::$sha2 = Str::contains($process->getErrorOutput(), 'SHA-512');
self::$aes256 = Str::contains($process->getErrorOutput(), 'AES-256');
}
}

View File

@ -0,0 +1,39 @@
<?php
/*
* SnmpCapabilities.php
*
* -Description-
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2021 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Http\Controllers\Ajax;
use Illuminate\Http\JsonResponse;
class SnmpCapabilities
{
public function __invoke(): JsonResponse
{
return new JsonResponse([
'auth' => \LibreNMS\SNMPCapabilities::supportedAuthAlgorithms(),
'crypto' => \LibreNMS\SNMPCapabilities::supportedCryptoAlgorithms(),
]);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,11 @@
{
"/js/app.js": "/js/app.js?id=5fb72abe404b2429231c",
"/js/app.js": "/js/app.js?id=cc34801c36c263f094da",
"/js/manifest.js": "/js/manifest.js?id=8d61162bb0caf92f60ff",
"/css/vendor.css": "/css/vendor.css?id=8d7b2ecb46047fe813e4",
"/css/app.css": "/css/app.css?id=cff4bdc70b4433113ccc",
"/css/app.css": "/css/app.css?id=54a173acc7d587a9afa4",
"/js/vendor.js": "/js/vendor.js?id=294cef17a3cf43045d61",
"/js/lang/de.js": "/js/lang/de.js?id=8959e785f5790d6b6836",
"/js/lang/en.js": "/js/lang/en.js?id=cad37e39e9721bd08fdd",
"/js/lang/en.js": "/js/lang/en.js?id=bd7598fcfc462394f0de",
"/js/lang/fr.js": "/js/lang/fr.js?id=707149152bde5b5e2b8d",
"/js/lang/it.js": "/js/lang/it.js?id=4e3b200da489000822dd",
"/js/lang/ru.js": "/js/lang/ru.js?id=f6b7c078755312a0907c",

View File

@ -670,23 +670,6 @@ function version_info($remote = false)
return $output;
}//end version_info()
/**
* Checks SNMPv3 capabilities
*
* SHA2 for Auth Algorithms (SHA-224,SHA-256,SHA-384,SHA-512)
* AES-192, AES-256 for Privacy Algorithms
*/
function snmpv3_capabilities(): array
{
$process = new Process([Config::get('snmpget', 'snmpget'), '--help']);
$process->run();
$ret['sha2'] = Str::contains($process->getErrorOutput(), 'SHA-512');
$ret['aes256'] = Str::contains($process->getErrorOutput(), 'AES-256');
return $ret;
}
/**
* Convert a MySQL binary v4 (4-byte) or v6 (16-byte) IP address to a printable string.
*

View File

@ -190,7 +190,6 @@ foreach (get_port_assoc_modes() as $mode) {
echo " <option value=\"$mode\" $selected>$mode</option>\n";
}
['sha2' => $snmpv3_sha2, 'aes256' => $snmpv3_aes256] = snmpv3_capabilities();
?>
</select>
</div>
@ -240,14 +239,13 @@ foreach (get_port_assoc_modes() as $mode) {
<label for="authalgo" class="col-sm-3 control-label">Auth Algorithm</label>
<div class="col-sm-9">
<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 ?: ' disabled'?>>SHA-224</option>
<option value="SHA-256"<?= $snmpv3_sha2 ?: ' disabled'?>>SHA-256</option>
<option value="SHA-384"<?= $snmpv3_sha2 ?: ' disabled'?>>SHA-384</option>
<option value="SHA-512"<?= $snmpv3_sha2 ?: ' disabled'?>>SHA-512</option>
<?php
foreach (\LibreNMS\SNMPCapabilities::authAlgorithms() as $algo => $enabled) {
echo "<option value=\"$algo\"" . ($enabled ?: ' disabled') . ">$algo</option>";
}
?>
</select>
<?php if (! $snmpv3_sha2) {?>
<?php if (! \LibreNMS\SNMPCapabilities::supportsSHA2()) {?>
<label class="text-left"><small>Some options are disabled. <a href="https://docs.librenms.org/Support/FAQ/#optional-requirements-for-snmpv3-sha2-auth">Read more here</a></small></label>
<?php } ?>
</div>
@ -262,13 +260,13 @@ foreach (get_port_assoc_modes() as $mode) {
<label for="cryptoalgo" class="col-sm-3 control-label">Crypto Algorithm</label>
<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_aes256 ?: ' disabled'?>>AES-192</option>
<option value="AES-256"<?= $snmpv3_aes256 ?: ' disabled'?>>AES-256</option>
<option value="AES-256-C"<?= $snmpv3_aes256 ?: ' disabled'?>>AES-256-C</option>
<option value="DES">DES</option>
<?php
foreach (\LibreNMS\SNMPCapabilities::cryptoAlgoritms() as $algo => $enabled) {
echo "<option value=\"$algo\"" . ($enabled ?: ' disabled') . ">$algo</option>";
}
?>
</select>
<?php if (! $snmpv3_aes256) {?>
<?php if (! \LibreNMS\SNMPCapabilities::supportsAES256()) {?>
<label class="text-left"><small>Some options are disabled. <a href="https://docs.librenms.org/Support/FAQ/#optional-requirements-for-snmpv3-sha2-auth">Read more here</a></small></label>
<?php } ?>
</div>
@ -277,7 +275,7 @@ foreach (get_port_assoc_modes() as $mode) {
</div>
<?php
if (Config::get('distributed_poller') === true) {
echo '
echo '
<div class="form-group">
<label for="poller_group" class="col-sm-3 control-label">Poller Group</label>
<div class="col-sm-9">
@ -285,16 +283,16 @@ if (Config::get('distributed_poller') === true) {
<option value="0"> Default poller group</option>
';
foreach (dbFetchRows('SELECT `id`,`group_name` FROM `poller_groups` ORDER BY `group_name`') as $group) {
echo '<option value="' . $group['id'] . '">' . $group['group_name'] . '</option>';
}
foreach (dbFetchRows('SELECT `id`,`group_name` FROM `poller_groups` ORDER BY `group_name`') as $group) {
echo '<option value="' . $group['id'] . '">' . $group['group_name'] . '</option>';
}
echo '
echo '
</select>
</div>
</div>
';
}//endif
}//endif
?>
<div class="form-group">
<label for="force_add" class="col-sm-3 control-label">Force add<br><small>(No ICMP or SNMP checks performed)</small></label>

View File

@ -301,7 +301,6 @@ foreach (get_port_assoc_modes() as $pam_id => $pam) {
echo ">$pam</option>\n";
}
['sha2' => $snmpv3_sha2, 'aes256' => $snmpv3_aes256] = snmpv3_capabilities();
echo " </select>
</div>
</div>
@ -357,19 +356,16 @@ echo " </select>
<div class='form-group'>
<label for='authalgo' class='col-sm-2 control-label'>Auth Algorithm</label>
<div class='col-sm-4'>
<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 ? '' : ' disabled') . ">SHA-224</option>
<option value='SHA-256' " . ($device['authalgo'] === 'SHA-256' ? 'selected' : '') . ($snmpv3_sha2 ? '' : ' disabled') . ">SHA-256</option>
<option value='SHA-384' " . ($device['authalgo'] === 'SHA-384' ? 'selected' : '') . ($snmpv3_sha2 ? '' : ' disabled') . ">SHA-384</option>
<option value='SHA-512' " . ($device['authalgo'] === 'SHA-512' ? 'selected' : '') . ($snmpv3_sha2 ? '' : ' disabled') . '>SHA-512</option>
</select>
';
if (! $snmpv3_sha2) {
<select id='authalgo' name='authalgo' class='form-control'>";
foreach (\LibreNMS\SNMPCapabilities::authAlgorithms() as $algo => $enabled) {
echo "<option value='$algo' " . ($device['authalgo'] === $algo ? 'selected' : '') . ($enabled ? '' : ' disabled') . ">$algo</option>\n";
}
echo '</select>';
if (! \LibreNMS\SNMPCapabilities::supportsSHA2()) {
echo '<label class="text-left"><small>Some options are disabled. <a href="https://docs.librenms.org/Support/FAQ/#optional-requirements-for-snmpv3-sha2-auth">Read more here</a></small></label>';
}
echo "
echo "
</div>
</div>
<div class='form-group'>
@ -381,15 +377,14 @@ if (! $snmpv3_sha2) {
<div class='form-group'>
<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' " . ($device['cryptoalgo'] === 'AES' ? 'selected' : '') . ">AES</option>
<option value='AES-192' " . ($device['cryptoalgo'] === 'AES-192' ? 'selected' : '') . ($snmpv3_aes256 ? '' : ' disabled') . ">AES-192</option>
<option value='AES-256' " . ($device['cryptoalgo'] === 'AES-256' ? 'selected' : '') . ($snmpv3_aes256 ? '' : ' disabled') . ">AES-256</option>
<option value='AES-256-C' " . ($device['cryptoalgo'] === 'AES-256-C' ? 'selected' : '') . ($snmpv3_aes256 ? '' : ' disabled') . ">AES-256 Cisco</option>
<option value='DES' " . ($device['cryptoalgo'] === 'DES' ? 'selected' : '') . '>DES</option>
</select>
<select id='cryptoalgo' name='cryptoalgo' class='form-control'>";
foreach (\LibreNMS\SNMPCapabilities::cryptoAlgoritms() as $algo => $enabled) {
echo "<option value='$algo' " . ($device['cryptoalgo'] === $algo ? 'selected' : '') . ($enabled ? '' : ' disabled') . ">$algo</option>\n";
}
echo '</select>
';
if (! $snmpv3_aes256) {
if (! \LibreNMS\SNMPCapabilities::supportsAES256()) {
echo '<label class="text-left"><small>Some options are disabled. <a href="https://docs.librenms.org/Support/FAQ/#optional-requirements-for-snmpv3-sha2-auth">Read more here</a></small></label>';
}
echo '

View File

@ -49,8 +49,7 @@
<label for="authalgo" class="col-sm-3 control-label" v-text="$t('settings.settings.snmp.v3.fields.authalgo')"></label>
<div class="col-sm-9">
<select class="form-control" id="authalgo" name="authalgo" v-model="item.authalgo" @change="updateItem(id, $event.target.id, $event.target.value)">
<option value="MD5">MD5</option>
<option value="SHA">SHA</option>
<option v-for="name in authAlgorithms" :value="name" v-text="name"></option>
</select>
</div>
</div>
@ -74,8 +73,7 @@
<label for="cryptoalgo" class="col-sm-3 control-label">Cryptoalgo</label>
<div class="col-sm-9">
<select class="form-control" id="cryptoalgo" v-model="item.cryptoalgo" @change="updateItem(id, $event.target.id, $event.target.value)">
<option value="AES">AES</option>
<option value="DES">DES</option>
<option v-for="name in cryptoAlgorithms" :value="name" v-text="name"></option>
</select>
</div>
@ -101,16 +99,24 @@
</template>
<script>
import BaseSetting from "./BaseSetting";
import BaseSetting from "./BaseSetting";
export default {
export default {
name: "SettingSnmp3auth",
mixins: [BaseSetting],
data() {
return {
localList: this.value
localList: this.value,
authAlgorithms: ['MD5', 'AES'],
cryptoAlgorithms: ['AES', 'DES'],
}
},
mounted() {
axios.get(route('snmp.capabilities')).then((res) => {
this.authAlgorithms = res.data.auth;
this.cryptoAlgorithms = res.data.crypto;
})
},
methods: {
addItem() {
this.localList.push({

View File

@ -42,8 +42,8 @@ Artisan::command('device:add
{--r|port=161 : ' . __('SNMP transport port') . '}
{--u|security-name=root : ' . __('SNMPv3 security username') . '}
{--A|auth-password= : ' . __('SNMPv3 authentication password') . '}
{--a|auth-protocol=md5 : ' . __('SNMPv3 authentication protocol') . ' [md5, sha, sha-512, sha-384, sha-256, sha-224]}
{--x|privacy-protocol=aes : ' . __('SNMPv3 privacy protocol') . ' [des, aes]}
{--a|auth-protocol=md5 : ' . __('SNMPv3 authentication protocol') . ' [' . implode(', ', \LibreNMS\SNMPCapabilities::supportedAuthAlgorithms()) . ']}
{--x|privacy-protocol=aes : ' . __('SNMPv3 privacy protocol') . ' [' . implode(', ', \LibreNMS\SNMPCapabilities::supportedCryptoAlgorithms()) . ']}
{--X|privacy-password= : ' . __('SNMPv3 privacy password') . '}
{--P|ping-only : ' . __('Add a ping only device') . '}
{--o|os=ping : ' . __('Ping only: specify OS') . '}
@ -60,11 +60,11 @@ Artisan::command('device:add
$this->error(__('Invalid SNMP transport'));
}
if (! in_array($this->option('auth-protocol'), ['md5', 'sha', 'sha-512', 'sha-384', 'sha-256', 'sha-224'])) {
if (! in_array($this->option('auth-protocol'), \LibreNMS\SNMPCapabilities::supportedAuthAlgorithms())) {
$this->error(__('Invalid authentication protocol'));
}
if (! in_array($this->option('privacy-protocol'), ['des', 'aes'])) {
if (! in_array($this->option('privacy-protocol'), \LibreNMS\SNMPCapabilities::supportedCryptoAlgorithms())) {
$this->error(__('Invalid privacy protocol'));
}

View File

@ -91,6 +91,7 @@ Route::group(['middleware' => ['auth'], 'guard' => 'auth'], function () {
Route::post('set_resolution', 'ResolutionController@set');
Route::get('netcmd', 'NetCommand@run');
Route::post('ripe/raw', 'RipeNccApiController@raw');
Route::get('snmp/capabilities', 'SnmpCapabilities')->name('snmp.capabilities');
});
Route::get('settings/list', 'SettingsController@listAll')->name('settings.list');