Skip to content

Commit 1715580

Browse files
ovalentiMolter73JoukoVirtanen
authored
ROX-29399: Directional external-IPs (#2130)
Add the `direction` attribute to the runtime-configuration to limit in which direction the External-IPs are enabled. Co-authored-by: Mauro Ezequiel Moltrasio <[email protected]> Co-authored-by: JoukoVirtanen <[email protected]>
1 parent b9e8e1f commit 1715580

12 files changed

+473
-137
lines changed

collector/lib/CollectorConfig.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ constexpr const char* CollectorConfig::kSyscalls[];
9191
constexpr bool CollectorConfig::kEnableProcessesListeningOnPorts;
9292

9393
const UnorderedSet<L4ProtoPortPair> CollectorConfig::kIgnoredL4ProtoPortPairs = {{L4Proto::UDP, 9}};
94-
;
9594

9695
CollectorConfig::CollectorConfig() {
9796
// Set default configuration values
@@ -439,7 +438,7 @@ std::ostream& operator<<(std::ostream& os, const CollectorConfig& c) {
439438
<< ", set_import_users:" << c.ImportUsers()
440439
<< ", collect_connection_status:" << c.CollectConnectionStatus()
441440
<< ", enable_detailed_metrics:" << c.EnableDetailedMetrics()
442-
<< ", enable_external_ips:" << c.EnableExternalIPs()
441+
<< ", external_ips:" << c.GetExternalIPsConf()
443442
<< ", track_send_recv:" << c.TrackingSendRecv();
444443
}
445444

collector/lib/CollectorConfig.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <internalapi/sensor/collector.pb.h>
1515

1616
#include "CollectionMethod.h"
17+
#include "ExternalIPsConfig.h"
1718
#include "HostConfig.h"
1819
#include "Logging.h"
1920
#include "NetworkConnection.h"
@@ -94,18 +95,13 @@ class CollectorConfig {
9495
bool ImportUsers() const { return import_users_; }
9596
bool CollectConnectionStatus() const { return collect_connection_status_; }
9697

97-
// EnableExternalIPs will check for the existence
98+
// GetEnableExternalIPs will check for the existence
9899
// of a runtime configuration, and defer to that value
99100
// otherwise, we rely on the feature flag (env var)
100-
bool EnableExternalIPs() const {
101+
ExternalIPsConfig GetExternalIPsConf() const {
101102
auto lock = ReadLock();
102-
if (runtime_config_.has_value()) {
103-
return runtime_config_.value()
104-
.networking()
105-
.external_ips()
106-
.enabled() == sensor::ExternalIpsEnabled::ENABLED;
107-
}
108-
return enable_external_ips_;
103+
104+
return ExternalIPsConfig(runtime_config_, enable_external_ips_);
109105
}
110106

111107
void RuntimeConfigHeuristics() {

collector/lib/ConnTracker.cpp

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ IPNet ConnectionTracker::NormalizeAddressNoLock(const Address& address, bool ena
112112
}
113113

114114
bool ConnectionTracker::ShouldNormalizeConnection(const Connection* conn) const {
115-
Endpoint local, remote = conn->remote();
115+
Endpoint remote = conn->remote();
116116
IPNet ipnet = NormalizeAddressNoLock(remote.address(), false);
117117

118118
return Address::IsCanonicalExternalIp(ipnet.address());
@@ -136,30 +136,31 @@ void ConnectionTracker::CloseConnections(ConnMap* old_conn_state, ConnMap* delta
136136
}
137137
}
138138

139-
/**
140-
* Closes connections that have the 255.255.255.255 external IP address
141-
*/
142-
void ConnectionTracker::CloseNormalizedConnections(ConnMap* old_conn_state, ConnMap* delta_conn) {
143-
CloseConnections(old_conn_state, delta_conn, [](const Connection* conn) {
144-
return Address::IsCanonicalExternalIp(conn->remote().address());
145-
});
146-
}
139+
void ConnectionTracker::CloseConnectionsOnExternalIPsConfigChange(ExternalIPsConfig prev_config, ConnMap* old_conn_state, ConnMap* delta_conn) const {
140+
bool ingress = external_ips_config_.IsEnabled(ExternalIPsConfig::Direction::INGRESS);
141+
bool egress = external_ips_config_.IsEnabled(ExternalIPsConfig::Direction::EGRESS);
147142

148-
/**
149-
* Closes unnormalized connections that would be normalized to the canonical external
150-
* IP address if external IPs was enabled
151-
*/
152-
void ConnectionTracker::CloseExternalUnnormalizedConnections(ConnMap* old_conn_state, ConnMap* delta_conn) {
153-
CloseConnections(old_conn_state, delta_conn, [this](const Connection* conn) {
154-
return ShouldNormalizeConnection(conn) && !Address::IsCanonicalExternalIp(conn->remote().address());
155-
});
156-
}
143+
auto should_close = [this](const Connection* conn, bool enabling_extIPs) {
144+
if (enabling_extIPs) {
145+
// Enabling: Close connections previously normalized
146+
return Address::IsCanonicalExternalIp(conn->remote().address());
147+
} else {
148+
// Disabling: Close connections that should now be normalized
149+
return !Address::IsCanonicalExternalIp(conn->remote().address()) && ShouldNormalizeConnection(conn);
150+
}
151+
};
157152

158-
void ConnectionTracker::CloseConnectionsOnRuntimeConfigChange(ConnMap* old_conn_state, ConnMap* delta_conn, bool enableExternalIPs) {
159-
if (enableExternalIPs) {
160-
CloseNormalizedConnections(old_conn_state, delta_conn);
161-
} else {
162-
CloseExternalUnnormalizedConnections(old_conn_state, delta_conn);
153+
if (egress != prev_config.IsEnabled(ExternalIPsConfig::Direction::EGRESS)) {
154+
CloseConnections(old_conn_state, delta_conn, [egress, should_close](const Connection* conn) -> bool {
155+
/* egress is when we are not server */
156+
return !conn->is_server() && should_close(conn, egress);
157+
});
158+
}
159+
if (ingress != prev_config.IsEnabled(ExternalIPsConfig::Direction::INGRESS)) {
160+
CloseConnections(old_conn_state, delta_conn, [ingress, should_close](const Connection* conn) -> bool {
161+
/* ingress is when we are server */
162+
return conn->is_server() && should_close(conn, ingress);
163+
});
163164
}
164165
}
165166

@@ -171,15 +172,17 @@ Connection ConnectionTracker::NormalizeConnectionNoLock(const Connection& conn)
171172
}
172173

173174
Endpoint local, remote = conn.remote();
175+
bool extIPs_ingress = external_ips_config_.IsEnabled(ExternalIPsConfig::Direction::INGRESS);
176+
bool extIPs_egress = external_ips_config_.IsEnabled(ExternalIPsConfig::Direction::EGRESS);
174177

175178
if (is_server) {
176179
// If this is the server, only the local port is relevant, while the remote port does not matter.
177180
local = Endpoint(IPNet(Address()), conn.local().port());
178-
remote = Endpoint(NormalizeAddressNoLock(conn.remote().address(), enable_external_ips_), 0);
181+
remote = Endpoint(NormalizeAddressNoLock(conn.remote().address(), extIPs_ingress), 0);
179182
} else {
180183
// If this is the client, the local port and address are not relevant.
181184
local = Endpoint();
182-
remote = Endpoint(NormalizeAddressNoLock(remote.address(), enable_external_ips_), remote.port());
185+
remote = Endpoint(NormalizeAddressNoLock(remote.address(), extIPs_egress), remote.port());
183186
}
184187

185188
return Connection(conn.container(), local, remote, conn.l4proto(), is_server);

collector/lib/ConnTracker.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <vector>
55

66
#include "Containers.h"
7+
#include "ExternalIPsConfig.h"
78
#include "Hash.h"
89
#include "NRadix.h"
910
#include "NetworkConnection.h"
@@ -100,10 +101,10 @@ class ConnectionTracker {
100101
template <typename T>
101102
static void UpdateOldState(UnorderedMap<T, ConnStatus>* old_state, const UnorderedMap<T, ConnStatus>& new_state, int64_t time_micros, int64_t afterglow_period_micros);
102103

103-
void CloseConnections(ConnMap* old_conn_state, ConnMap* delta_conn, std::function<bool(const Connection*)> predicate);
104-
void CloseNormalizedConnections(ConnMap* old_conn_state, ConnMap* delta_conn);
105-
void CloseExternalUnnormalizedConnections(ConnMap* old_conn_state, ConnMap* delta_conn);
106-
void CloseConnectionsOnRuntimeConfigChange(ConnMap* old_conn_state, ConnMap* delta_conn, bool enableExternalIPs);
104+
// Mark all matching connections as closed
105+
static void CloseConnections(ConnMap* old_conn_state, ConnMap* delta_conn, std::function<bool(const Connection*)> predicate);
106+
// Detect a change in the External-IPs config and report connections as closed if their representation is affected
107+
void CloseConnectionsOnExternalIPsConfigChange(ExternalIPsConfig prev_config, ConnMap* old_conn_state, ConnMap* delta_conn) const;
107108

108109
// ComputeDelta computes a diff between new_state and old_state
109110
template <typename T>
@@ -131,7 +132,7 @@ class ConnectionTracker {
131132

132133
void UpdateKnownPublicIPs(UnorderedSet<Address>&& known_public_ips);
133134
void UpdateKnownIPNetworks(UnorderedMap<Address::Family, std::vector<IPNet>>&& known_ip_networks);
134-
void EnableExternalIPs(bool enable) { enable_external_ips_ = enable; }
135+
void SetExternalIPsConfig(ExternalIPsConfig config) { external_ips_config_ = config; }
135136
void UpdateIgnoredL4ProtoPortPairs(UnorderedSet<L4ProtoPortPair>&& ignored_l4proto_port_pairs);
136137
void UpdateIgnoredNetworks(const std::vector<IPNet>& network_list);
137138
void UpdateNonAggregatedNetworks(const std::vector<IPNet>& network_list);
@@ -202,7 +203,7 @@ class ConnectionTracker {
202203

203204
UnorderedSet<Address> known_public_ips_;
204205
NRadixTree known_ip_networks_;
205-
bool enable_external_ips_ = false;
206+
ExternalIPsConfig external_ips_config_;
206207
UnorderedMap<Address::Family, bool> known_private_networks_exists_;
207208
UnorderedSet<L4ProtoPortPair> ignored_l4proto_port_pairs_;
208209
NRadixTree ignored_networks_;

collector/lib/ExternalIPsConfig.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include "ExternalIPsConfig.h"
2+
3+
namespace collector {
4+
5+
ExternalIPsConfig::ExternalIPsConfig(std::optional<sensor::CollectorConfig> runtime_config, bool default_enabled) {
6+
if (!runtime_config.has_value()) {
7+
direction_enabled_ = default_enabled ? Direction::BOTH : Direction::NONE;
8+
return;
9+
}
10+
11+
// At this point we know runtime_config has a value, we can access it directly
12+
const auto& external_ips = runtime_config->networking().external_ips();
13+
if (external_ips.enabled() != sensor::ExternalIpsEnabled::ENABLED) {
14+
direction_enabled_ = Direction::NONE;
15+
return;
16+
}
17+
18+
switch (external_ips.direction()) {
19+
case sensor::ExternalIpsDirection::INGRESS:
20+
direction_enabled_ = Direction::INGRESS;
21+
break;
22+
case sensor::ExternalIpsDirection::EGRESS:
23+
direction_enabled_ = Direction::EGRESS;
24+
break;
25+
default:
26+
direction_enabled_ = Direction::BOTH;
27+
break;
28+
}
29+
}
30+
31+
std::ostream& operator<<(std::ostream& os, const ExternalIPsConfig& config) {
32+
os << "direction(";
33+
34+
switch (config.GetDirection()) {
35+
case ExternalIPsConfig::Direction::NONE:
36+
os << "NONE";
37+
break;
38+
case ExternalIPsConfig::Direction::INGRESS:
39+
os << "INGRESS";
40+
break;
41+
case ExternalIPsConfig::Direction::EGRESS:
42+
os << "EGRESS";
43+
break;
44+
case ExternalIPsConfig::Direction::BOTH:
45+
os << "BOTH";
46+
break;
47+
default:
48+
os << "invalid";
49+
break;
50+
}
51+
52+
return os << ")";
53+
}
54+
55+
} // namespace collector

collector/lib/ExternalIPsConfig.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#pragma once
2+
3+
#include <assert.h>
4+
#include <optional>
5+
#include <ostream>
6+
7+
#include <internalapi/sensor/collector.pb.h>
8+
9+
namespace collector {
10+
11+
// Encapsulates the configuration of the External-IPs feature
12+
class ExternalIPsConfig {
13+
public:
14+
enum Direction {
15+
NONE = 0,
16+
INGRESS = 1 << 0,
17+
EGRESS = 1 << 1,
18+
BOTH = INGRESS | EGRESS,
19+
};
20+
21+
// Are External-IPs enabled in the provided direction ?
22+
bool IsEnabled(Direction direction) const {
23+
assert(direction != Direction::NONE);
24+
return (direction & direction_enabled_) == direction;
25+
}
26+
27+
// Direction in which External-IPs are enabled
28+
Direction GetDirection() const { return direction_enabled_; }
29+
30+
// Extract the External-IPs configuration from the provided runtime-conf.
31+
// If the runtime-configuration is unset then 'default_enabled' is used
32+
// as a fallback to enable in both directions.
33+
// 'runtime_config' should be locked prior to calling.
34+
ExternalIPsConfig(std::optional<sensor::CollectorConfig> runtime_config, bool default_enabled);
35+
36+
ExternalIPsConfig(Direction direction = Direction::NONE) : direction_enabled_(direction) {}
37+
38+
private:
39+
Direction direction_enabled_;
40+
};
41+
42+
std::ostream& operator<<(std::ostream& os, const ExternalIPsConfig& config);
43+
44+
} // end namespace collector

collector/lib/NetworkStatusNotifier.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ void NetworkStatusNotifier::RunSingle(IDuplexClientWriter<sensor::NetworkConnect
225225
auto next_scrape = std::chrono::system_clock::now();
226226
int64_t time_at_last_scrape = NowMicros();
227227

228-
bool prevEnableExternalIPs = config_.EnableExternalIPs();
228+
ExternalIPsConfig prevEnableExternalIPs = config_.GetExternalIPsConf();
229229

230230
while (writer->Sleep(next_scrape)) {
231231
CLOG(DEBUG) << "Starting network status notification";
@@ -242,18 +242,18 @@ void NetworkStatusNotifier::RunSingle(IDuplexClientWriter<sensor::NetworkConnect
242242
const sensor::NetworkConnectionInfoMessage* msg;
243243
ConnMap new_conn_state, delta_conn;
244244
AdvertisedEndpointMap new_cep_state;
245-
bool enableExternalIPs = config_.EnableExternalIPs();
245+
ExternalIPsConfig externalIPsConfig = config_.GetExternalIPsConf();
246246

247247
WITH_TIMER(CollectorStats::net_fetch_state) {
248-
conn_tracker_->EnableExternalIPs(enableExternalIPs);
248+
conn_tracker_->SetExternalIPsConfig(externalIPsConfig);
249249

250250
new_conn_state = conn_tracker_->FetchConnState(true, true);
251251
if (config_.EnableAfterglow()) {
252252
ConnectionTracker::ComputeDeltaAfterglow(new_conn_state, old_conn_state, delta_conn, time_micros, time_at_last_scrape, config_.AfterglowPeriod());
253-
if (prevEnableExternalIPs != enableExternalIPs) {
254-
conn_tracker_->CloseConnectionsOnRuntimeConfigChange(&old_conn_state, &delta_conn, enableExternalIPs);
255-
prevEnableExternalIPs = enableExternalIPs;
256-
}
253+
254+
conn_tracker_->CloseConnectionsOnExternalIPsConfigChange(prevEnableExternalIPs, &old_conn_state, &delta_conn);
255+
prevEnableExternalIPs = externalIPsConfig;
256+
257257
} else {
258258
ConnectionTracker::ComputeDelta(new_conn_state, &old_conn_state);
259259
}

collector/proto/third_party/stackrox

Submodule stackrox updated 3556 files

0 commit comments

Comments
 (0)