Skip to content

Commit 108c7d2

Browse files
committed
Fixed a bug where it would try to inject non-XML audit log files. Created a warning message if it doesn't find any log files.
1 parent 7e65e5e commit 108c7d2

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

Monitoring/ingest_nas_audit_logs_into_cloudwatch/README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ You can run this script as a standalone program or as a Lambda function. These d
1212

1313
## Prerequisites
1414
- An FSx for Data ONTAP file system.
15-
- Have NAS auditing configured and enabled on the FSx for Data ONTAP file system. Ensure you have selected the XML format for the audit logs. You can read this
15+
- An S3 bucket to store the "stats" file. The "stats" file is used to keep track of the last time the Lambda function successfully
16+
ingested audit logs from each file system. Its size will be small (i.e. less than a few megabytes).
17+
- Have NAS auditing configured and enabled on the FSx for Data ONTAP file system. **Ensure you have selected the XML format for the audit logs.** Also,
18+
ensure you have set up a rotation schedule. The program will only act on audit log files that have been finalized, and not the "active" one. You can read this
1619
[knowledge based article](https://kb.netapp.com/on-prem/ontap/da/NAS/NAS-KBs/How_to_set_up_NAS_auditing_in_ONTAP_9) for instructions on how to setup NAS auditing.
1720
- Have the NAS auditing configured to store the audit logs in a volume with the same name on all FSx for Data ONTAP file
1821
systems that you want to ingest the audit logs from.
@@ -35,6 +38,7 @@ Therefore, there needs to be an VPC endpoint for all the AWS services that the L
3538
- EC2.
3639
- You have created a role with the necessary permissions to allow the Lambda function to do the following:
3740

41+
<!--- Using HTML to create a table that has rowspan attributes since the markdown table syntax does not support that. --->
3842
<table>
3943
<tr><th>Service</td><th>Actions</td><th>Resources</th></tr>
4044
<tr><td>Fsx</td><td>fsx:DescribeFileSystems</td><td>&#42;</td></tr>
@@ -56,9 +60,11 @@ Where:
5660
- &lt;secretName&gt; - is the name of the secret that contains the credentials for the fsxadmin accounts.
5761

5862
Notes:
59-
- Since the Lambda function runs within your VPC it needs to be able to create an delete network interfaces.
63+
- Since the Lambda function runs within your VPC it needs to be able to create and delete network interfaces.
64+
- The AWS Security Group Policy builder incorrectly generates resource lines for the `CreateNetworkInterface`
65+
and `DeleteNetworkInterface` actions. The correct resource line is `arn:aws:ec2:&lt;region&gt;:&lt;accountID&gt;:&#42;`.
6066
- It needs to be able to create a log groups so it can create a log group for the diagnostic output from the Lambda function.
61-
- Since the ARN of any Secrets Manager secret has random characters at the end of it, you must add the `*` at the end.
67+
- Since the ARN of any Secrets Manager secret has random characters at the end of it, you must add the `*` at the end, or provide the full ARN of the secret.
6268

6369
## Deployment
6470
1. Create a Lambda deployment package by:
@@ -72,7 +78,9 @@ Notes:
7278
2. Within the AWS console, or using the AWS API, create a Lambda function with:
7379
1. Python 3.10, or higher, as the runtime.
7480
1. Set the permissions to the role created above.
75-
1. Under `Additional Configurations` select `Enable VPC` and select a VPC and Subnet that will have access to all the FSx for ONtAP file system management endpoints that you want to gather audit logs from.
81+
1. Under `Additional Configurations` select `Enable VPC` and select a VPC and Subnet that will have access to all the FSx for ONTAP
82+
file system management endpoints that you want to gather audit logs from. Also, select a Security Group that allows TCP port 443 outbound.
83+
Inbound rules don't matter since the Lambda function is not accessible from a network.
7684
1. Click `Create Function` and on the next page, under the `Code` tab, select `Upload From -> .zip file.` Provide the .zip file created by the steps above.
7785
1. From the `Configuration -> General` tab set the timeout to at least 30 seconds. You will may need to increase that if it has to process a lot of audit entries and/or process a lot of FSx for ONTAP file systems.
7886

Monitoring/ingest_nas_audit_logs_into_cloudwatch/ingest_audit_log.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ def lambda_handler(event, context): # pylint: disable=W0613
336336
# Get the password
337337
password = secrets.get(fsId)
338338
if password == None:
339-
print(f'No password found for {fsId}.')
339+
print(f'Warning: No password found for {fsId}.')
340340
continue
341341
#
342342
# Create a header with the basic authentication.
@@ -354,13 +354,17 @@ def lambda_handler(event, context): # pylint: disable=W0613
354354
volumeUUID = data['records'][0]['uuid'] # Since we specified the volume, and vserver name, there should only be one record.
355355

356356
if volumeUUID == None:
357-
print(f"Volume {config['volumeName']} not found for {fsId}.")
357+
print(f"Warning: Volume {config['volumeName']} not found for {fsId} under SVM: {config['vserverName']}.")
358358
continue
359359
#
360360
# Get all the files in the volume that match the audit file pattern.
361-
endpoint = f"https://{fsxn}/api/storage/volumes/{volumeUUID}/files?name=audit_{config['vserverName']}_D*&order_by=name%20asc&fields=name"
361+
endpoint = f"https://{fsxn}/api/storage/volumes/{volumeUUID}/files?name=audit_{config['vserverName']}_D*.xml&order_by=name%20asc&fields=name"
362362
response = http.request('GET', endpoint, headers=headersQuery, timeout=5.0)
363363
data = json.loads(response.data.decode('utf-8'))
364+
if data.get('num_records') == 0:
365+
print(f"Warning: No XML audit log files found on FsID: {fsId}; SvmID: {config['vserverName']}; Volume: {config['volumeName']}.")
366+
continue
367+
364368
for file in data['records']:
365369
filePath = file['name']
366370
if lastFileRead.get(fsxn) == None or getEpoch(filePath) > lastFileRead[fsxn]:

0 commit comments

Comments
 (0)