diff --git a/internal/threatfeed/handler.go b/internal/threatfeed/handler.go index a25ff58..c6a01c4 100644 --- a/internal/threatfeed/handler.go +++ b/internal/threatfeed/handler.go @@ -303,6 +303,15 @@ func handleHome(w http.ResponseWriter, r *http.Request) { } } +func handleDocs(w http.ResponseWriter, r *http.Request) { + tmpl := template.Must(template.ParseFS(templates, "templates/docs.html")) + err := tmpl.Execute(w, nil) + if err != nil { + fmt.Fprintln(os.Stderr, "Failed to parse /docs template:", err) + return + } +} + // handleHTML returns the threat feed as a web page for viewing in a browser. func handleHTML(w http.ResponseWriter, r *http.Request) { opt, err := parseParams(r) diff --git a/internal/threatfeed/server.go b/internal/threatfeed/server.go index 12876b6..b375561 100644 --- a/internal/threatfeed/server.go +++ b/internal/threatfeed/server.go @@ -54,10 +54,11 @@ func Start(c *config.Config) { mux := http.NewServeMux() mux.HandleFunc("GET /", enforcePrivateIP(handleNotFound)) mux.HandleFunc("GET /{$}", enforcePrivateIP(handleHome)) - mux.HandleFunc("GET /feed", enforcePrivateIP(disableCache(handlePlain))) + mux.HandleFunc("GET /docs", enforcePrivateIP(handleDocs)) + // Threat feed handlers. + mux.HandleFunc("GET /threatfeed", enforcePrivateIP(disableCache(handleHTML))) mux.HandleFunc("GET /plain", enforcePrivateIP(disableCache(handlePlain))) mux.HandleFunc("GET /csv", enforcePrivateIP(disableCache(handleCSV))) - mux.HandleFunc("GET /html", enforcePrivateIP(disableCache(handleHTML))) mux.HandleFunc("GET /json", enforcePrivateIP(disableCache(handleJSON))) mux.HandleFunc("GET /stix", enforcePrivateIP(disableCache(handleSTIX))) // TAXII 2.1 handlers. diff --git a/internal/threatfeed/templates/docs.html b/internal/threatfeed/templates/docs.html new file mode 100644 index 0000000..acaed8d --- /dev/null +++ b/internal/threatfeed/templates/docs.html @@ -0,0 +1,425 @@ + + + + + + Deceptifeed + + + + +
+
+

Endpoints

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EndpointFormatDescription
/plainPlainOne IP address per line. Suitable for firewall integration.
/csvCSVCSV format containing full threat feed details.
/jsonJSONJSON format containing full threat feed details.
/stixSTIXSTIX 2.1 Indicators containing full threat feed details.
/taxii2TAXIITAXII 2.1 API. See the TAXII section for usage details.
+ +
+
Example: Retrieve the threat feed formatted as plain text:
+
curl "http://threatfeed.example.com:9000/plain"
+
+
+
Example: Retrieve the threat feed formatted as JSON:
+
curl "http://threatfeed.example.com:9000/json"
+
+
+ +
+

Query Parameters

+

All endpoints support optional query parameters to customize how the threat feed is formatted. + The following query parameters are supported:

+ + + + + + + + + + + + + + + + + + + + + +
ParameterDescription
sortSort the results by a specific field. Valid values are: +
    +
  • added
  • +
  • ip
  • +
  • last_seen
  • +
  • threat_score
  • +
+
directionSpecify the sorting direction. Valid values are: +
    +
  • asc - Ascending order
  • +
  • desc - Descending order
  • +
+
last_seen_hoursFilter results to only include entries seen within the last specified number of hours.
+ +
+
Example: Retrieve the JSON feed, sorted by the last seen date in descending order:
+
curl "http://threatfeed.example.com:9000/json?sort=last_seen&direction=desc"
+
+
+
Example: Retrieve the plain text feed, filtered to include only IP addresses seen within the last 24 hours:
+
curl "http://threatfeed.example.com:9000/plain?last_seen_hours=24"
+
+
+ +
+

TAXII

+

