mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-06 07:36:37 +08:00
fix(agent): write nginx pid and temp dirs under data_dir for non-root runtime
OpenResty running as openflare can no longer write pid or client/proxy temp paths under the OpenResty install prefix. Templates and apply-time rendering now use __OPENFLARE_PID_PATH__ and __OPENFLARE_NGINX_CACHE_DIR__ under data_dir/var/run and data_dir/var/cache/nginx, with legacy pid path patched at apply. Consolidate runtimeuser path helpers into the main package file so IDEs resolve references across build tags.
This commit is contained in:
@@ -40,7 +40,6 @@ build-backend:
|
|||||||
|
|
||||||
build-agent:
|
build-agent:
|
||||||
@echo "==> Building agent version=$(VERSION)..."
|
@echo "==> Building agent version=$(VERSION)..."
|
||||||
bash scripts/fetch-agent-geoip-mmdb.sh
|
|
||||||
go build \
|
go build \
|
||||||
-ldflags "-s -w -X '$(MODULE)/internal/apps/agent/config.Version=$(VERSION)'" \
|
-ldflags "-s -w -X '$(MODULE)/internal/apps/agent/config.Version=$(VERSION)'" \
|
||||||
-o bin/openflare-agent \
|
-o bin/openflare-agent \
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ sidebar: false
|
|||||||
|
|
||||||
### 修复
|
### 修复
|
||||||
|
|
||||||
|
- 修复 Agent 以 `openflare` 非 root 运行时 OpenResty `-t`/reload 失败:nginx `pid` 与 `client_body_temp`/`proxy_temp` 等临时目录改写入 `data_dir/var/run` 与 `data_dir/var/cache/nginx`(`__OPENFLARE_PID_PATH__` / `__OPENFLARE_NGINX_CACHE_DIR__` 占位符),不再使用 OpenResty 安装目录下不可写路径。
|
||||||
|
|
||||||
- 修复 OpenResty 响应泄露版本号:默认主配置模板与 safe fallback 模板补充 `server_tokens off;`,隐藏 `Server` 头与错误页中的 nginx/OpenResty 版本信息。
|
- 修复 OpenResty 响应泄露版本号:默认主配置模板与 safe fallback 模板补充 `server_tokens off;`,隐藏 `Server` 头与错误页中的 nginx/OpenResty 版本信息。
|
||||||
|
|
||||||
- 修复 Agent 与 OpenResty worker 权限不一致导致 Pages/WAF 等静态资源 Permission denied:引入共享运行时用户 `openflare`(Agent 进程、OpenResty worker、文件属主统一);Docker 入口脚本在启动前修正 volume 属主并降权;本地 systemd 服务以 `openflare` 运行并授予 `CAP_NET_BIND_SERVICE`;`data_dir` 与 `pages_dir` 等路径在同步/Apply 时统一 `chown` 与 `0755/0644` 规范化。
|
- 修复 Agent 与 OpenResty worker 权限不一致导致 Pages/WAF 等静态资源 Permission denied:引入共享运行时用户 `openflare`(Agent 进程、OpenResty worker、文件属主统一);Docker 入口脚本在启动前修正 volume 属主并降权;本地 systemd 服务以 `openflare` 运行并授予 `CAP_NET_BIND_SERVICE`;`data_dir` 与 `pages_dir` 等路径在同步/Apply 时统一 `chown` 与 `0755/0644` 规范化。
|
||||||
|
|||||||
@@ -188,9 +188,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const safeDefaultFallbackMainConfig = `# This file is generated by OpenFlare safe default fallback.
|
const safeDefaultFallbackMainConfig = `# This file is generated by OpenFlare safe default fallback.
|
||||||
user ` + OpenFlareRuntimeUser + `;
|
user ` + runtimeuser.Name + `;
|
||||||
worker_processes auto;
|
worker_processes auto;
|
||||||
pid logs/nginx.pid;
|
pid __OPENFLARE_PID_PATH__;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
worker_connections 1024;
|
worker_connections 1024;
|
||||||
@@ -199,6 +199,11 @@ events {
|
|||||||
http {
|
http {
|
||||||
default_type text/plain;
|
default_type text/plain;
|
||||||
server_tokens off;
|
server_tokens off;
|
||||||
|
client_body_temp_path __OPENFLARE_NGINX_CACHE_DIR__/client_temp;
|
||||||
|
proxy_temp_path __OPENFLARE_NGINX_CACHE_DIR__/proxy_temp;
|
||||||
|
fastcgi_temp_path __OPENFLARE_NGINX_CACHE_DIR__/fastcgi_temp;
|
||||||
|
uwsgi_temp_path __OPENFLARE_NGINX_CACHE_DIR__/uwsgi_temp;
|
||||||
|
scgi_temp_path __OPENFLARE_NGINX_CACHE_DIR__/scgi_temp;
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen 80 default_server;
|
listen 80 default_server;
|
||||||
@@ -294,6 +299,9 @@ func (m *Manager) ensureOpenRestyWorkerReadAccess() error {
|
|||||||
if m.AccessLogPath != "" {
|
if m.AccessLogPath != "" {
|
||||||
targets = append(targets, filepath.Dir(m.AccessLogPath))
|
targets = append(targets, filepath.Dir(m.AccessLogPath))
|
||||||
}
|
}
|
||||||
|
if pidPath := m.pidRuntimePath(); pidPath != "" {
|
||||||
|
targets = append(targets, filepath.Dir(pidPath))
|
||||||
|
}
|
||||||
seen := make(map[string]struct{}, len(targets))
|
seen := make(map[string]struct{}, len(targets))
|
||||||
for _, target := range targets {
|
for _, target := range targets {
|
||||||
cleaned := filepath.Clean(strings.TrimSpace(target))
|
cleaned := filepath.Clean(strings.TrimSpace(target))
|
||||||
@@ -474,6 +482,9 @@ func (m *Manager) CurrentChecksum() (string, error) {
|
|||||||
errorLogPath := filepath.Join(filepath.Dir(accessLogPath), "error.log")
|
errorLogPath := filepath.Join(filepath.Dir(accessLogPath), "error.log")
|
||||||
normalizedMain = strings.ReplaceAll(normalizedMain, filepath.ToSlash(errorLogPath), openrestyrender.ErrorLogPlaceholder)
|
normalizedMain = strings.ReplaceAll(normalizedMain, filepath.ToSlash(errorLogPath), openrestyrender.ErrorLogPlaceholder)
|
||||||
}
|
}
|
||||||
|
if pidPath := m.pidRuntimePath(); pidPath != "" {
|
||||||
|
normalizedMain = strings.ReplaceAll(normalizedMain, filepath.ToSlash(pidPath), openrestyrender.PIDPathPlaceholder)
|
||||||
|
}
|
||||||
if luaDir := m.luaRuntimePath(); luaDir != "" {
|
if luaDir := m.luaRuntimePath(); luaDir != "" {
|
||||||
normalizedMain = strings.ReplaceAll(normalizedMain, luaDir, openrestyrender.LuaDirPlaceholder)
|
normalizedMain = strings.ReplaceAll(normalizedMain, luaDir, openrestyrender.LuaDirPlaceholder)
|
||||||
}
|
}
|
||||||
@@ -991,7 +1002,7 @@ func (m *Manager) writeSafeDefaultFallbackFiles() error {
|
|||||||
if err := os.WriteFile(m.RouteConfigPath, nil, nginxConfigFilePerm); err != nil {
|
if err := os.WriteFile(m.RouteConfigPath, nil, nginxConfigFilePerm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := os.WriteFile(m.MainConfigPath, []byte(m.safeDefaultFallbackMainConfig()), nginxConfigFilePerm); err != nil {
|
if err := os.WriteFile(m.MainConfigPath, []byte(m.renderMainConfig(m.safeDefaultFallbackMainConfig())), nginxConfigFilePerm); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -1228,6 +1239,30 @@ func (m *Manager) renderMainConfig(content string) string {
|
|||||||
errorLogPath := filepath.Join(filepath.Dir(accessLogPath), "error.log")
|
errorLogPath := filepath.Join(filepath.Dir(accessLogPath), "error.log")
|
||||||
rendered = strings.ReplaceAll(rendered, openrestyrender.ErrorLogPlaceholder, filepath.ToSlash(errorLogPath))
|
rendered = strings.ReplaceAll(rendered, openrestyrender.ErrorLogPlaceholder, filepath.ToSlash(errorLogPath))
|
||||||
}
|
}
|
||||||
|
if pidPath := m.pidRuntimePath(); pidPath != "" {
|
||||||
|
slashPIDPath := filepath.ToSlash(pidPath)
|
||||||
|
rendered = strings.ReplaceAll(rendered, openrestyrender.PIDPathPlaceholder, slashPIDPath)
|
||||||
|
rendered = strings.ReplaceAll(rendered, "pid logs/nginx.pid;", "pid "+slashPIDPath+";")
|
||||||
|
if err := os.MkdirAll(filepath.Dir(pidPath), nginxDirPerm); err != nil {
|
||||||
|
slog.Warn("ensure nginx pid directory failed", "path", filepath.Dir(pidPath), "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cacheDir := m.nginxCacheRuntimeDir(); cacheDir != "" {
|
||||||
|
slashCacheDir := filepath.ToSlash(cacheDir)
|
||||||
|
rendered = strings.ReplaceAll(rendered, openrestyrender.NginxCacheDirPlaceholder, slashCacheDir)
|
||||||
|
if !strings.Contains(rendered, "client_body_temp_path") {
|
||||||
|
writablePaths := fmt.Sprintf(
|
||||||
|
" client_body_temp_path %s/client_temp;\n proxy_temp_path %s/proxy_temp;\n fastcgi_temp_path %s/fastcgi_temp;\n uwsgi_temp_path %s/uwsgi_temp;\n scgi_temp_path %s/scgi_temp;\n",
|
||||||
|
slashCacheDir, slashCacheDir, slashCacheDir, slashCacheDir, slashCacheDir,
|
||||||
|
)
|
||||||
|
rendered = strings.Replace(rendered, "http {", "http {\n"+writablePaths, 1)
|
||||||
|
}
|
||||||
|
for _, subDir := range []string{"client_temp", "proxy_temp", "fastcgi_temp", "uwsgi_temp", "scgi_temp"} {
|
||||||
|
if err := os.MkdirAll(filepath.Join(cacheDir, subDir), nginxDirPerm); err != nil {
|
||||||
|
slog.Warn("ensure nginx cache directory failed", "path", filepath.Join(cacheDir, subDir), "error", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if luaDir := m.luaRuntimePath(); luaDir != "" {
|
if luaDir := m.luaRuntimePath(); luaDir != "" {
|
||||||
rendered = strings.ReplaceAll(rendered, openrestyrender.LuaDirPlaceholder, luaDir)
|
rendered = strings.ReplaceAll(rendered, openrestyrender.LuaDirPlaceholder, luaDir)
|
||||||
}
|
}
|
||||||
@@ -1339,6 +1374,30 @@ func (m *Manager) accessLogRuntimePath() string {
|
|||||||
return filepath.ToSlash(strings.TrimSpace(m.AccessLogPath))
|
return filepath.ToSlash(strings.TrimSpace(m.AccessLogPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Manager) varRuntimeDir() string {
|
||||||
|
if accessLogPath := strings.TrimSpace(m.AccessLogPath); accessLogPath != "" {
|
||||||
|
return filepath.Dir(filepath.Dir(filepath.Dir(accessLogPath)))
|
||||||
|
}
|
||||||
|
if mainConfigPath := strings.TrimSpace(m.MainConfigPath); mainConfigPath != "" {
|
||||||
|
return filepath.Clean(filepath.Join(filepath.Dir(mainConfigPath), "..", ".."))
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) pidRuntimePath() string {
|
||||||
|
if varRoot := m.varRuntimeDir(); varRoot != "" {
|
||||||
|
return filepath.ToSlash(filepath.Join(varRoot, "run", "nginx.pid"))
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Manager) nginxCacheRuntimeDir() string {
|
||||||
|
if varRoot := m.varRuntimeDir(); varRoot != "" {
|
||||||
|
return filepath.ToSlash(filepath.Join(varRoot, "cache", "nginx"))
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) luaRuntimePath() string {
|
func (m *Manager) luaRuntimePath() string {
|
||||||
if strings.TrimSpace(m.NginxLuaDir) == "" {
|
if strings.TrimSpace(m.NginxLuaDir) == "" {
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
package nginx
|
package nginx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
openrestyrender "github.com/Rain-kl/Wavelet/pkg/render/openresty"
|
|
||||||
|
|
||||||
"github.com/Rain-kl/Wavelet/internal/apps/agent/runtimeuser"
|
"github.com/Rain-kl/Wavelet/internal/apps/agent/runtimeuser"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OpenFlareRuntimeUser is the shared OS account for the agent process and
|
// OpenFlareRuntimeUser is the shared OS account for the agent process and
|
||||||
// OpenResty worker processes.
|
// OpenResty worker processes.
|
||||||
const OpenFlareRuntimeUser = openrestyrender.OpenFlareRuntimeUser
|
const OpenFlareRuntimeUser = runtimeuser.Name
|
||||||
|
|
||||||
// OpenRestyWorkerUser is an alias kept for internal call sites.
|
// OpenRestyWorkerUser is an alias kept for internal call sites.
|
||||||
const OpenRestyWorkerUser = OpenFlareRuntimeUser
|
const OpenRestyWorkerUser = runtimeuser.Name
|
||||||
|
|
||||||
// EnsureWorldTraversablePath makes targetDir and its ancestors world-traversable.
|
// EnsureWorldTraversablePath makes targetDir and its ancestors world-traversable.
|
||||||
func EnsureWorldTraversablePath(targetDir string) error {
|
func EnsureWorldTraversablePath(targetDir string) error {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ func EnsureProcessUser() error {
|
|||||||
slog.Warn("agent is not running as runtime user", "expected", Name, "euid", os.Geteuid())
|
slog.Warn("agent is not running as runtime user", "expected", Name, "euid", os.Geteuid())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if dropErr := dropTo(account); dropErr != nil {
|
if dropErr := dropToImpl(account); dropErr != nil {
|
||||||
return dropErr
|
return dropErr
|
||||||
}
|
}
|
||||||
slog.Info("agent dropped privileges to runtime user", "user", Name, "uid", account.UID)
|
slog.Info("agent dropped privileges to runtime user", "user", Name, "uid", account.UID)
|
||||||
@@ -108,4 +108,85 @@ func EnsurePathOwnership(root string, dirPerm os.FileMode, filePerm os.FileMode)
|
|||||||
return lookupErr
|
return lookupErr
|
||||||
}
|
}
|
||||||
return applyOwnershipAndModes(root, account, dirPerm, filePerm)
|
return applyOwnershipAndModes(root, account, dirPerm, filePerm)
|
||||||
|
}
|
||||||
|
|
||||||
|
var dropToImpl = func(account *Account) error {
|
||||||
|
return fmt.Errorf("drop to runtime user %s is not supported on this platform", account.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensureWorldTraversablePath(targetDir string) error {
|
||||||
|
const maxDepth = 12
|
||||||
|
current := filepath.Clean(strings.TrimSpace(targetDir))
|
||||||
|
if current == "" || current == "." {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for depth := 0; depth < maxDepth; depth++ {
|
||||||
|
if err := os.Chmod(current, DefaultDirPerm); err != nil { //nolint:gosec // parent dirs must be traversable by the runtime user
|
||||||
|
if os.IsNotExist(err) || os.IsPermission(err) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return fmt.Errorf("chmod %s: %w", current, err)
|
||||||
|
}
|
||||||
|
parent := filepath.Dir(current)
|
||||||
|
if parent == current {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
current = parent
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyOwnershipAndModes(root string, account *Account, dirPerm os.FileMode, filePerm os.FileMode) error {
|
||||||
|
return filepath.WalkDir(root, func(path string, entry os.DirEntry, walkErr error) error {
|
||||||
|
if walkErr != nil {
|
||||||
|
return walkErr
|
||||||
|
}
|
||||||
|
info, err := entry.Info()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if os.Geteuid() == 0 {
|
||||||
|
if chownErr := os.Chown(path, account.UID, account.GID); chownErr != nil && !os.IsNotExist(chownErr) { //nolint:gosec // path is under managed root walk
|
||||||
|
return fmt.Errorf("chown %s: %w", path, chownErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if entry.IsDir() {
|
||||||
|
if chmodErr := os.Chmod(path, dirPerm); chmodErr != nil && !os.IsNotExist(chmodErr) { //nolint:gosec // path is under managed root walk
|
||||||
|
return fmt.Errorf("chmod dir %s: %w", path, chmodErr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !info.Mode().IsRegular() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if chmodErr := os.Chmod(path, filePerm); chmodErr != nil && !os.IsNotExist(chmodErr) { //nolint:gosec // path is under managed root walk
|
||||||
|
return fmt.Errorf("chmod file %s: %w", path, chmodErr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensureModesOnly(root string, dirPerm os.FileMode, filePerm os.FileMode) error {
|
||||||
|
return filepath.WalkDir(root, func(path string, entry os.DirEntry, walkErr error) error {
|
||||||
|
if walkErr != nil {
|
||||||
|
return walkErr
|
||||||
|
}
|
||||||
|
info, err := entry.Info()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if entry.IsDir() {
|
||||||
|
if chmodErr := os.Chmod(path, dirPerm); chmodErr != nil && !os.IsNotExist(chmodErr) { //nolint:gosec // path is under managed root walk
|
||||||
|
return fmt.Errorf("chmod dir %s: %w", path, chmodErr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if !info.Mode().IsRegular() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if chmodErr := os.Chmod(path, filePerm); chmodErr != nil && !os.IsNotExist(chmodErr) { //nolint:gosec // path is under managed root walk
|
||||||
|
return fmt.Errorf("chmod file %s: %w", path, chmodErr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
}
|
}
|
||||||
@@ -4,96 +4,17 @@ package runtimeuser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
func dropTo(account *Account) error {
|
func init() {
|
||||||
if err := syscall.Setgid(account.GID); err != nil {
|
dropToImpl = func(account *Account) error {
|
||||||
return fmt.Errorf("setgid %d: %w", account.GID, err)
|
if err := syscall.Setgid(account.GID); err != nil {
|
||||||
}
|
return fmt.Errorf("setgid %d: %w", account.GID, err)
|
||||||
if err := syscall.Setuid(account.UID); err != nil {
|
|
||||||
return fmt.Errorf("setuid %d: %w", account.UID, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ensureWorldTraversablePath(targetDir string) error {
|
|
||||||
const maxDepth = 12
|
|
||||||
current := filepath.Clean(strings.TrimSpace(targetDir))
|
|
||||||
if current == "" || current == "." {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
for depth := 0; depth < maxDepth; depth++ {
|
|
||||||
if err := os.Chmod(current, DefaultDirPerm); err != nil { //nolint:gosec // parent dirs must be traversable by the runtime user
|
|
||||||
if os.IsNotExist(err) || os.IsPermission(err) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return fmt.Errorf("chmod %s: %w", current, err)
|
|
||||||
}
|
}
|
||||||
parent := filepath.Dir(current)
|
if err := syscall.Setuid(account.UID); err != nil {
|
||||||
if parent == current {
|
return fmt.Errorf("setuid %d: %w", account.UID, err)
|
||||||
break
|
|
||||||
}
|
|
||||||
current = parent
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func applyOwnershipAndModes(root string, account *Account, dirPerm os.FileMode, filePerm os.FileMode) error {
|
|
||||||
return filepath.WalkDir(root, func(path string, entry os.DirEntry, walkErr error) error {
|
|
||||||
if walkErr != nil {
|
|
||||||
return walkErr
|
|
||||||
}
|
|
||||||
info, err := entry.Info()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if os.Geteuid() == 0 {
|
|
||||||
if chownErr := os.Chown(path, account.UID, account.GID); chownErr != nil && !os.IsNotExist(chownErr) { //nolint:gosec // path is under managed root walk
|
|
||||||
return fmt.Errorf("chown %s: %w", path, chownErr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if entry.IsDir() {
|
|
||||||
if chmodErr := os.Chmod(path, dirPerm); chmodErr != nil && !os.IsNotExist(chmodErr) { //nolint:gosec // path is under managed root walk
|
|
||||||
return fmt.Errorf("chmod dir %s: %w", path, chmodErr)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if !info.Mode().IsRegular() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
mode := filePerm
|
|
||||||
if chmodErr := os.Chmod(path, mode); chmodErr != nil && !os.IsNotExist(chmodErr) { //nolint:gosec // path is under managed root walk
|
|
||||||
return fmt.Errorf("chmod file %s: %w", path, chmodErr)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func ensureModesOnly(root string, dirPerm os.FileMode, filePerm os.FileMode) error {
|
|
||||||
return filepath.WalkDir(root, func(path string, entry os.DirEntry, walkErr error) error {
|
|
||||||
if walkErr != nil {
|
|
||||||
return walkErr
|
|
||||||
}
|
|
||||||
info, err := entry.Info()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if entry.IsDir() {
|
|
||||||
if chmodErr := os.Chmod(path, dirPerm); chmodErr != nil && !os.IsNotExist(chmodErr) { //nolint:gosec // path is under managed root walk
|
|
||||||
return fmt.Errorf("chmod dir %s: %w", path, chmodErr)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if !info.Mode().IsRegular() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if chmodErr := os.Chmod(path, filePerm); chmodErr != nil && !os.IsNotExist(chmodErr) { //nolint:gosec // path is under managed root walk
|
|
||||||
return fmt.Errorf("chmod file %s: %w", path, chmodErr)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
@@ -109,7 +109,7 @@ const defaultOpenRestyMainConfigTemplate = `# This file is generated by OpenFlar
|
|||||||
user openflare;
|
user openflare;
|
||||||
worker_processes {{OpenRestyWorkerProcesses}};
|
worker_processes {{OpenRestyWorkerProcesses}};
|
||||||
worker_rlimit_nofile {{OpenRestyWorkerRlimitNofile}};
|
worker_rlimit_nofile {{OpenRestyWorkerRlimitNofile}};
|
||||||
pid logs/nginx.pid;
|
pid __OPENFLARE_PID_PATH__;
|
||||||
error_log {{OpenRestyErrorLogPath}} warn;
|
error_log {{OpenRestyErrorLogPath}} warn;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
@@ -120,6 +120,11 @@ http {
|
|||||||
include mime.types;
|
include mime.types;
|
||||||
default_type application/octet-stream;
|
default_type application/octet-stream;
|
||||||
server_tokens off;
|
server_tokens off;
|
||||||
|
client_body_temp_path __OPENFLARE_NGINX_CACHE_DIR__/client_temp;
|
||||||
|
proxy_temp_path __OPENFLARE_NGINX_CACHE_DIR__/proxy_temp;
|
||||||
|
fastcgi_temp_path __OPENFLARE_NGINX_CACHE_DIR__/fastcgi_temp;
|
||||||
|
uwsgi_temp_path __OPENFLARE_NGINX_CACHE_DIR__/uwsgi_temp;
|
||||||
|
scgi_temp_path __OPENFLARE_NGINX_CACHE_DIR__/scgi_temp;
|
||||||
{{OpenRestyConnectionUpgradeMap}}{{OpenRestyDefaultServerBlock}} log_format openflare_json escape=json '{"ts":"$time_iso8601","host":"$host","path":"$request_uri","remote_addr":"$remote_addr","status":$status,"request_time":$request_time,"bytes_sent":$body_bytes_sent,"request_length":$request_length}';
|
{{OpenRestyConnectionUpgradeMap}}{{OpenRestyDefaultServerBlock}} log_format openflare_json escape=json '{"ts":"$time_iso8601","host":"$host","path":"$request_uri","remote_addr":"$remote_addr","status":$status,"request_time":$request_time,"bytes_sent":$body_bytes_sent,"request_length":$request_length}';
|
||||||
access_log {{OpenRestyAccessLogPath}} openflare_json;
|
access_log {{OpenRestyAccessLogPath}} openflare_json;
|
||||||
sendfile on;
|
sendfile on;
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ const (
|
|||||||
RouteConfigPlaceholder = "__OPENFLARE_ROUTE_CONFIG__"
|
RouteConfigPlaceholder = "__OPENFLARE_ROUTE_CONFIG__"
|
||||||
AccessLogPlaceholder = "__OPENFLARE_ACCESS_LOG__"
|
AccessLogPlaceholder = "__OPENFLARE_ACCESS_LOG__"
|
||||||
ErrorLogPlaceholder = "__OPENFLARE_ERROR_LOG__"
|
ErrorLogPlaceholder = "__OPENFLARE_ERROR_LOG__"
|
||||||
|
PIDPathPlaceholder = "__OPENFLARE_PID_PATH__"
|
||||||
|
NginxCacheDirPlaceholder = "__OPENFLARE_NGINX_CACHE_DIR__"
|
||||||
LuaDirPlaceholder = "__OPENFLARE_LUA_DIR__"
|
LuaDirPlaceholder = "__OPENFLARE_LUA_DIR__"
|
||||||
ObservabilityListenPlaceholder = "__OPENFLARE_OBSERVABILITY_LISTEN__"
|
ObservabilityListenPlaceholder = "__OPENFLARE_OBSERVABILITY_LISTEN__"
|
||||||
ObservabilityPortPlaceholder = "__OPENFLARE_OBSERVABILITY_PORT__"
|
ObservabilityPortPlaceholder = "__OPENFLARE_OBSERVABILITY_PORT__"
|
||||||
@@ -36,7 +38,7 @@ const defaultMainConfigTemplate = `# This file is generated by OpenFlare. Do not
|
|||||||
user ` + OpenFlareRuntimeUser + `;
|
user ` + OpenFlareRuntimeUser + `;
|
||||||
worker_processes {{OpenRestyWorkerProcesses}};
|
worker_processes {{OpenRestyWorkerProcesses}};
|
||||||
worker_rlimit_nofile {{OpenRestyWorkerRlimitNofile}};
|
worker_rlimit_nofile {{OpenRestyWorkerRlimitNofile}};
|
||||||
pid logs/nginx.pid;
|
pid __OPENFLARE_PID_PATH__;
|
||||||
error_log {{OpenRestyErrorLogPath}} warn;
|
error_log {{OpenRestyErrorLogPath}} warn;
|
||||||
|
|
||||||
events {
|
events {
|
||||||
@@ -47,6 +49,11 @@ http {
|
|||||||
include mime.types;
|
include mime.types;
|
||||||
default_type application/octet-stream;
|
default_type application/octet-stream;
|
||||||
server_tokens off;
|
server_tokens off;
|
||||||
|
client_body_temp_path __OPENFLARE_NGINX_CACHE_DIR__/client_temp;
|
||||||
|
proxy_temp_path __OPENFLARE_NGINX_CACHE_DIR__/proxy_temp;
|
||||||
|
fastcgi_temp_path __OPENFLARE_NGINX_CACHE_DIR__/fastcgi_temp;
|
||||||
|
uwsgi_temp_path __OPENFLARE_NGINX_CACHE_DIR__/uwsgi_temp;
|
||||||
|
scgi_temp_path __OPENFLARE_NGINX_CACHE_DIR__/scgi_temp;
|
||||||
{{OpenRestyConnectionUpgradeMap}}{{OpenRestyDefaultServerBlock}} log_format openflare_json escape=json '{"ts":"$time_iso8601","host":"$host","path":"$request_uri","remote_addr":"$remote_addr","status":$status,"request_time":$request_time,"bytes_sent":$body_bytes_sent,"request_length":$request_length}';
|
{{OpenRestyConnectionUpgradeMap}}{{OpenRestyDefaultServerBlock}} log_format openflare_json escape=json '{"ts":"$time_iso8601","host":"$host","path":"$request_uri","remote_addr":"$remote_addr","status":$status,"request_time":$request_time,"bytes_sent":$body_bytes_sent,"request_length":$request_length}';
|
||||||
access_log {{OpenRestyAccessLogPath}} openflare_json;
|
access_log {{OpenRestyAccessLogPath}} openflare_json;
|
||||||
sendfile on;
|
sendfile on;
|
||||||
|
|||||||
Reference in New Issue
Block a user