Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Authentication with Nginx and LDAP backend

License

NotificationsYou must be signed in to change notification settings

stephane-martin/bouncer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

69 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nginx does not provide natively LDAP authentication. But it provides a genericauthentication module, that performs HTTP requests to a backend service to check ifa user is allowed to access the ressource(seengx_http_auth_request_module).

bouncer provides such a backend.

Features

Consul integration

  • bouncer configuration can be defined in Consul KV
  • if your LDAP directories are services registered in Consul,bouncer can find them
  • bouncer can register itself as a Consul service

LDAP authentication

bouncer can authenticate users based on a LDAP directory. Two authenticationschemes are supported: "direct LDAP bind" or "LDAP search and bind".

Multiple LDAP directories can be defined. In that case,bouncer willload-balance the LDAP requests among them.

On the front-end side, the user credentials can be given as "HTTP Basic"authentication headers, or via a classical form/session cookie.

Backend services

Your backend services don't have to deal with authentication anymore. Insteadthey rely on nginx andbouncer to perform the authentication separately.The services are given information about the current user by HTTP headers.

Check-health and statistics

For reliable monitoring,bouncer provides a simple health-check and some basic statistics.

Logging

  • logs are structured (using logrus), in a text or JSON format
  • logs and request logs are clearly separated
  • logs can be sent to syslog

Install

Prerequisites

  • Nginx, compiled with thengx_http_auth_request_module module.
  • LDAP server(s)
  • Redis is needed for some features (statistics, watching request flow)
  • Linux (should work on other UNIX too)
  • Only compiles on Go >= 1.8

Get it

go get -u github.com/stephane-martin/bouncer

The dependencies are vendored.

Configuration

Configuration sources

File

Seethe configuration example.

The configuration file has to bebouncer.toml. It is looked for in/etc andin the directory specified by the commandline flag--config=XXX.

Environment variables

It is also possible to configurebouncer through environment variables.See the function inenvmapping.gofor the mappings.

NAL_CACHE_EXPIRES="3M" NAL_REALM="My Realm" ... bouncer serve

Consul

The configuration can be stored in the key-value part of Consul. Put the parameters underthebouncer/conf/ prefix in Consul KV, and runbouncer withthe--consul flag.

For example:

consul kv put -http-addr=127.0.0.1:8500 bouncer/conf/cache/expires 3mconsul kv put -http-addr=127.0.0.1:8500 bouncer/conf/http/realm 'My Realm'bouncer serve --consul=http://127.0.0.1:8500

Configuring the LDAP servers

Multiple LDAP directories can be configured, for example one master and someslaves. In that case the LDAP requests used to authenticate users will berandomly load-balanced through the directories. Moreover, if one LDAP directoryis not responding, then another will be tried.

Configuring the LDAP directories has two steps :

  • configure the defaults parameters that would apply to all directories
  • configure the specific paramaters (mostly thehost) for each directory

In the configuration file

The default parameters are inside the[defaultldap] section. Here you definethe LDAP parameters than you want to share among all the directories.

Each individual LDAP directory must then be defined in an additional[[ldap]]section.

bouncer does not reload automatically when the configuration file ismodified. You need to send a SIGHUP to the process.

In Consul KV

In Consul KV you define the default LDAP parameters under the prefixbouncer/conf/defaultldap.

The individual LDAP servers can be defined underbouncer/ldap/[ID]/,where[ID] is a meaningless identifier.

bouncer automatically reloads when the configuration items in Consul KVare modified.

consul kv put -http-addr=127.0.0.1:8500 bouncer/conf/defaultldap/port 389...consul kv put -http-addr=127.0.0.1:8500 bouncer/ldap/1/host 127.0.0.1consul kv put -http-addr=127.0.0.1:8500 bouncer/ldap/2/host 10.1.1.1consul kv put -http-addr=127.0.0.1:8500 bouncer/ldap/2/port 636consul kv put -http-addr=127.0.0.1:8500 bouncer/ldap/2/tls_type tlsconsul kv put -http-addr=127.0.0.1:8500 bouncer/ldap/2/insecure true

By Consul discovery

