Page MenuHomeVyOS Platform

A feature for checking popular ports.
Closed, ResolvedPublicFEATURE REQUEST

Assigned To
Authored By
Unknown Object (User)
Mar 28 2024, 2:24 AM
Tags
None
Referenced Files
F4334412: image.png
May 28 2024, 6:46 AM
F4251618: scanport3.py
Mar 28 2024, 2:24 AM
F4251617: ports.txt
Mar 28 2024, 2:24 AM

Description

As an additional feature, nmap can be used to scan host ports or domain names. You can create a command in the main mode of the system and bind it to a script. The script scans ports from a separate file which can be updated or added at any time to the required ports.

Also VyOS has the library - import nmap

Could you accept the feature to create a pull request?

root@k:/t# ./scanport3.py
Enter remote host: 1.1.1.1

Scanning completed.
Open ports:
Port    Description
53      DNS (Domain Name System)
80      HTTP (Hypertext Transfer Protocol)
443     HTTPS (HTTP Secure)
8080    HTTP Alternate

Closed ports:
Port    Description
21      FTP (File Transfer Protocol)
22      SSH (Secure Shell)
23      Telnet
25      SMTP (Simple Mail Transfer Protocol)
110     POP3 (Post Office Protocol version 3)
123     NTP (Network Time Protocol)
143     IMAP (Internet Message Access Protocol)
465     SMTPS (SMTP Secure)
500     IPSec VPN (Internet Protocol Security)
587     SMTP (Submission)
993     IMAPS (IMAP Secure)
995     POP3S (POP3 Secure)
1433    MS SQL Server
1521    Oracle Database
1701    L2TP (Layer 2 Tunneling Protocol)
1723    PPTP (Point-to-Point Tunneling Protocol)
3306    MySQL
3389    Remote Desktop Protocol (RDP)
5432    PostgreSQL
5900    VNC (Virtual Network Computing)

Details

Version
-
Is it a breaking change?
Unspecified (possibly destroys the router)
Issue type
Unspecified (please specify)

Event Timeline

Unknown Object (User) created this task.Mar 28 2024, 2:24 AM
Unknown Object (User) added a subscriber: sever.

@sever what do you think about it?

I'm not sure that a list of ports will be helpful in this way.
From time to time, we need to scan specific ports.
What about

force scan-port-host <x.x.x.x> proto <tcp|udp> port '8080-8081,9200'
force port--discovery-host <x.x.x.x> proto <tcp|udp> port '8080'
force port-scan host <x.x.x.x> proto <tcp|udp> port '8080'

And use native nmap binaries (as python3 nmap module is not installed by default)
Also, it has XML format if you want a custom table:

sudo nmap -oX - 127.0.0.1
Viacheslav triaged this task as Wishlist priority.Mar 31 2024, 11:28 AM
Unknown Object (User) added a comment.Apr 1 2024, 12:58 AM

ok, i'll change a port list and nmap scenario

Personally I dont think its a good idea to be able to use VyOS as a jumphost towards victims of scanning.

Sure you can do this through bash mode but then also let this feature be available through bash mode only and not from regular op-mode?

That is you must have permission to enter bash mode and do sudo in order to run nmap.

Unknown Object (User) added a comment.May 28 2024, 6:46 AM

@sever what about it?

image.png (537×669 px, 43 KB)

#!/usr/bin/env python3

import subprocess

def main():
    # Ask for the IP address of the host
    ip_address = input("Enter the IP address of the host to scan: ")

    # Ask for the ports to scan
    ports = input("Enter the port or list of ports (e.g., 8080-8081,9200): ")

    # Ask for the protocol to scan
    protocol = input("Which protocol to scan (TCP/UDP): ").strip().upper()

    # Form the nmap command
    if protocol == "TCP":
        nmap_command = f"nmap -sT -p {ports} {ip_address}"
    elif protocol == "UDP":
        nmap_command = f"nmap -sU -p {ports} {ip_address}"
    else:
        print("Invalid protocol. Enter TCP or UDP.")
        return

    # Execute the nmap command
    try:
        result = subprocess.run(nmap_command.split(), capture_output=True, text=True)
        print(result.stdout)
    except Exception as e:
        print(f"Error executing nmap command: {e}")

if __name__ == "__main__":
    main()

Just dont, please see my comment fro april 2024.

Unknown Object (User) added a comment.May 29 2024, 5:43 AM

We will bind the code to a new command in operating mode (for example show ports). This will allow you to use the nmap command from operating mode. Just a convenient feature.

Unknown Object (User) added a comment.Jul 29 2024, 5:11 AM

show ports local <--- show opened ports on a local host

#!/usr/bin/env python3

import psutil
import socket

def get_open_ports():
    open_ports = []
    for conn in psutil.net_connections(kind='inet'):
        if conn.status == psutil.CONN_LISTEN:
            open_ports.append((conn.laddr.ip, conn.laddr.port, conn.type))
    return open_ports

