|
1 | 1 | package app |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "crypto/tls" |
| 5 | + "crypto/x509" |
4 | 6 | "fmt" |
| 7 | + "os" |
| 8 | + "strings" |
5 | 9 |
|
6 | 10 | "github.com/go-playground/validator/v10" |
7 | 11 | "github.com/langgenius/dify-plugin-daemon/pkg/entities/plugin_entities" |
@@ -69,7 +73,7 @@ type Config struct { |
69 | 73 | HuaweiOBSAccessKey string `envconfig:"HUAWEI_OBS_ACCESS_KEY"` |
70 | 74 | HuaweiOBSSecretKey string `envconfig:"HUAWEI_OBS_SECRET_KEY"` |
71 | 75 | HuaweiOBSServer string `envconfig:"HUAWEI_OBS_SERVER"` |
72 | | - HuaweiOBSPathStyle bool `envconfig:"HUAWEI_OBS_PATH_STYLE" default:"false"` |
| 76 | + HuaweiOBSPathStyle bool `envconfig:"HUAWEI_OBS_PATH_STYLE" default:"false"` |
73 | 77 |
|
74 | 78 | // volcengine tos |
75 | 79 | VolcengineTOSEndpoint string `envconfig:"VOLCENGINE_TOS_ENDPOINT"` |
@@ -110,12 +114,14 @@ type Config struct { |
110 | 114 | RoutinePoolSize int `envconfig:"ROUTINE_POOL_SIZE" validate:"required"` |
111 | 115 |
|
112 | 116 | // redis |
113 | | - RedisHost string `envconfig:"REDIS_HOST"` |
114 | | - RedisPort uint16 `envconfig:"REDIS_PORT"` |
115 | | - RedisPass string `envconfig:"REDIS_PASSWORD"` |
116 | | - RedisUser string `envconfig:"REDIS_USERNAME"` |
117 | | - RedisUseSsl bool `envconfig:"REDIS_USE_SSL"` |
118 | | - RedisDB int `envconfig:"REDIS_DB"` |
| 117 | + RedisHost string `envconfig:"REDIS_HOST"` |
| 118 | + RedisPort uint16 `envconfig:"REDIS_PORT"` |
| 119 | + RedisPass string `envconfig:"REDIS_PASSWORD"` |
| 120 | + RedisUser string `envconfig:"REDIS_USERNAME"` |
| 121 | + RedisDB int `envconfig:"REDIS_DB"` |
| 122 | + RedisUseSsl bool `envconfig:"REDIS_USE_SSL"` |
| 123 | + RedisSSLCertReqs string `envconfig:"REDIS_SSL_CERT_REQS"` |
| 124 | + RedisSSLCACerts string `envconfig:"REDIS_SSL_CA_CERTS"` |
119 | 125 |
|
120 | 126 | // redis sentinel |
121 | 127 | RedisUseSentinel bool `envconfig:"REDIS_USE_SENTINEL"` |
@@ -282,6 +288,54 @@ func (c *Config) GetLocalRuntimeMaxBufferSize() int { |
282 | 288 | return c.PluginRuntimeMaxBufferSize |
283 | 289 | } |
284 | 290 |
|
| 291 | +// RedisTLSConfig builds a *tls.Config for Redis based on envs. |
| 292 | +func (c *Config) RedisTLSConfig() (*tls.Config, error) { |
| 293 | + if !c.RedisUseSsl { |
| 294 | + return nil, nil |
| 295 | + } |
| 296 | + |
| 297 | + tlsConf := &tls.Config{ |
| 298 | + MinVersion: tls.VersionTLS12, |
| 299 | + } |
| 300 | + |
| 301 | + // Load custom CA certificates if provided |
| 302 | + if strings.TrimSpace(c.RedisSSLCACerts) != "" { |
| 303 | + pem, err := os.ReadFile(c.RedisSSLCACerts) |
| 304 | + if err != nil { |
| 305 | + return nil, fmt.Errorf("read REDIS_SSL_CA_CERTS: %w", err) |
| 306 | + } |
| 307 | + pool := x509.NewCertPool() |
| 308 | + if !pool.AppendCertsFromPEM(pem) { |
| 309 | + return nil, fmt.Errorf("failed to append CA certs from %s", c.RedisSSLCACerts) |
| 310 | + } |
| 311 | + tlsConf.RootCAs = pool |
| 312 | + } |
| 313 | + |
| 314 | + // Configure certificate verification based on REDIS_SSL_CERT_REQS |
| 315 | + certReqs := strings.ToUpper(strings.TrimSpace(c.RedisSSLCertReqs)) |
| 316 | + switch certReqs { |
| 317 | + case "CERT_NONE": |
| 318 | + // Skip all certificate verification (insecure) |
| 319 | + tlsConf.InsecureSkipVerify = true |
| 320 | + case "CERT_OPTIONAL", "CERT_REQUIRED", "": |
| 321 | + // Require valid certificate verification (default and most secure) |
| 322 | + // CERT_OPTIONAL is treated as CERT_REQUIRED for client-side TLS, |
| 323 | + // as servers almost always present certificates and the client's |
| 324 | + // choice is whether to validate them or not |
| 325 | + tlsConf.InsecureSkipVerify = false |
| 326 | + |
| 327 | + // Require CA certs to be explicitly provided when CERT_REQUIRED is set |
| 328 | + if certReqs == "CERT_REQUIRED" && strings.TrimSpace(c.RedisSSLCACerts) == "" { |
| 329 | + return nil, fmt.Errorf("REDIS_SSL_CA_CERTS must be provided when REDIS_SSL_CERT_REQS is set to CERT_REQUIRED") |
| 330 | + } |
| 331 | + default: |
| 332 | + // Invalid value - return an error instead of silently defaulting |
| 333 | + return nil, fmt.Errorf("invalid REDIS_SSL_CERT_REQS value: %s (valid options: CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED)", certReqs) |
| 334 | + } |
| 335 | + |
| 336 | + return tlsConf, nil |
| 337 | +} |
| 338 | + |
285 | 339 | type PlatformType string |
286 | 340 |
|
287 | 341 | const ( |
|
0 commit comments