ldapserver | ||
.gitignore | ||
acl.go | ||
config.json.example | ||
Dockerfile | ||
gobottin.hcl.example | ||
LICENSE | ||
main.go | ||
Makefile | ||
read.go | ||
README.md | ||
ssha.go | ||
util.go | ||
write.go |
gobottin
is a LDAP server that uses Consul's key-value store as a storage backend,
in order to provide a redundant (high-availability) LDAP server on a Nomad+Consul cluster.
It is a reimplementation of superboum's Bottin
using the Go programming language.
Features:
- most LDAP operations implemented (add, modify, delete, compare, search with most basic filters)
- TLS support with STARTTLS
- Access control through an ACL (hardcoded in the configuration file)
Building gobottin
can be done simply by running go build
in this folder.
gobottin
takes a single command line argument, -config <filename>
, which is the
path to its config file (defaults to ./config.json
).
The configuration file is a JSON file whose contents is described in the following section.
gobottin
is licensed under the terms of the GPLv3.
Server initialization
When gobottin
is launched on an empty database,
it creates a special admin entity with the name cn=admin,your_suffix
.
It will have a randomly generated password that is printed out by the server.
Check your logs to retrieve the password.
The admin entity has no powers other than those granted by the ACL rules, so unless you don't want to use it, make sure to keep rules that allow to bind to the admin entity and that allows the admin entity to do everything.
Configuration of gobottin
The LDAP suffix
gobottin
only handles LDAP entries under a given path, which is typically of
the form dn=sld,dn=tld
, where sld.tld
is your domain name. Specify this
suffix in the suffix
key of the json config file.
Connection to the Consul server
By default, gobottin
connects to the Consul server on localhost.
Change this by specifying the consul_host
key in the json config file.
Bind address
By default, gobottin
listens on all interfaces on port 389.
Change this by setting the bind_address
key in the json config file.
TLS
gobottin
supports TLS connections either as a mandatory default for all
connections or using the STARTLS functionnality of the LDAP protocol. To use
it, specify the following three keys in the json config file:
tls_server_name
: the host name that clients will use to reach your LDAP servertls_cert_file
: path to your TLS certificate (a.pem
file)tls_key_file
: path to your TLS key (a.pem
file)
Specify "use_starttls": true
to allow connections to start as insecure
connections and allow them to use the STARTTLS mechanism to upgrade to a secure
connection. If use_starttls
is not specified or set to false
, TLS is made
mandatory for all clients.
Access control list
gobottin
supports a flexible syntax to specify access rights to items in the database.
The ACL is specified as a list of rules. A request will be allowed if there exists a rule that allows it. Otherwise an insufficient permission error will be returned.
The list of ACL rules are specified in the acl
key of the json config file, as a list of strings whose structure is defined in the next paragraph.
Rule format
A rule is a string composed of five fields separated by :
. The fields are the following:
- The name of the user that must be bound (logged in) for the rule to apply. May contain wildcards such as
*
(see the format used by Go'spath.Match
). The special nameANONYMOUS
applies to clients before they bind to an LDAP entity. - The groups that the user must be a part of, separated by spaces. Wildcards may also be used. If several groups (or wildcard group patterns) are specified, for each pattern the user must be part of a group that matches it.
- The action, a subset of
bind
,read
,add
,delete
,modify
separated by spaces. - The target entity of the action as a pattern that may contain wildcards. The special word
SELF
is replaced by the entity name of the bound user before trying to match. - The allowed attributes for a read, add or modify operation. This is specified as a list of patterns to include and exclude attributes, separated by spaces. A pattern that starts by
!
is an exclude pattern, otherwise it is an include pattern. To read/write an attribute, it has to match at least one include pattern and not match any exclude pattern. Delete operations do not check for any attribute, thus as soon asdelete
is included in the allowed actions, the right to delete entities is granted.
Rule examples
-
Anybody (before binding) can bind to an entity under
ou=users,dc=gobottin,dc=eu
:ANONYMOUS::bind:*,ou=users,dc=gobottin,dc=eu:
-
Anybody (before binding) can bind to the specific admin entity:
ANONYMOUS::bind:cn=admin,dc=gobottin,dc=eu:
-
Anybody who is logged in can read anything that is not a userpassword attribute:
*,dc=gobottin,dc=eu::read:*:* !userpassword
-
Anybody can read and modify anything from their own entry:
*::read modify:SELF:*
-
The admin can read, add, modify, delete anything:
cn=admin,dc=gobottin,dc=eu::read add modify delete:*:*
-
Members of the admin group can read, add, modify, delete anything:
*:cn=admin,ou=groups,dc=gobottin,dc=eu:read add modify delete:*:*