Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T5661: Add show show ssh dynamic-protection attacker and show log ssh… #2369

Merged
merged 1 commit into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions op-mode-definitions/show-log.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -618,12 +618,20 @@
</properties>
<command>journalctl --no-hostname --boot --unit snmpd.service</command>
</leafNode>
<leafNode name="ssh">
<node name="ssh">
<properties>
<help>Show log for Secure Shell (SSH)</help>
</properties>
<command>journalctl --no-hostname --boot --unit ssh.service</command>
</leafNode>
<children>
<node name="dynamic-protection">
<properties>
<help>Show dynamic-protection log</help>
</properties>
<command>journalctl --no-hostname -p info -t sshguard -o short</command>
</node>
</children>
</node>
<tagNode name="tail">
<properties>
<help>Show last n changes to messages</help>
Expand Down
10 changes: 8 additions & 2 deletions op-mode-definitions/show-ssh.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,23 @@
<help>Show SSH server information</help>
</properties>
<children>
<node name="dynamic-protection">
<properties>
<help>Show SSH server dynamic-protection blocked attackers</help>
</properties>
<command>${vyos_op_scripts_dir}/ssh.py show_dynamic_protection</command>
</node>
<node name="fingerprints">
<properties>
<help>Show SSH server public key fingerprints</help>
</properties>
<command>${vyos_op_scripts_dir}/show-ssh-fingerprints.py</command>
<command>${vyos_op_scripts_dir}/ssh.py show_fingerprints</command>
<children>
<node name="ascii">
<properties>
<help>Show visual ASCII art representation of the public key</help>
</properties>
<command>${vyos_op_scripts_dir}/show-ssh-fingerprints.py --ascii</command>
<command>${vyos_op_scripts_dir}/ssh.py show_fingerprints --ascii</command>
</node>
</children>
</node>
Expand Down
49 changes: 0 additions & 49 deletions src/op_mode/show-ssh-fingerprints.py

This file was deleted.

100 changes: 100 additions & 0 deletions src/op_mode/ssh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#!/usr/bin/env python3
#
# Copyright 2017-2023 VyOS maintainers and contributors <[email protected]>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.

import json
import sys
import glob
import vyos.opmode
from vyos.utils.process import cmd
from vyos.configquery import ConfigTreeQuery
from tabulate import tabulate

def show_fingerprints(raw: bool, ascii: bool):
config = ConfigTreeQuery()
if not config.exists("service ssh"):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a dedicated exception for this case.

raise vyos.opmode.UnconfiguredSubsystem("SSH server is not enabled.")

publickeys = glob.glob("/etc/ssh/*.pub")

if publickeys:
keys = []
for keyfile in publickeys:
try:
if ascii:
keydata = cmd("ssh-keygen -l -v -E sha256 -f " + keyfile).splitlines()
else:
keydata = cmd("ssh-keygen -l -E sha256 -f " + keyfile).splitlines()
type = keydata[0].split(None)[-1].strip("()")
key_size = keydata[0].split(None)[0]
fingerprint = keydata[0].split(None)[1]
comment = keydata[0].split(None)[2:-1][0]
if ascii:
ascii_art = "\n".join(keydata[1:])
keys.append({"type": type, "key_size": key_size, "fingerprint": fingerprint, "comment": comment, "ascii_art": ascii_art})
else:
keys.append({"type": type, "key_size": key_size, "fingerprint": fingerprint, "comment": comment})
except:
# Ignore invalid public keys
pass
if raw:
return keys
else:
headers = {"type": "Type", "key_size": "Key Size", "fingerprint": "Fingerprint", "comment": "Comment", "ascii_art": "ASCII Art"}
output = "SSH server public key fingerprints:\n\n" + tabulate(keys, headers=headers, tablefmt="simple")
return output
else:
if raw:
return []
else:
return "No SSH server public keys are found."

def show_dynamic_protection(raw: bool):
config = ConfigTreeQuery()
if not config.exists("service ssh dynamic-protection"):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above, we have an exception specially for this case.

raise vyos.opmode.UnconfiguredSubsystem("SSH server dynamic-protection is not enabled.")

attackers = []
try:
# IPv4
attackers = attackers + json.loads(cmd("sudo nft -j list set ip sshguard attackers"))["nftables"][1]["set"]["elem"]
except:
pass
try:
# IPv6
attackers = attackers + json.loads(cmd("sudo nft -j list set ip6 sshguard attackers"))["nftables"][1]["set"]["elem"]
except:
pass
if attackers:
if raw:
return attackers
else:
output = "Blocked attackers:\n" + "\n".join(attackers)
return output
else:
if raw:
return []
else:
return "No blocked attackers."

if __name__ == '__main__':
try:
res = vyos.opmode.run(sys.modules[__name__])
if res:
print(res)
except (ValueError, vyos.opmode.Error) as e:
print(e)
sys.exit(1)