caddyipinfofree

package module
v0.0.0-...-f6400d9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 13, 2026 License: MIT Imports: 25 Imported by: 0

README

Caddy      IPInfo

Caddy x IPInfo

This project does not affiliate with Caddy nor IPInfo. It only extends Caddy with custom code to integrate the free databases provided by IPInfo into Caddy. Logo Copyright belongs to the corresponding project.

Caddy IPInfo free

Easy country and ASN lookup by IP with the free IPInfo database.

This module is still in development. Breaking changes will likely come. No stability checks yet.

Example

{
    # Required as a third-party handler
    order ipinfo_free first
    # Configure module
    ipinfo_free_config {
        url https://ipinfo.io/data/ipinfo_lite.mmdb?token=magicduck
        cron "10 16 * * *"
        path /tmp/caddy_ipinfo
    }
}

:8080 {
    ipinfo_free "{http.request.uri.query.ip}"

    header Content-Type text/plain
    respond <<TEXT
    IP: {ipinfo_free.ip}
                
    Country: {ipinfo_free.country} ({ipinfo_free.country_code})
    Continent: {ipinfo_free.continent} ({ipinfo_free.continent_code})
    ASN: {ipinfo_free.asn} {ipinfo_free.as_name} {ipinfo_free.as_domain}
    TEXT 200
}
$ curl "http://localhost:8080/?ip=1.1.1.1"
IP: 1.1.1.1
            
Country: Australia (AU)
Continent: Oceania (OC)
ASN: AS13335 Cloudflare, Inc. cloudflare.com

Why?

IPInfo distributes their country and ASN databases for free every 24h with full accuracy. With this module and a few lines of config in your Caddyfile, you can query the database anywhere with anything.

Installation

Web Download

Download a caddy binary from caddyserver.com with this package included here.

CLI Download (experimental)

This is equal to the version above but replaces your existing binary with the new one including the package.

Caddy has a feature to add packages to your current installation by running the following command:

caddy add-package github.com/oltdaniel/caddy-ipinfo-free
DIY Route

Build a custom binary of the latest caddy release with this module enabled.

CADDY_VERSION=latest xcaddy build --with github.com/oltdaniel/caddy-ipinfo-free
./caddy run

Directives

ipinfo_free_config (global)
Examples
ipinfo_free_config https://ipinfo.io/data/ipinfo_lite.mmdb?token=magicduck

ipinfo_free_config {
    url https://ipinfo.io/data/ipinfo_lite.mmdb?token=magicduck
    cron "10 16 * * *"
    path /tmp/caddy_ipinfo
    error_on_invalid_ip true
}
Values
Name Values Description
url valid ipinfo free database url This url can be easily found in the Dashboard of IPInfo after creating an account. Simply choose a database of your choice in the MMDB format and paste the url here. If you only choose the Country or ASN Database, only these values can be extracted and filled into the variables. The other values will simply be empty. If the Database with both types is chosen, all details will be available.
cron valid crontab notation

Default: 10 16 * * *
Customize how often you want to check for a new database. The official time is published by IPInfo in their FAQ here. Timezone is UTC.
path valid path to store the database

Default: os.TempDir() with directory caddy_ipinfo_free
This will be the path where the databases are stored after download. As there are different kinds of databases, we only accept a path and not a specific filename. Each database will be stored here by their corresponding names from the configured url.

If the configured path does not exist, the directories will be created. If not path is given, a temporary directory will be created in the systems temporary directory with the name caddy_ipinfo_free.
error_on_invalid_ip accepted input for strconv.ParseBool

Default: false
Allows enabling error logs when an invalid ip is given to the handler. If you debug something enabling this is recommended. The Variable ipinfo_free.error will be set regardless. The main use-case for this feature is to avoid overloading the logs in production when presented with invalid IPs by the client. NOTE: Previously known as quiet_on_invalid_ip, which made it more difficult to properly handle the default true state.
ipinfo_free (handler)
Examples
ipinfo_free
ipinfo_free 1
ipinfo_free on
ipinfo_free true
ipinfo_free enabled
ipinfo_free forwarded
ipinfo_free trusted
ipinfo_free "{http.request.uri.query.ip}"
Values Description
disabled, false, off, 0 Explicit disabling of looking up ip information.
enabled, true, on, 1, strict, empty The remote address of the request will be used to lookup the ip information.
forwarded Use the IP set in the X-Forwarded-For Header if present, else it will fallback to the remote address of the request.
trusted Same as forwarded but it will make sure that the ip from which the request comes is listed as a trusted proxy in the current caddy environment.
any value that is an IPv4 or IPv6 The mode field supports the Caddy placeholders which allows you to fully customize the IP that is used for lookup.

NOTE: If the value maps to an empty string, the remote address of the client will be used as a fallback.

Placeholder Variables

In order to support both the legacy free data downloads and the new lite database, all entry columns are exposed from the MMDB.

IPInfo switched from the old legacy format to the new lite database format, Introducing IPinfo Lite: Free, Accurate, and Unlimited IP Data for Everyone.

Legacy Free Database
Variable Example
ipinfo_free.error IP cannot be nil for lookup
ipinfo_free.ip 1.1.1.1
ipinfo_free.country AU
ipinfo_free.country_name Australia
ipinfo_free.continent OC
ipinfo_free.continent_name Oceania
ipinfo_free.asn AS13335
ipinfo_free.as_name Cloudflare, Inc.
ipinfo_free.as_domain cloudflare.com
New Lite Database
Variable Example
ipinfo_free.error IP cannot be nil for lookup
ipinfo_free.ip 1.1.1.1
ipinfo_free.country Australia
ipinfo_free.country_code AU
ipinfo_free.continent Oceania
ipinfo_free.continent_code OC
ipinfo_free.asn AS13335
ipinfo_free.as_name Cloudflare, Inc.
ipinfo_free.as_domain cloudflare.com

Advanced Examples

Just replace the body of the server from the Caddyfile example on top.

Change Response for Countries

This is a simple example on how the response can be changed for certain countries.

ipinfo_free

header Content-Type text/plain

@dach expression ({ipinfo_free.country_code} in ["DE", "CH", "AT"])

respond @dach "Hallo Besucher aus der DACH-Region!"
respond "Hello visitor from {ipinfo_free.country}"
Simple GeoIP API

Simply query with http://localhost:8080/?ip=IP.

ipinfo_free "{http.request.uri.query.ip}"

header Content-Type text/plain
respond <<TEXT
IP: {ipinfo_free.ip}
            
Country: {ipinfo_free.country} ({ipinfo_free.country_code})
Continent: {ipinfo_free.continent} ({ipinfo_free.continent_code})
ASN: {ipinfo_free.asn} {ipinfo_free.as_name} {ipinfo_free.as_domain}
TEXT 200
GeoIP API with Error Handling
@hasIP query ip=*

handle @hasIP {
    ipinfo_free "{http.request.uri.query.ip}"

    @hasError not vars {ipinfo_free.error} ""

    header Content-Type text/plain

    respond @hasError "Error: {ipinfo_free.error}" 400
    respond <<TEXT
    IP: {ipinfo_free.ip}
                    
    Country: {ipinfo_free.country} ({ipinfo_free.country_code})
    Continent: {ipinfo_free.continent} ({ipinfo_free.continent_code})
    ASN: {ipinfo_free.asn} {ipinfo_free.as_name} {ipinfo_free.as_domain}
    TEXT 200
}

respond "Error: Missing 'ip' query parameter" 400
More?

Do you have a neat way of using this library in your Caddyfile? Feel free to submit it.

Internals

This module will automatically update the database from ipinfo and store it in the configured path. You can freely configure the cron option to update the database in a timely manner of your choosing. However, the most frequent update rate that should be used is hourly as the database will only be updated by IPInfo every 24 hours.

Resources

Development

Clone, create example config and run with xcaddy.

git clone https://github.com/oltdaniel/caddy-ipinfo-free.git
cd caddy-ipinfo-free

CADDY_VERSION=master xcaddy run
# or
CADDY_VERSION=master xcaddy build --with github.com/oltdaniel/caddy-ipinfo-free=.
./caddy run

License

IP address data powered by IPinfo

GitHub License

Documentation

Index

Constants

View Source
const (
	DEFAULT_CRON = "10 16 * * *"

	CRON_NAME_UPDATE         = "update"
	CRON_NAME_INITIAL_UPDATE = "initial-update"

	ID_MODULE_STATE = "caddy.states.ipinfo-free"
)
View Source
const (
	ID_MODULE_HANDLER = "http.handlers.ipinfo-free"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type IPInfoFreeChecksumResponse

type IPInfoFreeChecksumResponse struct {
	Checksums struct {
		MD5    string `json:"md5"`
		SHA1   string `json:"sha1"`
		SHA256 string `json:"sha256"`
	} `json:"checksums"`
}

Structure to unmarshal response from https://ipinfo.io/data/free/country.mmdb/checksums?token=magicduck

type IPInfoFreeHandler

type IPInfoFreeHandler struct {
	Mode string `json:"mode,omitempty"`
	// contains filtered or unexported fields
}

func (IPInfoFreeHandler) CaddyModule

func (IPInfoFreeHandler) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information

func (*IPInfoFreeHandler) Provision

func (m *IPInfoFreeHandler) Provision(ctx caddy.Context) error

func (IPInfoFreeHandler) ServeHTTP

func (*IPInfoFreeHandler) UnmarshalCaddyfile

func (m *IPInfoFreeHandler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile implements caddyfile.Unmarshaler.

func (*IPInfoFreeHandler) Validate

func (m *IPInfoFreeHandler) Validate() error

type IPInfoFreeState

type IPInfoFreeState struct {
	Url              string `json:"url,omitempty"`
	Cron             string `json:"cron,omitempty"`
	Path             string `json:"path,omitempty"`
	ErrorOnInvalidIP bool   `json:"error_on_invalid_ip,omitempty"`
	// contains filtered or unexported fields
}

Define our module with optional json fields that can be stored by caddy

func (IPInfoFreeState) CaddyModule

func (IPInfoFreeState) CaddyModule() caddy.ModuleInfo

CaddyModule returns the Caddy module information

func (*IPInfoFreeState) Cleanup

func (m *IPInfoFreeState) Cleanup() error

func (*IPInfoFreeState) Provision

func (m *IPInfoFreeState) Provision(ctx caddy.Context) error

func (*IPInfoFreeState) Start

func (m *IPInfoFreeState) Start() error

func (*IPInfoFreeState) Stop

func (m *IPInfoFreeState) Stop() error

func (*IPInfoFreeState) UnmarshalCaddyfile

func (m *IPInfoFreeState) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

UnmarshalCaddyfile implements caddyfile.Unmarshaler

func (*IPInfoFreeState) Validate

func (m *IPInfoFreeState) Validate() error

type MMDBResult

type MMDBResult = map[string]any

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL