Fix #4: Try to reconnect when there is network problem
This commit is contained in:
parent
9b7d526d85
commit
c48c508be8
2
build
2
build
|
@ -3,7 +3,7 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
base='docker.io/tpimenta/nginx-ldap-auth'
|
base='docker.io/tpimenta/nginx-ldap-auth'
|
||||||
version='v1.0.2'
|
version='v1.0.3'
|
||||||
image="$base:$version"
|
image="$base:$version"
|
||||||
|
|
||||||
atexit() {
|
atexit() {
|
||||||
|
|
|
@ -19,7 +19,7 @@ func (p *Pool) Connect() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.conn != nil {
|
if p.conn != nil {
|
||||||
return nil
|
p.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
address := fmt.Sprintf("%s:%d", p.url, p.port)
|
address := fmt.Sprintf("%s:%d", p.url, p.port)
|
||||||
|
@ -37,6 +37,11 @@ func (p *Pool) Connect() error {
|
||||||
err = conn.StartTLS(&tls.Config{InsecureSkipVerify: true})
|
err = conn.StartTLS(&tls.Config{InsecureSkipVerify: true})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("It was not possble to start TLS, falling back to plain: %v.\n", err)
|
log.Printf("It was not possble to start TLS, falling back to plain: %v.\n", err)
|
||||||
|
conn.Close()
|
||||||
|
conn, err = ldap.Dial("tcp", address)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p.conn = conn
|
p.conn = conn
|
||||||
}
|
}
|
||||||
|
|
20
ldap/jail.go
Normal file
20
ldap/jail.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package ldap
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
ldap "gopkg.in/ldap.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *Pool) networkJail(f func() error) error {
|
||||||
|
err := f()
|
||||||
|
if err != nil && ldap.IsErrorWithCode(err, ldap.ErrorNetwork) {
|
||||||
|
log.Printf("Network problem, trying to reconnect once: %v.\n", err)
|
||||||
|
err = p.Connect()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = f()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
|
@ -10,7 +10,9 @@ func (p *Pool) Validate(username, password string) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
p.admin = false
|
p.admin = false
|
||||||
err = p.conn.Bind(username, password)
|
err = p.networkJail(func() error {
|
||||||
|
return p.conn.Bind(username, password)
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, err
|
return true, err
|
||||||
}
|
}
|
||||||
|
@ -28,7 +30,9 @@ func (p *Pool) auth() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := p.conn.Bind(p.username, p.password)
|
err := p.networkJail(func() error {
|
||||||
|
return p.conn.Bind(p.username, p.password)
|
||||||
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
p.admin = true
|
p.admin = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,22 +21,27 @@ func (p *Pool) Search(base, filter string, attr string) (bool, string, []string,
|
||||||
list = []string{attr}
|
list = []string{attr}
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := p.conn.Search(ldap.NewSearchRequest(
|
var res *ldap.SearchResult
|
||||||
base,
|
err = p.networkJail(func() error {
|
||||||
ldap.ScopeWholeSubtree,
|
res, err = p.conn.Search(ldap.NewSearchRequest(
|
||||||
ldap.NeverDerefAliases,
|
base,
|
||||||
0,
|
ldap.ScopeWholeSubtree,
|
||||||
0,
|
ldap.NeverDerefAliases,
|
||||||
false,
|
0,
|
||||||
filter,
|
0,
|
||||||
list,
|
false,
|
||||||
nil,
|
filter,
|
||||||
))
|
list,
|
||||||
|
nil,
|
||||||
|
))
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, "", nil, err
|
return false, "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(res.Entries) == 0 {
|
if res == nil || len(res.Entries) == 0 {
|
||||||
return true, "", nil, fmt.Errorf("No results for %s filter %s", base, filter)
|
return true, "", nil, fmt.Errorf("No results for %s filter %s", base, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ func (p *Service) Validate(username, password string) bool {
|
||||||
|
|
||||||
ok, err := p.validate(username, password)
|
ok, err := p.validate(username, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Could not validade user %s: %v\n", username, err)
|
log.Printf("Could not validate user %s: %v\n", username, err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
44
test-server
Executable file
44
test-server
Executable file
|
@ -0,0 +1,44 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
for name in ldap-test-server ldap-test-client; do
|
||||||
|
if docker ps -a --format '{{.Names}}' | egrep -q "^${name}\$"; then
|
||||||
|
docker rm -f "$name" || :
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
docker run \
|
||||||
|
-p 389:389 \
|
||||||
|
-p 636:636 \
|
||||||
|
--name ldap-test-server \
|
||||||
|
-d \
|
||||||
|
osixia/openldap:1.2.2
|
||||||
|
|
||||||
|
# docker exec ldap-test-server ldapsearch -x -H ldap://localhost -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w admin
|
||||||
|
|
||||||
|
cat > /tmp/config.yaml <<EOF
|
||||||
|
web: 0.0.0.0:5555
|
||||||
|
path: /
|
||||||
|
servers:
|
||||||
|
- ldap://$(hostname -I | cut -d\ -f1)
|
||||||
|
auth:
|
||||||
|
bindDN: cn=admin,dc=example,dc=org
|
||||||
|
bindPW: admin
|
||||||
|
user:
|
||||||
|
baseDN: dc=example,dc=org
|
||||||
|
filter: "(cn={0})"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
while ! nc -z -w5 127.0.0.1 389; do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
docker run \
|
||||||
|
-p 5555:5555 \
|
||||||
|
-v '/tmp/config.yaml:/etc/nginx-ldap-auth/config.yaml:ro' \
|
||||||
|
--name ldap-test-client \
|
||||||
|
-d \
|
||||||
|
docker.io/tpimenta/nginx-ldap-auth:v1.0.3
|
Reference in a new issue