diff --git a/op-mode-definitions/show-log.xml.in b/op-mode-definitions/show-log.xml.in index a2a210543..dcfede991 100644 --- a/op-mode-definitions/show-log.xml.in +++ b/op-mode-definitions/show-log.xml.in @@ -1,717 +1,725 @@ <?xml version="1.0"?> <interfaceDefinition> <node name="show"> <properties> <help>Show system information</help> </properties> <children> <tagNode name="log"> <properties> <help>Show last number of messages in master logging buffer</help> <completionHelp> <list><1-9999></list> </completionHelp> </properties> <command>if ${vyos_validators_dir}/numeric --range 1-9999 "$3"; then journalctl --no-hostname --boot --lines "$3"; fi</command> </tagNode> <node name="log"> <properties> <help>Show contents of current master logging buffer</help> </properties> <command>journalctl --no-hostname --boot</command> <children> <leafNode name="audit"> <properties> <help>Show audit logs</help> </properties> <command>cat /var/log/audit/audit.log</command> </leafNode> <leafNode name="all"> <properties> <help>Show contents of all master log files</help> </properties> <command>sudo bash -c 'eval $(lesspipe); less $_vyatta_less_options --prompt=".logm, file %i of %m., page %dt of %D" -- `printf "%s\n" /var/log/messages* | sort -nr`'</command> </leafNode> <leafNode name="authorization"> <properties> <help>Show listing of authorization attempts</help> </properties> <command>journalctl --no-hostname --boot --quiet SYSLOG_FACILITY=10 SYSLOG_FACILITY=4</command> </leafNode> <leafNode name="cluster"> <properties> <help>Show log for Cluster</help> </properties> <command>cat $(printf "%s\n" /var/log/messages* | sort -nr) | grep -e heartbeat -e cl_status -e mach_down -e ha_log</command> </leafNode> <leafNode name="conntrack-sync"> <properties> <help>Show log for Conntrack-sync</help> </properties> <command>journalctl --no-hostname --boot --unit conntrackd.service</command> </leafNode> <leafNode name="console-server"> <properties> <help>Show log for console server</help> </properties> <command>journalctl --no-hostname --boot --unit conserver-server.service</command> </leafNode> <node name="ids"> <properties> <help>Show log for for Intrusion Detection System</help> </properties> <children> <leafNode name="ddos-protection"> <properties> <help>Show log for DDOS protection</help> </properties> <command>journalctl --no-hostname --boot --unit fastnetmon.service</command> </leafNode> </children> </node> <node name="dhcp"> <properties> <help>Show log for Dynamic Host Control Protocol (DHCP)</help> </properties> <children> <node name="server"> <properties> <help>Show log for DHCP server</help> </properties> <command>journalctl --no-hostname --boot --unit isc-dhcp-server.service</command> </node> <node name="client"> <properties> <help>Show DHCP client logs</help> </properties> <command>journalctl --no-hostname --boot --unit "dhclient@*.service"</command> <children> <tagNode name="interface"> <properties> <help>Show DHCP client log on specific interface</help> <completionHelp> <script>${vyos_completion_dir}/list_interfaces --broadcast</script> </completionHelp> </properties> <command>journalctl --no-hostname --boot --unit "dhclient@$6.service"</command> </tagNode> </children> </node> </children> </node> <node name="dhcpv6"> <properties> <help>Show log for Dynamic Host Control Protocol IPv6 (DHCPv6)</help> </properties> <children> <node name="server"> <properties> <help>Show log for DHCPv6 server</help> </properties> <command>journalctl --no-hostname --boot --unit isc-dhcp-server6.service</command> </node> <node name="client"> <properties> <help>Show DHCPv6 client logs</help> </properties> <command>journalctl --no-hostname --boot --unit "dhcp6c@*.service"</command> <children> <tagNode name="interface"> <properties> <help>Show DHCPv6 client log on specific interface</help> <completionHelp> <script>${vyos_completion_dir}/list_interfaces</script> </completionHelp> </properties> <command>journalctl --no-hostname --boot --unit "dhcp6c@$6.service"</command> </tagNode> </children> </node> </children> </node> <node name="firewall"> <properties> <help>Show log for Firewall</help> </properties> <command>journalctl --no-hostname --boot -k | egrep "(ipv[46]|bri)-(FWD|INP|OUT|NAM)"</command> <children> <node name="bridge"> <properties> <help>Show firewall bridge log</help> </properties> <command>journalctl --no-hostname --boot -k | egrep "bri-(FWD|INP|OUT|NAM)"</command> <children> <node name="forward"> <properties> <help>Show Bridge forward firewall log</help> </properties> <command>journalctl --no-hostname --boot -k | grep bri-FWD</command> <children> <node name="filter"> <properties> <help>Show Bridge firewall forward filter</help> </properties> <command>journalctl --no-hostname --boot -k | grep bri-FWD-filter</command> <children> <tagNode name="rule"> <properties> <help>Show log for a rule in the specified firewall</help> <completionHelp> <path>firewall bridge forward filter rule</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | egrep "\[bri-FWD-filter-$8-[ADRJC]\]"</command> </tagNode> </children> </node> </children> </node> <tagNode name="name"> <properties> <help>Show custom Bridge firewall log</help> <completionHelp> <path>firewall bridge name</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | grep bri-NAM-$6</command> <children> <tagNode name="rule"> <properties> <help>Show log for a rule in the specified firewall</help> <completionHelp> <path>firewall bridge name ${COMP_WORDS[5]} rule</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | egrep "\[bri-NAM-$6-$8-[ADRJC]\]"</command> </tagNode> </children> </tagNode> </children> </node> <node name="ipv4"> <properties> <help>Show firewall IPv4 log</help> </properties> <command>journalctl --no-hostname --boot -k | egrep "ipv4-(FWD|INP|OUT|NAM)"</command> <children> <node name="forward"> <properties> <help>Show firewall IPv4 forward log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv4-FWD</command> <children> <node name="filter"> <properties> <help>Show firewall IPv4 forward filter log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv4-FWD-filter</command> <children> <tagNode name="rule"> <properties> <help>Show log for a rule in the specified firewall</help> <completionHelp> <path>firewall ipv4 forward filter rule</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | egrep "\[ipv4-FWD-filter-$8-[ADRJC]\]"</command> </tagNode> </children> </node> </children> </node> <node name="input"> <properties> <help>Show firewall IPv4 input log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv4-INP</command> <children> <node name="filter"> <properties> <help>Show firewall IPv4 input filter log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv4-INP-filter</command> <children> <tagNode name="rule"> <properties> <help>Show log for a rule in the specified firewall</help> <completionHelp> <path>firewall ipv4 input filter rule</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | egrep "\[ipv4-INP-filter-$8-[ADRJC]\]"</command> </tagNode> </children> </node> </children> </node> <tagNode name="name"> <properties> <help>Show custom IPv4 firewall log</help> <completionHelp> <path>firewall ipv4 name</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | grep ipv4-NAM-$6</command> <children> <tagNode name="rule"> <properties> <help>Show log for a rule in the specified firewall</help> <completionHelp> <path>firewall ipv4 name ${COMP_WORDS[5]} rule</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | egrep "\[ipv4-NAM-$6-$8-[ADRJC]\]"</command> </tagNode> </children> </tagNode> <node name="output"> <properties> <help>Show firewall IPv4 output log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv4-OUT</command> <children> <node name="filter"> <properties> <help>Show firewall IPv4 output filter log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv4-OUT-filter</command> <children> <tagNode name="rule"> <properties> <help>Show log for a rule in the specified firewall</help> <completionHelp> <path>firewall ipv4 output filter rule</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | egrep "\[ipv4-OUT-filter-$8-[ADRJC]\]"</command> </tagNode> </children> </node> </children> </node> </children> </node> <node name="ipv6"> <properties> <help>Show firewall IPv6 log</help> </properties> <command>journalctl --no-hostname --boot -k | egrep "ipv6-(FWD|INP|OUT|NAM)"</command> <children> <node name="forward"> <properties> <help>Show firewall IPv6 forward log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv6-FWD</command> <children> <node name="filter"> <properties> <help>Show firewall IPv6 forward filter log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv6-FWD-filter</command> <children> <tagNode name="rule"> <properties> <help>Show log for a rule in the specified firewall</help> <completionHelp> <path>firewall ipv6 forward filter rule</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | egrep "\[ipv6-FWD-filter-$8-[ADRJC]\]"</command> </tagNode> </children> </node> </children> </node> <node name="input"> <properties> <help>Show firewall IPv6 input log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv6-INP</command> <children> <node name="filter"> <properties> <help>Show firewall IPv6 input filter log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv6-INP-filter</command> <children> <tagNode name="rule"> <properties> <help>Show log for a rule in the specified firewall</help> <completionHelp> <path>firewall ipv6 input filter rule</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | egrep "\[ipv6-INP-filter-$8-[ADRJC]\]"</command> </tagNode> </children> </node> </children> </node> <tagNode name="name"> <properties> <help>Show custom IPv6 firewall log</help> <completionHelp> <path>firewall ipv6 name</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | grep ipv6-NAM-$6</command> <children> <tagNode name="rule"> <properties> <help>Show log for a rule in the specified firewall</help> <completionHelp> <path>firewall ipv6 name ${COMP_WORDS[5]} rule</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | egrep "\[ipv6-NAM-$6-$8-[ADRJC]\]"</command> </tagNode> </children> </tagNode> <node name="output"> <properties> <help>Show firewall IPv6 output log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv6-OUT</command> <children> <node name="filter"> <properties> <help>Show firewall IPv6 output filter log</help> </properties> <command>journalctl --no-hostname --boot -k | grep ipv6-OUT-filter</command> <children> <tagNode name="rule"> <properties> <help>Show log for a rule in the specified firewall</help> <completionHelp> <path>firewall ipv6 output filter rule</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot -k | egrep "\[ipv6-OUT-filter-$8-[ADRJC]\]"</command> </tagNode> </children> </node> </children> </node> </children> </node> </children> </node> <leafNode name="flow-accounting"> <properties> <help>Show log for flow-accounting</help> </properties> <command>journalctl --no-hostname --boot --unit uacctd.service</command> </leafNode> <leafNode name="https"> <properties> <help>Show log for HTTPs</help> </properties> <command>journalctl --no-hostname --boot --unit nginx.service</command> </leafNode> <tagNode name="image"> <properties> <help>Show contents of master log file for image</help> <completionHelp> <script>compgen -f /lib/live/mount/persistence/boot/ | grep -v grub | sed -e s@/lib/live/mount/persistence/boot/@@</script> </completionHelp> </properties> <command>less $_vyatta_less_options --prompt=".log, page %dt of %D" -- /lib/live/mount/persistence/boot/$4/rw/var/log/messages</command> <children> <leafNode name="all"> <properties> <help>Show contents of all master log files for image</help> </properties> <command>eval $(lesspipe); less $_vyatta_less_options --prompt=".log?m, file %i of %m., page %dt of %D" -- `printf "%s\n" /lib/live/mount/persistence/boot/$4/rw/var/log/messages* | sort -nr`</command> </leafNode> <leafNode name="authorization"> <properties> <help>Show listing of authorization attempts for image</help> </properties> <command>less $_vyatta_less_options --prompt=".log, page %dt of %D" -- /lib/live/mount/persistence/boot/$4/rw/var/log/auth.log</command> </leafNode> <tagNode name="tail"> <properties> <help>Show last changes to messages</help> <completionHelp> <list><NUMBER></list> </completionHelp> </properties> <command>tail -n "$6" /lib/live/mount/persistence/boot/$4/rw/var/log/messages | ${VYATTA_PAGER:-cat}</command> </tagNode> </children> </tagNode> <leafNode name="ipoe-server"> <properties> <help>Show log for IPoE server</help> </properties> <command>journalctl --no-hostname --boot --unit accel-ppp@ipoe.service</command> </leafNode> <leafNode name="kernel"> <properties> <help>Show log for Linux Kernel</help> </properties> <command>journalctl --no-hostname --boot --dmesg</command> </leafNode> <leafNode name="lldp"> <properties> <help>Show log for Link Layer Discovery Protocol (LLDP)</help> </properties> <command>journalctl --no-hostname --boot --unit lldpd.service</command> </leafNode> <leafNode name="nat"> <properties> <help>Show log for Network Address Translation (NAT)</help> </properties> <command>egrep -i "kernel:.*\[NAT-[A-Z]{3,}-[0-9]+(-MASQ)?\]" $(find /var/log -maxdepth 1 -type f -name messages\* | sort -t. -k2nr)</command> </leafNode> <leafNode name="nhrp"> <properties> <help>Show log for Next Hop Resolution Protocol (NHRP)</help> </properties> <command>journalctl --no-hostname --boot --unit opennhrp.service</command> </leafNode> <leafNode name="ntp"> <properties> <help>Show log for Network Time Protocol (NTP)</help> </properties> <command>journalctl --no-hostname --boot --unit chrony.service</command> </leafNode> <node name="macsec"> <properties> <help>Show log for MACsec</help> </properties> <command>journalctl --no-hostname --boot --unit "wpa_supplicant-macsec@*.service"</command> <children> <tagNode name="interface"> <properties> <help>Show MACsec log on specific interface</help> <completionHelp> <path>interfaces macsec</path> </completionHelp> </properties> <command>SRC=$(cli-shell-api returnValue interfaces macsec "$5" source-interface); journalctl --no-hostname --boot --unit "wpa_supplicant-macsec@$SRC.service"</command> </tagNode> </children> </node> <node name="openvpn"> <properties> <help>Show log for OpenVPN</help> </properties> <command>journalctl --no-hostname --boot --unit openvpn@*.service</command> <children> <tagNode name="interface"> <properties> <help>Show OpenVPN log on specific interface</help> <completionHelp> <path>interfaces openvpn</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot --unit openvpn@$5.service</command> </tagNode> </children> </node> <node name="pppoe"> <properties> <help>Show log for PPPoE interface</help> </properties> <command>journalctl --no-hostname --boot --unit "ppp@pppoe*.service"</command> <children> <tagNode name="interface"> <properties> <help>Show PPPoE log on specific interface</help> <completionHelp> <path>interfaces pppoe</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot --unit "ppp@$5.service"</command> </tagNode> </children> </node> <leafNode name="pppoe-server"> <properties> <help>Show log for PPPoE server</help> </properties> <command>journalctl --no-hostname --boot --unit accel-ppp@pppoe.service</command> </leafNode> <node name="protocol"> <properties> <help>Show log for Routing Protocol</help> </properties> <children> <leafNode name="ospf"> <properties> <help>Show log for OSPF</help> </properties> <command>journalctl --boot /usr/lib/frr/ospfd</command> </leafNode> <leafNode name="ospfv3"> <properties> <help>Show log for OSPF for IPv6</help> </properties> <command>journalctl --boot /usr/lib/frr/ospf6d</command> </leafNode> <leafNode name="bgp"> <properties> <help>Show log for BGP</help> </properties> <command>journalctl --boot /usr/lib/frr/bgpd</command> </leafNode> <leafNode name="rip"> <properties> <help>Show log for RIP</help> </properties> <command>journalctl --boot /usr/lib/frr/ripd</command> </leafNode> <leafNode name="ripng"> <properties> <help>Show log for RIPng</help> </properties> <command>journalctl --boot /usr/lib/frr/ripngd</command> </leafNode> <leafNode name="static"> <properties> <help>Show log for static route</help> </properties> <command>journalctl --boot /usr/lib/frr/staticd</command> </leafNode> <leafNode name="multicast"> <properties> <help>Show log for Multicast protocol</help> </properties> <command>journalctl --boot /usr/lib/frr/pimd</command> </leafNode> <leafNode name="isis"> <properties> <help>Show log for ISIS</help> </properties> <command>journalctl --boot /usr/lib/frr/isisd</command> </leafNode> <leafNode name="nhrp"> <properties> <help>Show log for NHRP</help> </properties> <command>journalctl --boot /usr/lib/frr/nhrpd</command> </leafNode> <leafNode name="bfd"> <properties> <help>Show log for BFD</help> </properties> <command>journalctl --boot /usr/lib/frr/bfdd</command> </leafNode> <leafNode name="mpls"> <properties> <help>Show log for MPLS</help> </properties> <command>journalctl --boot /usr/lib/frr/ldpd</command> </leafNode> </children> </node> <leafNode name="router-advert"> <properties> <help>Show log for Router Advertisement Daemon (radvd)</help> </properties> <command>journalctl --no-hostname --boot --unit radvd.service</command> </leafNode> <leafNode name="snmp"> <properties> <help>Show log for Simple Network Monitoring Protocol (SNMP)</help> </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> <completionHelp> <list><NUMBER></list> </completionHelp> </properties> <command>tail -n "$4" /var/log/messages | ${VYATTA_PAGER:-cat}</command> </tagNode> <node name="tail"> <properties> <help>Show last 10 lines of /var/log/messages file</help> </properties> <command>tail -n 10 /var/log/messages</command> </node> <leafNode name="vpn"> <properties> <help>Monitor last lines of ALL Virtual Private Network services</help> </properties> <command>journalctl --no-hostname --boot --unit strongswan.service --unit accel-ppp@*.service --unit ocserv.service</command> </leafNode> <leafNode name="ipsec"> <properties> <help>Show log for IPsec</help> </properties> <command>journalctl --no-hostname --boot --unit strongswan.service</command> </leafNode> <leafNode name="l2tp"> <properties> <help>Show log for L2TP</help> </properties> <command>journalctl --no-hostname --boot --unit accel-ppp@l2tp.service</command> </leafNode> <leafNode name="openconnect"> <properties> <help>Show log for OpenConnect</help> </properties> <command>journalctl --no-hostname --boot --unit ocserv.service</command> </leafNode> <leafNode name="pptp"> <properties> <help>Show log for PPTP</help> </properties> <command>journalctl --no-hostname --boot --unit accel-ppp@pptp.service</command> </leafNode> <leafNode name="sstp"> <properties> <help>Show log for Secure Socket Tunneling Protocol (SSTP) server</help> </properties> <command>journalctl --no-hostname --boot --unit accel-ppp@sstp.service</command> </leafNode> <node name="sstpc"> <properties> <help>Show log for Secure Socket Tunneling Protocol (SSTP) client</help> </properties> <command>journalctl --no-hostname --boot --unit "ppp@sstpc*.service"</command> <children> <tagNode name="interface"> <properties> <help>Show SSTP client log on specific interface</help> <completionHelp> <path>interfaces sstpc</path> </completionHelp> </properties> <command>journalctl --no-hostname --boot --unit "ppp@$5.service"</command> </tagNode> </children> </node> <leafNode name="vpp"> <properties> <help>Show log for Vector Packet Processor (VPP)</help> </properties> <command>journalctl --no-hostname --boot --unit vpp.service</command> </leafNode> <leafNode name="vrrp"> <properties> <help>Show log for Virtual Router Redundancy Protocol (VRRP)</help> </properties> <command>journalctl --no-hostname --boot --unit keepalived.service</command> </leafNode> <leafNode name="webproxy"> <properties> <help>Show log for Webproxy</help> </properties> <command>journalctl --no-hostname --boot --unit squid.service</command> </leafNode> </children> </node> </children> </node> </interfaceDefinition> diff --git a/op-mode-definitions/show-ssh.xml.in b/op-mode-definitions/show-ssh.xml.in index dc6e0d02e..88faecada 100644 --- a/op-mode-definitions/show-ssh.xml.in +++ b/op-mode-definitions/show-ssh.xml.in @@ -1,28 +1,34 @@ <?xml version="1.0"?> <interfaceDefinition> <node name="show"> <children> <node name="ssh"> <properties> <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> </children> </node> </children> </node> </interfaceDefinition> diff --git a/src/op_mode/show-ssh-fingerprints.py b/src/op_mode/show-ssh-fingerprints.py deleted file mode 100644 index 913baae46..000000000 --- a/src/op_mode/show-ssh-fingerprints.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2017-2023 VyOS maintainers and contributors <maintainers@vyos.io> -# -# 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 sys -import glob -import argparse -from vyos.utils.process import cmd - -# Parse command line -parser = argparse.ArgumentParser() -parser.add_argument("--ascii", help="Show visual ASCII art representation of the public key", action="store_true") -args = parser.parse_args() - -# Get list of server public keys -publickeys = glob.glob("/etc/ssh/*.pub") - -if publickeys: - print("SSH server public key fingerprints:\n", flush=True) - for keyfile in publickeys: - if args.ascii: - try: - print(cmd("ssh-keygen -l -v -E sha256 -f " + keyfile) + "\n", flush=True) - # Ignore invalid public keys - except: - pass - else: - try: - print(cmd("ssh-keygen -l -E sha256 -f " + keyfile) + "\n", flush=True) - # Ignore invalid public keys - except: - pass -else: - print("No SSH server public keys are found.", flush=True) - -sys.exit(0) diff --git a/src/op_mode/ssh.py b/src/op_mode/ssh.py new file mode 100755 index 000000000..c09b2166f --- /dev/null +++ b/src/op_mode/ssh.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +# +# Copyright 2017-2023 VyOS maintainers and contributors <maintainers@vyos.io> +# +# 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"): + 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"): + 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)