Skip to content
Knut Ahlers edited this page Apr 22, 2019 · 8 revisions

The configuration is mainly done using a YAML configuration file. Some options are configurable through command line flags and can be looked up using --help flag.

For an example configuration see the config.yaml file in this repository. Within the next sections the options are explained in more detail:

Login form

The login form can be customized with its wording and the default login method.

login:
  title: "luzifer.io - Login"
  default_method: "simple"
  default_redirect: "https://luzifer.io/"
  hide_mfa_field: false
  names:
    simple: "Username / Password"
    yubikey: "Yubikey"

Most options should explain themselves, the names dictionary maps IDs of the authentication methods (shown in the title of their config section below) to human readable strings. You can set any string you need and your user recognizes.

When setting the default_redirect your users are able to bookmark your login page (password managers tend to do this) and are redirected to this URL in case no go= parameter was found when the login page was called.

In case you don't want to show up the "MFA Token" fields even though the providers being used does support them (for example if you are not using MFA and don't want to confuse your users) you can set the hide_mfa_field flag to hide them.

Cookie Settings

Most of the cookie settings are pre-set to sane defaults but you definitly need to configure some.

cookie:
  domain: ".example.com"
  authentication_key: "Ff1uWJcLouKu9kwxgbnKcU3ps47gps72sxEz79TGHFCpJNCPtiZAFDisM4MWbstH"
  expire: 3600        # Optional, default: 3600
  prefix: "nginx-sso" # Optional, default: nginx-sso
  secure: true        # Optional, default: false

Adjust the domain to your service. So if all of your services live under *.luzifer.io you want to set the domain to .luzifer.io. The authentication_key needs to be set to some unique string not known to others. It is used to validate nobody messed with your session cookies. If this is leaked (or you just used the default) attackers can just set any username inside the corresponding cookie and are able to access your services!

If you are accessing your services through HTTPs you want to enable secure cookies. Also you should think about customizing the cookie prefix and the expire time of the cookie.

HTTP Listener

This section configures where you can reach the program using HTTP and where you will point your nginx to. The example below shows the defaults and you don't need to change them.

listen:
  addr: "127.0.0.1"
  port: 8082

Pay attention if you are running the docker container you need to change the IP to 0.0.0.0 to expose the port in the container. If you miss this the service will not be available.

Audit Logging

nginx-sso can be configured to write an audit log which for example can be used to detect brute-force attacks on passwords. By default the audit logging is disabled and gets enabled by providing targets in the audit_log section of the config.

Due to the fact we do have several credential providers the login and logout events do not contain an username. The username is only known in requests the user is doing after their login so the access_denied and validate events contains it.

audit_log:
  targets:
    - fd://stdout
    - file:///var/log/nginx-sso/audit.jsonl
  events: ['access_denied', 'login_success', 'login_failure', 'logout', 'validate']
  headers: ['x-origin-uri']
  trusted_ip_headers: ["X-Forwarded-For", "RemoteAddr", "X-Real-IP"]
  • targets - required - Supported targets are fd://stdout, fd://stderr or any file://... URI
  • events - required - All supported events are listed above in the example. Pay attention validate is a quite verbose event
  • headers - optional - List of headers to include into the log entry (for details about the headers see the ACL section below)
  • trusted_ip_headers - optional - List of headers to use for reading the real IP the request is coming from (defaults see example above)

Access Control Lists

The rules of the ACL are the most complex part of the configuration and you should take your time to make this bullet-proof. If you mess up you're probably are getting complaints from your users because the default policy applied is to deny all access. So in the end you are configuring a white-list here.

acl:
  rule_sets:
  - rules:
    - field: "host"
      equals: "test.example.com"
    - field: "x-origin-uri"
      regexp: "^/api"
    allow: ["luzifer", "@admins"]

Each rule_sets entry consists of three parts: rules, allow and deny directives. You can supply as many rules as you need, they are connected using AND logic per rule-set.

Each rules entry has two mandantory and three optional fields of which at least one must be set:

  • field - required - Selector of the header your nginx is sending to the /auth endpoint (e.g. Host, X-Origin-URI, ...)
  • invert - required - Boolean used to invert the matching: What was true will be false. Useful for "does not match this regexp" rules (default: false)
  • present - optional - Boolean stating a certain header must exist or must not exist
  • regexp - optional - String containing a regexp which must match the contents of the header selected by field
  • equals - optional - String which must fully match the contents of the header selected by field

The allow and deny directives are arrays of users and groups. Groups are prefixed using an @ sign. There is a simple logic: Users before groups, denies before allows. So if you allow the group @test containing the user mike but deny the user mike, mike will not be able to access the matching sites.

A special group exists for all authenticated users: @_authenticated. This group does not need to be assigned to an user but automatically contains all logged in users. You can use that group in the allow directive to have all users with a valid login be able to access the resource.