forked from Deuxfleurs/bottin
Allow for both TLS and non-TLS connections
This commit is contained in:
parent
66c6479770
commit
dce432426e
3 changed files with 100 additions and 58 deletions
34
README.md
34
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
|
||||
|
||||
|
|
|
@ -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:",
|
||||
|
|
92
main.go
92
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
|
||||
Bind string
|
||||
BindSecure string
|
||||
ConsulHost string
|
||||
|
||||
Acl ACL
|
||||
|
||||
TLSConfig *tls.Config
|
||||
UseStartTLS bool
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -91,10 +92,10 @@ func readConfig() Config {
|
|||
|
||||
ret := Config{
|
||||
Suffix: config_file.Suffix,
|
||||
BindAddress: config_file.BindAddress,
|
||||
Bind: config_file.Bind,
|
||||
BindSecure: config_file.BindSecure,
|
||||
ConsulHost: config_file.ConsulHost,
|
||||
Acl: acl,
|
||||
UseStartTLS: config_file.UseStartTLS,
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// 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)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
ldapserver.Stop()
|
||||
}()
|
||||
|
||||
if config.TLSConfig != nil && !config.UseStartTLS {
|
||||
secureConn := func(s *ldap.Server) {
|
||||
s.Listener = tls.NewListener(s.Listener, config.TLSConfig)
|
||||
if ldapServer != nil {
|
||||
ldapServer.Stop()
|
||||
}
|
||||
err = ldapserver.ListenAndServe(config.BindAddress, secureConn)
|
||||
} else {
|
||||
err = ldapserver.ListenAndServe(config.BindAddress)
|
||||
if ldapServerSecure != nil {
|
||||
ldapServerSecure.Stop()
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
func (server *Server) newUserState() ldap.UserState {
|
||||
return &State{
|
||||
login: Login{
|
||||
user: "ANONYMOUS",
|
||||
groups: []string{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue