Skip to content

Commit 809331e

Browse files
committed
Initial commit
0 parents  commit 809331e

35 files changed

+2411
-0
lines changed

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Dockerfile

.github/workflows/lint.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Linting
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
jobs:
10+
lint-code:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-go@v5
15+
with:
16+
go-version: '^1.24'
17+
18+
- name: Lint
19+
uses: golangci/golangci-lint-action@v7
20+
with:
21+
version: v2.0.2
22+
23+
lint-terraform:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- uses: actions/checkout@v4
27+
- uses: opentofu/setup-opentofu@v1
28+
with:
29+
tofu_version: 1.9
30+
31+
- name: Format
32+
run: tofu fmt -check
33+
working-directory: ./terraform
34+
35+
- name: Init
36+
run: tofu init
37+
working-directory: ./terraform
38+
39+
- name: Validate
40+
run: tofu validate
41+
working-directory: ./terraform

.github/workflows/release.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Releasing
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
permissions:
9+
contents: write
10+
id-token: write
11+
attestations: write
12+
13+
jobs:
14+
goreleaser:
15+
runs-on: ubuntu-latest
16+
steps:
17+
-
18+
name: Checkout
19+
uses: actions/checkout@v4
20+
with:
21+
fetch-depth: 0
22+
-
23+
name: Set up Go
24+
uses: actions/setup-go@v5
25+
with:
26+
go-version: '^1.24'
27+
28+
-
29+
name: Set up cosign
30+
uses: sigstore/cosign-installer@v3.8.1
31+
32+
-
33+
name: Set up homebrew deploy key
34+
shell: bash
35+
env:
36+
HOMEBREW_GH_DEPLOY_KEY: ${{ secrets.HOMEBREW_GH_DEPLOY_KEY }}
37+
run: |
38+
echo $HOMEBREW_GH_DEPLOY_KEY | base64 -d > /tmp/HOMEBREW_GH_DEPLOY_KEY
39+
chmod 700 /tmp/HOMEBREW_GH_DEPLOY_KEY
40+
41+
-
42+
name: Run GoReleaser
43+
uses: goreleaser/goreleaser-action@v6
44+
with:
45+
distribution: goreleaser
46+
version: '~> v2'
47+
args: release --clean
48+
env:
49+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50+
- uses: actions/attest-build-provenance@v2
51+
with:
52+
subject-path: "dist/*.tar.gz,dist/*.zip"

.github/workflows/test.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [ "main" ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
jobs:
10+
run-tests:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-go@v5
15+
with:
16+
go-version: '^1.24'
17+
18+
- name: Build
19+
run: go build -v github.com/mark-adams/gcp-ip-list/cmd/gcp-ip-list
20+
21+
- name: Test
22+
run: go test -v ./...

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
terraform/.terraform*
2+
terraform/*.tfstate*
3+
.vscode# Added by goreleaser init:
4+
dist/

.goreleaser.yaml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
version: 2
2+
3+
before:
4+
hooks:
5+
# You may remove this if you don't use go modules.
6+
- go mod tidy
7+
# you may remove this if you don't need go generate
8+
- go generate ./...
9+
10+
builds:
11+
- main: ./cmd/gcp-ip-list
12+
ldflags:
13+
- "-X main.version={{.Version}}"
14+
env:
15+
- CGO_ENABLED=0
16+
goos:
17+
- linux
18+
- windows
19+
- darwin
20+
21+
archives:
22+
- formats: [tar.gz]
23+
# this name template makes the OS and Arch compatible with the results of `uname`.
24+
name_template: >-
25+
{{ .ProjectName }}_
26+
{{- title .Os }}_
27+
{{- if eq .Arch "amd64" }}x86_64
28+
{{- else if eq .Arch "386" }}i386
29+
{{- else }}{{ .Arch }}{{ end }}
30+
{{- if .Arm }}v{{ .Arm }}{{ end }}
31+
# use zip for windows archives
32+
format_overrides:
33+
- goos: windows
34+
formats: [zip]
35+
36+
changelog:
37+
sort: asc
38+
filters:
39+
exclude:
40+
- "^docs:"
41+
- "^test:"
42+
- "^chore:"
43+
- "^ci:"
44+
45+
binary_signs:
46+
- cmd: cosign
47+
# copied from archives.name_template above
48+
signature: >-
49+
{{ .ProjectName }}_
50+
{{- title .Os }}_
51+
{{- if eq .Arch "amd64" }}x86_64
52+
{{- else if eq .Arch "386" }}i386
53+
{{- else }}{{ .Arch }}{{ end }}
54+
{{- if .Arm }}v{{ .Arm }}{{ end }}.cosign.bundle'
55+
args:
56+
- "sign-blob"
57+
- "--bundle=${signature}"
58+
- "${artifact}"
59+
- "--yes" # needed on cosign 2.0.0+
60+
61+
brews:
62+
-
63+
repository:
64+
owner: mark-adams
65+
name: homebrew-gcp-ip-list
66+
branch: main
67+
68+
git:
69+
url: 'ssh://git@github.com/mark-adams/homebrew-gcp-ip-list.git'
70+
private_key: '/tmp/HOMEBREW_GH_DEPLOY_KEY'

CONTRIBUTING.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Contributions are welcome! Before submitting a PR, please [file an issue](https://github.com/mark-adams/gcp-ip-list/issues) if one does not already exist to discuss your ideas! This can help avoid wasted effort and speed up the review process quite a bit!
2+
3+
Once you've got your change ready, you can [submit a pull request](https://github.com/mark-adams/gcp-ip-list/compare). Please make sure your change has all of the following:
4+
- A good description of the change
5+
- Includes tests covering the new feature or fixed logic
6+
7+
This project tries to follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) so please make sure your commit messages contain the proper prefixes. Some common examples are listed below.
8+
9+
- `feat:` for a new feature or new functionality
10+
- `fix:` for bugfixes
11+
- `docs:` for changes to the documentation
12+
- `ci:` for changes to the build process

Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM golang:1.24 as builder
2+
3+
WORKDIR $GOPATH/src/github.com/mark-adams/gcp-ip-list
4+
COPY . .
5+
6+
RUN go get -v ./...
7+
RUN GOOS=linux CGO_ENABLED=0 go build -o /go/bin/gcp-ip-list github.com/mark-adams/gcp-ip-list/cmd/gcp-ip-list
8+
9+
FROM cgr.dev/chainguard/static
10+
11+
COPY --from=builder /go/bin/gcp-ip-list /bin/gcp-ip-list
12+
13+
ENTRYPOINT ["/bin/gcp-ip-list"]

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Mark Adams
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# GCP IP List
2+
3+
[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/mark-adams/gcp-ip-list) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/mark-adams/gcp-ip-list/main/LICENSE) [![Build Status](https://github.com/mark-adams/gcp-ip-list/actions/workflows/test.yml/badge.svg)](https://github.com/mark-adams/gcp-ip-list/actions/workflows/test.yml)
4+
5+
6+
`gcp-ip-list` is a CLI tool (and library) written in Go to simplify the process of retrieving IP addresses from infrastructure hosted on Google Cloud Platform (GCP).
7+
8+
Most enumeration tooling today uses the normal CRUD REST APIs provided by Google to retrieve GCP assets and their IP address information. This is less than ideal because it typically involves interacting with several different Google APIs and puts additional load on the very same APIs that are used as the control plane for GCP customers. In addition, it is quite slow especially if you have a large number of projects.
9+
10+
This tool takes a different approach and queries information about assets from Google's [Cloud Asset Inventory API](https://cloud.google.com/asset-inventory/docs/overview) instead. This allows us to use a single API to pull down all the data about assets that could potentially have public IP addresses assigned to them which allows us to download data for organizations of any size much more efficiently.
11+
12+
# Installation
13+
14+
<table>
15+
<tr>
16+
<td>Homebrew (macOS or Linux)</td>
17+
<td>
18+
<code>brew tap mark-adams/gcp-ip-list && brew install gcp-ip-list</code>
19+
</td>
20+
</tr>
21+
</table>
22+
23+
Pre-built binaries are also avalable from the [Releases page](https://github.com/mark-adams/gcp-ip-list/releases)
24+
25+
If your system has a [supported version of Go](https://go.dev/dl/), you can build from source.
26+
27+
```
28+
go install github.com/mark-adams/gcp-ip-list/cmd/gcp-ip-list@latest
29+
```
30+
31+
# Running the tool
32+
33+
Since this tool uses the [Google Cloud Client Libraries for Go](https://github.com/googleapis/google-cloud-go), the application will authenticate with Google using [Application Default Credentials](https://cloud.google.com/docs/authentication/application-default-credentials).
34+
35+
## Usage
36+
```
37+
$ gcp-ip-list -h
38+
Usage of gcp-ip-list:
39+
-format string
40+
The output format (csv, json, table, list) (default "table")
41+
-private
42+
Include private IPs only
43+
-public
44+
Include public IPs only
45+
-scope string
46+
The scope (organization, folder, or project) to search (i.e. projects/abc-123 or organizations/123456)
47+
-version
48+
Display the current version
49+
```
50+
51+
### Use as a library
52+
Core functionality of the CLI is exposed via Go APIs as well in the `github.com/mark-adams/gcp-ip-list/pkg/go` package via the `GetAllAddressesFromAssetInventory()` and `GetAddressesFromAssetInventory()` functions in case you want to incoporate this functionality into your own application.
53+
54+
## Examples
55+
56+
### Table output
57+
```
58+
$ gcp-ip-list --scope=projects/sample-project -public
59+
+----------------+--------------+---------------------------------------+-------------------------------------------------------------------------------------------------------------------------+
60+
| ADDRESS | ADDRESS TYPE | RESOURCE TYPE | RESOURCE NAME |
61+
+----------------+--------------+---------------------------------------+-------------------------------------------------------------------------------------------------------------------------+
62+
| 35.244.150.176 | public | compute.googleapis.com/ForwardingRule | //compute.googleapis.com/projects/sample-project/global/forwardingRules/ip-list-test-forwarding-rule-external |
63+
| 34.54.75.78 | public | compute.googleapis.com/ForwardingRule | //compute.googleapis.com/projects/sample-project/global/forwardingRules/ip-list-test-forwarding-rule-external-static |
64+
| 34.83.163.216 | public | compute.googleapis.com/Instance | //compute.googleapis.com/projects/sample-project/zones/us-west1-a/instances/ip-list-test-vm |
65+
| 34.105.8.244 | public | compute.googleapis.com/Router | //compute.googleapis.com/projects/sample-project/regions/us-west1/routers/ip-list-test-router |
66+
| 34.19.43.198 | public | container.googleapis.com/Cluster | //container.googleapis.com/projects/sample-project/locations/us-west1/clusters/ip-list-test-cluster |
67+
| 34.127.47.18 | public | sqladmin.googleapis.com/Instance | //cloudsql.googleapis.com/projects/sample-project/instances/ip-list-test-db |
68+
+----------------+--------------+---------------------------------------+-------------------------------------------------------------------------------------------------------------------------+
69+
```
70+
71+
### List output
72+
73+
```
74+
$ gcp-ip-list --scope=projects/sample-project -public -format=list
75+
35.244.150.176
76+
34.54.75.78
77+
34.83.163.216
78+
34.105.8.244
79+
34.19.43.198
80+
34.127.47.18
81+
```
82+
83+
This mode is handy for piping to your favorite port scanning tool like `nmap` or `naabu`:
84+
```
85+
gcp-ip-list --scope=projects/sample-project -public -format=list | nmap -iL -
86+
```
87+
88+
### CSV & JSON output
89+
90+
You can get the same output as the default table format but in CSV or JSON as well:
91+
92+
```
93+
gcp-ip-list --scope=projects/sample-project -public -format=csv
94+
```
95+
96+
```
97+
gcp-ip-list --scope=projects/sample-project -public -format=json
98+
```
99+
100+
# Contributing
101+
See our [Contribution guidelines](CONTRIBUTING.md)
102+
103+
## Terraform resources
104+
The `terraform` directory contains sample resources that are handy when doing local development on `gcp-ip-list`.
105+
If you add support for a new resource type, please add the appropriate Terraform resources in the same PR.
106+
107+
# Releases
108+
New releases can be found on the [Releases](page).
109+
110+
## Verifying signatures
111+
Binaries built by this project are signed using Sigstore.
112+
113+
To verify the signature for a given binary, you can use [cosign](https://github.com/sigstore/cosign):
114+
115+
```
116+
$ cosign verify-blob gcp-ip-list_Darwin_x86_64/gcp-ip-list \
117+
--bundle gcp-ip-list_Darwin_x86_64.cosign.bundle \
118+
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
119+
--certificate-identity=https://github.com/mark-adams/gcp-ip-list/.github/workflows/release.yml@refs/tags/<version>
120+
Verified OK
121+
```
122+
123+
# Troubleshooting
124+
125+
## Could not find default credentials
126+
127+
```
128+
error getting public addresses: error setting up client: credentials: could not find default credentials. See https://cloud.google.com/docs/authentication/external/set-up-adc for more information
129+
```
130+
131+
This means that you're likely running the tool locally from your workstation without having application default credentials set up. You can follow the link in the message or run `gcloud auth application-default login` to authenticate with GCP and obtain the proper credentials.
132+
133+
## Cloud Asset API has not been used in project X before
134+
135+
This tool depends on the Cloud Asset Inventory API being enabled. Luckily, the error message points you in the right direction. Look for "Enable it by visiting https://..." in the error message and visit that page to enable the API.

0 commit comments

Comments
 (0)