Skip to content

Commit fa3c36c

Browse files
committed
Merge branch 'main' into support-otel-pipelines
2 parents e0c5a0e + 1e8bd29 commit fa3c36c

22 files changed

+486
-125
lines changed

Makefile

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ GOBIN ?= $$(go env GOPATH)/bin
1717
# | OS_RELEASE | OS_VERSION | NOTES |
1818
# | ---------------- | ----------------------------------------- | -------------------------------------------------------------- |
1919
# | amazonlinux | 2, 2023 | |
20-
# | ubuntu | 20.04, 22.04 24.04 | |
20+
# | ubuntu | 22.04, 24.04 25.04 | |
2121
# | debian | bullseye-slim, bookworm-slim | |
22-
# | redhatenterprise | 8, 9 | |
23-
# | rockylinux | 8, 9 | |
24-
# | almalinux | 8, 9 | |
25-
# | alpine | 3.18, 3.19, 3.20, 3.21 3.22 | |
26-
# | oraclelinux | 8, 9 | |
22+
# | redhatenterprise | 8, 9, 10 | |
23+
# | rockylinux | 8, 9, 10 | |
24+
# | almalinux | 8, 9, 10 | |
25+
# | alpine | 3.19, 3.20, 3.21 3.22 | |
26+
# | oraclelinux | 8, 9, 10 | |
2727
# | suse | sle15 | |
2828
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
2929
OS_RELEASE ?= ubuntu

internal/collector/otel_collector_plugin.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -549,15 +549,10 @@ func (oc *Collector) updateNginxAppProtectTcplogReceivers(nginxConfigContext *mo
549549
oc.config.Collector.Receivers.TcplogReceivers = make(map[string]*config.TcplogReceiver)
550550
}
551551

552-
if nginxConfigContext.NAPSysLogServers != nil {
553-
napLoop:
554-
for _, napSysLogServer := range nginxConfigContext.NAPSysLogServers {
555-
if oc.doesTcplogReceiverAlreadyExist(napSysLogServer) {
556-
continue napLoop
557-
}
558-
552+
if nginxConfigContext.NAPSysLogServer != "" {
553+
if !oc.doesTcplogReceiverAlreadyExist(nginxConfigContext.NAPSysLogServer) {
559554
oc.config.Collector.Receivers.TcplogReceivers["nginx_app_protect"] = &config.TcplogReceiver{
560-
ListenAddress: napSysLogServer,
555+
ListenAddress: nginxConfigContext.NAPSysLogServer,
561556
Operators: []config.Operator{
562557
{
563558
Type: "add",
@@ -614,12 +609,10 @@ func (oc *Collector) configDeletedNapReceivers(nginxConfigContext *model.NginxCo
614609
elements[tcplogReceiver.ListenAddress] = true
615610
}
616611

617-
if nginxConfigContext.NAPSysLogServers != nil {
612+
if nginxConfigContext.NAPSysLogServer != "" {
618613
addressesToDelete := make(map[string]bool)
619-
for _, napAddress := range nginxConfigContext.NAPSysLogServers {
620-
if !elements[napAddress] {
621-
addressesToDelete[napAddress] = true
622-
}
614+
if !elements[nginxConfigContext.NAPSysLogServer] {
615+
addressesToDelete[nginxConfigContext.NAPSysLogServer] = true
623616
}
624617

625618
return addressesToDelete

internal/collector/otel_collector_plugin_test.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -736,9 +736,7 @@ func TestCollector_updateNginxAppProtectTcplogReceivers(t *testing.T) {
736736
require.NoError(t, err)
737737

738738
nginxConfigContext := &model.NginxConfigContext{
739-
NAPSysLogServers: []string{
740-
"localhost:151",
741-
},
739+
NAPSysLogServer: "localhost:151",
742740
}
743741

744742
assert.Empty(t, conf.Collector.Receivers.TcplogReceivers)
@@ -771,9 +769,7 @@ func TestCollector_updateNginxAppProtectTcplogReceivers(t *testing.T) {
771769
t.Run("Test 4: NewCollector tcplogReceiver added and deleted another", func(tt *testing.T) {
772770
tcplogReceiverDeleted := collector.updateNginxAppProtectTcplogReceivers(
773771
&model.NginxConfigContext{
774-
NAPSysLogServers: []string{
775-
"localhost:152",
776-
},
772+
NAPSysLogServer: "localhost:152",
777773
},
778774
)
779775

internal/config/config_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ func agentConfig() *Config {
865865
},
866866
AllowedDirectories: []string{
867867
"/etc/nginx/", "/etc/nginx-agent/", "/usr/local/etc/nginx/", "/var/run/nginx/", "/var/log/nginx/",
868-
"/usr/share/nginx/modules/",
868+
"/usr/share/nginx/modules/", "/etc/app_protect/",
869869
},
870870
Collector: &Collector{
871871
ConfigPath: "/etc/nginx-agent/nginx-agent-otelcol.yaml",

internal/config/defaults.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ func DefaultAllowedDirectories() []string {
109109
"/usr/share/nginx/modules",
110110
"/var/run/nginx",
111111
"/var/log/nginx",
112+
"/etc/app_protect",
112113
}
113114
}
114115

internal/datasource/config/nginx_config_parser.go

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ const (
4747

4848
type (
4949
NginxConfigParser struct {
50-
agentConfig *config.Config
50+
agentConfig *config.Config
51+
previousNAPSysLogServer string
5152
}
5253
)
5354

@@ -65,7 +66,8 @@ type (
6566

6667
func 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

Comments
 (0)