diff --git a/.gitignore b/.gitignore index 225b4d0c..6ab491f9 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ nginx-ui resources/development/nginx app/.env app/.status_hash +casdoor.pub diff --git a/api/nginx/nginx_log.go b/api/nginx/nginx_log.go index 485e5005..2ac82319 100644 --- a/api/nginx/nginx_log.go +++ b/api/nginx/nginx_log.go @@ -2,9 +2,13 @@ package nginx import ( "encoding/json" + "fmt" "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/cache" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/logger" "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/settings" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "github.com/hpcloud/tail" @@ -30,6 +34,7 @@ type controlStruct struct { type nginxLogPageResp struct { Content string `json:"content"` Page int64 `json:"page"` + Error string `json:"error,omitempty"` } func GetNginxLogPage(c *gin.Context) { @@ -46,6 +51,9 @@ func GetNginxLogPage(c *gin.Context) { logPath, err := getLogPath(&control) if err != nil { + c.JSON(http.StatusInternalServerError, nginxLogPageResp{ + Error: err.Error(), + }) logger.Error(err) return } @@ -53,13 +61,17 @@ func GetNginxLogPage(c *gin.Context) { logFileStat, err := os.Stat(logPath) if err != nil { - c.JSON(http.StatusOK, nginxLogPageResp{}) + c.JSON(http.StatusInternalServerError, nginxLogPageResp{ + Error: err.Error(), + }) logger.Error(err) return } if !logFileStat.Mode().IsRegular() { - c.JSON(http.StatusOK, nginxLogPageResp{}) + c.JSON(http.StatusInternalServerError, nginxLogPageResp{ + Error: "log file is not regular file", + }) logger.Error("log file is not regular file:", logPath) return } @@ -67,7 +79,9 @@ func GetNginxLogPage(c *gin.Context) { f, err := os.Open(logPath) if err != nil { - c.JSON(http.StatusOK, nginxLogPageResp{}) + c.JSON(http.StatusInternalServerError, nginxLogPageResp{ + Error: err.Error(), + }) logger.Error(err) return } @@ -90,7 +104,9 @@ func GetNginxLogPage(c *gin.Context) { // seek _, err = f.Seek(offset, io.SeekStart) if err != nil && err != io.EOF { - c.JSON(http.StatusOK, nginxLogPageResp{}) + c.JSON(http.StatusInternalServerError, nginxLogPageResp{ + Error: err.Error(), + }) logger.Error(err) return } @@ -98,7 +114,9 @@ func GetNginxLogPage(c *gin.Context) { n, err := f.Read(buf) if err != nil && err != io.EOF { - c.JSON(http.StatusOK, nginxLogPageResp{}) + c.JSON(http.StatusInternalServerError, nginxLogPageResp{ + Error: err.Error(), + }) logger.Error(err) return } @@ -109,7 +127,30 @@ func GetNginxLogPage(c *gin.Context) { }) } +// isLogPathUnderWhiteList checks if the log path is under one of the paths in LogDirWhiteList +func isLogPathUnderWhiteList(path string) bool { + cacheKey := fmt.Sprintf("isLogPathUnderWhiteList:%s", path) + res, ok := cache.Get(cacheKey) + // no cache, check it + if !ok { + for _, whitePath := range settings.NginxSettings.LogDirWhiteList { + if helper.IsUnderDirectory(path, whitePath) { + cache.Set(cacheKey, true, 0) + return true + } + } + return false + } + return res.(bool) +} + func getLogPath(control *controlStruct) (logPath string, err error) { + if len(settings.NginxSettings.LogDirWhiteList) == 0 { + err = errors.New("The settings.NginxSettings.LogDirWhiteList has not been configured. " + + "For security reasons, please configure a whitelist of log directories. " + + "Please visit https://nginxui.com/guide/config-nginx.html for more information.") + return + } switch control.Type { case "site": var config *nginx.NgxConfig @@ -172,6 +213,11 @@ func getLogPath(control *controlStruct) (logPath string, err error) { logPath = path } + // check if logPath is under one of the paths in LogDirWhiteList + if !isLogPathUnderWhiteList(logPath) { + err = errors.New("The log path is not under the paths in LogDirWhiteList.") + return "", err + } return } diff --git a/app/src/views/nginx_log/NginxLog.vue b/app/src/views/nginx_log/NginxLog.vue index da187161..2facc992 100644 --- a/app/src/views/nginx_log/NginxLog.vue +++ b/app/src/views/nginx_log/NginxLog.vue @@ -59,6 +59,9 @@ function init() { nginx_log.page(0, control).then(r => { page.value = r.page - 1 addLog(r.content) + openWs() + }).catch(e => { + addLog(e.error) }) } @@ -68,11 +71,10 @@ function clearLog() { onMounted(() => { init() - openWs() }) onUnmounted(() => { - websocket.close() + websocket?.close() }) watch(auto_refresh, value => { diff --git a/casdoor.pub b/casdoor.pub new file mode 100644 index 00000000..ce210e59 --- /dev/null +++ b/casdoor.pub @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE3TCCAsWgAwIBAgIDAeJAMA0GCSqGSIb3DQEBCwUAMCgxDjAMBgNVBAoTBWFk +bWluMRYwFAYDVQQDEw1jZXJ0LWJ1aWx0LWluMB4XDTI0MDcyOTAzMDUzM1oXDTQ0 +MDcyOTAzMDUzM1owKDEOMAwGA1UEChMFYWRtaW4xFjAUBgNVBAMTDWNlcnQtYnVp +bHQtaW4wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDh0c2zvM21NDNi +xZmSQVPOtckiH/K80mHQ99e+xzdGrZugaw00tyTOMVRot+Bv1cggcJXmFcVaa9Da +siIcIQ6jT3w7mINsrErYu4nz9tELd4BZUM6tytN+khVqo73p/NbRsnmX8ykMyrgx +YCBknNoSxh7glLSmKcj4uQ12dYakRPr0QNnDwU7fpPfB7N4O88yXWpbqWaABwqBx +S6+tYUp9Wx74mH8c917w5xXx8EI5eC+dJOAeVXrbzqD7OdC+uo8m7f06HAX1vRE/ +MQS0BDx8tDGtqOvdJbVxdnS6MQ2E3vmuusFseDcKVgqTF/7b76y5uNyBBux5zfpt +G1O3bquMlQ8mSedK8BBcbI79gXYJRWazMBXvAdacaV93dF1s0EEjYXiBManAci2d +lH8zzs4TNpE0t3adYiPbGPW1F6Q+HaV52MDVpFwG9Ld0kJmKhkvoWiSXl58Db3VN +Ef8Jjo2xF+5o9685CQ2o9L0RalcHxMxy1+6wdKMSp7PReYpIiEgmkAhUsKePOVmr +JwL46/4EulcXrh+ASjobmknHzdBQEK+MHapb/XWewX4mzq777gPmP8RdILTHsc1m +/hbR8uW9iTfo9LQFvXwnIPVfX0wzFXSZzSg/zLb2tN5D7VlDenUAdCDT1zNOfz5m +9vLYwfo5GzXIkp2py0G40vrZlv7C9wIDAQABoxAwDjAMBgNVHRMBAf8EAjAAMA0G +CSqGSIb3DQEBCwUAA4ICAQBp1Bx+mShpumQiVb2hv0amSzAKADyYIX3Xcef68rPu +Eb+7HSCmQf4yyI9eU1TyvQCLbjum3U3OhDWwAiRvxOwj0oO/Q+dOUEZxTjbL9UF3 +4LIrUUBMRhRgy3wK73qy3o8hAcRtQyexUW7eoFS+7L++6XQOvMkYAtLO0DQCHeKG +loiQa5RuWbzQDdP7810DLvNF8IMA8t9KKaKGybYze9WTzRUMTDbXby8pVs8DG7JI +zIW6neEmtsVbxufk/nthG1b83/yZxe0StL42xI7f4xgguhkfd68E4lpf/gp91EAM +K6MbTmCqkB68c0wOSXpWYkte7EvXTTmMSKf6FnMgOtqdxqYYMknLk4ZdI7tMqS31 +rpb9XxjBgXFbB18oOSDbW64KPMjE7vuOx+o32BTHKsUWxOiDc8+0ELrbhG2Bm1Gj +CYkx9bq5iTLDwtZZlPoA8O/T0TJzBTtC/tlEdpHSkkLoEaWsx0nT9ipRWck1Kj59 +NGJkArbrpq9Ee8tWJKqTN/pv0X8r+MxowIY2dKvwweokXb7R6k9nfXyGw8ji22Hv +H4iibv9FEyVFQ16HPR6fIKg9yE9u0223UhJZEwohA4DylCxpmI/YSXbUmzQJwjBP +27qvT4Y07xsdNqIbkwhb5yEQB5huivITD+SBwI5NwDfUeY6eF/BEHpRq+Uy3itx0 +SA== +-----END CERTIFICATE----- diff --git a/docs/guide/config-nginx.md b/docs/guide/config-nginx.md index 274e1dab..54c8e4d0 100644 --- a/docs/guide/config-nginx.md +++ b/docs/guide/config-nginx.md @@ -33,6 +33,20 @@ In Nginx UI v2, we parse the output of the `nginx -V` command to get the default If you need to set a different path, you can use this option. ::: +### LogDirWhiteList + +- Type: `[]string` +- Version:`>= v2.0.0-beta.36` +- Example: `/var/log/nginx,/var/log/sites` + +This option is used to set the whitelist of directories for the Nginx logs viewer in Nginx UI. + +::: warning Warning +For security reasons, you must specify the directories where the logs are stored. + +Only logs within these directories can be viewed online. +::: + ## Service Monitoring and Control In this section, we will introduce configuration options in Nginx UI for monitoring and controlling Nginx services. diff --git a/docs/package.json b/docs/package.json index a01a0c9c..e3b9b912 100644 --- a/docs/package.json +++ b/docs/package.json @@ -7,11 +7,11 @@ "docs:preview": "vitepress preview" }, "dependencies": { - "vitepress": "^1.3.4", + "vitepress": "^1.4.0", "vue": "^3.5.11" }, "devDependencies": { - "@types/node": "^22.7.4", + "@types/node": "^22.7.5", "less": "^4.2.0" }, "license": "AGPL-3.0", diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml index e06d03fe..54275261 100644 --- a/docs/pnpm-lock.yaml +++ b/docs/pnpm-lock.yaml @@ -9,15 +9,15 @@ importers: .: dependencies: vitepress: - specifier: ^1.3.4 - version: 1.3.4(@algolia/client-search@4.24.0)(@types/node@22.7.4)(less@4.2.0)(postcss@8.4.47)(search-insights@2.13.0) + specifier: ^1.4.0 + version: 1.4.0(@algolia/client-search@4.24.0)(@types/node@22.7.5)(less@4.2.0)(postcss@8.4.47)(search-insights@2.13.0) vue: specifier: ^3.5.11 version: 3.5.11 devDependencies: '@types/node': - specifier: ^22.7.4 - version: 22.7.4 + specifier: ^22.7.5 + version: 22.7.5 less: specifier: ^4.2.0 version: 4.2.0 @@ -350,20 +350,20 @@ packages: cpu: [x64] os: [win32] - '@shikijs/core@1.21.1': - resolution: {integrity: sha512-scBQo4V4O4WZLEDg11e75UPmXoCMq4Ya2A16U6efi/aTiR4o7T/GMNWZs2rq1U8dEvFKGxJZxiUy+tXgmr/4vw==} + '@shikijs/core@1.22.0': + resolution: {integrity: sha512-S8sMe4q71TJAW+qG93s5VaiihujRK6rqDFqBnxqvga/3LvqHEnxqBIOPkt//IdXVtHkQWKu4nOQNk0uBGicU7Q==} - '@shikijs/engine-javascript@1.21.1': - resolution: {integrity: sha512-29EG4KYKlAona8yikEx8uoKbK7N2YoXUO26LS1GOIxpMMIAlQS9UFONg95lkGmIfp1rRcvCvSpYYIJ/blsQxvg==} + '@shikijs/engine-javascript@1.22.0': + resolution: {integrity: sha512-AeEtF4Gcck2dwBqCFUKYfsCq0s+eEbCEbkUuFou53NZ0sTGnJnJ/05KHQFZxpii5HMXbocV9URYVowOP2wH5kw==} - '@shikijs/engine-oniguruma@1.21.1': - resolution: {integrity: sha512-PvfEtXCDbQZc9ud0SC0bPiuMbul44Cv0Ky2go4SsvVkYAAKYJsMe/Hx7nxThW8yS0r+w8USa0WfOtQKsD9DU9A==} + '@shikijs/engine-oniguruma@1.22.0': + resolution: {integrity: sha512-5iBVjhu/DYs1HB0BKsRRFipRrD7rqjxlWTj4F2Pf+nQSPqc3kcyqFFeZXnBMzDf0HdqaFVvhDRAGiYNvyLP+Mw==} - '@shikijs/transformers@1.21.1': - resolution: {integrity: sha512-97csTb0Gv8eLbglPDhNZTuAI9eCXOujNqD4qK6H0cjFNK+NBhkRIU02RgmYHZ7yNyLary6cEzY6WmUWb+al3MQ==} + '@shikijs/transformers@1.22.0': + resolution: {integrity: sha512-k7iMOYuGQA62KwAuJOQBgH2IQb5vP8uiB3lMvAMGUgAMMurePOx3Z7oNqJdcpxqZP6I9cc7nc4DNqSKduCxmdg==} - '@shikijs/types@1.21.1': - resolution: {integrity: sha512-yLuTJTCHmYznerJ0nxF+f2rBKHQf2FMAd08QL/3du2xNBy/7yQ8CjuKN4Zc+Pk0vfIFzdBoxdzvEXE4JtXoR4Q==} + '@shikijs/types@1.22.0': + resolution: {integrity: sha512-Fw/Nr7FGFhlQqHfxzZY8Cwtwk5E9nKDUgeLjZgt3UuhcM3yJR9xj3ZGNravZZok8XmEZMiYkSMTPlPkULB8nww==} '@shikijs/vscode-textmate@9.3.0': resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==} @@ -386,8 +386,8 @@ packages: '@types/mdurl@2.0.0': resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} - '@types/node@22.7.4': - resolution: {integrity: sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==} + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} @@ -691,8 +691,8 @@ packages: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true - shiki@1.21.1: - resolution: {integrity: sha512-jSOKRHyQJxGOW3kJflmwzHJbp/kjg6hP8LYuVbCPw5oyX+fSNNoCywvcCD3w9eHbj2rvNljt7YMa5BP5Xi+nHg==} + shiki@1.22.0: + resolution: {integrity: sha512-/t5LlhNs+UOKQCYBtl5ZsH/Vclz73GIqT2yQsCBygr8L/ppTdmpL4w3kPLoZJbMKVWtoG77Ue1feOjZfDxvMkw==} source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} @@ -784,8 +784,8 @@ packages: terser: optional: true - vitepress@1.3.4: - resolution: {integrity: sha512-I1/F6OW1xl3kW4PaIMC6snxjWgf3qfziq2aqsDoFc/Gt41WbcRv++z8zjw8qGRIJ+I4bUW7ZcKFDHHN/jkH9DQ==} + vitepress@1.4.0: + resolution: {integrity: sha512-JXCv4EsKTDyAFb6C/UjZr7nsGAzZ6mafVk2rx7rG5o8N+B/4QstIk+iEOe/9dKoU6V624UIC6g1pZ+K63rxhlw==} hasBin: true peerDependencies: markdown-it-mathjax3: ^4 @@ -1081,31 +1081,31 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.24.0': optional: true - '@shikijs/core@1.21.1': + '@shikijs/core@1.22.0': dependencies: - '@shikijs/engine-javascript': 1.21.1 - '@shikijs/engine-oniguruma': 1.21.1 - '@shikijs/types': 1.21.1 + '@shikijs/engine-javascript': 1.22.0 + '@shikijs/engine-oniguruma': 1.22.0 + '@shikijs/types': 1.22.0 '@shikijs/vscode-textmate': 9.3.0 '@types/hast': 3.0.4 hast-util-to-html: 9.0.3 - '@shikijs/engine-javascript@1.21.1': + '@shikijs/engine-javascript@1.22.0': dependencies: - '@shikijs/types': 1.21.1 + '@shikijs/types': 1.22.0 '@shikijs/vscode-textmate': 9.3.0 oniguruma-to-js: 0.4.3 - '@shikijs/engine-oniguruma@1.21.1': + '@shikijs/engine-oniguruma@1.22.0': dependencies: - '@shikijs/types': 1.21.1 + '@shikijs/types': 1.22.0 '@shikijs/vscode-textmate': 9.3.0 - '@shikijs/transformers@1.21.1': + '@shikijs/transformers@1.22.0': dependencies: - shiki: 1.21.1 + shiki: 1.22.0 - '@shikijs/types@1.21.1': + '@shikijs/types@1.22.0': dependencies: '@shikijs/vscode-textmate': 9.3.0 '@types/hast': 3.0.4 @@ -1131,7 +1131,7 @@ snapshots: '@types/mdurl@2.0.0': {} - '@types/node@22.7.4': + '@types/node@22.7.5': dependencies: undici-types: 6.19.8 @@ -1141,9 +1141,9 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-vue@5.1.4(vite@5.4.8(@types/node@22.7.4)(less@4.2.0))(vue@3.5.11)': + '@vitejs/plugin-vue@5.1.4(vite@5.4.8(@types/node@22.7.5)(less@4.2.0))(vue@3.5.11)': dependencies: - vite: 5.4.8(@types/node@22.7.4)(less@4.2.0) + vite: 5.4.8(@types/node@22.7.5)(less@4.2.0) vue: 3.5.11 '@vue/compiler-core@3.5.11': @@ -1504,12 +1504,12 @@ snapshots: semver@5.7.2: optional: true - shiki@1.21.1: + shiki@1.22.0: dependencies: - '@shikijs/core': 1.21.1 - '@shikijs/engine-javascript': 1.21.1 - '@shikijs/engine-oniguruma': 1.21.1 - '@shikijs/types': 1.21.1 + '@shikijs/core': 1.22.0 + '@shikijs/engine-javascript': 1.22.0 + '@shikijs/engine-oniguruma': 1.22.0 + '@shikijs/types': 1.22.0 '@shikijs/vscode-textmate': 9.3.0 '@types/hast': 3.0.4 @@ -1574,24 +1574,25 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite@5.4.8(@types/node@22.7.4)(less@4.2.0): + vite@5.4.8(@types/node@22.7.5)(less@4.2.0): dependencies: esbuild: 0.21.5 postcss: 8.4.47 rollup: 4.24.0 optionalDependencies: - '@types/node': 22.7.4 + '@types/node': 22.7.5 fsevents: 2.3.3 less: 4.2.0 - vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.7.4)(less@4.2.0)(postcss@8.4.47)(search-insights@2.13.0): + vitepress@1.4.0(@algolia/client-search@4.24.0)(@types/node@22.7.5)(less@4.2.0)(postcss@8.4.47)(search-insights@2.13.0): dependencies: '@docsearch/css': 3.6.2 '@docsearch/js': 3.6.2(@algolia/client-search@4.24.0)(search-insights@2.13.0) - '@shikijs/core': 1.21.1 - '@shikijs/transformers': 1.21.1 + '@shikijs/core': 1.22.0 + '@shikijs/transformers': 1.22.0 + '@shikijs/types': 1.22.0 '@types/markdown-it': 14.1.2 - '@vitejs/plugin-vue': 5.1.4(vite@5.4.8(@types/node@22.7.4)(less@4.2.0))(vue@3.5.11) + '@vitejs/plugin-vue': 5.1.4(vite@5.4.8(@types/node@22.7.5)(less@4.2.0))(vue@3.5.11) '@vue/devtools-api': 7.4.6 '@vue/shared': 3.5.11 '@vueuse/core': 11.1.0(vue@3.5.11) @@ -1599,8 +1600,8 @@ snapshots: focus-trap: 7.6.0 mark.js: 8.11.1 minisearch: 7.1.0 - shiki: 1.21.1 - vite: 5.4.8(@types/node@22.7.4)(less@4.2.0) + shiki: 1.22.0 + vite: 5.4.8(@types/node@22.7.5)(less@4.2.0) vue: 3.5.11 optionalDependencies: postcss: 8.4.47 diff --git a/docs/zh_CN/guide/config-nginx.md b/docs/zh_CN/guide/config-nginx.md index 1387a218..98c4e36d 100644 --- a/docs/zh_CN/guide/config-nginx.md +++ b/docs/zh_CN/guide/config-nginx.md @@ -34,6 +34,20 @@ Nginx 日志对于监控、排查问题和维护您的 Web 服务器至关重要 如果您需要设置不同的路径,您可以使用此选项。 ::: +### LogDirWhiteList + +- 类型:`[]string` +- 版本:`>= v2.0.0-beta.36` +- 示例:`/var/log/nginx,/var/log/sites` + +此选项用于为 Nginx UI 设置日志查看器的目录白名单。 + +::: warning 警告 +出于安全原因,您必须指定存储日志的目录。 + +只有这些目录中的日志可以在线查看。 +::: + ## 服务监控与控制 在本节中,我们将会介绍 Nginx UI 中关于 Nginx 服务的监控和控制命令的配置选项。 diff --git a/docs/zh_TW/guide/config-nginx.md b/docs/zh_TW/guide/config-nginx.md index 5dfb5448..6a50c240 100644 --- a/docs/zh_TW/guide/config-nginx.md +++ b/docs/zh_TW/guide/config-nginx.md @@ -33,6 +33,20 @@ Nginx 日誌對於監控、排查問題和維護您的 Web 伺服器至關重要 如果您需要設置不同的路徑,您可以使用此選項。 ::: +### LogDirWhiteList + +- 類型:`[]string` +- 版本:`>= v2.0.0-beta.36` +- 示例:`/var/log/nginx,/var/log/sites` + +此選項用於為 Nginx UI 設置日誌查看器的目錄白名單。 + +::: warning 警告 +出於安全原因,您必須指定存儲日誌的目錄。 + +只有這些目錄中的日誌可以在線查看。 +::: + ## 服務監控與控制 在本節中,我們將會介紹 Nginx UI 中關於 Nginx 服務的監控和控制命令的配置選項。 diff --git a/settings/nginx.go b/settings/nginx.go index 9a4c9067..9be09184 100644 --- a/settings/nginx.go +++ b/settings/nginx.go @@ -1,13 +1,14 @@ package settings type Nginx struct { - AccessLogPath string `json:"access_log_path" protected:"true"` - ErrorLogPath string `json:"error_log_path" protected:"true"` - ConfigDir string `json:"config_dir" protected:"true"` - PIDPath string `json:"pid_path" protected:"true"` - TestConfigCmd string `json:"test_config_cmd" protected:"true"` - ReloadCmd string `json:"reload_cmd" protected:"true"` - RestartCmd string `json:"restart_cmd" protected:"true"` + AccessLogPath string `json:"access_log_path" protected:"true"` + ErrorLogPath string `json:"error_log_path" protected:"true"` + LogDirWhiteList []string `json:"log_dir_white_list" protected:"true"` + ConfigDir string `json:"config_dir" protected:"true"` + PIDPath string `json:"pid_path" protected:"true"` + TestConfigCmd string `json:"test_config_cmd" protected:"true"` + ReloadCmd string `json:"reload_cmd" protected:"true"` + RestartCmd string `json:"restart_cmd" protected:"true"` } var NginxSettings = Nginx{