Browse Source

Rebrand to Bottin (with Superboum's benediction)

pull/1/head
Alex 8 months ago
parent
commit
7962e7b262
7 changed files with 55 additions and 55 deletions
  1. +2
    -2
      .gitignore
  2. +2
    -2
      Dockerfile
  3. +10
    -10
      Makefile
  4. +20
    -20
      README.md
  5. +2
    -2
      bottin.hcl.example
  6. +6
    -6
      config.json.example
  7. +13
    -13
      main.go

+ 2
- 2
.gitignore View File

@@ -1,3 +1,3 @@
gobottin
gobottin.static
bottin
bottin.static
config.json

+ 2
- 2
Dockerfile View File

@@ -1,5 +1,5 @@
FROM scratch

ADD gobottin.static /gobottin
ADD bottin.static /bottin

ENTRYPOINT ["/gobottin"]
ENTRYPOINT ["/bottin"]

+ 10
- 10
Makefile View File

@@ -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

+ 20
- 20
README.md View File

@@ -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 <filename>`, which is the
Bottin 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.
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:*:*`

gobottin.hcl.example → bottin.hcl.example View File

@@ -12,7 +12,7 @@ job "directory" {
task "server" {
driver = "docker"
config {
image = "lxpz/gobottin_amd64:12"
image = "lxpz/bottin_amd64:12"
readonly_rootfs = true
port_map {
ldap_port = 389
@@ -23,7 +23,7 @@ job "directory" {
}

artifact {
source = "http://127.0.0.1:8500/v1/kv/configuration/directory/gobottin/config.json?raw"
source = "http://127.0.0.1:8500/v1/kv/configuration/directory/bottin/config.json?raw"
destination = "secrets/config.json"
mode = "file"
}

+ 6
- 6
config.json.example View File

@@ -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:*:*"
]
}


+ 13
- 13
main.go View File

@@ -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)
}


Loading…
Cancel
Save