Terminal-based geopolitical threat intelligence toolkit. Collects, processes, and summarizes cyber threat intelligence from open-source RSS feeds, SpiderFoot OSINT scans, and Shodan IP enrichment — entirely in the terminal, no GUI required.
██ ███ ████ ██ ███ ███ █ █ ████ ████ █
█ █ █ █ █ █ █ █ █ █ ██ █ █ █ █
█ █ ███ ███ █ █ ███ █ █ ██ █ ███ █
█ █ █ █ █ █ █ █ █ █ █ █ █ █
██ █ █ ██ █ █ ███ █ █ █ ████ ████
intel collect— fetch 9+ threat intel RSS/Atom feeds and auto-process them into structured JSONintel report— generate an INTSUM-style intelligence summary from the latest processed dataintel scan --domain <d>— run a SpiderFoot OSINT scan and extract high-risk findingsintel enrich --ip <ip>— enrich an IP via Shodan (falls back to ipinfo.io if Shodan is unavailable)- Cron-ready —
scripts/run_intel.shhandles unattended runs with per-run logs and history tracking - No external runtime dependencies beyond Python packages in
requirements.txt
| Requirement | Version |
|---|---|
| Python | 3.9+ |
| pip | any recent |
| OS | Linux (Ubuntu/Debian/Kali recommended) |
Optional:
- Shodan API key — for
intel enrichwith full host data (falls back to ipinfo.io without one) - AlienVault OTX API key — for the OTX pulse feed
- SpiderFoot — for
intel scan(pip install spiderfootor clone from GitHub)
git clone https://github.com/GlobalReconReport/opfor-intel.git
cd opfor-intel
# Standard install (into current Python environment)
bash install.sh
# Or with a dedicated virtualenv
bash install.sh --venvinstall.sh will:
- Verify Python 3.9+
- Install all pip dependencies from
requirements.txt - Create runtime directories (
raw_intel/,processed_intel/,reports/,logs/) - Optionally install an
intelcommand to/usr/local/bin
All settings live in config.yaml. Edit it before running.
Feeds are enabled by default. To disable one, set enabled: false.
rss_feeds:
- name: "thehackernews"
url: "https://feeds.feedburner.com/TheHackersNews"
type: "rss"
auth_required: false
enabled: true - name: "alienvault_otx"
url: "https://otx.alienvault.com/api/v1/pulses/subscribed"
type: "api"
auth_required: true
enabled: true # change to true
api_key: "PASTE_KEY_HERE"Get a free key at otx.alienvault.com.
shodan:
api_key: "PASTE_KEY_HERE"Get a key at account.shodan.io. If blank or missing, intel enrich falls back to ipinfo.io automatically.
spiderfoot:
cli_path: "/usr/local/bin/sf"
modules: "sfp_dnsresolve,sfp_threatminer,sfp_virustotal,sfp_shodan"Install SpiderFoot with pip install spiderfoot or follow the SpiderFoot docs.
python3 main.py collectFetches all enabled RSS/API feeds, saves raw JSON to raw_intel/, then auto-processes each file to processed_intel/.
python3 main.py reportReads the most recent processed intel file, generates an INTSUM-style summary, prints to terminal, and saves a .txt copy to reports/.
python3 main.py enrich --ip 1.2.3.4Queries Shodan (or ipinfo.io as fallback) for org, OS, open ports, and risk flags.
python3 main.py scan --domain example.comRuns SpiderFoot against the domain with the configured modules. Requires SpiderFoot to be installed.
Pass --debug to any command for full stack traces and verbose log output:
python3 main.py --debug collectOPFOR Intel is feed-driven — what you collect depends entirely on what sources you point it at. This section walks you through focusing the tool on any region, country, or subject area in under 5 minutes.
Most news sites and threat blogs publish a free RSS feed. To find one:
- Go to the website you want to monitor
- Look for a link that says "RSS", "Feed", or an orange radio-wave icon
- Or try adding
/feedor/rssto the end of the site URL:
https://example-site.com/feed
https://example-site.com/rss
https://example-site.com/rss.xml
If none of those work, Google it:
site:example-site.com RSS feed
Examples by region/topic:
| Target | Source | Feed URL |
|---|---|---|
| MENA general | Al Jazeera English | https://www.aljazeera.com/xml/rss/all.xml |
| Africa security | Institute for Security Studies | https://issafrica.org/feed |
| Cyber/Middle East | CyberScoop | https://cyberscoop.com/feed |
| Iran | Radio Farda | https://www.radiofarda.com/api/ztrqiuol_ot |
| Israel/Palestine | Times of Israel | https://www.timesofisrael.com/feed |
| Africa | AllAfrica | https://allafrica.com/tools/headlines/rdf/latest/headlines.rdf |
| NATO/Europe | Bellingcat | https://www.bellingcat.com/feed |
| Threat Intel | Recorded Future | https://www.recordedfuture.com/feed |
Open config.yaml in any text editor:
nano config.yamlScroll to the rss_feeds: section and add your feed at the bottom of the list using this exact format:
- name: "aljazeera"
url: "https://www.aljazeera.com/xml/rss/all.xml"
type: "rss"
auth_required: false
enabled: trueRules:
name— one word, no spaces, lowercase. This becomes the filename prefix in your output.url— the full RSS feed URLtype— always"rss"unless the source is a JSON APIauth_required— set tofalsefor all public feedsenabled— set totrueto activate,falseto pause without deleting
Save and close the file (Ctrl+X then Y then Enter if using nano).
python3 main.py collectYou will see output like:
[INFO] Starting RSS collection (11 feed(s) configured)...
[INFO] Collected 38 items from aljazeera
Collected 38 items (0 failed, 0 skipped) [status: ok]
→ /path/to/raw_intel/rss_aljazeera_20260412T120000Z.json
Processed 1 file(s) → processed_intel/
Each feed saves as a separate timestamped JSON file. The tool automatically processes the raw data and extracts IP addresses and domain indicators.
python3 main.py reportThe report will show:
- Which source the latest intelligence came from
- Any IP addresses extracted from the content
- Domain indicators found in the text
- A plain-English assessment
- A confidence rating (Low / Medium / High)
The report is also saved automatically to the reports/ folder as a .txt file you can archive or share.
If an IP address shows up in your report, run:
python3 main.py enrich --ip <ip_address>Example:
python3 main.py enrich --ip 185.220.101.45This queries ipinfo.io (free, no account needed) and returns:
- Who owns the IP (organization)
- Where it's located
- Hostname if available
If you have a Shodan API key configured, it will also return open ports and risk flags.
If a domain appears repeatedly in your reports and you want deeper information:
python3 main.py scan --domain example.comThis requires SpiderFoot to be installed. It will return open ports, services, and any breach data associated with the domain.
# 1. Add MENA feeds to config.yaml (one-time setup)
nano config.yaml
# 2. Collect fresh intelligence
python3 main.py collect
# 3. Generate your INTSUM
python3 main.py report
# 4. Enrich any IP that surfaced
python3 main.py enrich --ip <ip_from_report>
# 5. Scan any domain of interest
python3 main.py scan --domain <domain_from_report>Run Step 2 and 3 daily, or automate with cron to receive fresh intelligence every 6 hours without lifting a finger.
scripts/run_intel.sh runs collect then report unattended, writes a per-run log to logs/, and appends a one-line summary to logs/run_history.txt.
Set up a crontab entry to run every 6 hours:
crontab -eAdd:
0 */6 * * * /bin/bash /path/to/opfor-intel/scripts/run_intel.sh >> /path/to/opfor-intel/logs/cron.log 2>&1
Replace /path/to/opfor-intel with the absolute path to the cloned repo.
Manual run:
bash scripts/run_intel.sh
bash scripts/run_intel.sh --debug # verbose outputCheck run history:
cat logs/run_history.txtopfor-intel/
├── main.py # CLI entry point (Typer)
├── config.yaml # All settings and feed configuration
├── requirements.txt # Python dependencies
├── install.sh # Setup script
├── findings/ # Documented operational findings (IOCs, threat briefs)
│
├── collectors/
│ └── rss_collector.py # RSS/Atom and API feed fetching
│
├── connectors/
│ ├── shodan_connector.py # Shodan IP enrichment + ipinfo.io fallback
│ └── spiderfoot_connector.py # SpiderFoot OSINT scan runner
│
├── analysis/
│ └── processor.py # Extracts IPs and domains from raw JSON
│
├── output/
│ └── report_generator.py # INTSUM report formatting
│
├── utils/
│ ├── banner.py # ASCII banner
│ ├── errors.py # Custom exception hierarchy
│ └── logger.py # Module-level logging singleton
│
├── scripts/
│ └── run_intel.sh # Cron automation script
│
├── raw_intel/ # Raw feed JSON (gitignored)
├── processed_intel/ # Structured indicator JSON (gitignored)
├── reports/ # INTSUM text reports (gitignored)
└── logs/ # Run logs and history (gitignored)
config.yaml
│
▼
[collect] rss_collector ──► raw_intel/*.json
│
▼ (auto-process)
processor.py ──► processed_intel/*.json
│
▼
[report] report_generator ──► reports/intsum_*.txt + terminal
[scan] spiderfoot_connector ──► processed_intel/*.json ──► terminal
[enrich] shodan_connector ──► terminal
| Feed | Type | Auth Required |
|---|---|---|
| The Hacker News | RSS | No |
| BleepingComputer | RSS | No |
| Krebs on Security | RSS | No |
| Dark Reading | RSS | No |
| Threatpost | RSS | No |
| SANS ISC | RSS | No |
| CISA | RSS | No |
| SecurityWeek | RSS | No |
| ESET Blog | RSS | No |
| RFI English | RSS | No |
| Radio Dabanga | RSS | No |
| Libya Herald | RSS | No |
| Wardheernews | RSS | No |
| Al Monitor | RSS | No |
| AlienVault OTX | API | Yes (free key) |
- Never commit real API keys —
config.yamlcontains placeholder values. If you add real keys locally, consider keepingconfig.yamlin.gitignoreor using a separateconfig.local.yaml. - All runtime data (
raw_intel/,processed_intel/,reports/,logs/) is gitignored by default. - No data is sent anywhere except to the configured feed URLs and API endpoints.
MIT