If your LDAP servers are registered in Consul as service with healthchecks, you don't need to (statically) define the LDAP servers in bouncerconfiguration. Instead, just tell bouncer where to find the LDAPservices. bouncer will try the discovery if you provide the--ldap-service-name commandline option. Only LDAP servers that are registeredin Consul with a passing health-check will be discovered.

bouncer serve --consul=http://127.0.0.1:8500 --ldap-service-name slapd --ldap-datacenter ldapdc

This means: look for services calledslapd, that's defined in theldapdcConsul datacenter. Theslapd hosts and ports, discovered in Consul, completed bydefaultldap parameters, will be used as LDAP servers to perform theauthentication.

It is also possible to filter the discovered LDAP services by a Consul tag with--ldap-tag.

To print the currently discovered and visible LDAP servers from Consul:

bouncer discovered --consul=http://127.0.0.1:8500 --ldap-service-name slapd --ldap-datacenter ldapdc

The discovery is dynamic: LDAP servers will be added/removed to the list whentheir Concul health-checks succeed/fail.

Check configuration

To check bouncer configuration, use theprint-config command:

# Without consulbouncer print-config# With consul (merge configuration from file and Consul KV)bouncer print-config --consul=http://127.0.0.1:8500# Also print the current discovered LDAP directories:bouncer print-config --consul=http://127.0.0.1:8500 --discover --ldap-service-name slapd --ldap-datacenter ldapdc

Main commands

Running

Launchingbouncer

bouncer listens on two ports: one for the main Auth service, the otherone for the API service. The ports are configurable.

To start listening, usebouncer serve.

Logging

There are two kinds of logs: the 'normal logs', that tracebounceractivity, and the 'request logs', that trace the received requests and theirresults.

By default, the normals logs are written tostderr, and the request logs tostdout.

If the--syslog flag is provided, they will both be sent to thelocal syslog daemon. (They use different syslog tags).

To write the normal logs to a file, use--logfile=XXX. Similarly use--req-logfile=YYY for the request logs.

Logs are written in text format by default. Use the--json flag to write themas JSON instead.

Log verbosity can be set for the normal logs and the request logs respectivelywith the--loglevel and--req-loglevel flags. Successful authenticationswill only be logged in the request logs at level 'DEBUG'.

Redis and the request logs

If Redis is enabled in configuration, the request logs:

  • will be written to some Redis sorted sets. (We can calculate some metrics fromRedis afterwards).
  • will be erased from Redis after some configurable period.
  • will be published as a Redis PUBSUB. (We can synchronously expose the requestlogs this way).

Registering in Consul

bouncer can register itself as a Consul service:bouncer serve --consul=XXX --register.

Stopping

Send SIGTERM or SIGINT to thebouncer process.

Reload the configuration file

Send SIGHUP to thebouncer process.

Watch the flow of requests

If Redis in enabled, you can watch the request logs as they are generated withthemonitor command. For example, try:

bouncer serve --req-loglevel=DEBUG

Then in another terminal:

bouncer monitor --json

HTTP endpoints

Auth service

The Auth service listens on address/port defined by configuration parametershttp.bind_addr andhttp.port.

It provides the following endpoints:

  • /nginx: where Nginx should send the authentication subrequests.
  • /auth: authentication through HTTP POST: in the incoming request,username andpassword should be set as HTTPapplication/x-www-form-urlencodedparameters. Returns 200, 401, 403... like the /nginx endpoint.
  • /health: simple health-check endpoint. Returns 200 if everything looks OK.

API service

The API service listens on address/port defined by configuration parametersapi.bind_addr andapi.port.

It provides the following endpoints:

  • /status: returns 200 and a dummy message ifbouncer is running
  • /health: simple health-check endpoint. Returns 200 if everything looks OK.
  • /conf: returns the current configuration
  • /reload: POST there to trigger a configuration reload
  • /stats: if Redis is enabled, some metrics are returned in a JSON format.
  • /events: if Redis is enabled, the request logs are posted there as ServerSide Events.

How to get user information in the backend services

The backend services that are protected by bouncer get informationabout the authenticated user through the following ways:

  • TheAuthorization HTTP header is passed. Optionaly, the user passwordcan be masked in that header ifhttp.mask_password is true.
  • The username is passed in theX-REMOTE-USER HTTP header.
  • If a RSA private key is defined inbouncer configuration, a signedJWT token is passed in theX-REMOTE-JWT header.

