containernetworking / plugins

Some reference and example networking plugins, maintained by the CNI team.
Apache License 2.0
2.21k stars 784 forks source link

portmap: nftables support #519

Closed greenpau closed 4 years ago

greenpau commented 4 years ago

@AlbanBedel , @aojea , @squeed , @dcbw , @rosenhouse , @mccv1r0 , @mrostecki , @huynguyennovem , @xcelsion , @tgross , please help with adding support for nftables by sharing your thoughts on the subject. Would love to see full support for nftables (the https://github.com/google/nftables implements Go-native API).

In firewall plugin, there is a support for firewalld and iptables (default). (started adding nftables here). When coding, there is a clear distinction between the two firewall backend.

In portmap plugin, I do not see a distinction between the various backend in this plugin. Is it because iptables takes care of both iptables and firewalld?

What is the best way forward to with adding support for nftables in portmap plugin?

(p.s. got your names from git log --pretty=format:"%an%x09" plugins/meta/portmap | sort | uniq)

PavelSosin-320 commented 4 years ago

@greenpau I'm trying to solve the problem of the same kind: Running Podman in CentOS8 WSL2 distro which uses Microsoft Linux Kernel i.e. without any firewall. Microsoft Linux kernel developed to run as WSL distro has very reduced networking and all networking capabilities are provided by WSL2 virtual network switch including eth0 interface with a volatile IP address. The kernel has no firewall but nobody expects to find a firewall in the lightweight VM always created inside Windows Host OS. Docker CE and Docker desktop daemons are ready to tolerate the absence of iptables under certain conditions and only issue warning "iptables are not supported" Firewall is not always needed when Linux runs inside VM containers. All WSL2 VM eth0 ports are mapped to the Host Windows machine network using NIC without any configuration. The problem is in Podman - it fails every time when podman network plugin gets non-zero return code from iptables. Maybe, disable firewall capability will be even enough to solve the problem.

greenpau commented 4 years ago

@PavelSosin-320 , please open a separate issue for this and cc: @greenpau on it so I can help you. I think I might know what the issue in your case is. Also, please post your CNI config in the newly created issue, together with the errors you receive.

P.S. This issue is really about the separation of various backends for portmap plugin. It was written focusing on iptables implementation only.

greenpau commented 4 years ago

FYI. I implemented portmap plugin for nftables: https://github.com/greenpau/cni-plugins#getting-started

Once portmap is expanded to accept other backends, it could be easily plugged in at this point:. https://github.com/greenpau/cni-plugins/blob/main/pkg/portmap/cmd.go#L12

PavelSosin-320 commented 4 years ago

Thanks, Paul! Meanwhile, I've found a workaround:
podman run -it -p 3000:3000 -v "$(pwd):/home/project:cached" --name=theia --network=host theiaide/theia it works but, as you can see with the host network. It is not enough to create Pod. To explicitly designate that my VM container has no firewall I removed (renamed) iptables and ip6tables files in /etc/sysconfig. The CNI configuration file /etc/cni/net.d /87-podman-bridge.conflist looks:

{
    "cniVersion": "0.4.0",
    "name": "podman",
    "plugins": [
    {
            "type": "bridge",
            "bridge": "cni-podman0",
            "isGateway": true,
            "ipMasq": true,
            "ipam": {
        "type": "host-local",
        "routes": [
            {
            "dst": "0.0.0.0/0"
            }
        ],
        "ranges": [
            [
            {
                "subnet": "10.88.0.0/16",
                "gateway": "10.88.0.1"
            }
            ]
        ]
            }
    },
    {
            "type": "portmap",
            "capabilities": {
        "portMappings": true
            }
    },
    {
            "type": "firewall"
    }
    ]
}

and, indeed, Podman0 network is created in my VM, and Podman network inspect shows the same configuration. Occasionally, I found that my distro has nft utility and nft list returns nothing as I expected.

greenpau commented 4 years ago

@PavelSosin-320 , set ipMasq to false in your config.

iptizer commented 4 years ago

Is it possible, that the incomplete implementation results in issues like this: https://github.com/projectcalico/calico/issues/3412 ? Meaning that i.e. ports are not deleted correctly from nftables?

PavelSosin-320 commented 4 years ago

@greenpau ipMasq = false doesn't help. CNI tries to use iptables anyway. iptables returns exit code 4 with a warning with the recommendation to use legacy iptables, I tried it in shell and it doesn't work too. My distro has nft installed. iptables --version says so. A similar issue related to the installed iptables version has been reported to Docker Desktop for Windows. It is built as an Alpine image. In the past, Docker-desktop only issued a warning when iptables are not supported but now it became an error. NFT for Alpine exists. Maybe, NFT is the 1st choice anyway?
On the other hand, I would like to ask what all firewall rules protect inside WSL VM if this VM has no separate network or network segment. It connected to the host network via Dummy V-switch. It communicates with the outer world via eth0 interface and volatile IP address.

greenpau commented 4 years ago

@PavelSosin-320 , do you use bridge plugin? Bridge needs ipmasq false. Then, you need to remove references to portmap and firewall plugins

PavelSosin-320 commented 4 years ago

@greenpau The iptables issue became very argent: the related issue has been reported as DockerDesktop issue a few days ago. Docker Desktop is built on Alpine Linux. The nft package exists for Alpine but by default Docker Desktop uses iptables.

After complete removal of all plugins except the bridge plugin I got the same result. I also found in my original .conflist the following firewall configuration: { "type": "firewall", "backend": "" } What does backend: "" means, no-backed or default, i.e. iptables? From my practice, it is always better to add isActive property to every plugin configuration to eas testing and maintenance. In all distro which I use NFT either pre-installed or can be added in a few minutes together with tools necessary for configuration conversion - iptables-translate. Even Alpine Linux used by Docker-Desktop has such utility. Why statement podman / docker network create can't detect cli provided by the platform to use it by the default?

greenpau commented 4 years ago

@PavelSosin-320 , you completely polluted the original issue I posted about ...

Aside from that, if in your CNI config you have "type": "firewall", "type": "portmap", and "type": "bridge", then iptables will be invoked by all three plugins. If you don't need firewall and portmap, then remove references to these plugins.

Per bridge plugin, to disable the calling of iptables by the plugin, you should set ipMasq to false inside that plugin. See https://github.com/greenpau/cni-plugins/blob/6b7a838e15f159e8695df59b4f4f722ca3f49118/assets/net.d/87-podman-bridge.conflist#L6-L9 for an example.

PavelSosin-320 commented 4 years ago

Unfortunately, dnf finds 1.6.4 as a latest available version for CentOS8 In this version initial installation didn't create a configuration file for the default podman network similar to your description. Also, podman network create didn't do it. I tried to find options of podman network create command but podman refused to accept any. It means the stable version of podman v2 is missed in the official RedHat repository. The latest podman 2 version is marked as RHEL. I understand that I'm playing an insider role trying to use podman in the environment which is not officially supported - WSL CentOS8 distro. My goal is to achieve better usability than the lame Docker Desktop for Windows recommended currently by MS. I will apply your recommendations just after the holidays.

greenpau commented 4 years ago

@PavelSosin-320 , if you running centos 8, then just use my cni plugins: https://github.com/greenpau/cni-plugins/blob/6b7a838e15f159e8695df59b4f4f722ca3f49118/assets/net.d/87-podman-bridge.conflist#L27-L36

unknowndevQwQ commented 1 year ago

I recommend reopening this issue because containernetworking/plugins still does not work with nftables/in any case does not need iptables