Skip to content

Access Control

Connection Level

Connection level access control handles IP addresses before the request is even processed. If an IP is blocked, the connection will be dropped (and logged if configured).

Supported Filters

TypeExampleMaxMind Credentials Required
IP addressip:1.2.3.4No
CIDRcidr:1.2.3.4/32No
ISO country codecountry:USYes
Timezonetz:Asia/ShanghaiYes

ACL Configuration

KeyTypeDescriptionRequiredDefault
defaultstringDefault actionYesallow
allow_localboolAllow local addressesNotrue
allowFilter ListAllow listNo[]
denyFilter ListDeny listNo[]
logobjectLog configurationNo{}

ACL Example

yaml
# config.yml
acl:
  default: allow # or deny (default: allow)
  allow_local: true # or false (default: true)
  allow:
    - ip:1.2.3.4
    - cidr:1.2.3.4/32
    - country:US
    - tz:Asia/Shanghai
  deny:
    - ip:1.2.3.4
    - cidr:1.2.3.4/32
    - country:US
    - tz:Asia/Shanghai
  log:
    buffer_size: 65536 # (default: 64KB)
    path: /app/logs/acl.log # (default: none)
    stdout: false # (default: false)
    keep: last 10 # (default: none)
    log_allowed: true # (default: false)
providers:
  maxmind:
    account_id: 123456
    license_key: your-license-key
    database: geolite # or geoip2 if you have subscription

Request Level

Request level access control handles IP addresses after the request is processed. If an IP is blocked, GoDoxy will response a HTTP error code with an error message (and logged if configured).

NOTE

HTTP Access loggers can be configured

  • in config.yml under entrypoint section
  • per route in docker labels or route files

Request Whitelist Configuration

KeyTypeDescriptionRequiredDefault
allowIP/CIDR listAllow listNo[]
status_codeintStatus codeNo403
messagestringError messageNoIP not allowed

Request Whitelist Example

yaml
# config.yml
entrypoint:
  middlewares: # allow only local (private) ips
    - use: CIDRWhiteList
      allow:
        - 127.0.0.1/32
        - 172.16.0.0/12
        - 192.168.0.0/16
        - 10.0.0.0/8
      status_code: 403
      message: Forbidden
  access_log:
    format: json
    path: /app/logs/access.json.log
    filters: # skip logging requests from local (private) ips
      cidr:
        negative: true
        values:
          - 127.0.0.1/32
          - 172.16.0.0/12
          - 192.168.0.0/16
          - 10.0.0.0/8
    fields:
      headers:
        default: drop # drop app headers in log
        config: # keep only these
          X-Real-Ip: keep
          CF-Connecting-Ip: keep
          X-Forwarded-For: keep

# docker labels
proxy.#1.middlewares.cidr_whitelist: |
  allow:
    - 10.0.0.0/8
    - 192.168.0.0/16
  status_code: 403
  message: "IP not allowed"

Access Logging

Common Fields

KeyTypeDescriptionAllowed ValuesDefault
pathstringAccess log path/var/log/access.logrequired
stdoutboolEnable stdout logging (can be used with path)true or falsefalse
keep or retentionSee belowRetention policy30 days
rotate_intervaldurationLog rotation intervalDuration1h

Log rotation

NOTE

To enable log rotation, you may set keep or retention to a retention policy.

Default: 30 days

Format:

  • {N} days|weeks|months (e.g. 30 days)
  • {N} KB|MB|GB|kb|mb|gb (e.g. 100 MB for 100 Megabytes, 100 mb for 100 Megabits)
  • last {N} (e.g. last 10 for last 10 lines)

HTTP Access Log

FieldTypeDescriptionAllowed valuesDefault
formatstringaccess log formatcommon, combined, jsoncombined
filtersobjectaccess log filters (optional)
filters.*.negativeboolnegative filterstrue or falsefalse
filters.status_codes.valuesinteger or integer rangestatus code filters
filters.method.valuesstringmethod filtersGET, POST, ...
filters.host.valuesstringhost filtershostname
filters.headers.valuesstringheaders filterscase-sensitive key or key=value
filters.cidr.valuesstringCIDR filterssee below
fieldsobjectaccess log fieldssee below
fields.*.defaultstring (field mode)default field behaviorkeep, drop, redactSee Explanation
fields.*.configkey:value mapping (key is case-sensitive)headers fieldskey: field_mode
fields.headers.config.*stringheaders fieldsheader: field_mode
fields.query.config.*stringquery fieldsquery: field_mode
fields.cookies.config.*stringcookies fieldscookie: field_mode

Explanation

  • Multiple access loggers can share the same log file
  • When filters.*.negative is set to true, request that matches any of the negative filters will not be logged
  • When fields.*.default is set to keep, that field will be logged
  • When fields.*.default is set to redact, that field will be redacted as REDACTED
    • fields.query.default = redact will replace query string into like ?key=REDACTED
    • other field config has effect only when access_log.format is set to json
  • When fields.*.default is set to drop, that field will be dropped
  • Default field config:
    • query.default = keep
    • cookies.default = drop
    • headers.default = drop

ACL Log

FieldTypeDescriptionRequiredAllowed valuesDefault
log_allowedboollog when IP is allowedbooltrue or falsefalse

Full Example

yaml
# config.yml
entrypoint:
  access_log:
    format: json
    path: /var/log/example.log
    filters:
      status_codes:
        values:
          - 200-299
          - 101
      method:
        values:
          - GET
      host:
        values:
          - example.y.z
      headers:
        negative: true
        values:
          - foo=bar # when key "foo" is present and value is `bar`
          - baz # when key "bar" is present
      cidr:
        values:
          - 192.168.10.0/24
    fields:
      headers:
        default: keep
        config:
          foo: redact
      query:
        default: drop
        config:
          foo: keep
      cookies:
        default: redact
        config:
          foo: keep

# route file
# same as above, but under your app config, e.g.
app1:
  access_log:
    format: json
    ...

# docker labels - string as inline mapping
proxy.app1.access_log: |
  format: json
  ...

# docker labels - full label
proxy.app1.access_log.format: json
proxy.app1.access_log.filters.status_codes.values: 200-299,300
proxy.app1.access_log.fields.headers.config.foo: redact

Released under the MIT License.