To define a RSA private key, provide the path to a PEM-encoded file insignature.private_key_path, or directly the PEM-encoded key insignature.private_key_content.

(To generate such a private key, you can usebouncer generate-rsa-keys.)

HTTP Basic Authentication: Nginx configuration example

Adapt it to your needs.

server {location/backend_service_to_protect{auth_request /nginx;# gather info from HTTP response headersauth_request_set$remote$upstream_http_x_remote_user;auth_request_set$auth$upstream_http_authorization;auth_request_set$backendjwt$upstream_http_x_remote_jwt;# pass info to the backend serviceproxy_set_header REMOTE_USER$remote;proxy_set_header REMOTE-USER$remote;proxy_set_header X-REMOTE-USER$remote;proxy_set_header X-REMOTE-JWT$backendjwt;proxy_set_header Authorization$auth;    }location= /nginx{internal;proxy_pass http://BOUNCER_HOST:BOUNCER_PORT;proxy_pass_request_body off;proxy_set_header Content-Length"";# pass some information to bouncer about the incoming request# (useful for the request logs)proxy_set_header X-Forwarded-Server$http_host;proxy_set_header X-Forwarded-Host$http_host:443;proxy_set_header X-Original-URI$request_uri;proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_header X-Real-IP$remote_addr;proxy_set_header Forwarded"for=$remote_addr; proto=https";proxy_set_header X-Forwarded-Port443;proxy_set_header X-Forwarded-Proto https;    }}

Cookie-based Authentication: Nginx configuration example

server {listen4343 ssl http2;server_name myapp.example.org;    ...location/{error_page401=200 /nal-login-page;auth_request /nginx;# gather info from HTTP response headersauth_request_set$remote$upstream_http_x_remote_user;auth_request_set$auth$upstream_http_authorization;auth_request_set$backendjwt$upstream_http_x_remote_jwt;# pass info to the backend serviceproxy_set_header REMOTE_USER$remote;proxy_set_header REMOTE-USER$remote;proxy_set_header X-REMOTE-USER$remote;proxy_set_header X-REMOTE-JWT$backendjwt;proxy_set_header Authorization$auth;    }location/login{proxy_pass http://BOUNCER_HOST:BOUNCER_PORT/nal-login-page;proxy_set_header X-Real-IP$remote_addr;proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto https;proxy_set_header X-Forwarded-Host$http_host:443;proxy_set_header X-Forwarded-Server$http_host;proxy_set_header X-Forwarded-Port443;proxy_set_header Forwarded"for=$remote_addr; proto=https";proxy_set_header X-Scheme https;proxy_set_header X-Forwarded-Ssl on;proxy_set_header X-Url-Scheme https;proxy_set_header X-Original-Uri$request_uri;proxy_set_header X-Login-Uri$uri;    }location/logout{proxy_pass http://BOUNCER_HOST:BOUNCER_PORT/nal-logout-page;proxy_set_header X-Real-IP$remote_addr;proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto https;proxy_set_header X-Forwarded-Host$http_host:443;proxy_set_header X-Forwarded-Server$http_host;proxy_set_header X-Forwarded-Port443;proxy_set_header Forwarded"for=$remote_addr; proto=https";proxy_set_header X-Scheme https;proxy_set_header X-Forwarded-Ssl on;proxy_set_header X-Url-Scheme https;proxy_set_header X-Original-Uri$request_uri;    }location= /nginx{internal;proxy_pass http://BOUNCER_HOST:BOUNCER_PORT;proxy_pass_request_body off;proxy_set_header Content-Length"";proxy_set_header X-Forwarded-Server$http_host;proxy_set_header X-Forwarded-Host$http_host:443;proxy_set_header X-Original-URI$request_uri;proxy_set_header X-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_header X-Real-IP$remote_addr;proxy_set_header Forwarded"for=$remote_addr; proto=https";proxy_set_header X-Forwarded-Port443;proxy_set_header X-Forwarded-Proto https;    }}

Releases

No releases published

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp