aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2020-01-27 16:32:39 +0100
committerAlex Auvolat <alex@adnab.me>2020-01-27 16:32:39 +0100
commitdce432426e325ab43757da9485c612421c912957 (patch)
treec0c545881343db783369de26fd55530facc81e75
parent66c64797706a2e62424c3523564b99f0597cde03 (diff)
downloadbottin-dce432426e325ab43757da9485c612421c912957.tar.gz
bottin-dce432426e325ab43757da9485c612421c912957.zip
Allow for both TLS and non-TLS connections
-rw-r--r--README.md34
-rw-r--r--config.json.example2
-rw-r--r--main.go118
3 files changed, 98 insertions, 56 deletions
diff --git a/README.md b/README.md
index 259c234..5a696e7 100644
--- a/README.md
+++ b/README.md
@@ -44,25 +44,39 @@ suffix in the `suffix` key of the json config file.
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
+## Bind addresses
-By default, `gobottin` listens on all interfaces on port 389.
-Change this by setting the `bind_address` key in the json config file.
+### Insecure port
+
+By default, `gobottin` 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.
+
+### Secure port
+
+If a TLS configuration is provided (see next section), `gobottin` 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`
+will not listen for TLS connections.
## 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:
+`gobottin` 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:
- `tls_server_name`: the host name that clients will use to reach your LDAP server
- `tls_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.
+If a TLS configuration is provided, the `STARTTLS` mechanism may be used on the
+insecure port, independently of whether the secure port is enabled or not.
+
+The secure port is disabled and a warning is shown if the `bind_secure` value
+is set (non-empty) and no valid TLS configuration is provided.
## Access control list
diff --git a/config.json.example b/config.json.example
index f4c2781..4249e26 100644
--- a/config.json.example
+++ b/config.json.example
@@ -1,6 +1,6 @@
{
"suffix": "dc=gobottin,dc=eu",
- "bind_address": "127.0.0.1:10389",
+ "bind": "127.0.0.1:1389",
"acl": [
"ANONYMOUS::bind:*,ou=users,dc=gobottin,dc=eu:",
"ANONYMOUS::bind:cn=admin,dc=gobottin,dc=eu:",
diff --git a/main.go b/main.go
index 88ea3dd..a8acc18 100644
--- a/main.go
+++ b/main.go
@@ -35,24 +35,24 @@ const ATTR_MODIFYTIMESTAMP = "modifytimestamp"
type ConfigFile struct {
Suffix string `json:"suffix"`
- BindAddress string `json:"bind_address"`
+ Bind string `json:"bind"`
+ BindSecure string `json:"bind_secure"`
ConsulHost string `json:"consul_host"`
Acl []string `json:"acl"`
TLSCertFile string `json:"tls_cert_file"`
TLSKeyFile string `json:"tls_key_file"`
TLSServerName string `json:"tls_server_name"`
- UseStartTLS bool `json:"use_starttls"`
}
type Config struct {
- Suffix string
- BindAddress string
- ConsulHost string
+ Suffix string
+ Bind string
+ BindSecure string
+ ConsulHost string
Acl ACL
- TLSConfig *tls.Config
- UseStartTLS bool
+ TLSConfig *tls.Config
}
type Server struct {
@@ -71,7 +71,8 @@ var configFlag = flag.String("config", "./config.json", "Configuration file path
func readConfig() Config {
config_file := ConfigFile{
- BindAddress: "0.0.0.0:389",
+ Bind: "0.0.0.0:389",
+ BindSecure: "0.0.0.0:636",
}
bytes, err := ioutil.ReadFile(*configFlag)
@@ -90,11 +91,11 @@ func readConfig() Config {
}
ret := Config{
- Suffix: config_file.Suffix,
- BindAddress: config_file.BindAddress,
- ConsulHost: config_file.ConsulHost,
- Acl: acl,
- UseStartTLS: config_file.UseStartTLS,
+ Suffix: config_file.Suffix,
+ Bind: config_file.Bind,
+ BindSecure: config_file.BindSecure,
+ ConsulHost: config_file.ConsulHost,
+ Acl: acl,
}
if config_file.TLSCertFile != "" && config_file.TLSKeyFile != "" && config_file.TLSServerName != "" {
@@ -116,8 +117,6 @@ func readConfig() Config {
Certificates: []tls.Certificate{cert},
ServerName: config_file.TLSServerName,
}
- } else {
- log.Printf("Warning: no TLS configuration provided, running an insecure server.")
}
return ret
@@ -152,17 +151,7 @@ func main() {
panic(err)
}
- //Create a new LDAP Server
- ldapserver := ldap.NewServer()
- ldapserver.NewUserState = func() ldap.UserState {
- return &State{
- login: Login{
- user: "ANONYMOUS",
- groups: []string{},
- },
- }
- }
-
+ // Create routes
routes := ldap.NewRouteMux()
routes.Bind(gobottin.handleBind)
@@ -172,33 +161,72 @@ func main() {
routes.Delete(gobottin.handleDelete)
routes.Modify(gobottin.handleModify)
- if config.TLSConfig != nil && config.UseStartTLS {
+ if config.TLSConfig != nil {
routes.Extended(gobottin.handleStartTLS).
RequestName(ldap.NoticeOfStartTLS).Label("StartTLS")
}
- ldapserver.Handle(routes)
+ // Create LDAP servers
+ var ldapServer, ldapServerSecure *ldap.Server = nil, nil
- go func() {
- // When CTRL+C, SIGINT and SIGTERM signal occurs
- // Then stop server gracefully
- ch := make(chan os.Signal)
- signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
- <-ch
- close(ch)
- ldapserver.Stop()
- }()
+ // Bind on standard LDAP port without TLS
+ if config.Bind != "" {
+ ldapServer = ldap.NewServer()
+ ldapServer.Handle(routes)
+ ldapServer.NewUserState = gobottin.newUserState
+ go func() {
+ err := ldapServer.ListenAndServe(config.Bind)
+ if err != nil {
+ panic(err)
+ }
+ }()
+ }
- if config.TLSConfig != nil && !config.UseStartTLS {
- secureConn := func(s *ldap.Server) {
- s.Listener = tls.NewListener(s.Listener, config.TLSConfig)
+ // Bind on LDAP secure port with TLS
+ if config.BindSecure != "" {
+ if config.TLSConfig != nil {
+ ldapServerSecure := ldap.NewServer()
+ ldapServerSecure.Handle(routes)
+ ldapServerSecure.NewUserState = gobottin.newUserState
+ secureConn := func(s *ldap.Server) {
+ s.Listener = tls.NewListener(s.Listener, config.TLSConfig)
+ }
+ go func() {
+ err := ldapServerSecure.ListenAndServe(config.BindSecure, secureConn)
+ if err != nil {
+ panic(err)
+ }
+ }()
+ } else {
+ fmt.Printf("Warning: no valid TLS configuration was provided, not binding on %s", config.BindSecure)
}
- err = ldapserver.ListenAndServe(config.BindAddress, secureConn)
- } else {
- err = ldapserver.ListenAndServe(config.BindAddress)
}
- if err != nil {
- panic(err)
+
+ if ldapServer == nil && ldapServerSecure == nil {
+ panic("Not doing anything.")
+ }
+
+ // When CTRL+C, SIGINT and SIGTERM signal occurs
+ // Then stop server gracefully
+ ch := make(chan os.Signal)
+ signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
+ <-ch
+ close(ch)
+
+ if ldapServer != nil {
+ ldapServer.Stop()
+ }
+ if ldapServerSecure != nil {
+ ldapServerSecure.Stop()
+ }
+}
+
+func (server *Server) newUserState() ldap.UserState {
+ return &State{
+ login: Login{
+ user: "ANONYMOUS",
+ groups: []string{},
+ },
}
}