Access control
Ferron supports several access control patterns, from simple IP-based block/allow rules to authenticated areas with HTTP Basic Authentication or an external authentication backend.
Restrict a path by client IP (block/allow)
Use block and allow directives to control access by IP or CIDR range:
# Replace "example.com" with your domain name.
example.com {
location / {
root /var/www/html
}
// Only allow these networks to access /admin; everyone else gets 403.
location /admin {
allow "203.0.113.0/24" "2001:db8:1234::/48"
root /var/www/admin
}
}When allow is configured, only the listed IPs/CIDRs are permitted. All others receive a 403 Forbidden response.
Combined block and allow
When both block and allow are configured:
- If the IP matches an
allowentry and ablockentry → blocked (block takes precedence) - If the IP matches only an
allowentry → allowed - If the IP matches only a
blockentry → blocked - If the IP matches neither → allowed (unless the allow list is non-empty)
example.com {
root /var/www/html
allow "192.168.1.0/24"
block "192.168.1.100"
}In this example: 192.168.1.50 → allowed, 192.168.1.100 → blocked, 10.0.0.1 → denied.
Block sensitive paths globally
Use a global block to deny access across all hosts:
* {
// Block known abusive addresses globally.
block "198.51.100.10" "203.0.113.0/24"
}Protect an area with Basic Auth
Use the basic_auth directive to require HTTP Basic Authentication:
# Replace "example.com" with your domain name.
example.com {
location / {
root /var/www/html
}
location /admin {
basic_auth {
realm "Admin Area"
users {
admin "$argon2id$v=19$m=19456,t=2,p=1$..."
}
}
root /var/www/admin
}
}Only hashed passwords are supported. The following hash formats are accepted:
| Prefix | Algorithm |
|---|---|
$argon2id$ | Argon2id (recommended) |
$argon2i$ | Argon2i |
$argon2d$ | Argon2d |
$pbkdf2$ | PBKDF2 |
$pbkdf2-sha256$ | PBKDF2-SHA256 |
$scrypt$ | scrypt |
Brute-force protection
Brute-force protection is enabled by default:
example.com {
location /admin {
basic_auth {
realm "Admin Area"
users {
admin "$argon2id$v=19$m=19456,t=2,p=1$..."
}
brute_force_protection {
enabled true
max_attempts 5
lockout_duration 15m
window 5m
}
}
}
}Conditional access control
Use named matchers with if/if_not for more complex access control logic:
match internal_network {
request.header.x_forwarded_for ~ "^10\\.0\\.0\\."
}
example.com {
location /admin {
if_not internal_network {
abort
}
root /var/www/admin
}
}This aborts the connection for any request that does not come from the 10.0.0.0/8 network.
Deny access to sensitive files
Use conditional matching to block access to dotfiles and sensitive paths:
match sensitive_path {
request.uri.path ~ "^/(?:\\. |config|private|backup)"
}
example.com {
root /var/www/html
if sensitive_path {
status 403 {
body "Access denied"
}
}
}Forwarded authentication
For external authentication, use the auth_to directive to forward each request to an authentication backend:
example.com {
auth_to http://auth.example.com/auth
location / {
root /var/www/html
}
}When the backend returns a success status (2xx), the request continues. On failure (4xx/5xx), the backend’s response is returned to the client. Headers from the auth response can be copied to the original request for downstream use:
api.example.com {
auth_to http://auth.example.com/validate {
copy X-Auth-User X-Auth-Roles
}
proxy http://backend:8080
}For full configuration details, see Forwarded authentication.
Notes and troubleshooting
- If Ferron is behind a reverse proxy/load balancer, configure
client_ip_from_headerso IP-based rules use the client IP rather than the proxy IP. See HTTP host directives. - Test restrictive rules with a temporary endpoint first to avoid locking yourself out.
- Prefer
locationmatches when possible; use conditional matchers only when you need pattern matching. - For Basic Auth, always use TLS — credentials are sent in the
Authorizationheader on every request. - For forwarded authentication backends behind TLS, ensure the backend’s certificate is valid or use
no_verification truefor development/testing. - For complex logic (method/header/path combinations), use conditional configuration. See Conditionals and variables.
- For directive details (
block,allow), see HTTP response control. - For Basic Auth details, see HTTP basic authentication.
- For forwarded authentication details, see Forwarded authentication.