- help_live/index.ex: 2,642→173 lines, 15 section modules + sidebar extracted MikroTik now real section, dead if false removed - agent_channel.ex: 2,506→1,751 lines, 3 helper modules extracted (heartbeat/subscriptions/job_builder), decode_and_process/4 eliminates 8 repeated handle_in patterns, guard-based size checks - antenna_catalog.ex: 1,174→47 lines, 107 specs → priv/antennas/catalog.json - topology.ex: unbounded query → batched loading (100/batch), all guard errors fixed, zero if/case/cond conditionals - proto: decoder_macros.ex + field_specs.ex infrastructure for macro-generated protobuf decoders
334 lines
15 KiB
Elixir
334 lines
15 KiB
Elixir
defmodule ToweropsWeb.HelpLive.Sections.Mikrotik do
|
|
@moduledoc false
|
|
use ToweropsWeb, :html
|
|
|
|
import ToweropsWeb.HelpLive.Sections.Helpers
|
|
|
|
def render(assigns) do
|
|
~H"""
|
|
<div class="p-6">
|
|
<h2 class="text-xl font-bold text-gray-900 dark:text-white mb-4">MikroTik Configuration</h2>
|
|
|
|
<div class="prose prose-sm dark:prose-invert max-w-none">
|
|
<p class="text-gray-600 dark:text-gray-400">
|
|
Towerops supports read-only monitoring of MikroTik RouterOS devices via SSH.
|
|
In addition to SNMP polling, SSH access allows Towerops to retrieve detailed system information
|
|
and create configuration backups of your MikroTik devices for disaster recovery and audit purposes.
|
|
</p>
|
|
|
|
<div class="mt-4 space-y-4">
|
|
<div class="p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg">
|
|
<div class="flex gap-3">
|
|
<.icon
|
|
name="hero-information-circle"
|
|
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5"
|
|
/>
|
|
<div>
|
|
<h4 class="text-sm font-semibold text-blue-900 dark:text-blue-300 mb-1">
|
|
Read-Only Access
|
|
</h4>
|
|
<p class="text-sm text-blue-800 dark:text-blue-300">
|
|
Towerops currently operates in read-only mode for MikroTik devices. Configuration changes,
|
|
reboots, and other administrative actions are not supported. This ensures your device
|
|
configurations remain unchanged by monitoring operations.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg">
|
|
<div class="flex gap-3">
|
|
<.icon
|
|
name="hero-server"
|
|
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5"
|
|
/>
|
|
<div>
|
|
<h4 class="text-sm font-semibold text-blue-900 dark:text-blue-300 mb-1">
|
|
Cloud or Agent-Based Connections
|
|
</h4>
|
|
<p class="text-sm text-blue-800 dark:text-blue-300">
|
|
Both SNMP polling and SSH connections to MikroTik devices can be performed from either
|
|
Towerops cloud infrastructure or your remote poller (agent). For publicly accessible devices,
|
|
cloud polling is the simplest option. For devices on private networks or when you prefer
|
|
to keep SSH credentials on your local network, deploy a remote poller. The device assignment
|
|
determines which poller handles both SNMP and SSH operations.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mt-6 mb-3">
|
|
Security Best Practices
|
|
</h3>
|
|
|
|
<p class="text-gray-600 dark:text-gray-400">
|
|
For security purposes, it is strongly recommended to create a dedicated read-only user account
|
|
for Towerops rather than using an administrator account. This follows the principle of least
|
|
privilege and minimizes potential security risks. Even though Towerops only performs read-only
|
|
operations, limiting the account permissions provides defense in depth.
|
|
</p>
|
|
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mt-6 mb-3">
|
|
Creating a Read-Only User
|
|
</h3>
|
|
|
|
<p class="text-gray-600 dark:text-gray-400">
|
|
Connect to your MikroTik device via SSH or terminal and execute the following commands to
|
|
create a read-only user named <.code>towerops</.code>:
|
|
</p>
|
|
|
|
<div class="mt-4 space-y-3">
|
|
<div>
|
|
<p class="text-sm text-gray-700 dark:text-gray-300 mb-2 font-medium">
|
|
Step 1: Create a new user group with read-only permissions
|
|
</p>
|
|
<div class="p-4 bg-black rounded-lg not-prose">
|
|
<div class="flex items-start gap-2">
|
|
<code class="text-sm text-white font-mono break-all flex-1">
|
|
/user group add name=readonly policy=ssh,read,test,api
|
|
</code>
|
|
<button
|
|
type="button"
|
|
phx-click={JS.dispatch("phx:copy", to: "#step1-command")}
|
|
class="flex-shrink-0 p-1 text-blue-400 hover:text-blue-300"
|
|
title="Copy to clipboard"
|
|
>
|
|
<.icon name="hero-clipboard-document" class="h-4 w-4" />
|
|
</button>
|
|
<input
|
|
type="hidden"
|
|
id="step1-command"
|
|
value="/user group add name=readonly policy=ssh,read,test,api"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<p class="text-sm text-gray-700 dark:text-gray-300 mb-2 font-medium">
|
|
Step 2: Create the monitoring user with a strong password
|
|
</p>
|
|
<div class="p-4 bg-black rounded-lg not-prose">
|
|
<div class="flex items-start gap-2">
|
|
<code class="text-sm text-white font-mono break-all flex-1">
|
|
/user add name=towerops password={if @generated_password,
|
|
do: @generated_password,
|
|
else: "YOUR_STRONG_PASSWORD"} group=readonly
|
|
</code>
|
|
<%= if @generated_password do %>
|
|
<button
|
|
type="button"
|
|
phx-click={JS.dispatch("phx:copy", to: "#generated-password-value")}
|
|
class="flex-shrink-0 p-1 text-blue-400 hover:text-blue-300"
|
|
title="Copy to clipboard"
|
|
>
|
|
<.icon name="hero-clipboard-document" class="h-4 w-4" />
|
|
</button>
|
|
<input type="hidden" id="generated-password-value" value={@generated_password} />
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<div class="mt-3 flex items-start gap-3">
|
|
<.button
|
|
type="button"
|
|
phx-click="generate_password"
|
|
disabled={@password_generating}
|
|
>
|
|
<%= if @password_generating do %>
|
|
<.icon name="hero-arrow-path" class="h-4 w-4 mr-1 animate-spin" /> Generating...
|
|
<% else %>
|
|
<.icon name="hero-sparkles" class="h-4 w-4 mr-1" /> Regenerate Random Password
|
|
<% end %>
|
|
</.button>
|
|
<%= if @generated_password do %>
|
|
<p class="text-xs text-yellow-600 dark:text-yellow-400 font-medium mt-1.5">
|
|
⚠️ This truly random password from random.org will only be shown once!
|
|
</p>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<p class="text-sm text-gray-700 dark:text-gray-300 mb-2 font-medium">
|
|
Step 3: Verify the user was created successfully
|
|
</p>
|
|
<div class="p-4 bg-black rounded-lg not-prose">
|
|
<div class="flex items-start gap-2">
|
|
<code class="text-sm text-white font-mono break-all flex-1">
|
|
/user print detail where name=towerops
|
|
</code>
|
|
<button
|
|
type="button"
|
|
phx-click={JS.dispatch("phx:copy", to: "#step3-command")}
|
|
class="flex-shrink-0 p-1 text-blue-400 hover:text-blue-300"
|
|
title="Copy to clipboard"
|
|
>
|
|
<.icon name="hero-clipboard-document" class="h-4 w-4" />
|
|
</button>
|
|
<input
|
|
type="hidden"
|
|
id="step3-command"
|
|
value="/user print detail where name=towerops"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mt-8 mb-3">
|
|
Permissions Explained
|
|
</h3>
|
|
|
|
<p class="text-gray-600 dark:text-gray-400">
|
|
The
|
|
<.code>readonly</.code>
|
|
group includes the following permissions. Note that while these
|
|
permissions are granted to the user account, Towerops only performs read operations and does
|
|
not make any configuration changes:
|
|
</p>
|
|
|
|
<div class="mt-4 bg-white dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-white/10 overflow-hidden">
|
|
<table class="min-w-full divide-y divide-gray-200 dark:divide-white/10">
|
|
<thead class="bg-gray-50 dark:bg-gray-800/75">
|
|
<tr>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Permission
|
|
</th>
|
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
|
|
Description
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-200 dark:divide-white/10">
|
|
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800">
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-mono text-gray-900 dark:text-white">
|
|
ssh
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-gray-600 dark:text-gray-400">
|
|
Allow SSH access to the device
|
|
</td>
|
|
</tr>
|
|
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800">
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-mono text-gray-900 dark:text-white">
|
|
read
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-gray-600 dark:text-gray-400">
|
|
Allow viewing configuration and status (read-only)
|
|
</td>
|
|
</tr>
|
|
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800">
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-mono text-gray-900 dark:text-white">
|
|
test
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-gray-600 dark:text-gray-400">
|
|
Allow executing diagnostic commands (ping, traceroute, etc.)
|
|
</td>
|
|
</tr>
|
|
<tr class="hover:bg-gray-50 dark:hover:bg-gray-800">
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-mono text-gray-900 dark:text-white">
|
|
api
|
|
</td>
|
|
<td class="px-6 py-4 text-sm text-gray-600 dark:text-gray-400">
|
|
Allow API access for automated monitoring
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="mt-6 p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg">
|
|
<div class="flex gap-3">
|
|
<.icon
|
|
name="hero-information-circle"
|
|
class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5"
|
|
/>
|
|
<div>
|
|
<h4 class="text-sm font-semibold text-blue-900 dark:text-blue-300 mb-1">
|
|
Important Notes
|
|
</h4>
|
|
<ul class="text-sm text-blue-800 dark:text-blue-300 space-y-1 list-disc list-inside">
|
|
<li>The read-only user cannot modify device configuration</li>
|
|
<li>No write, reboot, or sensitive permissions are granted</li>
|
|
<li>Use a strong, unique password for the monitoring account</li>
|
|
<li>Consider restricting SSH access by source IP if possible</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-white mt-8 mb-3">
|
|
Configuring in Towerops
|
|
</h3>
|
|
|
|
<p class="text-gray-600 dark:text-gray-400">
|
|
After creating the read-only user, configure SSH credentials in Towerops:
|
|
</p>
|
|
|
|
<div class="mt-4 space-y-4">
|
|
<div class="p-4 bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg">
|
|
<h4 class="text-sm font-semibold text-gray-900 dark:text-white mb-2">
|
|
Organization-Level Configuration
|
|
</h4>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400">
|
|
Navigate to
|
|
<.code>Organization Settings</.code>
|
|
→
|
|
<.code>MikroTik tab</.code>
|
|
to set default
|
|
SSH credentials for all MikroTik devices in your organization.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="p-4 bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg">
|
|
<h4 class="text-sm font-semibold text-gray-900 dark:text-white mb-2">
|
|
Site-Level Configuration
|
|
</h4>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400">
|
|
Navigate to
|
|
<.code>Sites</.code>
|
|
→ select a site →
|
|
<.code>Edit</.code>
|
|
to override
|
|
credentials for all devices at a specific location.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="p-4 bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-white/10 rounded-lg">
|
|
<h4 class="text-sm font-semibold text-gray-900 dark:text-white mb-2">
|
|
Device-Level Configuration
|
|
</h4>
|
|
<p class="text-sm text-gray-600 dark:text-gray-400">
|
|
When editing a MikroTik device, you can specify unique SSH credentials that override
|
|
organization and site defaults.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-6 p-4 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg">
|
|
<div class="flex gap-3">
|
|
<.icon
|
|
name="hero-shield-check"
|
|
class="h-5 w-5 text-yellow-600 dark:text-yellow-400 flex-shrink-0 mt-0.5"
|
|
/>
|
|
<div>
|
|
<h4 class="text-sm font-semibold text-yellow-900 dark:text-yellow-300 mb-1">
|
|
Security Recommendations
|
|
</h4>
|
|
<ul class="text-sm text-yellow-800 dark:text-yellow-300 space-y-1 list-disc list-inside">
|
|
<li>Always use SSL/TLS for SSH connections (API-SSL on port 8729)</li>
|
|
<li>Store credentials at the organization or site level when possible</li>
|
|
<li>Rotate passwords periodically following your security policies</li>
|
|
<li>Monitor access logs for unauthorized SSH connection attempts</li>
|
|
<li>
|
|
Consider using SSH keys instead of passwords (if supported by your setup)
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
"""
|
|
end
|
|
end
|