ip-lookup-api is a GraphQL service built with Go that queries and stores the Spamhaus Blocklist for malicious IP addresses.
First clone the repository:
git clone https://github.com/grantsavage/ip-lookup-api.git && cd ip-lookup-api
To bulid the service as a Docker container, run the following docker
command inside the project directory:
docker build -t iplookup:1.0 .
To build the service as an executable, first make sure go
version 1.16
is installed and install the dependencies:
go mod download
Then build the service by runnning:
make build
This will build the service into an executable named server
and place it in the project directory.
This service will respect the following environment variables:
Variable Name | Description | Required | Default |
---|---|---|---|
PORT | The port on which to bind the server to. | No | 8080 |
AUTH_USERNAME | The username which requests will be authenticated against. | Yes | |
AUTH_PASSWORD | The password which requests will be authenticated against. | Yes |
To run the service as a docker
container and configure the necessary environment variables, first build the image, then use the following command:
docker run -it -e PORT="8080" -e AUTH_USERNAME="secureworks" -e AUTH_PASSWORD="supersecret" -p 8080:8080 iplookup:1.0
Optionally add the -it
flag to view the container logs.
To run the executable, first build the executable, then use the following command:
PORT="3000" AUTH_USERNAME="secureworks" AUTH_PASSWORD="supersecret" ./server
The GraphQL endpoint for this service is at /graphql
.
First, create a basic authorization token by running the following command:
printf "%s:%s" "secureworks" "supersecret" | base64
Now use the generated token and set it as the Authorization
header like so:
Authorization: Basic <your token here>
With the authorization token set, you can enqueue IP addresses using by executing the following mutation at /graphql
:
mutation {
enqueue(ips: ["1.2.3.4"])
}
With the authorization token set, you can query the lookup details of an IP by executing the following query:
query {
getIPDetails(ip: "1.2.3.4") {
uuid
ip_address
response_code
created_at
updated_at
}
}
I did my best to separate the core concerns of the application into 4 major packages: auth
,db
,graph
, and dns
.
auth
: Provides the authentication mechanism and HTTP middlware for the application.db
: Provides an interface for the application to interact with the database.graph
: Defines and implements the resolvers for the GraphQL interface.dns
: Provides methods to handle validating IP addresses and performing the DNS host lookup of an IP.
- 99designs/gqlgen: Used to implement the GraphQL interface.
- go-chi.chi : Used to attach the authentiation middleware to the server.
- mattn/go-sqlite3 : Used to interact with the SQLite database.
- satori/go.uuid : Used to generate UUIDs for new IP lookup results.
- vektah/gqlparser/v2 : Used in conjunction with
99designs/gqlgen
. - DATA-DOG/go-sqlmock : Used in
db
test suite.
To run the test suites, run:
make test