github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/enforcer/applicationproxy/tcp/lookup.go (about) 1 package tcp 2 3 import ( 4 "fmt" 5 "net" 6 "strconv" 7 8 "go.aporeto.io/enforcerd/trireme-lib/collector" 9 "go.aporeto.io/enforcerd/trireme-lib/controller/constants" 10 "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/packet" 11 "go.aporeto.io/enforcerd/trireme-lib/controller/pkg/pucontext" 12 "go.aporeto.io/enforcerd/trireme-lib/policy" 13 "go.uber.org/zap" 14 ) 15 16 const indeterminateRemoteController = "" 17 18 // proxyFlowProperties is a struct used to pass flow information up 19 type proxyFlowProperties struct { 20 myControllerID string 21 SourceIP string 22 DestIP string 23 PolicyID string 24 ServiceID string 25 DestType collector.EndPointType 26 SourceType collector.EndPointType 27 SourcePort uint16 28 DestPort uint16 29 } 30 31 type lookup struct { 32 SourceIP net.IP 33 DestIP net.IP 34 SourcePort uint16 35 DestPort uint16 36 collector collector.EventCollector 37 puContext *pucontext.PUContext 38 pfp *proxyFlowProperties 39 client bool 40 } 41 42 // IDLookup performs policy lookup based on incoming tags from remote PU and matching against our policy DB. 43 // Stats reporting is done for: 44 // - all rejects 45 // - accepts on server 46 func (l *lookup) IDLookup(remoteController, remotePUID string, tags *policy.TagStore) bool { // nolint: staticcheck 47 48 remoteController = "" 49 // TODO: Enable this 50 // if remoteController == l.pfp.myControllerID { 51 // remoteController = "" 52 // } 53 54 report, packet := l.Policy(tags) 55 56 if packet.Action.Rejected() { 57 l.ReportStats( 58 collector.EndPointTypePU, 59 remoteController, 60 remotePUID, 61 collector.PolicyDrop, 62 report, 63 packet, 64 false, 65 ) 66 zap.L().Debug("lookup reject", zap.Bool("client", l.client), zap.Strings("tags", tags.GetSlice())) 67 return false 68 } 69 70 if !l.client && packet.Action.Accepted() { 71 l.ReportStats( 72 collector.EndPointTypePU, 73 remoteController, 74 remotePUID, 75 "N/A", 76 report, 77 packet, 78 false, 79 ) 80 zap.L().Debug("lookup accept", zap.Bool("client", l.client), zap.Strings("tags", tags.GetSlice())) 81 } 82 return true 83 } 84 85 // Policy performs policy lookup based on incoming tags from remote PU and matching against our policy DB. 86 // It also returns the report and packet policy. 87 func (l *lookup) Policy(tags *policy.TagStore) (*policy.FlowPolicy, *policy.FlowPolicy) { 88 89 var report *policy.FlowPolicy 90 var packet *policy.FlowPolicy 91 92 if l.client { 93 tags.AppendKeyValue(constants.PortNumberLabelString, fmt.Sprintf("%s/%s", constants.TCPProtoString, strconv.Itoa(int(l.DestPort)))) 94 report, packet = l.puContext.SearchTxtRules(tags, false) 95 } else { 96 tags.AppendKeyValue(constants.PortNumberLabelString, fmt.Sprintf("%s/%s", constants.TCPProtoString, strconv.Itoa(int(l.DestPort)))) 97 report, packet = l.puContext.SearchRcvRules(tags) 98 } 99 100 return report, packet 101 } 102 103 func (l *lookup) IPLookup() bool { 104 105 var report *policy.FlowPolicy 106 var packetPolicy *policy.FlowPolicy 107 var noPolicy error 108 109 if l.client { 110 report, packetPolicy, noPolicy = l.puContext.ApplicationACLPolicyFromAddr(l.DestIP, l.DestPort, packet.IPProtocolTCP) 111 } else { 112 report, packetPolicy, noPolicy = l.puContext.NetworkACLPolicyFromAddr(l.SourceIP, l.DestPort, packet.IPProtocolTCP) 113 } 114 115 matchString := "none" 116 if noPolicy != nil { 117 matchString = noPolicy.Error() 118 } 119 120 // Clients and Servers should reject and report if a reject action is found. 121 if packetPolicy.Action.Rejected() { 122 123 l.ReportStats( 124 collector.EndPointTypeExternalIP, 125 indeterminateRemoteController, 126 packetPolicy.ServiceID, 127 collector.PolicyDrop, 128 report, 129 packetPolicy, 130 false, 131 ) 132 zap.L().Debug( 133 "IP ACL Lookup Reject", 134 zap.Bool("client", l.client), 135 zap.String("match", matchString), 136 zap.String("src-ip", l.pfp.SourceIP), 137 zap.Uint16("src-port", l.SourcePort), 138 zap.String("dst-ip", l.pfp.DestIP), 139 zap.Uint16("dst-port", l.DestPort), 140 zap.String("report", report.PolicyID), 141 zap.String("policy", packetPolicy.PolicyID)) 142 return false 143 } 144 145 if !l.client && packetPolicy.Action.Accepted() { 146 l.ReportStats( 147 collector.EndPointTypeExternalIP, 148 indeterminateRemoteController, 149 packetPolicy.ServiceID, 150 "N/A", 151 report, 152 packetPolicy, 153 false, 154 ) 155 } 156 zap.L().Debug( 157 "IP ACL Lookup Accept", 158 zap.Bool("client", l.client), 159 zap.String("match", matchString), 160 zap.String("src-ip", l.pfp.SourceIP), 161 zap.Uint16("src-port", l.SourcePort), 162 zap.String("dst-ip", l.pfp.DestIP), 163 zap.Uint16("dst-port", l.DestPort), 164 zap.String("report", report.PolicyID), 165 zap.String("policy", packetPolicy.PolicyID)) 166 return true 167 } 168 169 func (l *lookup) ReportStats(remoteType collector.EndPointType, remoteController string, remotePUID string, mode string, report *policy.FlowPolicy, packet *policy.FlowPolicy, accept bool) { 170 171 dstController, dstID, srcController, srcID := "", "", "", "" 172 173 if l.client { 174 l.pfp.DestType = remoteType 175 if l.pfp.myControllerID != remoteController { 176 dstController = remoteController 177 } 178 dstID = remotePUID 179 srcID = l.puContext.ManagementID() 180 } else { 181 l.pfp.SourceType = remoteType 182 dstID = l.puContext.ManagementID() 183 if l.pfp.myControllerID != remoteController { 184 srcController = remoteController 185 } 186 srcID = remotePUID 187 } 188 189 if accept { 190 l.reportAcceptedFlow( 191 l.pfp, 192 srcID, 193 dstID, 194 l.puContext, 195 report, 196 packet, 197 srcController, 198 dstController, 199 ) 200 return 201 } 202 203 l.reportRejectedFlow( 204 l.pfp, 205 srcID, 206 dstID, 207 l.puContext, 208 mode, 209 report, 210 packet, 211 srcController, 212 dstController, 213 ) 214 } 215 216 func (l *lookup) reportFlow(flowproperties *proxyFlowProperties, sourceID string, destID string, context *pucontext.PUContext, mode string, report *policy.FlowPolicy, actual *policy.FlowPolicy, sourceController string, destController string) { 217 218 c := &collector.FlowRecord{ 219 ContextID: context.ID(), 220 Source: collector.EndPoint{ 221 ID: sourceID, 222 IP: flowproperties.SourceIP, 223 Port: flowproperties.SourcePort, 224 Type: flowproperties.SourceType, 225 }, 226 Destination: collector.EndPoint{ 227 ID: destID, 228 IP: flowproperties.DestIP, 229 Port: flowproperties.DestPort, 230 Type: flowproperties.DestType, 231 }, 232 233 Action: actual.Action, 234 DropReason: mode, 235 PolicyID: actual.PolicyID, 236 L4Protocol: packet.IPProtocolTCP, 237 ServiceType: policy.ServiceTCP, 238 ServiceID: flowproperties.ServiceID, 239 Namespace: context.ManagementNamespace(), 240 SourceController: sourceController, 241 DestinationController: destController, 242 } 243 244 if context.Annotations() != nil { 245 c.Tags = context.Annotations().GetSlice() 246 } 247 248 if report.ObserveAction.Observed() { 249 c.ObservedAction = report.Action 250 c.ObservedPolicyID = report.PolicyID 251 c.ObservedActionType = report.ObserveAction 252 } 253 254 l.collector.CollectFlowEvent(c) 255 } 256 257 func (l *lookup) reportAcceptedFlow(flowproperties *proxyFlowProperties, sourceID string, destID string, context *pucontext.PUContext, report *policy.FlowPolicy, packet *policy.FlowPolicy, sourceController string, destController string) { 258 259 l.reportFlow(flowproperties, sourceID, destID, context, "N/A", report, packet, sourceController, destController) 260 } 261 262 func (l *lookup) reportRejectedFlow(flowproperties *proxyFlowProperties, sourceID string, destID string, context *pucontext.PUContext, mode string, report *policy.FlowPolicy, packet *policy.FlowPolicy, sourceController string, destController string) { 263 264 if report == nil { 265 report = &policy.FlowPolicy{ 266 Action: policy.Reject | policy.Log, 267 PolicyID: "default", 268 } 269 } 270 if packet == nil { 271 packet = report 272 } 273 l.reportFlow(flowproperties, sourceID, destID, context, mode, report, packet, sourceController, destController) 274 }