Skip to content

Commit a24c756

Browse files
committed
Update project configuration and documentation
- Updated .golangci.yml to version 2 and re-enabled gofmt formatter. - Removed deprecated linter exclusions for test files and added exclusions for gosec. - Simplified docker-compose.yml by removing the version declaration. - Enhanced Dockerfile to include the internal directory for better organization. - Added .gitattributes for line-ending normalization. - Revised README.md to reflect the new project structure and features. - Updated documentation to clarify the use of the -attempts flag for DNS resolution. - Improved CODE_OF_CONDUCT.md with detailed community guidelines. - Adjusted CONTRIBUTING.md to link to the Code of Conduct. - Enhanced DEVELOPER_GUIDE.md with a comprehensive project structure overview.
1 parent 4f0430e commit a24c756

File tree

12 files changed

+119
-75
lines changed

12 files changed

+119
-75
lines changed

.golangci.yml

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
version: "2"
2+
13
run:
24
timeout: 5m
35

@@ -6,8 +8,6 @@ linters:
68
- errcheck
79
- govet
810
- staticcheck
9-
- gofmt
10-
- deadcode
1111
- gosec
1212
- gocritic
1313
- misspell
@@ -24,10 +24,13 @@ linters:
2424
- fmt.Fprintln
2525
- fmt.Fprintf
2626
- fmt.Println
27+
exclusions:
28+
rules:
29+
# Test files are allowed to use gosec-flagged patterns
30+
- path: _test\.go
31+
linters:
32+
- gosec
2733

28-
issues:
29-
exclude-rules:
30-
# Test files are allowed to use gosec-flagged patterns
31-
- path: _test\.go
32-
linters:
33-
- gosec
34+
formatters:
35+
enable:
36+
- gofmt

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ COPY go.mod ./
88
# Copy source code
99
COPY main.go ./
1010
COPY main_test.go ./
11+
COPY internal/ ./internal/
1112

1213
# Build the binary with optimizations
1314
RUN CGO_ENABLED=0 GOOS=linux go build -o subenum -ldflags="-w -s" .

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ subenum/
252252
├── Dockerfile # Multi-stage Alpine build
253253
├── docker-compose.yml # Compose orchestration
254254
├── Makefile # Build, test, lint, simulate, Docker targets
255+
├── .gitattributes # Line-ending normalization rules
255256
├── .golangci.yml # Linter configuration (golangci-lint v2)
256257
├── CHANGELOG.md # Versioned release history
257258
├── SECURITY.md # Vulnerability disclosure policy

docker-compose.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
version: '3.8'
2-
31
services:
42
subenum:
53
build: .

docs/ARCHITECTURE.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ internal/wordlist/reader.go — LoadWordlist (dedup + sanitize)
7373
* `d.DialContext(ctx, "udp", dnsServer)`: Establishes a UDP connection to the configured DNS server.
7474
* `resolver.LookupHost(timeoutCtx, domain)`: Performs the DNS lookup for the given domain. The context is derived from the caller via `context.WithTimeout(ctx, timeout)`, so both the per-query timeout and SIGINT cancellation are respected. It attempts to find A or AAAA records for the host.
7575
* The function returns `true` if `LookupHost` returns no error (i.e., the domain resolved), and `false` otherwise.
76-
* **Interactions**: Workers call `resolveDomainWithRetry`, which delegates to `resolveDomain` with retry logic. It takes a fully qualified domain name, timeout duration, DNS server address, verbose flag, and retry count as input. It outputs a boolean indicating whether the domain resolved successfully. The result is used to decide if the domain should be printed to the console and/or written to the output file.
76+
* **Interactions**: Workers call `dns.ResolveDomainWithRetry`, which delegates to `dns.ResolveDomain` with retry logic. It takes a fully qualified domain name, timeout duration, DNS server address, verbose flag, and retry count as input. It outputs a boolean indicating whether the domain resolved successfully. The result is used to decide if the domain should be printed to the console and/or written to the output file.
7777

7878
### 2.4. Concurrency Management (Worker Pool)
7979

