nginx_conf.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. package self_check
  2. import (
  3. "fmt"
  4. "os"
  5. "strings"
  6. "time"
  7. "github.com/0xJacky/Nginx-UI/internal/nginx"
  8. "github.com/tufanbarisyildirim/gonginx/config"
  9. "github.com/tufanbarisyildirim/gonginx/dumper"
  10. "github.com/tufanbarisyildirim/gonginx/parser"
  11. )
  12. // CheckNginxConfIncludeSites checks if nginx.conf include sites-enabled
  13. func CheckNginxConfIncludeSites() error {
  14. path := nginx.GetConfEntryPath()
  15. content, err := os.ReadFile(path)
  16. if err != nil {
  17. return ErrFailedToReadNginxConf
  18. }
  19. // parse nginx.conf
  20. p := parser.NewStringParser(string(content), parser.WithSkipValidDirectivesErr())
  21. c, err := p.Parse()
  22. if err != nil {
  23. return ErrParseNginxConf
  24. }
  25. // find http block
  26. for _, v := range c.Block.Directives {
  27. if v.GetName() == "http" {
  28. // find include sites-enabled
  29. for _, directive := range v.GetBlock().GetDirectives() {
  30. if directive.GetName() == "include" && len(directive.GetParameters()) > 0 &&
  31. directive.GetParameters()[0].Value == nginx.GetConfPath("sites-enabled/*") {
  32. return nil
  33. }
  34. }
  35. return ErrNginxConfNotIncludeSitesEnabled
  36. }
  37. }
  38. return ErrNginxConfNoHttpBlock
  39. }
  40. // CheckNginxConfIncludeStreams checks if nginx.conf include streams-enabled
  41. func CheckNginxConfIncludeStreams() error {
  42. path := nginx.GetConfEntryPath()
  43. content, err := os.ReadFile(path)
  44. if err != nil {
  45. return ErrFailedToReadNginxConf
  46. }
  47. // parse nginx.conf
  48. p := parser.NewStringParser(string(content), parser.WithSkipValidDirectivesErr())
  49. c, err := p.Parse()
  50. if err != nil {
  51. return ErrParseNginxConf
  52. }
  53. // find http block
  54. for _, v := range c.Block.Directives {
  55. if v.GetName() == "stream" {
  56. // find include sites-enabled
  57. for _, directive := range v.GetBlock().GetDirectives() {
  58. if directive.GetName() == "include" && len(directive.GetParameters()) > 0 &&
  59. directive.GetParameters()[0].Value == nginx.GetConfPath("streams-enabled/*") {
  60. return nil
  61. }
  62. }
  63. return ErrNginxConfNotIncludeStreamEnabled
  64. }
  65. }
  66. return ErrorNginxConfNoStreamBlock
  67. }
  68. // FixNginxConfIncludeSites attempts to fix nginx.conf include sites-enabled
  69. func FixNginxConfIncludeSites() error {
  70. path := nginx.GetConfEntryPath()
  71. content, err := os.ReadFile(path)
  72. if err != nil {
  73. return ErrFailedToReadNginxConf
  74. }
  75. // create a backup file (+.bak.timestamp)
  76. backupPath := fmt.Sprintf("%s.bak.%d", path, time.Now().Unix())
  77. err = os.WriteFile(backupPath, content, 0644)
  78. if err != nil {
  79. return ErrFailedToCreateBackup
  80. }
  81. // parse nginx.conf
  82. p := parser.NewStringParser(string(content), parser.WithSkipValidDirectivesErr())
  83. c, err := p.Parse()
  84. if err != nil {
  85. return ErrParseNginxConf
  86. }
  87. // find http block
  88. for _, v := range c.Block.Directives {
  89. if v.GetName() == "http" {
  90. // add include sites-enabled/* to http block
  91. includeDirective := &config.Directive{
  92. Name: "include",
  93. Parameters: []config.Parameter{{Value: nginx.GetConfPath("sites-enabled/*")}},
  94. }
  95. realBlock := v.GetBlock().(*config.HTTP)
  96. realBlock.Directives = append(realBlock.Directives, includeDirective)
  97. // write to file
  98. return os.WriteFile(path, []byte(dumper.DumpBlock(c.Block, dumper.IndentedStyle)), 0644)
  99. }
  100. }
  101. // if no http block, append http block with include sites-enabled/*
  102. content = append(content, fmt.Appendf(nil, "\nhttp {\n\tinclude %s;\n}\n", nginx.GetConfPath("sites-enabled/*"))...)
  103. return os.WriteFile(path, content, 0644)
  104. }
  105. // FixNginxConfIncludeStreams attempts to fix nginx.conf include streams-enabled
  106. func FixNginxConfIncludeStreams() error {
  107. path := nginx.GetConfEntryPath()
  108. content, err := os.ReadFile(path)
  109. if err != nil {
  110. return ErrFailedToReadNginxConf
  111. }
  112. // create a backup file (+.bak.timestamp)
  113. backupPath := fmt.Sprintf("%s.bak.%d", path, time.Now().Unix())
  114. err = os.WriteFile(backupPath, content, 0644)
  115. if err != nil {
  116. return ErrFailedToCreateBackup
  117. }
  118. // parse nginx.conf
  119. p := parser.NewStringParser(string(content), parser.WithSkipValidDirectivesErr())
  120. c, err := p.Parse()
  121. if err != nil {
  122. return ErrParseNginxConf
  123. }
  124. // find stream block
  125. for _, v := range c.Block.Directives {
  126. if v.GetName() == "stream" {
  127. // add include streams-enabled/* to stream block
  128. includeDirective := &config.Directive{
  129. Name: "include",
  130. Parameters: []config.Parameter{{Value: nginx.GetConfPath("streams-enabled/*")}},
  131. }
  132. realBlock := v.GetBlock().(*config.Block)
  133. realBlock.Directives = append(realBlock.Directives, includeDirective)
  134. // write to file
  135. return os.WriteFile(path, []byte(dumper.DumpBlock(c.Block, dumper.IndentedStyle)), 0644)
  136. }
  137. }
  138. // if no stream block, append stream block with include streams-enabled/*
  139. content = append(content, fmt.Appendf(nil, "\nstream {\n\tinclude %s;\n}\n", nginx.GetConfPath("streams-enabled/*"))...)
  140. return os.WriteFile(path, content, 0644)
  141. }
  142. // CheckNginxConfIncludeConfD checks if nginx.conf includes conf.d directory
  143. func CheckNginxConfIncludeConfD() error {
  144. path := nginx.GetConfEntryPath()
  145. content, err := os.ReadFile(path)
  146. if err != nil {
  147. return ErrFailedToReadNginxConf
  148. }
  149. // parse nginx.conf
  150. p := parser.NewStringParser(string(content), parser.WithSkipValidDirectivesErr())
  151. c, err := p.Parse()
  152. if err != nil {
  153. return ErrParseNginxConf
  154. }
  155. // find http block
  156. for _, v := range c.Block.Directives {
  157. if v.GetName() == "http" {
  158. // find include conf.d
  159. for _, directive := range v.GetBlock().GetDirectives() {
  160. if directive.GetName() == "include" && len(directive.GetParameters()) > 0 &&
  161. strings.HasPrefix(directive.GetParameters()[0].Value, nginx.GetConfPath("conf.d")) {
  162. return nil
  163. }
  164. }
  165. return ErrNginxConfNotIncludeConfD
  166. }
  167. }
  168. return ErrNginxConfNoHttpBlock
  169. }
  170. // FixNginxConfIncludeConfD attempts to fix nginx.conf to include conf.d directory
  171. func FixNginxConfIncludeConfD() error {
  172. path := nginx.GetConfEntryPath()
  173. content, err := os.ReadFile(path)
  174. if err != nil {
  175. return ErrFailedToReadNginxConf
  176. }
  177. // create a backup file (+.bak.timestamp)
  178. backupPath := fmt.Sprintf("%s.bak.%d", path, time.Now().Unix())
  179. err = os.WriteFile(backupPath, content, 0644)
  180. if err != nil {
  181. return ErrFailedToCreateBackup
  182. }
  183. // parse nginx.conf
  184. p := parser.NewStringParser(string(content), parser.WithSkipValidDirectivesErr())
  185. c, err := p.Parse()
  186. if err != nil {
  187. return ErrParseNginxConf
  188. }
  189. // find http block
  190. for _, v := range c.Block.Directives {
  191. if v.GetName() == "http" {
  192. // add include conf.d/*.conf to http block
  193. includeDirective := &config.Directive{
  194. Name: "include",
  195. Parameters: []config.Parameter{{Value: nginx.GetConfPath("conf.d/*.conf")}},
  196. }
  197. realBlock := v.GetBlock().(*config.HTTP)
  198. realBlock.Directives = append(realBlock.Directives, includeDirective)
  199. // write to file
  200. return os.WriteFile(path, []byte(dumper.DumpBlock(c.Block, dumper.IndentedStyle)), 0644)
  201. }
  202. }
  203. // if no http block, append http block with include conf.d/*.conf
  204. content = append(content, fmt.Appendf(nil, "\nhttp {\n\tinclude %s;\n}\n", nginx.GetConfPath("conf.d/*.conf"))...)
  205. return os.WriteFile(path, content, 0644)
  206. }