diff --git a/codis/admin/codis-fe-admin.sh b/codis/admin/codis-fe-admin.sh index b9e6872446..7ca15d76ea 100755 --- a/codis/admin/codis-fe-admin.sh +++ b/codis/admin/codis-fe-admin.sh @@ -18,6 +18,9 @@ CODIS_FE_DAEMON_FILE=$CODIS_LOG_DIR/codis-fe.out COORDINATOR_NAME="filesystem" COORDINATOR_ADDR="/tmp/codis" CODIS_FE_ADDR="0.0.0.0:9090" +CODIS_FE_TLS=1 +CODIS_FE_TLS_KEY="/usr/local/src/pika/codis/key.pem" +CODIS_FE_TLS_CERT="/usr/local/src/pika/codis/cert.pem" echo $CODIS_FE_CONF_FILE @@ -36,7 +39,7 @@ start) fi fi nohup "$CODIS_FE_BIN" "--assets-dir=${CODIS_FE_ASSETS_DIR}" "--$COORDINATOR_NAME=$COORDINATOR_ADDR" \ - "--log=$CODIS_FE_LOG_FILE" "--pidfile=$CODIS_FE_PID_FILE" "--log-level=INFO" "--listen=$CODIS_FE_ADDR" > "$CODIS_FE_DAEMON_FILE" 2>&1 < /dev/null & + "--tls=$CODIS_FE_TLS" "--tls-key=$CODIS_FE_TLS_KEY" "--tls-cert=$CODIS_FE_TLS_CERT" "--log=$CODIS_FE_LOG_FILE" "--pidfile=$CODIS_FE_PID_FILE" "--log-level=INFO" "--listen=$CODIS_FE_ADDR" > "$CODIS_FE_DAEMON_FILE" 2>&1 < /dev/null & ;; start-foreground) $CODIS_FE_BIN "--assets-dir=${CODIS_FE_ASSETS_DIR}" "--$COORDINATOR_NAME=$COORDINATOR_ADDR" \ diff --git a/codis/cmd/fe/main.go b/codis/cmd/fe/main.go index 663cc47086..c7e04879c9 100644 --- a/codis/cmd/fe/main.go +++ b/codis/cmd/fe/main.go @@ -4,6 +4,7 @@ package main import ( + "crypto/tls" "encoding/json" "fmt" "io/ioutil" @@ -56,7 +57,7 @@ func init() { func main() { const usage = ` Usage: - codis-fe [--ncpu=N] [--log=FILE] [--log-level=LEVEL] [--assets-dir=PATH] [--pidfile=FILE] (--dashboard-list=FILE|--zookeeper=ADDR [--zookeeper-auth=USR:PWD]|--etcd=ADDR [--etcd-auth=USR:PWD]|--filesystem=ROOT) --listen=ADDR + codis-fe [--ncpu=N] [--log=FILE] [--log-level=LEVEL] [--assets-dir=PATH] [--pidfile=FILE] (--dashboard-list=FILE|--zookeeper=ADDR [--zookeeper-auth=USR:PWD]|--etcd=ADDR [--etcd-auth=USR:PWD]|--filesystem=ROOT) --listen=ADDR [--tls-cert=FILE] [--tls-key=FILE] [--tls=N] codis-fe --version Options: @@ -196,10 +197,42 @@ Options: m.MapTo(r, (*martini.Routes)(nil)) m.Action(r.Handle) - l, err := net.Listen("tcp", listen) - if err != nil { - log.PanicErrorf(err, "listen %s failed", listen) + var l net.Listener + + if n, ok := utils.ArgumentInteger(d, "--tls"); ok && n == 1 { + + // Load server certificate and key + certFile, keyFile := utils.ArgumentMust(d, "--tls-cert"), utils.ArgumentMust(d, "--tls-key") + if certFile == "" || keyFile == "" { + log.Panic("TLS certificate or key file path must be provided") + } + cert, err := tls.LoadX509KeyPair(certFile, keyFile) + if err != nil { + log.PanicErrorf(err, "failed to load key pair: %s", err) + } + + // Create a TLS config + tlsConfig := &tls.Config{ + Certificates: []tls.Certificate{cert}, + } + + // Create a TLS listener + l, err = tls.Listen("tcp", listen, tlsConfig) + if err != nil { + log.PanicErrorf(err, "listen %s failed", listen) + } + + + }else{ + + l, err = net.Listen("tcp", listen) + if err != nil { + log.PanicErrorf(err, "listen %s failed", listen) + } + } + + defer l.Close() if s, ok := utils.Argument(d, "--pidfile"); ok { diff --git a/codis/config/proxy.toml b/codis/config/proxy.toml index 5f46885413..0a28d77dae 100644 --- a/codis/config/proxy.toml +++ b/codis/config/proxy.toml @@ -21,6 +21,9 @@ admin_addr = "0.0.0.0:11080" # Set bind address for proxy, proto_type can be "tcp", "tcp4", "tcp6", "unix" or "unixpacket". proto_type = "tcp4" +#proxy_tls = true +#proxy_tls_cert = "/usr/local/src/pika/codis/cert.pem" +#proxy_tls_key = "/usr/local/src/pika/codis/key.pem" proxy_addr = "0.0.0.0:19000" # Set jodis address & session timeout diff --git a/codis/pkg/models/proxy.go b/codis/pkg/models/proxy.go index 69e308adef..b4d3a965ab 100644 --- a/codis/pkg/models/proxy.go +++ b/codis/pkg/models/proxy.go @@ -11,6 +11,9 @@ type Proxy struct { ProtoType string `json:"proto_type"` ProxyAddr string `json:"proxy_addr"` + ProxyTLS bool `json:"proxy_tls"` + ProxyTLSCert string `json:"proxy_tls_cert"` + ProxyTLSKey string `json:"proxy_tls_key"` JodisPath string `json:"jodis_path,omitempty"` diff --git a/codis/pkg/models/store.go b/codis/pkg/models/store.go index aceb5bc83a..44f65ad6af 100644 --- a/codis/pkg/models/store.go +++ b/codis/pkg/models/store.go @@ -123,6 +123,25 @@ func (s *Store) Release() error { return s.client.Delete(s.LockPath()) } +func (s *Store) ReleaseByToken(token string) error { + b, err := s.client.Read(s.LockPath(),false) + if err != nil { + return err + } + + if b != nil { + t, err := Decode(b) + if err != nil { + return err + } + if t != nil && t.Token == token { + return s.Release() + } + } + + return nil +} + func (s *Store) LoadTopom(must bool) (*Topom, error) { return LoadTopom(s.client, s.product, must) } diff --git a/codis/pkg/models/topom.go b/codis/pkg/models/topom.go index 746141fbae..83530119e4 100644 --- a/codis/pkg/models/topom.go +++ b/codis/pkg/models/topom.go @@ -18,3 +18,11 @@ type Topom struct { func (t *Topom) Encode() []byte { return jsonEncode(t) } + +func Decode(b []byte) (*Topom, error) { + s := &Topom{} + if err := jsonDecode(s, b); err != nil { + return nil, fmt.Errorf("json decode error: %w", err) + } + return s,nil +} diff --git a/codis/pkg/proxy/config.go b/codis/pkg/proxy/config.go index 2901e7608c..aa29286318 100644 --- a/codis/pkg/proxy/config.go +++ b/codis/pkg/proxy/config.go @@ -37,6 +37,9 @@ admin_addr = "0.0.0.0:11080" # Set bind address for proxy, proto_type can be "tcp", "tcp4", "tcp6", "unix" or "unixpacket". proto_type = "tcp4" +#proxy_tls = true +#proxy_tls_cert = "/usr/local/src/pika/codis/cert.pem" +#proxy_tls_key = "/usr/local/src/pika/codis/key.pem" proxy_addr = "0.0.0.0:19000" # Set jodis address & session timeout @@ -166,6 +169,9 @@ type Config struct { ProxyDataCenter string `toml:"proxy_datacenter" json:"proxy_datacenter"` ProxyMaxClients int `toml:"proxy_max_clients" json:"proxy_max_clients"` + ProxyTLS bool `toml:"proxy_tls" json:"proxy_tls"` + ProxyTLSCert string `toml:"proxy_tls_cert" json:"proxy_tls_cert"` + ProxyTLSKey string `toml:"proxy_tls_key" json:"proxy_tls_key"` ProxyMaxOffheapBytes bytesize.Int64 `toml:"proxy_max_offheap_size" json:"proxy_max_offheap_size"` ProxyHeapPlaceholder bytesize.Int64 `toml:"proxy_heap_placeholder" json:"proxy_heap_placeholder"` diff --git a/codis/pkg/proxy/proxy.go b/codis/pkg/proxy/proxy.go index 575d1ffadf..cb1b9cac3b 100644 --- a/codis/pkg/proxy/proxy.go +++ b/codis/pkg/proxy/proxy.go @@ -4,6 +4,7 @@ package proxy import ( + "crypto/tls" "fmt" "net" "net/http" @@ -103,19 +104,55 @@ func New(config *Config) (*Proxy, error) { func (p *Proxy) setup(config *Config) error { proto := config.ProtoType - if l, err := net.Listen(proto, config.ProxyAddr); err != nil { - return errors.Trace(err) + + var l net.Listener + var err error + + if config.ProxyTLS { + log.Printf("TLS configuration: cert = %s, key = %s", config.ProxyTLSCert, config.ProxyTLSKey) + + // Load the TLS certificate + cert, err := tls.LoadX509KeyPair(config.ProxyTLSCert, config.ProxyTLSKey) + if err != nil { + return errors.Trace(err) + } + + // Set up TLS configuration to use TLS 1.2 or higher + tlsConfig := &tls.Config{ + Certificates: []tls.Certificate{cert}, + MinVersion: tls.VersionTLS12, + } + + // Create a TLS listener + l, err = tls.Listen(proto, config.ProxyAddr, tlsConfig) + if err != nil { + return errors.Trace(err) + } } else { - p.lproxy = l + log.Printf("Setting up a non-TLS listener") - x, err := utils.ReplaceUnspecifiedIP(proto, l.Addr().String(), config.HostProxy) + // Create a non-TLS listener + l, err = net.Listen(proto, config.ProxyAddr) if err != nil { - return err + return errors.Trace(err) } - p.model.ProtoType = proto - p.model.ProxyAddr = x } + // Common setup for both TLS and non-TLS + p.lproxy = l + + // Replace unspecified IP address with the specific host proxy address + x, err := utils.ReplaceUnspecifiedIP(proto, l.Addr().String(), config.HostProxy) + if err != nil { + log.Errorf("Failed to replace unspecified IP: %s", err) + return err + } + + // Update proxy model + p.model.ProtoType = proto + p.model.ProxyAddr = x + + proto = "tcp" if l, err := net.Listen(proto, config.AdminAddr); err != nil { return errors.Trace(err) diff --git a/codis/pkg/topom/topom.go b/codis/pkg/topom/topom.go index f2c34f6b58..67cd61d51c 100644 --- a/codis/pkg/topom/topom.go +++ b/codis/pkg/topom/topom.go @@ -169,7 +169,8 @@ func (s *Topom) Close() error { defer s.store.Close() if s.online { - if err := s.store.Release(); err != nil { + err := s.store.ReleaseByToken(s.model.Token); + if err != nil { log.ErrorErrorf(err, "store: release lock of %s failed", s.config.ProductName) return errors.Errorf("store: release lock of %s failed", s.config.ProductName) }