Last Updated: May 15, 2025
Astra is an open-source network scanning tool written in Python, designed for security researchers and network administrators. It enables users to scan IP ranges, resolve domains to IPs, and identify open ports with high flexibility. Unlike many existing tools, Astra operates locally without third-party API dependencies (e.g., no reliance on services like ipinfo.io for core functionality), prioritizing user control, privacy, and customization.
Astra was developed to address the need for a lightweight, customizable network scanner that:
This documentation is intended for developers and maintainers who wish to understand, maintain, or extend Astra’s functionality.
Astra’s core features are designed to be modular and extensible. Below is an overview of each feature and its implementation:
Domain Resolution:
apple.com) to multiple IPs using the dnspython library.astra/api.py via the get_cidr_ranges_local function./32 CIDR range for consistent handling with user-provided CIDR ranges.CIDR Scanning:
192.168.1.0/24) or comma-separated CIDR lists.ipaddress module.astra/api.py via the get_cidr_ranges function.Flexible Port Scanning:
--first-1000), 300 (--first-300), or custom ports (--ports 80,443).socket and concurrent.futures.ThreadPoolExecutor for efficiency.astra/network.py via the scan_network function.IP Limits:
--max-ips) caps the total number of IPs scanned across all CIDR ranges.--max-ips-per-cidr, --first-1-per-cidr, --first-2-per-cidr, --first-10-per-cidr) controls the number of IPs scanned per CIDR range.astra/network.py via the extract_ips function.Output Options:
--output, --output-format).astra/report.py via the save_results function.Verbose Logging:
--verbose, including CIDR ranges, IP counts, and scan progress.logging module, configured in astra/cli.py.Configurability:
~/.astra/config.json) for default settings (e.g., timeout, default ports).astra/config.py via the load_config function.Astra follows a modular design with distinct components for each major functionality. The architecture is structured to ensure separation of concerns, making it easy to modify or extend specific features.
Command-Line Parsing (astra/cli.py):
argparse.CIDR Resolution (astra/api.py):
IP Extraction (astra/network.py):
Network Scanning (astra/network.py):
Result Handling (astra/report.py):
Configuration (astra/config.py):
astra/
__init__.py: Package initializer.cli.py: Command-line interface and main entry point.api.py: Handles domain resolution and CIDR range processing.network.py: Manages IP extraction and network scanning.report.py: Formats and saves scan results.config.py: Loads configuration settings.astra.py: Entry script that calls cli.main().requirements.txt: Lists dependencies (e.g., dnspython).README.md: User-facing documentation.DEVELOPER.md: This file.cli.py: main()
get_cidr_ranges, extract_ips, scan_network, and save_results.api.py: get_cidr_ranges()
--cidr is provided, validates and returns the CIDR(s).get_cidr_ranges_local.api.py: get_cidr_ranges_local()
dns.resolver to fetch A records for a domain./32 CIDR ranges.network.py: extract_ips()
ipaddress.ip_network.max_ips_per_cidr) and global (max_ips) limits.network.py: scan_network()
max_workers) based on workload.report.py: save_results()
dnspython: For domain resolution (dns.resolver).argparse: Command-line argument parsing.logging: Verbose logging.socket: TCP scanning.ipaddress: CIDR range handling.concurrent.futures: Concurrent scanning.json and csv: Output formatting.Dependencies are listed in requirements.txt and can be installed with:
pip install -r requirements.txt
Astra’s modular design makes it straightforward to add new features or modify existing ones. Below are common extension scenarios:
astra/cli.py and locate the parse_args function.parser.add_argument. For example, to add a --scan-type argument:
parser.add_argument("--scan-type", choices=["tcp", "udp"], default="tcp", help="Type of scan to perform (tcp, udp)")
main. For example:
scan_type = args.scan_type
logging.info(f"Using scan type: {scan_type}")
astra/network.py.scan_port to support UDP by adding a scan_type parameter:
def scan_port(ip: str, port: int, timeout: float, scan_type: str = "tcp") -> bool:
try:
if scan_type == "tcp":
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
elif scan_type == "udp":
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(timeout)
result = sock.connect_ex((ip, port))
sock.close()
return result == 0
except socket.error:
return False
scan_network to pass the scan_type parameter to scan_port.astra/report.py.save_results to support the new format (e.g., XML):
if output_format == "xml":
import xml.etree.ElementTree as ET
root = ET.Element("scan_results")
# Add scan data to XML structure
tree = ET.ElementTree(root)
tree.write(output_file)
cli.py to include the new format in the --output-format choices:
parser.add_argument("--output-format", choices=["json", "csv", "xml"], help="Output format (json, csv, xml)")
max_workers in network.py’s scan_network function. Be cautious of system resource limits.cli.py to reduce I/O overhead in non-verbose mode.extract_ips to process IPs in batches if memory usage becomes an issue with large CIDR ranges.To ensure changes don’t break existing functionality:
Unit Tests:
unittest or pytest.Example test for extract_ips:
import unittest
from astra.network import extract_ips
class TestNetwork(unittest.TestCase):
def test_extract_ips(self):
cidr_ranges = ["192.168.1.0/30"]
ips = extract_ips(cidr_ranges, max_ips=2)
self.assertEqual(len(ips), 2)
self.assertEqual(ips, ["192.168.1.0", "192.168.1.1"])
if __name__ == "__main__":
unittest.main()
Manual Testing:
python3 astra.py apple.com --first-1000 --verbosepython3 astra.py --cidr 192.168.1.0/30 --first-300 --first-2-per-cidr --verbosepython3 astra.py apple.com --output results.json --verboseFork and Clone:
git clone https://github.com/bhaweshchaudhary/Astra.gitCreate a Feature Branch:
git checkout -b feature/your-feature-nameCode Style:
Commit Messages:
Pull Request:
git push origin feature/your-feature-nameTesting:
max_workers.api.py and network.py to use socket.AF_INET6.For questions or collaboration, reach out via GitHub issues at https://github.com/bhaweshchaudhary/astra.
Note: Astra is for ethical use only. Developers and maintainers must ensure that any use of the tool complies with legal and ethical standards. Unauthorized network scanning is illegal.