Solving the PTRACE_ATTACH Constraint in Docker Containers

Over the past two years, we have been using Docker extensively for both development and execution of systems in the production environment, and all current products for our customers are developed specifically for this containerization system. It is worth noting that Docker changes quite a lot from version to version, adding both additional features (Swarm, Compose) and additional tools to increase security and control applications.
So with great surprise, we recently discovered that a container that was developed and tested some time ago does not work in the current version of Docker. The fact is that the container was not quite typical and the strace utility was used inside it to analyze the behavior of the process. About this application, we previously wrote in detail on Habrahabr.
Today, our developers finally got their hands on the implementation of this problematic
container in the application and they found that it no longer works. Starting to figure out what is the reason for this behavior, we saw that strace, and specifically ptrace, cannot join processes and produces an error of the form:
strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted Could not attach to process. If your uid matches the uid of the target process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try again as the root user. For more details, see /etc/sysctl.d/10-ptrace.confThe case is quite rare, and the solution is not easily identified by the collective mind of the developers, although quite a lot of different hints are scattered. So what was the matter?
Seccomp Subsystem
In the new Linux OS kernels, the new Docker uses the seccomp kernel function, which allows you to block system calls inside the container. Docker documentation on this feature is here . Ptrace is among the blocked system calls. Fine-tuning the mechanism is carried out using the Docker run argument --security-opt seccomp=/path/to/file.json, which allows you to specify a file that describes what is allowed and what is not. Because our container is running in a secure environment, we disable this feature completely: --security-opt seccomp=unconfined.
Ptrace Behavior
Strace gave us a hint that there is some kind of pseudo file /proc/sys/kernel/yama/ptrace_scopethat also describes ptrace restrictions. We look in the kernel documentation and find out that everything is not so simple as it was before. The values 0-3 in this pseudo-file significantly change the behavior of ptrace:
- 0 - the UID of the tracing process must match the UID of the traced or be 0 (the behavior as before);
- 1 - limited ptrace, processes must be related, the traced process must be a descendant of the
tracing or the tracing process must have UID = 0; - 2 - the CAP_SYS_PTRACE flag must be set for the tracing process or the descendant sets the PTRACE_TRACEME flag;
- 3 - tracing is prohibited.
By completing
docker exec -it cat /proc/sys/kernel/yama/ptrace_scope we found that the file was set to 1, respectively, not being a related process, strace could not connect to the traced process. At the same time, an attempt to set 0 to / proc / sys / kernel / yama / ptrace_scope was unsuccessful; a message was received saying that "/ proc is read only".
Privileged Container Launch
To overcome this limitation, the Docker flag helped us to allow privileged execution: --privilegedand in the initialization of the application we added setting the value "0" to the / proc / sys / kernel / yama / ptrace_scope pseudo-file.
echo 0 > /proc/sys/kernel/yama/ptrace_scopeAs a result, the problem was successfully resolved. An example of a solution and arguments for launching a container can be found in our GitHub repository for web ssh proxies .
It was interesting to note that the Linux kernel receives significant security improvements and additional security settings management tools, which are difficult to learn about if you do not constantly keep abreast and work within applications that develop over long life cycles in stable environments. One fine day you discover a new amazing world of improvements that "suddenly" showed themselves thanks to just such an unfortunate event.