Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: isolation among all netavark bridge #703

Merged

Conversation

yassi-github
Copy link
Contributor

Currently, it appears that isolation is only enabled when both bridges are in isolate mode.
This means that communication with networks that do not have isolate enabled is still possible.

What about using isolate=strict to deny communication with networks that do not have isolate enabled?
Specifically, add a new chain of iptables and add a DROP rule to the chain for networks that do not have isolate enabled.

Here is a table showing the connectivity between networks before and after this change:

before:

|send\recv  |nonisol1   |nonisol1   |isol1      |isol2      |
|-----------|-----------|-----------|-----------|-----------|
|nonisol1   |     o     |     o     |     o     |     o     |
|nonisol2   |     o     |     o     |     o     |     o     |
|isol1      |     o     |     o     |     o     |     x     |
|isol2      |     o     |     o     |     x     |     o     |

after:

|send\recv  |nonisol1   |nonisol1   |isol1      |isol2      |strictisol1|strictisol2|
|-----------|-----------|-----------|-----------|-----------|-----------|-----------|
|nonisol1   |     o     |     o     |     o     |     o     |     x     |     x     |
|nonisol2   |     o     |     o     |     o     |     o     |     x     |     x     |
|isol1      |     o     |     o     |     o     |     x     |     x     |     x     |
|isol2      |     o     |     o     |     x     |     o     |     x     |     x     |
|strictisol1|     x     |     x     |     x     |     x     |     o     |     x     |
|strictisol2|     x     |     x     |     x     |     x     |     x     |     o     |

@yassi-github yassi-github force-pushed the strict-isolation branch 2 times, most recently from 48de7d3 to 51b24d3 Compare May 29, 2023 16:05
@yassi-github
Copy link
Contributor Author

@Luap99 @flouthoc
Is there anything else left to do for the review?
I'm new to OSS so sorry if I'm doing something wrong.

@Luap99
Copy link
Member

Luap99 commented May 30, 2023

@yassi-github No everything is good, I will try to take a look this week. I am a bit busy right now.

@yassi-github
Copy link
Contributor Author

@Luap99 OK, Thank you for your time. 😃

Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I like the idea of this new option. Please add tests for it, see the existing isolate test: https://github.com/containers/netavark/blob/main/test/100-bridge-iptables.bats#L632

I haven't verified if the iptables rules work correctly yet but the code looks mostly good, just some small comments.

@@ -73,3 +73,11 @@ pub struct IPAMAddresses {
pub net_addresses: Vec<types::NetAddress>,
pub nameservers: Vec<IpAddr>,
}

// IsolateOption is used to select isolate option value
#[derive(Clone, Debug, PartialEq)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Considering that this is a very simple type you can add the Copy trait there as well.
Then you can just remove the all the references for IsolateOption and pass it by value, that should simplify the code a bit.

