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

AppArmor policy to deny network is not working #44984

Open
vteratipally opened this issue Feb 13, 2023 · 14 comments · May be fixed by #45053
Open

AppArmor policy to deny network is not working #44984

vteratipally opened this issue Feb 13, 2023 · 14 comments · May be fixed by #45053
Labels
area/security/apparmor kind/bug Bugs are bugs. The cause may or may not be known at triage time so debugging may be needed. status/0-triage

Comments

@vteratipally
Copy link

vteratipally commented Feb 13, 2023

Description

The AppArmor policy to deny network is not working in v23.0.0 for Ubuntu docker image. It was working in v20.10.* versions.

Reproduce

  1. Use docker version 23.0.0
  2. Create apparmor policy for no network access
cat > /tmp/no_network <<EOF
#include <tunables/global>

profile no-network flags=(attach_disconnected,mediate_deleted) {
  #include <abstractions/base>
  network inet tcp,
  network inet udp,
  network inet icmp,

  deny network raw,
  deny network packet,
  file,
  mount,
}
EOF

  1. Load the profile in AppArmor /sbin/apparmor_parser --replace --write-cache /tmp/no_network
  2. Create a Dockerfile with Ubuntu 22.04 and ping capabilities
cat > Dockerfile <<EOF
FROM ubuntu:22.04
RUN apt-get update && apt install -y iputils-ping
EOF
  1. Create a docker image using docker build -t ubuntu-ping .
  2. Run a container with the policy docker run --rm -i --security-opt apparmor=no-network ubuntu-test:latest ping -c3 localhost

Results

PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.019 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.036 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.037 ms

--- localhost ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2036ms
rtt min/avg/max/mdev = 0.019/0.030/0.037/0.010 ms

Expected behavior

ping: socket: Permission denied

docker version

Client:
 Version:           23.0.0
 API version:       1.42
 Go version:        go1.19.4
 Git commit:        e92dd87c3209361f29b692ab4b8f0f9248779297
 Built:             Sun Feb 12 10:45:24 2023
 OS/Arch:           linux/amd64
 Context:           default

Server:
 Engine:
  Version:          23.0.0
  API version:      1.42 (minimum version 1.12)
  Go version:       go1.19.4
  Git commit:       d7573ab
  Built:            Sun Feb 12 11:28:34 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.15
  GitCommit:        5b842e528e99d4d4c1686467debf2bd4b88ecd86
 runc:
  Version:          1.1.4
  GitCommit:        a916309fff0f838eb94e928713dbc3c0d0ac7aa4
 docker-init:
  Version:          0.19.0
  GitCommit:        fec3683b971d9c3ef73f284f176672c44b448662

docker info

Client:
 Context:    default
 Debug Mode: false

Server:
 Containers: 7
  Running: 0
  Paused: 0
  Stopped: 7
 Images: 1
 Server Version: 23.0.0
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 5b842e528e99d4d4c1686467debf2bd4b88ecd86
 runc version: a916309fff0f838eb94e928713dbc3c0d0ac7aa4
 init version: fec3683b971d9c3ef73f284f176672c44b448662
 Security Options:
  apparmor
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 5.15.93+
 Operating System: Container-Optimized OS from Google
 OSType: linux
 Architecture: x86_64
 CPUs: 1
 Total Memory: 3.594GiB
 Name: cos-dev
 ID: b1a5ed41-79a8-4462-b55c-c4fd0c91d01b
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:
  https://mirror.gcr.io/
 Live Restore Enabled: true

Additional Info

No response

@vteratipally vteratipally added kind/bug Bugs are bugs. The cause may or may not be known at triage time so debugging may be needed. status/0-triage labels Feb 13, 2023
@neersighted
Copy link
Member

Your provided reproduction seems to work for me just fine -- I notice that in the example you have both no-network and no-ping. Are you sure you're referencing the correct profile?

It's also worth noting that this will be very crude until #41442 or a successor is implemented, but I assume since what you want works on 20.10 that you're well-aware of the limitations. Still, more steps to reproduce are needed.

@vteratipally
Copy link
Author

It is reproducible on Container-Optimized OS from GCP. But I have updated the reproduction steps for Ubuntu and Debian.

@neersighted
Copy link
Member

Have you tested the reproduction on Ubuntu? It still does not work for me.

Also, who is providing the packaging for Container-Optimized OS? I assume it's backed into the base image?

@vteratipally
Copy link
Author

Yes, it is backed into the base image in Container-Optimized OS.

For ubuntu images in GCP it is still reproducible.

@vteratipally
Copy link
Author

Issue seemed to be here: a826ca3

The logic userNS is not respecting that even though the daemon is run in private mode, it is still considering it as default.

@thaJeztah
Copy link
Member

This seems to be related to;

I'm wondering though; if your intent is to have no networking at all, wouldn't --network=none provide this?

docker run -it --rm --network=none alpine ping -c1 google.com
ping: bad address 'google.com'

@vteratipally
Copy link
Author

Actually, we have a test to validate the docker with apparmor functionality. The reproduction steps mentioned above is what the test does to validate its functionality.

In the above it is still missing the running with security-opt enabled means in private mode but not with the user namespace enabled. So even with the security mode enabled, we are still running the docker containers similar to privileged mode.

@vteratipally
Copy link
Author

When the container is run in privileged mode, the sysctl values can be modified to allow all connections, but in case of apparmor security profile, all connections shouldn't be allowed but with the change #41030, the sysctl values are overrided and apparmor security profile is not respected with respect to ping.

@cpuguy83
Copy link
Member

I see the same exact behavior between 20.10 and 23.0 (ping works).

@vteratipally
Copy link
Author

I see the same exact behavior between 20.10 and 23.0 (ping works).

This issue is first seen in 20.10.13

@thaJeztah
Copy link
Member

That would be because this PR back ported the fix to 20.10;

As far as I can see, this is the intended behaviour since #41030, but I don't see immediately how AppArmor would be related to this.

Also duplicate(ish) / related:

@nobellium1997
Copy link

I did wanna mention here that the documentation for docker advertises this no-ping behavior which is probably why this issue exists:

https://docs.docker.com/engine/security/apparmor/#nginx-example-profile

I think if it's expected that ping should still work despite the profile, then the section here where ping is supposed to be blocked should probably be removed.

@neersighted
Copy link
Member

@thaJeztah
Copy link
Member

I did wanna mention here that the documentation for docker advertises this no-ping behavior which is probably why this issue exists:

https://docs.docker.com/engine/security/apparmor/#nginx-example-profile

I think if it's expected that ping should still work despite the profile, then the section here where ping is supposed to be blocked should probably be removed.

Ah, good callout. I guess the docs there used ping as an easy to demonstrate example. Probably should be rewritten to use something else as an example. /cc @dvdksn @akerouanton

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/security/apparmor kind/bug Bugs are bugs. The cause may or may not be known at triage time so debugging may be needed. status/0-triage
Projects
None yet
5 participants