-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Support for NAP Pre-compiled Publication
Add Agent support for pre-compiled NAP content published via an external source.
- Loading branch information
Showing
26 changed files
with
1,162 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/** | ||
* Copyright (c) F5, Inc. | ||
* | ||
* This source code is licensed under the Apache License, Version 2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
package nap | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"time" | ||
|
||
"github.com/nginx/agent/v2/src/core" | ||
|
||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
// getAttackSignaturesVersion gets the version of the attack signatures package that is | ||
// installed on the system, the version format is YYYY.MM.DD. | ||
func getAttackSignaturesVersion(versionFile string) (string, error) { | ||
// Check if attack signatures version file exists | ||
logger.Debugf("Checking for the required NAP attack signatures version file - %v\n", versionFile) | ||
installed, err := core.FileExists(versionFile) | ||
if !installed && err == nil { | ||
return "", nil | ||
} else if err != nil { | ||
return "", err | ||
} | ||
|
||
// Get the version bytes | ||
versionBytes, err := ioutil.ReadFile(versionFile) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
// Read bytes into object | ||
attackSigVersionDateTime := napRevisionDateTime{} | ||
err = yaml.UnmarshalStrict([]byte(versionBytes), &attackSigVersionDateTime) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
// Convert revision date into the proper version format | ||
attackSigTime, err := time.Parse(time.RFC3339, attackSigVersionDateTime.RevisionDatetime) | ||
if err != nil { | ||
return "", err | ||
} | ||
attackSignatureReleaseVersion := fmt.Sprintf("%d.%02d.%02d", attackSigTime.Year(), attackSigTime.Month(), attackSigTime.Day()) | ||
logger.Debugf("Converted attack signature version (%s) found in %s to - %s\n", attackSigVersionDateTime.RevisionDatetime, ATTACK_SIGNATURES_UPDATE_FILE, attackSignatureReleaseVersion) | ||
|
||
return attackSignatureReleaseVersion, nil | ||
} |
70 changes: 70 additions & 0 deletions
70
src/extensions/nginx-app-protect/nap/attack_signatures_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/** | ||
* Copyright (c) F5, Inc. | ||
* | ||
* This source code is licensed under the Apache License, Version 2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
package nap | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
const ( | ||
testAttackSigVersionFile = "/tmp/test-attack-sigs-version.yaml" | ||
testAttackSigVersionFileContents = `--- | ||
checksum: t+N7AHGIKPhdDwb8zMZh2w | ||
filename: signatures.bin.tgz | ||
revisionDatetime: 2022-02-24T20:32:01Z` | ||
) | ||
|
||
func TestGetAttackSignaturesVersion(t *testing.T) { | ||
testCases := []struct { | ||
testName string | ||
versionFile string | ||
attackSigDateTime *napRevisionDateTime | ||
expVersion string | ||
expError error | ||
}{ | ||
{ | ||
testName: "AttackSignaturesInstalled", | ||
versionFile: testAttackSigVersionFile, | ||
attackSigDateTime: &napRevisionDateTime{ | ||
RevisionDatetime: "2022-02-24T20:32:01Z", | ||
}, | ||
expVersion: "2022.02.24", | ||
expError: nil, | ||
}, | ||
{ | ||
testName: "AttackSignaturesNotInstalled", | ||
versionFile: ATTACK_SIGNATURES_UPDATE_FILE, | ||
attackSigDateTime: nil, | ||
expVersion: "", | ||
expError: nil, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.testName, func(t *testing.T) { | ||
// Create a fake version file if required by test | ||
if tc.attackSigDateTime != nil { | ||
err := os.WriteFile(tc.versionFile, []byte(testAttackSigVersionFileContents), 0644) | ||
require.NoError(t, err) | ||
|
||
defer func() { | ||
err := os.Remove(tc.versionFile) | ||
require.NoError(t, err) | ||
}() | ||
} | ||
|
||
version, err := getAttackSignaturesVersion(tc.versionFile) | ||
assert.Equal(t, err, tc.expError) | ||
assert.Equal(t, tc.expVersion, version) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
* Copyright (c) F5, Inc. | ||
* | ||
* This source code is licensed under the Apache License, Version 2.0 license found in the | ||
* LICENSE file in the root directory of this source tree. | ||
*/ | ||
|
||
package nap | ||
|
||
import ( | ||
"path" | ||
|
||
"github.com/nginx/agent/sdk/v2" | ||
"github.com/nginx/agent/sdk/v2/proto" | ||
|
||
"github.com/nginxinc/nginx-go-crossplane" | ||
) | ||
|
||
// getContent parses the config for NAP policies and profiles | ||
func getContent(cfg *proto.NginxConfig) ([]string, []string) { | ||
policyMap := make(map[string]bool) | ||
profileMap := make(map[string]bool) | ||
|
||
for _, directory := range cfg.GetDirectoryMap().GetDirectories() { | ||
for _, file := range directory.GetFiles() { | ||
confFile := path.Join(directory.GetName(), file.GetName()) | ||
payload, err := crossplane.Parse(confFile, | ||
&crossplane.ParseOptions{ | ||
SingleFile: false, | ||
StopParsingOnError: true, | ||
}, | ||
) | ||
if err != nil { | ||
continue | ||
} | ||
for _, conf := range payload.Config { | ||
err = sdk.CrossplaneConfigTraverse(&conf, | ||
func(parent *crossplane.Directive, directive *crossplane.Directive) (bool, error) { | ||
switch directive.Directive { | ||
case "app_protect_policy_file": | ||
if len(directive.Args) == 1 { | ||
_, policy := path.Split(directive.Args[0]) | ||
policyMap[policy] = true | ||
} | ||
case "app_protect_security_log": | ||
if len(directive.Args) == 2 { | ||
_, profile := path.Split(directive.Args[0]) | ||
profileMap[profile] = true | ||
} | ||
} | ||
return true, nil | ||
}) | ||
if err != nil { | ||
continue | ||
} | ||
} | ||
if err != nil { | ||
continue | ||
} | ||
} | ||
} | ||
policies := []string{} | ||
for policy, _ := range policyMap { | ||
policies = append(policies, policy) | ||
} | ||
profiles := []string{} | ||
for profile, _ := range profileMap { | ||
profiles = append(profiles, profile) | ||
} | ||
|
||
return policies, profiles | ||
} |
Oops, something went wrong.