parse_option(&self.info.network.options, OPTION_ISOLATE)?.unwrap_or(false);
// let isolate: String =
// parse_option(&self.info.network.options, OPTION_ISOLATE)?.unwrap_or(ISOLATE_OPTION_FALSE.to_string());
let isolate: IsolateOption = get_isolate_option(&self.info.network.options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely keep using parse_option() here, we only do not want to error for the teardown code path. In validate we should error out here.

Err(e) => {
// just log we still try to do as much as possible for cleanup
error!("failed to parse {} option: {}", OPTION_ISOLATE, e);
ISOLATE_OPTION_FALSE.to_string()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can just return IsolateOption::Never here

@Luap99
Copy link
Member

Luap99 commented Jun 1, 2023

And thanks for your contribution of course.

@baude
Copy link
Member

baude commented Jun 7, 2023

/approve
LGTM

@openshift-ci openshift-ci bot added the approved label Jun 7, 2023
@Luap99
Copy link
Member

Luap99 commented Jun 8, 2023

@mheon PTAL, can this be done with firewalld? I would like to avoid adding firewall driver specific options that we cannot support in other backends. Once we enable other backends we have to implement there as well. The problem is end users have no idea about what driver will be used and I really do not want critical security options only work with one implementation.

Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also could you squash the commits please.

Comment on lines 676 to 705
expected_rc=1 run_in_container_netns 1 ping -w 1 -c 1 10.89.2.2
expected_rc=1 run_in_container_netns 1 ping -w 1 -c 1 10.89.3.2
expected_rc=1 run_in_container_netns 2 ping -w 1 -c 1 10.89.0.2
expected_rc=1 run_in_container_netns 2 ping -w 1 -c 1 10.89.1.2
expected_rc=1 run_in_container_netns 2 ping -w 1 -c 1 10.89.3.2
expected_rc=1 run_in_container_netns 3 ping -w 1 -c 1 10.89.0.2
expected_rc=1 run_in_container_netns 3 ping -w 1 -c 1 10.89.1.2
expected_rc=1 run_in_container_netns 3 ping -w 1 -c 1 10.89.2.2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comments here what checks what, i.e from network x to y. If one thing here fails it is a nightmare to debug.

Comment on lines 695 to 740
expected_rc=1 run_in_container_netns 1 ping -w 1 -c 1 fd92::2
expected_rc=1 run_in_container_netns 1 ping -w 1 -c 1 fd93::2
expected_rc=1 run_in_container_netns 2 ping -w 1 -c 1 fd90::2
expected_rc=1 run_in_container_netns 2 ping -w 1 -c 1 fd99::2
expected_rc=1 run_in_container_netns 2 ping -w 1 -c 1 fd93::2
expected_rc=1 run_in_container_netns 3 ping -w 1 -c 1 fd90::2
expected_rc=1 run_in_container_netns 3 ping -w 1 -c 1 fd99::2
expected_rc=1 run_in_container_netns 3 ping -w 1 -c 1 fd92::2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

@mheon
Copy link
Member

mheon commented Jun 8, 2023

@Luap99 Not with the present implementation. Firewalld keeps everything in the same zone right now. Theoretically we could change this to have a 1:1 network:firewalld zone relationship which would allow us to do this, but within the same zone everything is treated as trusted - so we can't block traffic.

@Luap99
Copy link
Member

Luap99 commented Jun 8, 2023

@mheon What is the state of firewalld implementation then? I guess this is already a problem with the current isolate=true/false behavior? I think this needs to be supported by firewalld if we ever want to enable firewalld. But given how long we have been pushing this I have doubts that this is going to happen soon.

In any case I think this PR is good and solves a real problem and the firewalld future is something for us maintainers to figure out and should not block this PR from merging.

@mheon
Copy link
Member

mheon commented Jun 8, 2023

You are correct, firewalld does not support isolation at the moment.

Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks
/lgtm

In order to create networks with podman network create --opt isolate=strict we need to patch c/common to accept that new value.
Do you want to make a PR there to enable it? If not I can do it.

ref: https://github.com/containers/common/blob/20def0054c6e1841e1b33fe4ecc45c0ab3c29e6f/libnetwork/netavark/config.go#L189-L195

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Jun 16, 2023

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: baude, Luap99, yassi-github

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-robot openshift-merge-robot merged commit 36feb44 into containers:main Jun 16, 2023
@yassi-github
Copy link
Contributor Author

yassi-github commented Jun 16, 2023

LGTM, thanks /lgtm

Glad I could contribute!

In order to create networks with podman network create --opt isolate=strict we need to patch c/common to accept that new value. Do you want to make a PR there to enable it? If not I can do it.

ref: https://github.com/containers/common/blob/20def0054c6e1841e1b33fe4ecc45c0ab3c29e6f/libnetwork/netavark/config.go#L189-L195

I'd like to try it.

EDIT: created PR to c/common! (containers/common#1513)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants