Codex bwrap Loopback Error: An AppArmor Troubleshooting Case on Ubuntu 24.04
This investigation started with one error:
bwrap: loopback: Failed RTM_NEWADDR: Operation not permitted
Codex CLI 0.162.0 was running on Ubuntu 24.04.5 LTS. Even pwd could not execute through its sandbox. A comparison pointed to AppArmor: temporarily relaxing the unprivileged user namespace restriction let the command run; restoring it brought the sandbox failure back. Loading a dedicated configuration for the system bwrap eventually produced a successful execution record.
This article draws on that ChatGPT troubleshooting conversation and official documentation checked for publication. The original record establishes functional recovery, without validating a complete security policy. The observed workaround and the documented repair path are described separately. Usernames and session identifiers are omitted; /work/project replaces the original working directory in output examples.
Locate the failing operation
bwrap is the bubblewrap command. Its network setup source sends a Netlink RTM_NEWADDR request to add 127.0.0.1/8 to lo, and emits this error if that operation fails.
Start by investigating permission to perform that sandbox setup step. The message alone does not identify AppArmor, an outer container policy, or another restriction as the cause. It does not imply that the host network interface needs reconfiguration.
Collect the environment and correlate denial logs
Run these checks in the Linux environment where the failure occurs:
cat /etc/os-release
codex --version
systemd-detect-virt
id
sysctl kernel.unprivileged_userns_clone user.max_user_namespaces
sysctl kernel.apparmor_restrict_unprivileged_userns
grep -E 'CapEff|Seccomp|NoNewPrivs' /proc/self/status
command -v bwrap
The conversation recorded these results:
| Check | Observed value | What it establishes |
|---|---|---|
| OS | Ubuntu 24.04.5 LTS | Distribution-specific AppArmor policy matters |
| Codex | 0.162.0, standalone installation | The case concerns this version |
| Virtualization detection | none |
The detector identified no virtualization |
kernel.unprivileged_userns_clone |
1 |
This namespace switch was enabled |
user.max_user_namespaces |
4126513 |
The quota was not zero |
| AppArmor userns restriction | 1 |
Enabled; logs are needed to connect it to the failure |
| Checking process | CapEff=0, NoNewPrivs=0, Seccomp=0 |
A snapshot of that process, not future children |
Zero effective capabilities in an ordinary user process are insufficient to explain this failure. Ubuntu 24.04 can allow namespace creation while denying later use of capabilities inside it. An enabled userns switch therefore does not establish permission to configure the loopback interface. Ubuntu release notes
Reproduce the error and immediately inspect the matching time window:
sudo journalctl -k --since "5 minutes ago" \
| grep -Ei 'apparmor|DENIED|userns|bwrap'
These were the important log fields discussed in the conversation:
apparmor="DENIED" operation="capable" profile="unprivileged_userns" capability=12 capname="net_admin"
The conversation also mentioned a setpcap denial. The network-management denial fits the loopback failure, but correlate timestamps, PIDs, and process names before attributing a log entry to Codex. The sysctl value alone is insufficient evidence.
Make the test reach the shell command
One diagnostic run stopped with a different error:
Not inside a trusted directory and --skip-git-repo-check was not specified.
That run stopped at the repository check and did not test successful sandbox execution. In a test directory you control, use:
codex exec --skip-git-repo-check 'pwd'
This flag addresses the repository check; it does not grant AppArmor permissions. In this case, temporarily relaxing the restriction produced a real command execution record. After restoration, the same test failed again. Together with the denial logs, that comparison implicated AppArmor.
There was another trap: after a failed tool execution, Codex answered with the working directory from its environment context. A path in the final response is insufficient proof. Check for the shell command, its succeeded record, and its actual output.
Check the distribution bwrap profile first
Initially, bwrap was absent from PATH, while Codex reported a bundled helper. Installing system bubblewrap still left a sandbox failure. Having the executable and having the required policy are separate checks.
The official OpenAI sandbox documentation describes PATH selection and an extra Ubuntu 24.04 AppArmor profile. The following is that documented repair path; it was not the configuration tested in the original conversation.
Install the packages and inspect the executable:
sudo apt update
sudo apt install bubblewrap apparmor-profiles apparmor-utils
command -v bwrap
readlink -f "$(command -v bwrap)"
bwrap --version
Check existing policy and the additional profile file:
sudo aa-status
sudo grep -R -n -E 'bwrap|bubblewrap' /etc/apparmor.d
ls -l /usr/share/apparmor/extra-profiles/bwrap-userns-restrict
Package versions and local changes matter. Read and back up any existing destination file. Avoid overwriting custom policy or installing competing profiles for the same executable. If the source file is absent, check the package version and repository first.
When the source exists and no conflicting policy is present, copy and load it:
sudo install -m 0644 \
/usr/share/apparmor/extra-profiles/bwrap-userns-restrict \
/etc/apparmor.d/bwrap-userns-restrict
sudo apparmor_parser -r /etc/apparmor.d/bwrap-userns-restrict
Verify policy state and repeat the test:
sysctl kernel.apparmor_restrict_unprivileged_userns
sudo aa-status | grep -i bwrap
codex exec --skip-git-repo-check 'pwd'
If it fails, inspect fresh logs, especially whether the process still lands under profile="unprivileged_userns". Confirm which executable actually runs. Finding a bwrap on PATH identifies a candidate; it does not independently prove that a particular execution matched the intended profile.
What restored the original case
The final part of the conversation identified /usr/bin/bwrap. With no dedicated bwrap profile visible in the reported checks, the following permissive test configuration was created and loaded:
abi <abi/4.0>,
include <tunables/global>
profile bwrap /usr/bin/bwrap flags=(unconfined) {
userns,
capability net_admin,
capability setpcap,
}
Its file was /etc/apparmor.d/usr.bin.bwrap. The subsequent pwd test produced this execution record, with the directory replaced by an example value:
sandbox: read-only
/usr/bin/zsh -lc pwd
succeeded in 0ms:
/work/project
That establishes functional recovery in this case. The unconfined flag makes this a permissive profile; the two capability entries do not turn it into a minimal allowlist. Its attachment targets /usr/bin/bwrap, beyond a single Codex invocation. Ubuntu describes this profile mode in its release notes.
The procedure included restoring the global restriction to 1. However, the final successful run was not followed by fresh sysctl and profile-status output. The record supports successful execution, without proving a complete security review or that every subsequent workload will succeed.
If this custom configuration is already installed, back it up, unload the test profile, and move its policy file out of /etc/apparmor.d before replacing it with the distribution profile. Inspect attachment paths instead of loading both and hoping they work together.
Preserve the original value during temporary diagnostics
The conversation used kernel.apparmor_restrict_unprivileged_userns=0 for comparison. This affects the whole host and belongs only in an administrator-controlled environment where a brief change is acceptable. Try the distribution policy first. If a comparison is still needed, preserve the original value and restore it on exit.
This Bash script restores the value it read, rather than assuming the previous setting was 1:
#!/usr/bin/env bash
set -euo pipefail
sudo -v
original_userns=$(sysctl -n kernel.apparmor_restrict_unprivileged_userns)
restore_userns() {
sudo sysctl -w "kernel.apparmor_restrict_unprivileged_userns=${original_userns}"
}
trap restore_userns EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
codex exec --skip-git-repo-check 'pwd'
An exit trap cannot handle power loss or SIGKILL, and restoration can itself fail. Check sysctl kernel.apparmor_restrict_unprivileged_userns afterward and restore the recorded value if necessary. Do not persist the diagnostic value of 0 in a sysctl configuration file.
Verify the same operation before testing more
Keep the user, directory, and sandbox mode consistent for the first retest. Confirm actual tool execution, the intended loaded profile, the expected global restriction value, and the absence of related denials in that time window. Then test the reads, writes, or network operations required by the real project. A successful pwd covers only a minimal execution path.
Docker and LXC require separate investigation of the outer container policy. This case’s systemd-detect-virt result cannot be generalized to containers, and Seccomp=0 in the checking process does not establish the policy of every later child.
The two misleading checkpoints in this case were a run stopped by repository validation and a directory supplied from model context after execution failed. Correlating the original error, matching denial logs, and real tool output identifies which step the repair actually changed.
- 原文作者:春江暮客
- 原文链接:https://www.bobobk.com/en/codex-bwrap-loopback-apparmor-ubuntu.html
- 版权声明:本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。
相关文章
- curl in Practice: Check Your Website After Deployment
- Rsync in Practice: Preview File Changes Before Syncing over SSH
- SSH Config in Practice: Use One Server Name in Terminals and Scripts
- Codex Project Rules: Use AGENTS.md to Keep AI Coding Consistent
- Connect Codex to LiteLLM with Nginx as One Model Gateway