Prechádzať zdrojové kódy

feat: enhance environment variable handling and security features

CalciumIon 1 rok pred
rodič
commit
2f01a2125f
5 zmenil súbory, kde vykonal 16 pridanie a 3 odobranie
  1. 5 0
      README.md
  2. 1 0
      common/constants.go
  3. 1 1
      common/crypto.go
  4. 6 1
      common/init.go
  5. 3 1
      main.go

+ 5 - 0
README.md

@@ -89,6 +89,7 @@
 - `COHERE_SAFETY_SETTING`:Cohere模型[安全设置](https://docs.cohere.com/docs/safety-modes#overview),可选值为 `NONE`, `CONTEXTUAL`,`STRICT`,默认为 `NONE`。
 - `COHERE_SAFETY_SETTING`:Cohere模型[安全设置](https://docs.cohere.com/docs/safety-modes#overview),可选值为 `NONE`, `CONTEXTUAL`,`STRICT`,默认为 `NONE`。
 - `GEMINI_VISION_MAX_IMAGE_NUM`:Gemini模型最大图片数量,默认为 `16`,设置为 `-1` 则不限制。
 - `GEMINI_VISION_MAX_IMAGE_NUM`:Gemini模型最大图片数量,默认为 `16`,设置为 `-1` 则不限制。
 - `MAX_FILE_DOWNLOAD_MB`: 最大文件下载大小,单位 MB,默认为 `20`。
 - `MAX_FILE_DOWNLOAD_MB`: 最大文件下载大小,单位 MB,默认为 `20`。
+- `CRYPTO_SECRET`:加密密钥,用于加密数据库内容。
 ## 部署
 ## 部署
 > [!TIP]
 > [!TIP]
 > 最新版Docker镜像:`calciumion/new-api:latest`  
 > 最新版Docker镜像:`calciumion/new-api:latest`  
@@ -98,6 +99,10 @@
 > docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower -cR
 > docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower -cR
 > ```
 > ```
 
 
+### 多机部署
+- 必须设置环境变量 `SESSION_SECRET`,否则会导致多机部署时登录状态不一致。
+- 如果公用Redis,必须设置 `CRYPTO_SECRET`,否则会导致多机部署时Redis内容无法解密。
+
 ### 部署要求
 ### 部署要求
 - 本地数据库(默认):SQLite(Docker 部署默认使用 SQLite,必须挂载 `/data` 目录到宿主机)
 - 本地数据库(默认):SQLite(Docker 部署默认使用 SQLite,必须挂载 `/data` 目录到宿主机)
 - 远程数据库:MySQL 版本 >= 5.7.8,PgSQL 版本 >= 9.6
 - 远程数据库:MySQL 版本 >= 5.7.8,PgSQL 版本 >= 9.6

+ 1 - 0
common/constants.go

@@ -30,6 +30,7 @@ var DefaultCollapseSidebar = false // default value of collapse sidebar
 // Any options with "Secret", "Token" in its key won't be return by GetOptions
 // Any options with "Secret", "Token" in its key won't be return by GetOptions
 
 
 var SessionSecret = uuid.New().String()
 var SessionSecret = uuid.New().String()
+var CryptoSecret = uuid.New().String()
 
 
 var OptionMap map[string]string
 var OptionMap map[string]string
 var OptionMapRWMutex sync.RWMutex
 var OptionMapRWMutex sync.RWMutex

+ 1 - 1
common/crypto.go

@@ -14,7 +14,7 @@ func GenerateHMACWithKey(key []byte, data string) string {
 }
 }
 
 
 func GenerateHMAC(data string) string {
 func GenerateHMAC(data string) string {
-	h := hmac.New(sha256.New, []byte(SessionSecret))
+	h := hmac.New(sha256.New, []byte(CryptoSecret))
 	h.Write([]byte(data))
 	h.Write([]byte(data))
 	return hex.EncodeToString(h.Sum(nil))
 	return hex.EncodeToString(h.Sum(nil))
 }
 }

+ 6 - 1
common/init.go

@@ -22,7 +22,7 @@ func printHelp() {
 	fmt.Println("Usage: one-api [--port <port>] [--log-dir <log directory>] [--version] [--help]")
 	fmt.Println("Usage: one-api [--port <port>] [--log-dir <log directory>] [--version] [--help]")
 }
 }
 
 
-func init() {
+func LoadEnv() {
 	flag.Parse()
 	flag.Parse()
 
 
 	if *PrintVersion {
 	if *PrintVersion {
@@ -45,6 +45,11 @@ func init() {
 			SessionSecret = ss
 			SessionSecret = ss
 		}
 		}
 	}
 	}
+	if os.Getenv("CRYPTO_SECRET") != "" {
+		CryptoSecret = os.Getenv("CRYPTO_SECRET")
+	} else {
+		CryptoSecret = SessionSecret
+	}
 	if os.Getenv("SQLITE_PATH") != "" {
 	if os.Getenv("SQLITE_PATH") != "" {
 		SQLitePath = os.Getenv("SQLITE_PATH")
 		SQLitePath = os.Getenv("SQLITE_PATH")
 	}
 	}

+ 3 - 1
main.go

@@ -33,9 +33,11 @@ var indexPage []byte
 func main() {
 func main() {
 	err := godotenv.Load(".env")
 	err := godotenv.Load(".env")
 	if err != nil {
 	if err != nil {
-		common.SysError("failed to load .env file: " + err.Error())
+		common.SysLog("Support for .env file is disabled")
 	}
 	}
 
 
+	common.LoadEnv()
+
 	common.SetupLogger()
 	common.SetupLogger()
 	common.SysLog("New API " + common.Version + " started")
 	common.SysLog("New API " + common.Version + " started")
 	if os.Getenv("GIN_MODE") != "debug" {
 	if os.Getenv("GIN_MODE") != "debug" {