@@ -85,7 +85,7 @@ internal/wordlist/reader.go — LoadWordlist (dedup + sanitize)
8585
* `wg.Add(1)`: Increments the `WaitGroup` counter for each worker started.
8686
* `go func() { ... }()`: Each worker runs in its own goroutine.
8787
* `defer wg.Done()`: Decrements the `WaitGroup` counter when the goroutine exits.
88-
* `for subdomainPrefix := range subdomains { ... }`: Each worker continuously reads subdomain prefixes from the `subdomains` channel until the channel is closed. For each prefix, it constructs the full domain and calls `resolveDomain()`.
88+
* `for subdomainPrefix := range subdomains { ... }`: Each worker continuously reads subdomain prefixes from the `subdomains` channel until the channel is closed. For each prefix, it constructs the full domain and calls `dns.ResolveDomainWithRetry()`.
8989
* **Closing the Channel (`close(subdomains)`)**: After all subdomain prefixes from the wordlist have been sent to the `subdomains` channel, the channel is closed. This signals to the worker goroutines that no more work will be added.
9090
* **Waiting for Completion (`wg.Wait()`)**: The main goroutine blocks until all worker goroutines have called `wg.Done()`, ensuring all lookups are finished.
9191
* **Interactions**: This component orchestrates the parallel execution of DNS lookups. It receives subdomain prefixes from the Wordlist Processing component (via the `subdomains` channel) and utilizes the DNS Resolution Engine within each worker goroutine. The number of workers is controlled by the Argument Parsing component.
@@ -131,12 +131,12 @@ The flow of data through the `subenum` application can be summarized as follows:
131131
5. **Work Distribution**: The `subdomains` channel acts as a queue for the **Concurrency Management (Worker Pool)** component.
132132
* Worker goroutines (number determined by the `-t` flag) pick up these prefixes from the channel.
133133
6. **Subdomain Construction**: Each worker goroutine takes a `subdomainPrefix` and concatenates it with the `targetDomain` (e.g., `subdomainPrefix + "." + targetDomain`) to form a `fullDomain` string.
134-
7. **DNS Lookup**: The `fullDomain` string, the `timeout` value, and the DNS server are passed to the `resolveDomain` function within the **DNS Resolution Engine**.
135-
* The `resolveDomain` function attempts to resolve the `fullDomain`.
134+
7. **DNS Lookup**: The `fullDomain` string, the `timeout` value, and the DNS server are passed to `dns.ResolveDomainWithRetry` within the **DNS Resolution Engine**.
135+
* `dns.ResolveDomain` attempts to resolve the `fullDomain`.
136136
* It returns `true` if the domain resolves successfully, `false` otherwise.
137137
* If verbose mode is enabled, it also prints detailed information about the resolution attempt.
138138
8. **Output Generation**:
139-
* If `resolveDomain` returns `true`, the worker goroutine uses the **Output Formatting** component to print the `fullDomain` to the standard output.
139+
* If the resolution returns `true`, the worker goroutine uses the **Output Formatting** component to print the `fullDomain` to the standard output.
140140
* The atomic counter for found subdomains is incremented.
141141
9. **Progress Tracking**: After each DNS lookup:
142142
* The atomic counter for processed entries is incremented.

docs/CODE_OF_CONDUCT.md

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
1-
# Code of Conduct
1+
---
2+
layout: default
3+
title: Code of Conduct
4+
---
25

3-
*(A standard Code of Conduct, like the Contributor Covenant, will be added here.)*
6+
# Contributor Covenant Code of Conduct
47

5-
Our Pledge
8+
## Our Pledge
9+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone.
610

