diff --git a/.github/scripts/update.sh b/.github/scripts/update.sh new file mode 100755 index 0000000..47cf004 --- /dev/null +++ b/.github/scripts/update.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +function getCfPrefs() { + curl -s "https://api.bgpview.io/asn/${1}/prefixes" | \ + jq -r '.data.ipv4_prefixes[] | select(.description | try test("Cloud(f|F)")) | .parent.prefix' +} + +DB="$(echo -e "$(getCfPrefs "13335")\n$(getCfPrefs "395747")" | sort -u)" + +if [[ "$(echo "${DB}" | wc -l)" != "$(curl -skL "${1}" | wc -l)" ]]; then + echo "${DB}" > db/prefixes.txt +fi diff --git a/.github/workflows/build.yml b/.github/workflows/build.yaml similarity index 83% rename from .github/workflows/build.yml rename to .github/workflows/build.yaml index d5bf915..c039456 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yaml @@ -5,15 +5,15 @@ on: - master pull_request: -jobs: +jobs: build: - name: Dependencies + name: Build... runs-on: ubuntu-latest steps: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.14 + go-version: 1.18 - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yaml similarity index 58% rename from .github/workflows/release.yml rename to .github/workflows/release.yaml index 70cb60a..95bba31 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yaml @@ -4,25 +4,24 @@ on: tags: - v* -jobs: - release: +jobs: + release: runs-on: ubuntu-latest - steps: - - - name: "Check out code" + steps: + - name: "Check out code" uses: actions/checkout@v2 with: fetch-depth: 0 - - - name: "Set up Go" + + - name: "Set up Go" uses: actions/setup-go@v2 with: - go-version: 1.14 - - - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - name: "Create release on GitHub" + go-version: 1.18 + + - name: "Create release on GitHub" uses: goreleaser/goreleaser-action@v2 + env: + GITHUB_TOKEN: "${{ secrets.RELEASE_TOKEN }}" with: args: "release --rm-dist" version: latest \ No newline at end of file diff --git a/.github/workflows/update.yaml b/.github/workflows/update.yaml new file mode 100644 index 0000000..5e7569f --- /dev/null +++ b/.github/workflows/update.yaml @@ -0,0 +1,37 @@ +name: Update DB +on: + schedule: + - cron: "0 0 * * 0" # at 00:00 on Sunday + workflow_dispatch: + +jobs: + update: + runs-on: ubuntu-latest + steps: + - name: "Install dependencies" + run: sudo apt install curl jq -y + + - name: "Check out code" + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: "Update DB..." + id: update + run: | + ./.github/scripts/update.sh ${{ secrets.LOCAL_DB }} + echo "::set-output name=changes::$(git status -s | wc -l)" + echo "::set-output name=date::$(date)" + + - name: Create Pull Request + if: steps.update.outputs.changes > 0 + uses: peter-evans/create-pull-request@v3 + with: + body: "Automated update CloudFlare IPv4 prefixes data." + branch-suffix: "short-commit-hash" + branch: "update/db" + commit-message: "db: Update DB ${{ steps.update.date }}" + committer: "Dwi Siswanto " + delete-branch: true + reviewers: "dwisiswant0" + title: "db: Update DB ${{ steps.update.date }}" \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ac446a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +cf-check \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml index 159af65..b81e685 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,6 +1,6 @@ builds: - binary: cf-check - main: main.go + main: . goos: - linux - windows diff --git a/LICENSE b/LICENSE index 261eeb9..eede210 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2022 Dwi Siswanto Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index b2b10d4..1cc5ee2 100644 --- a/README.md +++ b/README.md @@ -4,27 +4,29 @@ Check an Host is Owned by CloudFlare. ## Install 1. Grab from [releases page](https://github.com/dwisiswant0/cf-check/releases), or -2. If you have [Go1.13+](https://go.dev/dl/) compiler installed & configured: +2. If you have [Go1.18+](https://go.dev/dl/) compiler installed & configured: -``` -▶ go install github.com/dwisiswant0/cf-check@latest +```console +$ go install github.com/dwisiswant0/cf-check@latest ``` ## Usage -``` -▶ echo "uber.com" | cf-check +```console +$ echo "uber.com" | cf-check +34.98.127.226 ``` or -``` -▶ cf-check -d +```console +$ cf-check -d ``` ### Flags -``` +```console +$ cf-check -h Usage of cf-check: -c int Set the concurrency level (default: 20) @@ -37,6 +39,10 @@ Usage of cf-check: The goal is that you don't need to do a port scan if it's proven that the IP is owned by Cloudflare. +```console +$ subfinder -silent -d uber.com | filter-resolved | cf-check -d | anew | naabu -silent -verify | httpx -silent ``` -▶ subfinder -silent -d uber.com | filter-resolved | cf-check -d | anew | naabu -silent -verify | httpx -silent -``` \ No newline at end of file + +## License + +`cf-check` is distributed under Apache License 2.0. \ No newline at end of file diff --git a/check.go b/check.go new file mode 100644 index 0000000..c1c5e94 --- /dev/null +++ b/check.go @@ -0,0 +1,23 @@ +package main + +import "net" + +func isCloudflare(ip net.IP) bool { + for _, c := range cidrs { + if c == "" { + continue + } + + hosts, err := hosts(c) + if err != nil { + continue + } + + for _, host := range hosts { + if host == ip.String() { + return true + } + } + } + return false +} diff --git a/db/db.go b/db/db.go new file mode 100644 index 0000000..5d04250 --- /dev/null +++ b/db/db.go @@ -0,0 +1,7 @@ +package db + +import "strings" + +func init() { + Prefs = strings.Split(prefs, "\n") +} diff --git a/db/prefixes.txt b/db/prefixes.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/db/prefixes.txt @@ -0,0 +1 @@ + diff --git a/db/vars.go b/db/vars.go new file mode 100644 index 0000000..abd7938 --- /dev/null +++ b/db/vars.go @@ -0,0 +1,9 @@ +package db + +import _ "embed" + +var ( + //go:embed prefixes.txt + prefs string + Prefs []string +) diff --git a/go.mod b/go.mod index d4bc714..39ddf13 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,3 @@ module github.com/dwisiswant0/cf-check -go 1.13 +go 1.18 diff --git a/main.go b/main.go index d8a8a33..e0fade9 100644 --- a/main.go +++ b/main.go @@ -3,19 +3,13 @@ package main import ( "bufio" "flag" - "fmt" "net" "net/url" "os" "strings" - "sync" ) func main() { - var wg sync.WaitGroup - var domainMode, showCloudflare bool - var sc *bufio.Scanner - concurrency := 20 flag.IntVar(&concurrency, "c", concurrency, "Set the concurrency level") @@ -79,87 +73,3 @@ func main() { close(jobs) wg.Wait() } - -func show(host string, ip net.IP, mode bool) { - if mode { - fmt.Println(host) - } else { - fmt.Println(ip) - } -} - -func inc(ip net.IP) { - for j := len(ip) - 1; j >= 0; j-- { - ip[j]++ - if ip[j] > 0 { - break - } - } -} - -func hosts(cidr string) ([]string, error) { - ip, ipnet, err := net.ParseCIDR(cidr) - if err != nil { - return nil, err - } - - var ips []string - for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) { - ips = append(ips, ip.String()) - } - - lenIPs := len(ips) - switch { - case lenIPs < 2: - return ips, nil - default: - return ips[1 : len(ips)-1], nil - } -} - -func isCloudflare(ip net.IP) bool { - cidrs := []string{ - "173.245.48.0/20", - "103.21.244.0/22", - "103.22.200.0/22", - "103.31.4.0/22", - "141.101.64.0/18", - "108.162.192.0/18", - "190.93.240.0/20", - "188.114.96.0/20", - "197.234.240.0/22", - "198.41.128.0/17", - "162.158.0.0/15", - "104.16.0.0/12", - "172.64.0.0/13", - "131.0.72.0/22", - "104.24.0.0/14", - } - - for i := range cidrs { - hosts, err := hosts(cidrs[i]) - if err != nil { - continue - } - - for _, host := range hosts { - if host == ip.String() { - return true - } - } - } - return false -} - -func isStdin() bool { - f, e := os.Stdin.Stat() - if e != nil { - return false - } - - if f.Mode()&os.ModeNamedPipe == 0 { - return false - } - - return true -} diff --git a/utils.go b/utils.go new file mode 100644 index 0000000..cb646a4 --- /dev/null +++ b/utils.go @@ -0,0 +1,57 @@ +package main + +import ( + "fmt" + "net" + "os" +) + +func show(host string, ip net.IP, mode bool) { + if mode { + fmt.Println(host) + } else { + fmt.Println(ip) + } +} + +func inc(ip net.IP) { + for j := len(ip) - 1; j >= 0; j-- { + ip[j]++ + if ip[j] > 0 { + break + } + } +} + +func hosts(cidr string) ([]string, error) { + ip, ipnet, err := net.ParseCIDR(cidr) + if err != nil { + return nil, err + } + + var ips []string + for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) { + ips = append(ips, ip.String()) + } + + lenIPs := len(ips) + switch { + case lenIPs < 2: + return ips, nil + default: + return ips[1 : len(ips)-1], nil + } +} + +func isStdin() bool { + f, e := os.Stdin.Stat() + if e != nil { + return false + } + + if f.Mode()&os.ModeNamedPipe == 0 { + return false + } + + return true +} diff --git a/vars.go b/vars.go new file mode 100644 index 0000000..c15d052 --- /dev/null +++ b/vars.go @@ -0,0 +1,17 @@ +package main + +import ( + "bufio" + "sync" + + "github.com/dwisiswant0/cf-check/db" +) + +var ( + wg sync.WaitGroup + sc *bufio.Scanner + + domainMode, showCloudflare bool + + cidrs = db.Prefs +)