Add source IP and port fields to Goldmane flow logs#10714
Add source IP and port fields to Goldmane flow logs#10714ravikalla wants to merge 3 commits intoprojectcalico:masterfrom
Conversation
Addresses issue projectcalico#10601 by adding source IP address and port information to the Goldmane flows API. This allows security teams to identify the source of network traffic, which is particularly useful for detecting malicious inbound traffic from external networks. Changes: - Add source_ip and source_port fields to FlowKey protobuf definition - Update Goldmane Go types to include source IP/port fields - Modify Felix conversion logic to extract IP data from flow tuples - Update Whisker API response structures to include source IP/port - Add comprehensive unit tests for all components - Maintain full backward compatibility with existing flows The implementation supports both IPv4 and IPv6 addresses and gracefully handles legacy flows without source IP information.
|
Ravi Kalla seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
There was a problem hiding this comment.
Pull Request Overview
This PR adds source IP address and port fields to the Goldmane flow logs API to provide security teams with better visibility into network traffic sources. The enhancement maintains full backward compatibility while extending the data model across the entire flow pipeline.
- Added
source_ip(string) andsource_port(int64) fields to the protobuf FlowKey message - Updated Go structs and conversion functions throughout the Felix → Goldmane → Whisker pipeline
- Enhanced API responses to include source IP/port information in JSON output
Reviewed Changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| goldmane/proto/api.proto | Added source_ip and source_port fields to FlowKey message |
| goldmane/proto/api.pb.go | Generated protobuf code with new fields and getter methods |
| goldmane/pkg/types/flow.go | Updated FlowKey structs and conversion functions for source IP/port |
| goldmane/pkg/types/flow_test.go | Added test data with source IP/port values |
| felix/collector/goldmane/client.go | Implemented IP conversion between net.IP and string formats |
| felix/collector/goldmane/client_test.go | Added comprehensive tests for IP conversion functions |
| whisker-backend/pkg/apis/v1/flows.go | Added SourceIP and SourcePort fields to FlowResponse struct |
| whisker-backend/pkg/handlers/v1/protoconvert.go | Updated conversion to include source IP/port in API responses |
| whisker-backend/pkg/handlers/v1/protoconvert_test.go | Added tests for API conversion with source IP data |
|
/sem-approve |
|
Cool - thanks for looking at this issue. @ravikalla I had a use case question that I'm interested in before we get into technical feedback if that's OK. Also tagging @andrenth since you opened the related issue #10601 . Do you have a particular use case for source ports? We support this as an option in Calico Enterprise / Cloud but have found the source ports to usually not be useful since they're almost always ephemeral and are also very high volume. We had a bug once where an archiving setup was making a connection per log, and each connection then generated a new log killing the whole logging system; so IMO it's not usually worth the extra load and risk. |
|
@matthewdupre source ports would be just for completeness but if it's infeasible, the source IP is the information that's usually needed. |
This commit adds the missing destination IP field to the Goldmane flow logging system, ensuring complete IP address tracking for both source and destination endpoints. Changes: Add dest_ip field (field 18) to FlowKey protobuf definition Update FlowKeyDestination struct to include DestIP field Add DestIP() getter method to FlowKey Update all proto conversion functions to handle destination IP Fix ConvertGoldmaneToFlowlog to properly convert both IPs Update ConvertFlowlogToGoldmane to include destination IP Add comprehensive test coverage for IPv4, IPv6, and edge cases This fixes the issue where destination IPs were lost during the FlowLog to Goldmane conversion process.
I see that source ports are typically ephemeral and can significantly increase log volume.
I was primarily addressing the missing destination IP issue identified in the PR comment. The source port was already being captured and transmitted in the existing code - I didn't add that functionality. If you believe that source ports should be optional or removed entirely due to the volume/risk concerns you mentioned, I'd be happy to:
What would you recommend? Should I modify this PR to address the source port concern, or would that be better handled as a separate issue/PR? |
goldmane/pkg/types/flow.go
Outdated
| SourceName string | ||
| SourceNamespace string | ||
| SourceType proto.EndpointType | ||
| SourceIP string |
There was a problem hiding this comment.
Adding new fields to the Key has a fairly big impact on scalability. Even just IP address will increase the potential number of records needed very significantly - for example if a large Deployment is connecting to another large Deployment right now that will only create two Flows (one for egress and one for ingress), but with IP addresses that would increase to n (or perhaps n^2 if each pod talks to many pods).
I suggest instead adding arrays of IPs to the Flow; so the number of Flows remains the same and we don't need to duplicate all the other data for each different source IP address.
We could also place a configurable limit on the number of IPs included, which will cap the total amount of data (not just the number of flows). When Goldmane needs to combine multiple Flows with the same FlowKey it can then merge the arrays and truncate to the limit.
There was a problem hiding this comment.
@matthewdupre I've implemented your suggested solution in the latest commit. I removed the SourceIP and SourcePort fields from FlowKeySource and added SourceIPs and SourcePorts arrays to the Flow struct instead.
I also added the MergeFlows functionality that combines flows with the same FlowKey while deduplicating IPs and ports. The implementation includes configurable limits with a default of 100 IPs and 100 ports per flow through a FlowConfig struct.
The protobuf definitions have been updated to include the new repeated fields for source_ips and source_ports, and all conversion functions now handle the array fields properly.
This change maintains the same number of FlowKeys regardless of pod count, so your example scenario now creates just 1 FlowKey instead of n square FlowKeys, with source IPs stored in bounded arrays.
matthewdupre
left a comment
There was a problem hiding this comment.
I have one scalability related concern with the API change I've described below. Please let me know if you need any further explanation or help making the adjustment.
Addresses reviewer feedback to prevent exponential FlowKey growth.
matthewdupre
left a comment
There was a problem hiding this comment.
Few leftover bits of API change
| DestName: p.DestName, | ||
| DestNamespace: p.DestNamespace, | ||
| DestType: p.DestType, | ||
| DestIP: p.DestIp, |
There was a problem hiding this comment.
DestinationIP(s) should be symmetric with SourceIPs. Specifically: it should move out of the key and be a slice, like SourceIPs.
| EndpointType source_type = 3; | ||
|
|
||
| // SourceIP is the IP address of the source endpoint. | ||
| string source_ip = 16; |
There was a problem hiding this comment.
This shouldn't be here: source_ips lives in the Flow
| string source_ip = 16; | ||
|
|
||
| // SourcePort is the source port number. | ||
| int64 source_port = 17; |
There was a problem hiding this comment.
As mentioned above, please remove source ports for now; let's get IPs working and then worry about ports if we get a compelling use case
| int64 source_port = 17; | ||
|
|
||
| // DestIP is the IP address of the destination endpoint. | ||
| string dest_ip = 18; |
There was a problem hiding this comment.
Please move this to the Flow and make it repeated
|
@ravikalla is this one still something you're interested in working on? |
|
This PR is stale because it has been open for 60 days with no activity. |
|
I'd be more than happy to help get this PR over the finish line. While I appreciate that Felix's trace logging gives me the flow information I need to help build |
|
Yeah, I'd love to see this one get in as well. |
|
This PR is stale because it has been open for 60 days with no activity. |
|
@matthewdupre @caseydavenport @benfiola , can this PR be merged? This's been open for a while now. |
|
sorry, everyone 😞 - unfortunately, i've since moved over to cilium as i wanted to write policies targeting DNS names without having a third-party dependency e.g. calico cloud. as a result, i don't think i'll be the one to wrap up this PR. with that said, @pavankumarinnamuri, i believe this is indeed a stale PR as it hasn't received any updates in about 9 months. there's still feedback from @matthewdupre that needs to be addressed, and until then, i imagine this PR isn't ready to be integrated. |
Summary
This PR addresses issue #10601 by adding source IP address and port information to the Goldmane flows API. This enhancement provides security teams with valuable visibility into the source of network traffic, which is particularly useful for identifying malicious inbound traffic from external networks.
Changes
Core Implementation
source_ip(string) andsource_port(int64) fields to theFlowKeymessageKey Features
Testing
Comprehensive Test Coverage
Test Scenarios Verified
Backward Compatibility
This PR maintains 100% backward compatibility:
Example
Before (existing flows)
{ "source_name": "frontend-app", "source_namespace": "production", "dest_name": "api-service", "dest_port": 443 }After (new flows with source IP)
{ "source_name": "frontend-app", "source_namespace": "production", "source_ip": "10.244.1.100", "source_port": 45678, "dest_name": "api-service", "dest_port": 443 }Test Plan
Closes #10601