From 7962e7b26201506d38bff049d6d20c0fb81df38e Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Fri, 31 Jan 2020 22:15:40 +0100 Subject: Rebrand to Bottin (with Superboum's benediction) --- .gitignore | 4 ++-- Dockerfile | 4 ++-- Makefile | 20 +++++++++--------- README.md | 40 +++++++++++++++++------------------ bottin.hcl.example | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ config.json.example | 12 +++++------ gobottin.hcl.example | 60 ---------------------------------------------------- main.go | 26 +++++++++++------------ 8 files changed, 113 insertions(+), 113 deletions(-) create mode 100644 bottin.hcl.example delete mode 100644 gobottin.hcl.example diff --git a/.gitignore b/.gitignore index 9fd0402..d739b6f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -gobottin -gobottin.static +bottin +bottin.static config.json diff --git a/Dockerfile b/Dockerfile index afc0b36..955e617 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ FROM scratch -ADD gobottin.static /gobottin +ADD bottin.static /bottin -ENTRYPOINT ["/gobottin"] +ENTRYPOINT ["/bottin"] diff --git a/Makefile b/Makefile index 0860814..13fed94 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,15 @@ -all: gobottin +all: bottin -gobottin: main.go ssha.go util.go acl.go read.go write.go +bottin: main.go ssha.go util.go acl.go read.go write.go go get -d -v - go build -v + go build -v -o bottin -gobottin.static: main.go ssha.go util.go acl.go read.go write.go +bottin.static: main.go ssha.go util.go acl.go read.go write.go go get -d -v - CGO_ENABLED=0 GOOS=linux go build -a -v -o gobottin.static + CGO_ENABLED=0 GOOS=linux go build -a -v -o bottin.static -docker: gobottin.static - docker build -t lxpz/gobottin_amd64:$(TAG) . - docker push lxpz/gobottin_amd64:$(TAG) - docker tag lxpz/gobottin_amd64:$(TAG) lxpz/gobottin_amd64:latest - docker push lxpz/gobottin_amd64:latest +docker: bottin.static + docker build -t lxpz/bottin_amd64:$(TAG) . + docker push lxpz/bottin_amd64:$(TAG) + docker tag lxpz/bottin_amd64:$(TAG) lxpz/bottin_amd64:latest + docker push lxpz/bottin_amd64:latest diff --git a/README.md b/README.md index 5a696e7..b932328 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -`gobottin` is a LDAP server that uses Consul's key-value store as a storage backend, +Bottin 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](https://github.com/superboum/bottin) using the Go programming language. @@ -10,18 +10,18 @@ Features: - Access control through an ACL (hardcoded in the configuration file) -Building `gobottin` can be done simply by running `go build` in this folder. +Building Bottin can be done simply by running `go build` in this folder. -`gobottin` takes a single command line argument, `-config `, which is the +Bottin takes a single command line argument, `-config `, 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. +Bottin is licensed under the terms of the GPLv3. # Server initialization -When `gobottin` is launched on an empty database, +When Bottin 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. @@ -31,39 +31,39 @@ 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` +# Configuration of Bottin ## The LDAP suffix -`gobottin` only handles LDAP entries under a given path, which is typically of +Bottin 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. +By default, Bottin connects to the Consul server on localhost. Change this by specifying the `consul_host` key in the json config file. ## Bind addresses ### Insecure port -By default, `gobottin` listens on all interfaces on port 389 for standard +By default, Bottin listens on all interfaces on port 389 for standard non-TLS connections. Change the value of the `bind` key in the json config file to change this behaviour (default value: `0.0.0.0:389`). An empty string -will disable this port and `gobottin` will not listen for non-TLS connections. +will disable this port and Bottin will not listen for non-TLS connections. ### Secure port -If a TLS configuration is provided (see next section), `gobottin` also listens +If a TLS configuration is provided (see next section), Bottin also listens on all interfaces on port 636 for TLS connections. Change the value of the `bind_secure` key in the json config file to change this behaviour (default -value: `0.0.0.0:636`). An empty string will disable this port and `gobottin` +value: `0.0.0.0:636`). An empty string will disable this port and Bottin will not listen for TLS connections. ## TLS -`gobottin` supports TLS connections using either fully secure connections or +Bottin supports TLS connections using either fully secure connections or using the STARTLS functionnality of the LDAP protocol to upgrade from an insecure connection. To use it, specify the following three keys in the json config file: @@ -80,7 +80,7 @@ is set (non-empty) and no valid TLS configuration is provided. ## Access control list -`gobottin` supports a flexible syntax to specify access rights to items in the database. +Bottin 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. @@ -98,20 +98,20 @@ A rule is a string composed of five fields separated by `:`. The fields are the ### 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 an entity under `ou=users,dc=bottin,dc=eu`: + `ANONYMOUS::bind:*,ou=users,dc=bottin,dc=eu:` - Anybody (before binding) can bind to the specific admin entity: - `ANONYMOUS::bind:cn=admin,dc=gobottin,dc=eu:` + `ANONYMOUS::bind:cn=admin,dc=bottin,dc=eu:` - Anybody who is logged in can read anything that is not a userpassword attribute: - `*,dc=gobottin,dc=eu::read:*:* !userpassword` + `*,dc=bottin,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:*:*` + `cn=admin,dc=bottin,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:*:*` + `*:cn=admin,ou=groups,dc=bottin,dc=eu:read add modify delete:*:*` diff --git a/bottin.hcl.example b/bottin.hcl.example new file mode 100644 index 0000000..310e5b2 --- /dev/null +++ b/bottin.hcl.example @@ -0,0 +1,60 @@ +job "directory" { + datacenters = ["dc1"] + type = "service" + + constraint { + attribute = "${attr.cpu.arch}" + value = "amd64" + } + + group "ldap" { + count = 2 + task "server" { + driver = "docker" + config { + image = "lxpz/bottin_amd64:12" + readonly_rootfs = true + port_map { + ldap_port = 389 + } + volumes = [ + "secrets/config.json:/config.json" + ] + } + + artifact { + source = "http://127.0.0.1:8500/v1/kv/configuration/directory/bottin/config.json?raw" + destination = "secrets/config.json" + mode = "file" + } + + resources { + memory = 100 + network { + port "ldap_port" { + static = "389" + } + } + } + + service { + tags = ["bottin"] + port = "ldap_port" + address_mode = "host" + name = "bottin" + check { + type = "tcp" + port = "ldap_port" + interval = "60s" + timeout = "5s" + check_restart { + limit = 3 + grace = "90s" + ignore_warnings = false + } + } + } + } + } +} + diff --git a/config.json.example b/config.json.example index 4249e26..a1840db 100644 --- a/config.json.example +++ b/config.json.example @@ -1,13 +1,13 @@ { - "suffix": "dc=gobottin,dc=eu", + "suffix": "dc=bottin,dc=eu", "bind": "127.0.0.1:1389", "acl": [ - "ANONYMOUS::bind:*,ou=users,dc=gobottin,dc=eu:", - "ANONYMOUS::bind:cn=admin,dc=gobottin,dc=eu:", - "*,dc=gobottin,dc=eu::read:*:* !userpassword", + "ANONYMOUS::bind:*,ou=users,dc=bottin,dc=eu:", + "ANONYMOUS::bind:cn=admin,dc=bottin,dc=eu:", + "*,dc=bottin,dc=eu::read:*:* !userpassword", "*::read modify:SELF:*", - "cn=admin,dc=gobottin,dc=eu::read add modify delete:*:*", - "*:cn=admin,ou=groups,dc=gobottin,dc=eu:read add modify delete:*:*" + "cn=admin,dc=bottin,dc=eu::read add modify delete:*:*", + "*:cn=admin,ou=groups,dc=bottin,dc=eu:read add modify delete:*:*" ] } diff --git a/gobottin.hcl.example b/gobottin.hcl.example deleted file mode 100644 index ac42b06..0000000 --- a/gobottin.hcl.example +++ /dev/null @@ -1,60 +0,0 @@ -job "directory" { - datacenters = ["dc1"] - type = "service" - - constraint { - attribute = "${attr.cpu.arch}" - value = "amd64" - } - - group "ldap" { - count = 2 - task "server" { - driver = "docker" - config { - image = "lxpz/gobottin_amd64:12" - readonly_rootfs = true - port_map { - ldap_port = 389 - } - volumes = [ - "secrets/config.json:/config.json" - ] - } - - artifact { - source = "http://127.0.0.1:8500/v1/kv/configuration/directory/gobottin/config.json?raw" - destination = "secrets/config.json" - mode = "file" - } - - resources { - memory = 100 - network { - port "ldap_port" { - static = "389" - } - } - } - - service { - tags = ["bottin"] - port = "ldap_port" - address_mode = "host" - name = "bottin" - check { - type = "tcp" - port = "ldap_port" - interval = "60s" - timeout = "5s" - check_restart { - limit = 3 - grace = "90s" - ignore_warnings = false - } - } - } - } - } -} - diff --git a/main.go b/main.go index 174bde6..05a2a19 100644 --- a/main.go +++ b/main.go @@ -140,13 +140,13 @@ func main() { } kv := consul_client.KV() - // Create gobottin server - gobottin := Server{ - logger: log.New(os.Stdout, "[gobottin] ", log.LstdFlags), + // Create bottin server + bottin := Server{ + logger: log.New(os.Stdout, "[bottin] ", log.LstdFlags), config: config, kv: kv, } - err = gobottin.init() + err = bottin.init() if err != nil { panic(err) } @@ -154,15 +154,15 @@ func main() { // Create routes routes := ldap.NewRouteMux() - routes.Bind(gobottin.handleBind) - routes.Search(gobottin.handleSearch) - routes.Add(gobottin.handleAdd) - routes.Compare(gobottin.handleCompare) - routes.Delete(gobottin.handleDelete) - routes.Modify(gobottin.handleModify) + routes.Bind(bottin.handleBind) + routes.Search(bottin.handleSearch) + routes.Add(bottin.handleAdd) + routes.Compare(bottin.handleCompare) + routes.Delete(bottin.handleDelete) + routes.Modify(bottin.handleModify) if config.TLSConfig != nil { - routes.Extended(gobottin.handleStartTLS). + routes.Extended(bottin.handleStartTLS). RequestName(ldap.NoticeOfStartTLS).Label("StartTLS") } @@ -173,7 +173,7 @@ func main() { if config.Bind != "" { ldapServer = ldap.NewServer() ldapServer.Handle(routes) - ldapServer.NewUserState = gobottin.newUserState + ldapServer.NewUserState = bottin.newUserState go func() { err := ldapServer.ListenAndServe(config.Bind) if err != nil { @@ -187,7 +187,7 @@ func main() { if config.TLSConfig != nil { ldapServerSecure := ldap.NewServer() ldapServerSecure.Handle(routes) - ldapServerSecure.NewUserState = gobottin.newUserState + ldapServerSecure.NewUserState = bottin.newUserState secureConn := func(s *ldap.Server) { s.Listener = tls.NewListener(s.Listener, config.TLSConfig) } -- cgit v1.2.3