forevd is a forward and reverse proxy that helps deliver authentication and, optionally,
authorization as a sidecar.
This project was created to help eliminate any need to add authentication into your application code.
At the moment, forevd, runs using Apache, so you will need to have httpd or docker image of it
available at runtime.
- Apache
- nginx (TBD)
The following proivides some details on how to run forevd. The way the options work is that
anything provided immediately on the CLI, are "global" defaults; if you then provide config
(optionally files), via the --locations, --ldap or --oidc options, then those will override
the CLI options, of, e.g. --backend and --location.
You can optionally provide config files for more complicated setups; this section provides soem
examples, which can be found in the etc directory.
The config files use Jinja2 templating via environment variables, so, instead of putting values in
directly, you can use the form {{ ENV_VAR_NAME }} to have the environment varibale injected at
runtime.
The following command line options support files: --locations, --ldap or --oidc, via the @
symbol, similar to curl's command line option --data, for example, --oidc @etc/oidc.yaml
This config allows you to provide much more control over each "location" or "endpoint" to your reverse proxy. For example, using different backends for different URLs or adding authorization. The format of the file is a dictionary of locations, or endpoints, and their correspondign data.
There are 5 key config options for each location:
path: the path, location or endpoint of what to protect or unprotectmatch: whether the path value is a regex or matchauthc: this is the authentication (akaauthc) key, representing what authc to enable; this is dictionary with keys being eithermtlsoroidc.authz: this is the authorization (akaauthz) key, representing what authz to enable; this is dictionary with keys, see below example and details at the Authorization section.
Note: remember that global authentication options --oidc and mtls, so if you want to set OIDC
across all endpoints, except, say, /api, you would need to disable it explicitly with:
- path: /api
authc:
oidc: falseThe following adds LDAP group and static user authorization to /
- path: /
authz:
join_type: "any"
ldap:
url: "ldaps://127.0.0.1/DC=foo,DC=example,DC=com"
bind-dn: "foo"
bind-pw: "{{ LDAP_BINDID_PASSWORD }}"
groups:
- "CN=foobar,OU=groups,DC=example,DC=com"
users:
- erick.bourgeoisLet's break this down a bit:
- the high level keys are endpoints
- the next level is authorization config
- the
join_typekey word tellsforevdhow to "combine" or join the two different authorizations, values are:any: if any of the authorization types match, allow connection throughall: all of the authorization types must match to allow connection through
This is useful for adding any other global OIDC config; there are required fields for the auth to
work, e.g. ClientID and ClientSecret.
ProviderMetadataUrl: "https://{{ OIDC_PROVIDER_NAME }}.us.auth0.com/.well-known/openid-configuration"
RedirectURI: "https://erick-pro.jeb.ca:8080/secure/redirect_uri"
ClientId: "{{ OIDC_CLIENT_ID }}"
ClientSecret: "{{ OIDC_CLIENT_SECRET }}"
Scope: '"openid profile"'
PKCEMethod: S256
RemoteUserClaim: nicknameThis is used for global LDAP config, e.g. setting cache information for mod_ldap. Note: The LDAP
prefix is stripped, as it's redundant and it's added as part of the config generation.
SharedCacheSize: 500000
CacheEntries: 1024
CacheTTL: 600
OpCacheEntries: 1024
OpCacheTTL: 600The following command provides termination of mTLS on / and passes connections to a backend at
http://0.0.0.0:8080
forevd --debug --listen 0.0.0.0:8080 \
--ca-cert $PWD/../certs/ca/ca-cert.pem
--cert $PWD/../certs/server.crt
--cert-key $PWD/../certs/server.key
--backend http://localhost:8081
--location /
--mtls require
--server-name example.com
--var-dir /var/tmp/apache
To add authorization, it's recommended you use a config file for the --locations command line.
There is currently support for LDAP group lookups, static user names, or allow all valid users. Here are the keys supported:
allow_all: this key let'sforevdknow to allow all valid users throughjoin_type: this is the "join" type between all authorizations setup
any: if any of the authorization types match, allow connection throughall: all of the authorization types must match to allow connection through
ldap: this is the LDAP configuration for group lookups, keys are:url: LDAP URL, e.g.ldaps://127.0.0.1/DC=foo,DC=example,DC=combind-dn: the DN for bind operationbind-pw: the password for bind operationgroups: a list of groups DNs
users: a list of user names to verify against
See Locations Example for more detail.