def format_address(ip, port):
    if ip == '0.0.0.0':
        ip = 'All IPv4 addresses'
    elif ip == '::':
        ip = 'All IPv6 addresses'
    elif ip == '::1':
        ip = 'localhost (IPv6)'
    elif ip == '127.0.0.1':
        ip = 'localhost (IPv4)'
    return f"{ip}:{port}"

def main():
    open_ports = get_open_ports()
    if open_ports:
        print("Open ports on localhost:")
        print("{:<25} {:<10}".format("Address", "Protocol"))
        print("-" * 35)
        for ip, port, conn_type in open_ports:
            protocol = 'TCP' if conn_type == socket.SOCK_STREAM else 'UDP'
            print("{:<25} {:<10}".format(format_address(ip, port), protocol))
    else:
        print("No open ports on localhost.")

if __name__ == "__main__":
    main()

show ports <HOST_IP> <--- show opened ports on a remote host (scan popular ports)

#!/usr/bin/env python3

import socket
import sys

# List of popular ports to scan
popular_ports = [
    20, 21, 22, 23, 25, 53, 80, 110, 123, 135, 137, 138, 139, 143, 161, 162, 179, 389, 443, 445, 465, 514, 587, 993, 995, 1080, 1433, 1434, 1521, 1723, 3306, 3389, 5060, 5432, 5900, 5938, 8080, 8443, 8888
]

def scan_ports(host):
    open_ports = []
    for port in popular_ports:
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(1)
            result = sock.connect_ex((host, port))
            if result == 0:
                open_ports.append(port)
            sock.close()
        except Exception as e:
            print(f"Error scanning port {port}: {e}")
            break
    return open_ports

def main(host):
    open_ports = scan_ports(host)
    if open_ports:
        print(f"Open ports on {host}:")
        for port in open_ports:
            print(f"Port {port} is open")
    else:
        print(f"No open ports found on {host}.")

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python open_ports_remote.py <IP>")
        sys.exit(1)

    remote_host = sys.argv[1]
    main(remote_host)

show ports <HOST_IP> services <--- show opened ports and services on a remote host (scan popular ports)

#!/usr/bin/env python3

import socket
import sys
from concurrent.futures import ThreadPoolExecutor, as_completed

# List of popular ports to scan with their corresponding service names
popular_ports = {
    20: 'FTP',
    21: 'FTP',
    22: 'SSH',
    23: 'Telnet',
    25: 'SMTP',
    53: 'DNS',
    80: 'HTTP',
    110: 'POP3',
    123: 'NTP',
    135: 'MS-RPC',
    137: 'NetBIOS',
    138: 'NetBIOS',
    139: 'NetBIOS',
    143: 'IMAP',
    161: 'SNMP',
    162: 'SNMP',
    179: 'BGP',
    389: 'LDAP',
    443: 'HTTPS',
    445: 'SMB',
    465: 'SMTPS',
    514: 'Syslog',
    587: 'SMTP',
    993: 'IMAPS',
    995: 'POP3S',
    1080: 'SOCKS',
    1433: 'MSSQL',
    1434: 'MSSQL',
    1521: 'Oracle',
    1723: 'PPTP',
    3306: 'MySQL',
    3389: 'RDP',
    5060: 'SIP',
    5432: 'PostgreSQL',
    5900: 'VNC',
    5938: 'TeamViewer',
    8080: 'HTTP-Proxy',
    8443: 'HTTPS-Alt',
    8888: 'HTTP-Alt'
}

def scan_port(host, port):
    try:
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
            sock.settimeout(1)
            result = sock.connect_ex((host, port))
            if result == 0:
                return port
    except Exception as e:
        print(f"Error scanning port {port}: {e}")
    return None

def main(host):
    open_ports = []
    with ThreadPoolExecutor(max_workers=100) as executor:
        futures = {executor.submit(scan_port, host, port): port for port in popular_ports}
        for future in as_completed(futures):
            port = future.result()
            if port:
                open_ports.append(port)

    if open_ports:
        print(f"Open ports on {host}:")
        for port in open_ports:
            service_name = popular_ports.get(port, "Unknown")
            print(f"Port {port} ({service_name}) is open")
    else:
        print(f"No open ports found on {host}.")

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python open_ports_remote.py <IP>")
        sys.exit(1)

    remote_host = sys.argv[1]
    main(remote_host)
syncer closed this task as Not Applicable.Nov 1 2024, 2:37 PM
syncer subscribed.
This comment was removed by syncer.

The blog post over at https://blog.vyos.io/vyos-project-october-2024-update claims this have been implemented, there is a merge from 10th sept 2024 claiming to be merged - yet this task have been closed with "not applicable - out of scope for VyOS".

So is this implemented or is not implemented?

syncer changed the task status from Not Applicable to Resolved.Nov 2 2024, 12:36 PM

Thanks - resolved means its implemented as the blog post stated :-)

@Apachez i think we need to add status Implemented for feature request it makes more sense
and for bugs mark them as resolved