From 2dd442c24dad7c1a3a6b0be3251305fcb2ed1050 Mon Sep 17 00:00:00 2001 From: madic-creates <3735459+madic-creates@users.noreply.github.com> Date: Fri, 17 Oct 2025 17:37:35 +0200 Subject: [PATCH] Allow self-signed certificates --- auth/iam.go | 3 +- auth/iam_ldap.go | 83 ++++++++++++++++++++++++++++--------------- cmd/versitygw/main.go | 8 +++++ extra/example.conf | 5 +++ 4 files changed, 69 insertions(+), 30 deletions(-) diff --git a/auth/iam.go b/auth/iam.go index bcb9ad6..bd13d84 100644 --- a/auth/iam.go +++ b/auth/iam.go @@ -119,6 +119,7 @@ type Opts struct { LDAPRoleAtr string LDAPUserIdAtr string LDAPGroupIdAtr string + LDAPTLSSkipVerify bool VaultEndpointURL string VaultNamespace string VaultSecretStoragePath string @@ -159,7 +160,7 @@ func New(o *Opts) (IAMService, error) { case o.LDAPServerURL != "": svc, err = NewLDAPService(o.RootAccount, o.LDAPServerURL, o.LDAPBindDN, o.LDAPPassword, o.LDAPQueryBase, o.LDAPAccessAtr, o.LDAPSecretAtr, o.LDAPRoleAtr, o.LDAPUserIdAtr, - o.LDAPGroupIdAtr, o.LDAPObjClasses) + o.LDAPGroupIdAtr, o.LDAPObjClasses, o.LDAPTLSSkipVerify) fmt.Printf("initializing LDAP IAM with %q\n", o.LDAPServerURL) case o.S3Endpoint != "": svc, err = NewS3(o.RootAccount, o.S3Access, o.S3Secret, o.S3Region, o.S3Bucket, diff --git a/auth/iam_ldap.go b/auth/iam_ldap.go index c16d862..27cabc8 100644 --- a/auth/iam_ldap.go +++ b/auth/iam_ldap.go @@ -15,7 +15,9 @@ package auth import ( + "crypto/tls" "fmt" + "net/url" "strconv" "strings" "sync" @@ -26,57 +28,80 @@ import ( ) type LdapIAMService struct { - conn *ldap.Conn - queryBase string - objClasses []string - accessAtr string - secretAtr string - roleAtr string - groupIdAtr string - userIdAtr string - rootAcc Account - url string - bindDN string - pass string - mu sync.Mutex + conn *ldap.Conn + queryBase string + objClasses []string + accessAtr string + secretAtr string + roleAtr string + groupIdAtr string + userIdAtr string + rootAcc Account + url string + bindDN string + pass string + tlsSkipVerify bool + mu sync.Mutex } var _ IAMService = &LdapIAMService{} -func NewLDAPService(rootAcc Account, url, bindDN, pass, queryBase, accAtr, secAtr, roleAtr, userIdAtr, groupIdAtr, objClasses string) (IAMService, error) { - if url == "" || bindDN == "" || pass == "" || queryBase == "" || accAtr == "" || +func NewLDAPService(rootAcc Account, ldapURL, bindDN, pass, queryBase, accAtr, secAtr, roleAtr, userIdAtr, groupIdAtr, objClasses string, tlsSkipVerify bool) (IAMService, error) { + if ldapURL == "" || bindDN == "" || pass == "" || queryBase == "" || accAtr == "" || secAtr == "" || roleAtr == "" || userIdAtr == "" || groupIdAtr == "" || objClasses == "" { return nil, fmt.Errorf("required parameters list not fully provided") } - conn, err := ldap.DialURL(url) + + conn, err := dialLDAP(ldapURL, tlsSkipVerify) if err != nil { return nil, fmt.Errorf("failed to connect to LDAP server: %w", err) } err = conn.Bind(bindDN, pass) if err != nil { + conn.Close() return nil, fmt.Errorf("failed to bind to LDAP server %w", err) } return &LdapIAMService{ - conn: conn, - queryBase: queryBase, - objClasses: strings.Split(objClasses, ","), - accessAtr: accAtr, - secretAtr: secAtr, - roleAtr: roleAtr, - userIdAtr: userIdAtr, - groupIdAtr: groupIdAtr, - rootAcc: rootAcc, - url: url, - bindDN: bindDN, - pass: pass, + conn: conn, + queryBase: queryBase, + objClasses: strings.Split(objClasses, ","), + accessAtr: accAtr, + secretAtr: secAtr, + roleAtr: roleAtr, + userIdAtr: userIdAtr, + groupIdAtr: groupIdAtr, + rootAcc: rootAcc, + url: ldapURL, + bindDN: bindDN, + pass: pass, + tlsSkipVerify: tlsSkipVerify, }, nil } +// dialLDAP establishes an LDAP connection with optional TLS configuration +func dialLDAP(ldapURL string, tlsSkipVerify bool) (*ldap.Conn, error) { + u, err := url.Parse(ldapURL) + if err != nil { + return nil, fmt.Errorf("invalid LDAP URL: %w", err) + } + + // For ldaps:// URLs, use DialURL with custom TLS config if needed + if u.Scheme == "ldaps" && tlsSkipVerify { + tlsConfig := &tls.Config{ + InsecureSkipVerify: tlsSkipVerify, + } + return ldap.DialURL(ldapURL, ldap.DialWithTLSConfig(tlsConfig)) + } + + // For ldap:// or when TLS verification is enabled, use standard DialURL + return ldap.DialURL(ldapURL) +} + func (ld *LdapIAMService) reconnect() error { ld.conn.Close() - conn, err := ldap.DialURL(ld.url) + conn, err := dialLDAP(ld.url, ld.tlsSkipVerify) if err != nil { return fmt.Errorf("failed to reconnect to LDAP server: %w", err) } diff --git a/cmd/versitygw/main.go b/cmd/versitygw/main.go index a1e5990..aa4f37a 100644 --- a/cmd/versitygw/main.go +++ b/cmd/versitygw/main.go @@ -65,6 +65,7 @@ var ( ldapQueryBase, ldapObjClasses string ldapAccessAtr, ldapSecAtr, ldapRoleAtr string ldapUserIdAtr, ldapGroupIdAtr string + ldapTLSSkipVerify bool vaultEndpointURL, vaultNamespace string vaultSecretStoragePath string vaultSecretStorageNamespace string @@ -404,6 +405,12 @@ func initFlags() []cli.Flag { EnvVars: []string{"VGW_IAM_LDAP_GROUP_ID_ATR"}, Destination: &ldapGroupIdAtr, }, + &cli.BoolFlag{ + Name: "iam-ldap-tls-skip-verify", + Usage: "disable TLS certificate verification for LDAP connections (insecure, for self-signed certificates)", + EnvVars: []string{"VGW_IAM_LDAP_TLS_SKIP_VERIFY"}, + Destination: &ldapTLSSkipVerify, + }, &cli.StringFlag{ Name: "iam-vault-endpoint-url", Usage: "vault server url", @@ -692,6 +699,7 @@ func runGateway(ctx context.Context, be backend.Backend) error { LDAPRoleAtr: ldapRoleAtr, LDAPUserIdAtr: ldapUserIdAtr, LDAPGroupIdAtr: ldapGroupIdAtr, + LDAPTLSSkipVerify: ldapTLSSkipVerify, VaultEndpointURL: vaultEndpointURL, VaultNamespace: vaultNamespace, VaultSecretStoragePath: vaultSecretStoragePath, diff --git a/extra/example.conf b/extra/example.conf index 95bc444..7477fb3 100644 --- a/extra/example.conf +++ b/extra/example.conf @@ -279,6 +279,11 @@ ROOT_SECRET_ACCESS_KEY= #VGW_IAM_LDAP_ROLE_ATR= #VGW_IAM_LDAP_USER_ID_ATR= #VGW_IAM_LDAP_GROUP_ID_ATR= +# Disable TLS certificate verification for LDAP connections (insecure, allows +# self-signed certificates). This should only be used in testing environments +# or when using self-signed certificates. The default is false (verification +# enabled). +#VGW_IAM_LDAP_TLS_SKIP_VERIFY=false # The FreeIPA options will enable the FreeIPA IAM service with accounts stored # in an external FreeIPA service. Currently the FreeIPA IAM service only