@@ -47,7 +47,8 @@ const (
4747
4848type (
4949 NginxConfigParser struct {
50- agentConfig * config.Config
50+ agentConfig * config.Config
51+ previousNAPSysLogServer string
5152 }
5253)
5354
6566
6667func NewNginxConfigParser (agentConfig * config.Config ) * NginxConfigParser {
6768 return & NginxConfigParser {
68- agentConfig : agentConfig ,
69+ agentConfig : agentConfig ,
70+ previousNAPSysLogServer : "" ,
6971 }
7072}
7173
@@ -107,6 +109,7 @@ func (ncp *NginxConfigParser) createNginxConfigContext(
107109 payload * crossplane.Payload ,
108110) (* model.NginxConfigContext , error ) {
109111 napSyslogServersFound := make (map [string ]bool )
112+ napEnabled := false
110113
111114 nginxConfigContext := & model.NginxConfigContext {
112115 InstanceID : instance .GetInstanceMeta ().GetInstanceId (),
@@ -139,7 +142,7 @@ func (ncp *NginxConfigParser) createNginxConfigContext(
139142 func (ctx context.Context , parent , directive * crossplane.Directive ) error {
140143 switch directive .Directive {
141144 case "include" :
142- include := ncp .parseIncludeDirective (directive )
145+ include := ncp .parseIncludeDirective (directive , & conf )
143146
144147 nginxConfigContext .Includes = append (nginxConfigContext .Includes , include )
145148 case "log_format" :
@@ -173,19 +176,11 @@ func (ncp *NginxConfigParser) createNginxConfigContext(
173176 }
174177 case "app_protect_security_log" :
175178 if len (directive .Args ) > 1 {
176- syslogArg := directive .Args [1 ]
177- re := regexp .MustCompile (`syslog:server=([\S]+)` )
178- matches := re .FindStringSubmatch (syslogArg )
179- if len (matches ) > 1 {
180- syslogServer := matches [1 ]
181- if ! napSyslogServersFound [syslogServer ] {
182- nginxConfigContext .NAPSysLogServers = append (
183- nginxConfigContext .NAPSysLogServers ,
184- syslogServer ,
185- )
186- napSyslogServersFound [syslogServer ] = true
187- slog .DebugContext (ctx , "Found NAP syslog server" , "address" , syslogServer )
188- }
179+ napEnabled = true
180+ sysLogServer := ncp .findLocalSysLogServers (directive .Args [1 ])
181+ if sysLogServer != "" && ! napSyslogServersFound [sysLogServer ] {
182+ napSyslogServersFound [sysLogServer ] = true
183+ slog .DebugContext (ctx , "Found NAP syslog server" , "address" , sysLogServer )
189184 }
190185 }
191186 }
@@ -207,6 +202,17 @@ func (ncp *NginxConfigParser) createNginxConfigContext(
207202 nginxConfigContext .PlusAPI = plusAPI
208203 }
209204
205+ if len (napSyslogServersFound ) > 0 {
206+ syslogServer := ncp .findAvailableSyslogServers (ctx , napSyslogServersFound )
207+ if syslogServer != "" {
208+ nginxConfigContext .NAPSysLogServer = syslogServer
209+ ncp .previousNAPSysLogServer = syslogServer
210+ }
211+ } else if napEnabled {
212+ slog .WarnContext (ctx , "Could not find available local NGINX App Protect syslog server. " +
213+ "Security violations will not be collected." )
214+ }
215+
210216 fileMeta , err := files .FileMeta (conf .File )
211217 if err != nil {
212218 slog .WarnContext (ctx , "Unable to get file metadata" , "file_name" , conf .File , "error" , err )
@@ -218,12 +224,58 @@ func (ncp *NginxConfigParser) createNginxConfigContext(
218224 return nginxConfigContext , nil
219225}
220226
221- func (ncp * NginxConfigParser ) parseIncludeDirective (directive * crossplane.Directive ) string {
227+ func (ncp * NginxConfigParser ) findAvailableSyslogServers (ctx context.Context , napSyslogServers map [string ]bool ) string {
228+ if ncp .previousNAPSysLogServer != "" {
229+ if _ , ok := napSyslogServers [ncp .previousNAPSysLogServer ]; ok {
230+ return ncp .previousNAPSysLogServer
231+ }
232+ }
233+
234+ for napSyslogServer := range napSyslogServers {
235+ ln , err := net .Listen ("tcp" , napSyslogServer )
236+ if err != nil {
237+ slog .DebugContext (ctx , "NAP syslog server is not reachable" , "address" , napSyslogServer ,
238+ "error" , err )
239+
240+ continue
241+ }
242+ ln .Close ()
243+
244+ slog .DebugContext (ctx , "Found valid NAP syslog server" , "address" , napSyslogServer )
245+
246+ return napSyslogServer
247+ }
248+
249+ return ""
250+ }
251+
252+ func (ncp * NginxConfigParser ) findLocalSysLogServers (sysLogServer string ) string {
253+ re := regexp .MustCompile (`syslog:server=([\S]+)` )
254+ matches := re .FindStringSubmatch (sysLogServer )
255+ if len (matches ) > 1 {
256+ host , _ , err := net .SplitHostPort (matches [1 ])
257+ if err != nil {
258+ return ""
259+ }
260+
261+ ip := net .ParseIP (host )
262+ if ip .IsLoopback () || strings .EqualFold (host , "localhost" ) {
263+ return matches [1 ]
264+ }
265+ }
266+
267+ return ""
268+ }
269+
270+ func (ncp * NginxConfigParser ) parseIncludeDirective (
271+ directive * crossplane.Directive ,
272+ configFile * crossplane.Config ,
273+ ) string {
222274 var include string
223275 if filepath .IsAbs (directive .Args [0 ]) {
224276 include = directive .Args [0 ]
225277 } else {
226- include = filepath .Join (filepath .Dir (directive .File ), directive .Args [0 ])
278+ include = filepath .Join (filepath .Dir (configFile .File ), directive .Args [0 ])
227279 }
228280
229281 return include
0 commit comments