mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-16 15:07:46 +00:00
genpolicy: add rule for AddARPNeighbors
When the network interface provisioned by the CNI has static ARP table entries, the runtime calls AddARPNeighbor to propagate these to the agent. As of today, these calls are simply rejected. In order to allow the calls, we do some sanity checks on the arguments: We must ensure that we don't unexpectedly route traffic to the host that was not intended to leave the VM. In a first approximation, this applies to loopback IPs and devices. However, there may be other sensitive ranges (for example, VPNs between VMs), so there should be some flexibility for users to restrict this further. This is why we introduce a setting, similar to UpdateRoutes, that allows restricting the neighbor IPs further. The only valid state of an ARP neighbor entry is NUD_PERMANENT, which has a value of 128 [1]. This is already enforced by the runtime. According to rtnetlink(7), valid flag values are 8 and 128, respectively [2], thus we allow any combination of these. [1]: https://github.com/torvalds/linux/blob/4790580/include/uapi/linux/neighbour.h#L72 [2]: https://github.com/torvalds/linux/blob/4790580/include/uapi/linux/neighbour.h#L49C20-L53 Fixes: #11664 Signed-off-by: Markus Rudy <mr@edgeless.systems>
This commit is contained in:
parent
af01434226
commit
3eb0641431
@ -347,6 +347,14 @@
|
||||
"^127\\.(?:[0-9]{1,3}\\.){2}[0-9]{1,3}$"
|
||||
]
|
||||
},
|
||||
"AddARPNeighborsRequest": {
|
||||
"forbidden_device_names": [
|
||||
"lo"
|
||||
],
|
||||
"forbidden_cidrs_regex": [
|
||||
"^127\\.(?:[0-9]{1,3}\\.){2}[0-9]{1,3}$"
|
||||
]
|
||||
},
|
||||
"CloseStdinRequest": false,
|
||||
"ReadStreamRequest": false,
|
||||
"UpdateEphemeralMountsRequest": false,
|
||||
|
@ -1400,6 +1400,25 @@ UpdateInterfaceRequest if {
|
||||
print("UpdateInterfaceRequest: true")
|
||||
}
|
||||
|
||||
AddARPNeighborsRequest if {
|
||||
p_defaults := policy_data.request_defaults.AddARPNeighborsRequest
|
||||
print("AddARPNeighborsRequest: policy =", p_defaults)
|
||||
|
||||
every i_neigh in input.neighbors.ARPNeighbors {
|
||||
print("AddARPNeighborsRequest: i_neigh =", i_neigh)
|
||||
|
||||
not i_neigh.device in p_defaults.forbidden_device_names
|
||||
i_neigh.toIPAddress.mask == ""
|
||||
every p_cidr in p_defaults.forbidden_cidrs_regex {
|
||||
not regex.match(p_cidr, i_neigh.toIPAddress.address)
|
||||
}
|
||||
i_neigh.state == 128
|
||||
bits.or(i_neigh.flags, 136) == 136
|
||||
}
|
||||
|
||||
print("AddARPNeighborsRequest: true")
|
||||
}
|
||||
|
||||
CloseStdinRequest if {
|
||||
policy_data.request_defaults.CloseStdinRequest == true
|
||||
}
|
||||
|
@ -355,6 +355,16 @@ pub struct UpdateInterfaceRequestDefaults {
|
||||
forbidden_hw_addrs: Vec<String>,
|
||||
}
|
||||
|
||||
/// UpdateInterfaceRequest settings from genpolicy-settings.json.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct AddARPNeighborsRequestDefaults {
|
||||
/// Explicitly blocked interface names. Intent is to block changes to loopback interface.
|
||||
forbidden_device_names: Vec<String>,
|
||||
/// Explicitly blocked IP address ranges.
|
||||
/// Should include loopback addresses and other CIDRs that should not be routed outside the VM.
|
||||
forbidden_cidrs_regex: Vec<String>,
|
||||
}
|
||||
|
||||
/// Settings specific to each kata agent endpoint, loaded from
|
||||
/// genpolicy-settings.json.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
@ -374,6 +384,9 @@ pub struct RequestDefaults {
|
||||
/// Allow the host to configure only used raw_flags and reject names/mac addresses of the loopback.
|
||||
pub UpdateInterfaceRequest: UpdateInterfaceRequestDefaults,
|
||||
|
||||
/// Allow the host to configure only used raw_flags and reject names/mac addresses of the loopback.
|
||||
pub AddARPNeighborsRequest: AddARPNeighborsRequestDefaults,
|
||||
|
||||
/// Allow the Host to close stdin for a container. Typically used with WriteStreamRequest.
|
||||
pub CloseStdinRequest: bool,
|
||||
|
||||
|
@ -13,8 +13,8 @@ mod tests {
|
||||
use std::str;
|
||||
|
||||
use protocols::agent::{
|
||||
CopyFileRequest, CreateContainerRequest, CreateSandboxRequest, ExecProcessRequest,
|
||||
RemoveContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest,
|
||||
AddARPNeighborsRequest, CopyFileRequest, CreateContainerRequest, CreateSandboxRequest,
|
||||
ExecProcessRequest, RemoveContainerRequest, UpdateInterfaceRequest, UpdateRoutesRequest,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -32,6 +32,7 @@ mod tests {
|
||||
RemoveContainer(RemoveContainerRequest),
|
||||
UpdateInterface(UpdateInterfaceRequest),
|
||||
UpdateRoutes(UpdateRoutesRequest),
|
||||
AddARPNeighbors(AddARPNeighborsRequest),
|
||||
}
|
||||
|
||||
impl Display for TestRequest {
|
||||
@ -44,6 +45,7 @@ mod tests {
|
||||
TestRequest::RemoveContainer(_) => write!(f, "RemoveContainerRequest"),
|
||||
TestRequest::UpdateInterface(_) => write!(f, "UpdateInterfaceRequest"),
|
||||
TestRequest::UpdateRoutes(_) => write!(f, "UpdateRoutesRequest"),
|
||||
TestRequest::AddARPNeighbors(_) => write!(f, "AddARPNeighborsRequest"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -240,6 +242,11 @@ mod tests {
|
||||
runtests("updateinterface").await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_add_arp_neighbors() {
|
||||
runtests("addarpneighbors").await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_container_network_namespace() {
|
||||
runtests("createcontainer/network_namespace").await;
|
||||
|
9
src/tools/genpolicy/tests/policy/testdata/addarpneighbors/pod.yaml
vendored
Normal file
9
src/tools/genpolicy/tests/policy/testdata/addarpneighbors/pod.yaml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dummy
|
||||
spec:
|
||||
runtimeClassName: kata-cc-isolation
|
||||
containers:
|
||||
- name: dummy
|
||||
image: registry.k8s.io/pause:3.6@sha256:3d380ca8864549e74af4b29c10f9cb0956236dfb01c40ca076fb6c37253234db
|
156
src/tools/genpolicy/tests/policy/testdata/addarpneighbors/testcases.json
vendored
Normal file
156
src/tools/genpolicy/tests/policy/testdata/addarpneighbors/testcases.json
vendored
Normal file
@ -0,0 +1,156 @@
|
||||
[
|
||||
{
|
||||
"description": "compliant neighbors",
|
||||
"allowed": true,
|
||||
"request": {
|
||||
"type": "AddARPNeighbors",
|
||||
"neighbors": {
|
||||
"ARPNeighbors": [
|
||||
{
|
||||
"toIPAddress": {
|
||||
"family": 0,
|
||||
"address": "10.0.0.1",
|
||||
"mask": ""
|
||||
},
|
||||
"device": "eth0",
|
||||
"lladdr": "00:00:5e:00:53:01",
|
||||
"state": 128,
|
||||
"flags": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "allowed flags: NTF_PROXY",
|
||||
"allowed": true,
|
||||
"request": {
|
||||
"type": "AddARPNeighbors",
|
||||
"neighbors": {
|
||||
"ARPNeighbors": [
|
||||
{
|
||||
"toIPAddress": {
|
||||
"family": 0,
|
||||
"address": "10.0.0.1",
|
||||
"mask": ""
|
||||
},
|
||||
"device": "eth0",
|
||||
"lladdr": "00:00:5e:00:53:01",
|
||||
"state": 128,
|
||||
"flags": 8
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "allowed flags: NTF_ROUTER",
|
||||
"allowed": true,
|
||||
"request": {
|
||||
"type": "AddARPNeighbors",
|
||||
"neighbors": {
|
||||
"ARPNeighbors": [
|
||||
{
|
||||
"toIPAddress": {
|
||||
"family": 0,
|
||||
"address": "10.0.0.1",
|
||||
"mask": ""
|
||||
},
|
||||
"device": "eth0",
|
||||
"lladdr": "00:00:5e:00:53:01",
|
||||
"state": 128,
|
||||
"flags": 128
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "bad interface",
|
||||
"allowed": false,
|
||||
"request": {
|
||||
"type": "AddARPNeighbors",
|
||||
"neighbors": {
|
||||
"ARPNeighbors": [
|
||||
{
|
||||
"toIPAddress": {
|
||||
"family": 0,
|
||||
"address": "10.0.0.1",
|
||||
"mask": ""
|
||||
},
|
||||
"device": "lo",
|
||||
"lladdr": "00:00:5e:00:53:01",
|
||||
"state": 128,
|
||||
"flags": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "bad IP",
|
||||
"allowed": false,
|
||||
"request": {
|
||||
"type": "AddARPNeighbors",
|
||||
"neighbors": {
|
||||
"ARPNeighbors": [
|
||||
{
|
||||
"toIPAddress": {
|
||||
"family": 0,
|
||||
"address": "127.1.2.3",
|
||||
"mask": ""
|
||||
},
|
||||
"device": "eth0",
|
||||
"lladdr": "00:00:5e:00:53:01",
|
||||
"state": 128,
|
||||
"flags": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "bad state",
|
||||
"allowed": false,
|
||||
"request": {
|
||||
"type": "AddARPNeighbors",
|
||||
"neighbors": {
|
||||
"ARPNeighbors": [
|
||||
{
|
||||
"toIPAddress": {
|
||||
"family": 0,
|
||||
"address": "10.0.0.1",
|
||||
"mask": ""
|
||||
},
|
||||
"device": "eth0",
|
||||
"lladdr": "00:00:5e:00:53:01",
|
||||
"state": 0,
|
||||
"flags": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "bad flags",
|
||||
"allowed": false,
|
||||
"request": {
|
||||
"type": "AddARPNeighbors",
|
||||
"neighbors": {
|
||||
"ARPNeighbors": [
|
||||
{
|
||||
"toIPAddress": {
|
||||
"family": 0,
|
||||
"address": "10.0.0.1",
|
||||
"mask": ""
|
||||
},
|
||||
"device": "eth0",
|
||||
"lladdr": "00:00:5e:00:53:01",
|
||||
"state": 128,
|
||||
"flags": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
Loading…
Reference in New Issue
Block a user