7-
In the interest of fostering an open and welcoming environment, we as
8-
contributors and maintainers pledge to making participation in our project and
9-
our community a harassment-free experience for everyone, regardless of age, body
10-
size, disability, ethnicity, sex characteristics, gender identity and expression,
11-
level of experience, education, socio-economic status, nationality, personal
12-
appearance, race, religion, or sexual identity and orientation.
11+
## Our Standards
12+
Examples of behavior that contributes to a positive environment:
13+
- Using welcoming and inclusive language
14+
- Being respectful of differing viewpoints and experiences
15+
- Gracefully accepting constructive criticism
16+
- Focusing on what is best for the community
17+
18+
Examples of unacceptable behavior:
19+
- Harassment, trolling, or insulting comments
20+
- Public or private harassment
21+
- Publishing others' private information without permission
22+
- Other conduct which could reasonably be considered inappropriate
23+
24+
## Enforcement
25+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening a [Security Advisory](https://github.com/TMHSDigital/subenum/security/advisories/new) or contacting the maintainers privately.
26+
27+
## Attribution
28+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.

docs/CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ title: Contributing
77

88
We welcome contributions! Please read this guide to understand how you can contribute.
99

10-
*Refer to `CODE_OF_CONDUCT.md`.*
10+
See the [Code of Conduct](CODE_OF_CONDUCT.html).
1111

1212
## Development Environment Setup
1313

@@ -23,7 +23,7 @@ We welcome contributions! Please read this guide to understand how you can contr
2323
1. **Fork the repository** on GitHub
2424
2. **Clone your fork**:
2525
```bash
26-
git clone https://github.com/TMHSDigital/subenum.git
26+
git clone https://github.com/YOUR-USERNAME/subenum.git
2727
cd subenum
2828
```
2929
3. **Set up the upstream remote**:

docs/DEVELOPER_GUIDE.md

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -54,43 +54,62 @@ To work with `subenum`, you'll need:
5454

5555
```
5656
subenum/
57-
├── main.go # Main application code
58-
├── main_test.go # Test suite
59-
├── go.mod # Go module definition
60-
├── Makefile # Build, test, lint, Docker targets
61-
├── Dockerfile # Multi-stage Docker build
62-
├── docker-compose.yml # Docker Compose config
63-
├── .golangci.yml # Linter configuration
64-
├── README.md # Project overview
65-
├── LICENSE # License information
66-
├── SECURITY.md # Security policy and disclosure
6757
├── .github/
6858
│ ├── workflows/
69-
│ │ ├── go.yml # CI: build, test, lint, release
70-
│ │ ├── pages.yml # GitHub Pages deployment
71-
│ │ └── codeql.yml # CodeQL security scanning
72-
│ ├── dependabot.yml # Automated dependency updates
73-
│ ├── PULL_REQUEST_TEMPLATE.md
74-
│ └── ISSUE_TEMPLATE/ # Bug report & feature request templates
75-
├── docs/ # Documentation (served via GitHub Pages)
76-
│ ├── _config.yml # Jekyll site configuration
77-
│ ├── index.md # Site home page
78-
│ ├── ARCHITECTURE.md # Architectural details
79-
│ ├── DEVELOPER_GUIDE.md # This file
80-
│ ├── CODE_OF_CONDUCT.md # Community guidelines
81-
│ ├── CONTRIBUTING.md # Contribution guidelines
82-
│ └── docker.md # Docker usage guide
59+
│ │ ├── go.yml # CI: build, test, lint, release
60+
│ │ ├── codeql.yml # Weekly CodeQL security analysis
61+
│ │ └── pages.yml # GitHub Pages deployment
62+
│ ├── ISSUE_TEMPLATE/
63+
│ │ ├── bug_report.md # Structured bug report form
64+
│ │ └── feature_request.md # Feature proposal template
65+
│ ├── CODE_OF_CONDUCT.md # Contributor Covenant v2.1
66+
│ ├── CONTRIBUTING.md # Points to docs/CONTRIBUTING.md
67+
│ ├── dependabot.yml # Automated dependency updates
68+
│ └── PULL_REQUEST_TEMPLATE.md
8369
├── data/
84-
│ └── wordlist.txt # Default wordlist
85-
├── examples/ # Example files and usage demos
86-
│ ├── sample_wordlist.txt # Sample subdomain prefixes
87-
│ ├── sample_domains.txt # Sample domain list
88-
│ └── advanced_usage.md # Advanced usage examples
70+
│ └── wordlist.txt # Default wordlist for Docker/Make
71+
├── docs/
72+
│ ├── ARCHITECTURE.md # Internals: worker pool, context, output
73+
│ ├── CODE_OF_CONDUCT.md # Community guidelines (Jekyll page)
74+
│ ├── CONTRIBUTING.md # PR workflow, testing, ethical guidelines
75+
│ ├── DEVELOPER_GUIDE.md # This file
76+
│ ├── DOCUMENTATION_STRUCTURE.md
77+
│ ├── docker.md # Container setup and volume mounting
78+
│ ├── _config.yml # Jekyll config for GitHub Pages
79+
│ └── index.md # GitHub Pages landing page
80+
├── examples/
81+
│ ├── sample_wordlist.txt # 50-entry starter wordlist
82+
│ ├── sample_domains.txt # Sample domain list
83+
│ ├── advanced_usage.md # Scripting and integration patterns
84+
│ ├── demo.sh # Quick demo script
85+
│ └── multi_domain_scan.sh # Batch scanning example
86+
├── internal/
87+
│ ├── dns/
88+
│ │ ├── resolver.go # ResolveDomain, ResolveDomainWithRetry, CheckWildcard
89+
│ │ ├── resolver_test.go # DNS resolution and wildcard detection tests
90+
│ │ ├── simulate.go # SimulateResolution (synthetic DNS)
91+
│ │ └── simulate_test.go # Simulation logic tests
92+
│ ├── output/
93+
│ │ ├── writer.go # Thread-safe output (results→stdout, rest→stderr)
94+
│ │ └── writer_test.go # Output writer tests
95+
│ └── wordlist/
96+
│ ├── reader.go # LoadWordlist (dedup + sanitize)
97+
│ └── reader_test.go # Wordlist loading and dedup tests
8998
├── tools/
90-
│ ├── wordlist-gen.go # Wordlist generator utility
91-
│ └── README.md # Wordlist generator docs
92-
└── logs/
93-
└── CHANGELOG.md # Project change history
99+
│ ├── wordlist-gen.go # Custom wordlist generator utility
100+
│ └── README.md # Wordlist generator docs
101+
├── .gitattributes # Line-ending normalization rules
102+
├── .golangci.yml # Linter configuration (golangci-lint v2)
103+
├── main.go # CLI entry point: flag parsing, wiring
104+
├── main_test.go # CLI-level tests: validation, flag logic
105+
├── go.mod # Go module (zero external dependencies)
106+
├── Dockerfile # Multi-stage Alpine build
107+
├── docker-compose.yml # Compose orchestration
108+
├── Makefile # Build, test, lint, simulate, Docker targets
109+
├── CHANGELOG.md # Versioned release history
110+
├── README.md # Project overview
111+
├── SECURITY.md # Vulnerability disclosure policy
112+
└── LICENSE # GNU General Public License v3.0
94113
```
95114
96115
## Running Tests
@@ -112,12 +131,14 @@ go test -v -short ./...
112131
When adding new features or modifying existing ones, please ensure you add appropriate tests. Here's a basic structure for tests:
113132

114133
```go
115-
package main
134+
package dns_test
116135

117136
import (
118137
"context"
119138
"testing"
120139
"time"
140+
141+
"github.com/TMHSDigital/subenum/internal/dns"
121142
)
122143

123144
func TestResolveDomain(t *testing.T) {
@@ -143,7 +164,7 @@ func TestResolveDomain(t *testing.T) {
143164

144165
for _, tc := range testCases {
145166
t.Run(tc.name, func(t *testing.T) {
146-
result := resolveDomain(context.Background(), tc.domain, tc.timeout, DefaultDNSServer, false)
167+
result := dns.ResolveDomain(context.Background(), tc.domain, tc.timeout, "8.8.8.8:53", false)
147168
if result != tc.expected {
148169
t.Errorf("Expected %v for domain %s, got %v", tc.expected, tc.domain, result)
149170
}
@@ -221,7 +242,6 @@ Areas for potential enhancement include:
221242
* **Output Formats**: Supporting different output formats (JSON, CSV) in addition to the current plain text output file (`-o`).
222243
* **Result Filtering**: Allowing users to filter results based on DNS record types.
223244
* **Recursive Enumeration**: Adding support for recursive subdomain enumeration (e.g., finding subdomains of discovered subdomains).
224-
* **Wildcard Detection**: Detecting wildcard DNS records that resolve all subdomains.
225245
* **Rate Limiting**: Adding configurable rate limiting for DNS queries to avoid triggering abuse detection.
226246
227247
When working on new features, please update the documentation accordingly and add tests to cover the new functionality.

docs/docker.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@ docker run --rm -v $(pwd)/data:/data subenum \
8484
example.com
8585
```
8686

87-
### Using Retries for Unreliable Networks
87+
### Using Multiple Attempts for Unreliable Networks
8888

89-
The `-retries` flag re-attempts failed DNS lookups before marking a subdomain as unresolved:
89+
The `-attempts` flag sets the total DNS resolution attempts per subdomain:
9090

9191
```bash
9292
docker run --rm -v $(pwd)/data:/data subenum \
9393
-w /data/wordlist.txt \
94-
-retries 3 \
94+
-attempts 3 \
9595
-timeout 2000 \
9696
example.com
9797
```

docs/index.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ A Go-based CLI tool for subdomain enumeration designed for educational purposes
1212
- Fast, concurrent DNS lookup of subdomains using customizable wordlists
1313
- Configurable concurrency level and timeout settings
1414
- Support for custom DNS servers with proper validation
15+
- Wildcard DNS detection with double-probe confirmation; continue with `-force`
16+
- Wordlist deduplication and sanitization on load
17+
- Clean stdout/stderr separation (results to stdout, progress/verbose to stderr)
18+
- Configurable resolution attempts per subdomain (`-attempts`)
1519
- Verbose mode for detailed output
1620
- Real-time progress tracking
1721
- Output to file with `-o` flag
18-
- DNS retry mechanism for transient failure resilience
1922
- Graceful shutdown on Ctrl+C (SIGINT/SIGTERM)
2023
- Simulation mode for safe testing without network access
2124
- Domain and DNS server input validation

0 commit comments

Comments
 (0)