The threat feed is accessible via a TAXII 2.1 API. + This allows for integration with Threat Intelligence Platforms (TIPs) like OpenCTI and Microsoft Sentinel.

+

To access via TAXII 2.1, clients typically require the API root URL and a collection ID. + The API root URL is available on the threat feed server at the path /taxii2/api/. + Three collections are available: indicators, sightings, and observables.

+

Key Details

+ + +
+
Example: Retrieve the TAXII 2.1 Indicators collection:
+
curl "http://threatfeed.example.com:9000/taxii2/api/collections/indicators/objects/"
+
+
+
+ + diff --git a/internal/threatfeed/templates/home.html b/internal/threatfeed/templates/home.html index 778c0f6..8691620 100644 --- a/internal/threatfeed/templates/home.html +++ b/internal/threatfeed/templates/home.html @@ -40,8 +40,7 @@ /* Logo */ /* ==== */ .logo { - max-height: 63px; - max-width: 370px; + max-width: 280px; } /* ======== */ @@ -71,62 +70,6 @@ margin-top: 1rem; } - /* ===== */ - /* Badge */ - /* ===== */ - .badge { - align-items: center; - background-color: transparent; - border: 1px solid #a7e521; - border-radius: 3px; - color: #a7e521; - font-size: 0.75rem; - font-weight: bold; - line-height: 0; - padding: 0.13rem 0.65rem; - text-transform: uppercase; - } - - /* ==== */ - /* Code */ - /* ==== */ - pre { - background-color: black; - border-radius: 3px; - color: #ffff55; - font-family: 'Menlo', 'Consolas', 'Monaco', 'Liberation Mono', 'Lucida Console', monospace; - font-size: 0.875rem; - margin-bottom: 0; - margin-top: 0.75rem; - overflow-x: auto; - padding: 1.25rem 1rem; - } - - code { - background: black; - color: #55ffff; - font-family: 'Menlo', 'Consolas', 'Monaco', 'Liberation Mono', 'Lucida Console', monospace; - font-size: 1rem; - padding: 0 0.2rem; - text-wrap: wrap; - word-wrap: break-word; - } - - /* ======= */ - /* Figures */ - /* ======= */ - figure { - margin: 0; - } - - figcaption { - font-size: 1rem; - line-height: 1rem; - margin-bottom: 0; - margin-top: 3rem; - padding: 0; - } - /* ===== */ /* Lists */ /* ===== */ @@ -137,42 +80,6 @@ ul { margin-bottom: 0; } - - ul.no-bullets { - list-style-type: none; - padding-left: 0; - } - - /* ====== */ - /* Tables */ - /* ====== */ - table { - align-items: center; - border: none; - margin-top: 1.5rem; - width: 100%; - } - - th { - background: transparent; - color: #f0f0f0; - font-size: 1.15rem; - font-weight: bold; - padding: 0.3rem 1rem 0.3rem 0; - text-align: left; - } - - tbody.align-top { - vertical-align: top; - } - - td { - background: transparent; - border-bottom: none; - color: #e0e0e0; - padding: 0.75rem 1rem 0.75rem 0; - text-align: left; - } /* ======= */ /* Anchors */ @@ -183,23 +90,30 @@ text-underline-offset: 0.25rem; } - a.endpoint { - font-family: 'Menlo', 'Consolas', 'Monaco', 'Liberation Mono', 'Lucida Console', monospace; - font-size: 1.05rem; - text-underline-offset: 0.375rem; - } - a:hover { - color: #ffac11; + color: #fa1; text-decoration: none; } a:active { - background: #ffac11; + background: #fa1; color: black; text-decoration: none; } + a.logo { + width: 100%; + display: inline-block; + } + a.logo:hover { + text-decoration: none; + box-shadow: 0 -8px 0 0 black inset, 0 -9px #333 inset; + } + + a.logo:active { + background: inherit; + } + /* ============= */ /* Media Queries */ /* ============= */ @@ -228,41 +142,6 @@ margin-bottom: 0; padding-bottom: 4rem; } - - pre { - overflow-wrap: break-word; - text-wrap-mode: wrap; - } - - .api-table > thead th { - display: none; - } - .api-table > tbody td { - display: block; - padding: 0.3rem 0; - } - - .api-table tr > td:last-of-type { - margin-bottom: 1.75rem; - padding-bottom: 2rem; - } - - .api-table [row-header] { - position: relative; - vertical-align: middle; - } - - .api-table [row-header]:before { - content: attr(row-header); - display: inline-block; - vertical-align: middle; - text-align: left; - width: 6.5rem; - padding-right: 1rem; - font-weight: bold; - white-space: nowrap; - overflow: hidden; - } } @media (max-width: 450px) { @@ -270,155 +149,40 @@ width: 90vw; } - code { - font-size: 0.875rem; + a.logo { + width: 90vw; } }

Threat Feed

-

Welcome to the Threat Feed! The feed lists IP addresses that have interacted with Deceptifeed's honeypots. - It is available in the following formats:

+

The threat feed lists IP addresses that have interacted with Deceptifeed's honeypots. Its goal is to + help you build an automated defense system. +

+

+ View the threat feed from your browser to explore the data. + See the documentation for details on accessing the threat feed in different formats. +

+

+ Supported formats include: +

- -
-

Endpoints

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EndpointFormatDescription
/plainPlainOne IP address per line. Suitable for firewall integration.
/htmlHTMLUser-friendly web page for monitoring the threat feed.
/csvCSVCSV format containing full threat feed details.
/jsonJSONJSON format containing full threat feed details.
/stixSTIXSTIX 2.1 Indicators containing full threat feed details.
/taxii2TAXIITAXII 2.1 API. See the TAXII section for usage details.
- -
-
Example: Retrieve the threat feed formatted as plain text:
-
curl "http://threatfeed.example.com:9000/plain"
-
-
-
Example: Retrieve the threat feed formatted as JSON:
-
curl "http://threatfeed.example.com:9000/json"
-
-
- -
-

Query Parameters

-

All endpoints support optional query parameters to customize how the threat feed is formatted. - The following query parameters are supported:

- - - - - - - - - - - - - - - - - - - - - -
ParameterDescription
sortSort the results by a specific field. Valid values are: -
    -
  • added
  • -
  • ip
  • -
  • last_seen
  • -
  • threat_score
  • -
-
directionSpecify the sorting direction. Valid values are: -
    -
  • asc - Ascending order
  • -
  • desc - Descending order
  • -
-
last_seen_hoursFilter results to only include entries seen within the last specified number of hours.
- -
-
Example: Retrieve the JSON feed, sorted by the last seen date in descending order:
-
curl "http://threatfeed.example.com:9000/json?sort=last_seen&direction=desc"
-
-
-
Example: Retrieve the plain text feed, filtered to include only IP addresses seen within the last 24 hours:
-
curl "http://threatfeed.example.com:9000/plain?last_seen_hours=24"
-
-
- -
-

TAXII

-

The threat feed is accessible via a TAXII 2.1 API. - This allows for integration with Threat Intelligence Platforms (TIPs) like OpenCTI and Microsoft Sentinel.

-

To access via TAXII 2.1, clients typically require the API root URL and a collection ID. - The API root URL is available on the threat feed server at the path /taxii2/api/. - Three collections are available: indicators, sightings, and observables.

-

Key Details

- - -
-
Example: Retrieve the TAXII 2.1 Indicators collection:
-
curl "http://threatfeed.example.com:9000/taxii2/api/collections/indicators/objects/"
-
-
diff --git a/internal/threatfeed/templates/htmlfeed.html b/internal/threatfeed/templates/htmlfeed.html index 11144bd..f65869b 100644 --- a/internal/threatfeed/templates/htmlfeed.html +++ b/internal/threatfeed/templates/htmlfeed.html @@ -25,8 +25,7 @@ /* Logo */ /* ==== */ .logo { - max-height: 63px; - max-width: 370px; + max-width: 280px; } /* ====== */ @@ -124,13 +123,13 @@ } a:hover { - color: #ffac11; + color: #fa1; text-decoration: underline; text-underline-offset: .1875rem; } a:active { - background: #ffac11; + background: #fa1; color: black; text-decoration: none; }