αα»ααααα·ααΆαααΊαααααΈαα»α αααααααα·αααααααααΆ αα·α Seccomp
BPF αααααααΌααα·ααΈααααΆαα’αΆαα»ααΆαααΎααααΈαααααΈαααΊαααααααα·αααααααααααααΆα αα»ααααα·ααΆα α¬ααααΏαα αααααΆααα ααα»ααααα α’αααα’αα·ααααααααΊαααααΆααα·αααΆ ααΆααΆαααα·αααα’αααα»αααΆαααααΎααΆαααααααααααααΆ ααΎααααΈαααααΎαααΆαα―ααααααααΎαααΆααα αααα»α Seccomp αααα’αα»ααααααααα Seccomp αααααΆααααααααααααα·ααΈ BPF αααααααΌαααΆαααααααΆααααΆ Seccomp BPF α αα αααα»αααααΌαααα ααΎαααΉαααααααααΆ Seccomp ααΆα’αααΈ αα·ααααααααααΆααααΌαααΆαααααΎα αααααΆααααα’αααααΉααααααΈααααααααα Seccomp filters αααααααΎαααααα·ααΈ BPF α αααααΆααααΈααα ααΎαααΉααα·αα·αααααΎαααααα BPF αααααααΆααααααΆαα½ααααααααΌαααΆααα½ααααα αΌααα αααα»αααΊααααααααΆαααααΌαα»ααα»ααααα·ααΆαααΈαα»α α
αααΌαα»ααα»ααααα·ααΆαααΈαα»α (LSM) ααΊααΆαααααααααααααααααααΌααααα»ααααα»αααΆααααα’αΆα ααααΌαααΆαααααΎααΎααααΈα’αα»ααααααααΌαα»ααααα·ααΆααααααααααα»ααααααααααααααΆαα LSM α’αΆα ααααΌαααΆαααααΎαααααααΆαααα αααα»ααααααΆααααααααΊααα ααΌα ααΆ Apparmor, SELinux αα·α Tomoyo α
α αΌαα αΆααααααΎααααααΆααα·ααΆααααΆα’αααΈαααααααΆαααααααΈαα»α α
αααααααα·ααα
ααααΉαααΆααααααααααΆαααααααΈαα»α ααΊααΆ α’αααααααΌααααααααΆαα’αα»ααααΆαααααΎαααΆααααααααΆααα·αααα·ααΎααααΈα’αα»αααααα·α αα ααΆαααΆααααΆαααα½α ααα»ααααααααα·αααααΎ suid αααααΆαααααααααααα α¬ααΎαα·αααΌα ααααααααααΎα±ααααααΎαααΆαααΆααα·αααα· ααΆαααααααααααααΆαααααΆαααΆααααα αΆα αα·αα’αα»ααααΆαα±ααααααΎαααΆαα’αα»αααααα·α αα ααΆααα½αα ααα½αα α§ααΆα ααα ααααα·αααΎαααααα·ααΈααααα’αααααααΌαααΆαααΎαα ααααααααΆααα·αααα· αα·ααΆαααΆ 80 αααα½αα±ααααΆαααααΎαααΆαααααΎαααΆαααΆ root α’αααα’αΆα αααααα±ααααΆααΌααααααααΆα CAP_NET_BIND_SERVICE α
αα·α αΆαααΆαααααα·ααΈ Go αααααΆααααααααΆ main.goα
package main
import (
"net/http"
"log"
)
func main() {
log.Fatalf("%v", http.ListenAndServe(":80", nil))
}
αααααα·ααΈααααααααΎαααΆαααΈααα HTTP αα ααΎα ααα 80 (αααααΊααΆα ααααααααΆααα·αααα·)α ααΆααααααΆααΎαααααΎαααΆαααΆααααΆαααααααΆααααΈααΆαα αααααα
$ go build -o capabilities main.go
$ ./capabilities
ααααααΆαααΆααααα αααααΆαααΎααα·αααααααα·αααα·ααΆ root ααΌααααααΉααααααα α»ααα αααααααΆααα αααα
2019/04/25 23:17:06 listen tcp :80: bind: permission denied
exit status 1
capsh (αααααα·ααΈαααααααααααα) ααΊααΆα§ααααααααααααΎαααΆααααααΆαα½αααΉααααα»ααααααααΆαααΆααααΆαααα½αα
αααα»αααααΈααα ααΌα αααααΆααααααΆαααα½α ααα αΎα αααα½αα±ααααΆαααααααα·αααα·ααΆ root αααααα α’αααα’αΆα ααΎαααΆαααααΆααα ααααααααΆααα·αααα·ααααααααααΌααααααααΆα cap_net_bind_service αα½αααΆαα½αααΉαα’αααΈααααααααααααααΆααα αααα»ααααααα·ααΈαα½α α αΎαα ααΎααααΈααααΎααΌα αααα ααΎαα’αΆα ααααΆαααααααα·ααΈααααααΎαααΆ capshα
# capsh --caps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep'
--keep=1 --user="nobody"
--addamb=cap_net_bind_service -- -c "./capabilities"
αααααααααααααΈαααα»ααααααααα·α α
- capsh - ααααΎ capsh ααΆαααα
- βcaps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep' - αααααΆαααΎαααααΌαααΆαααααΆααααααΌαα’αααααααΎααααΆαα (ααΎααα·αα ααααααΎαααΆαααΆ root) ααΎαααΉααααααΆαα cap_net_bind_service αα·ααααααααΆααααα»αααΆαααααΆααααααΌαααααααααΆααα’αααααααΎααααΆαααα·αααααΆααααΈ root αα ααααΆαααααΆααααΆααααΊ cap_setuid αα·α cap_setgid α
- βkeep=1 β ααΎαα αααααααΆαααααααΆααααααΆαααα‘αΎααα αααααααΌαααΈααααΈ root α
- βuser=βnobodyβ β α’αααβααααΎβα α»αβαααααβαααβααααΎαααΆαβαααααα·ααΈβααΉαβααααΆαβααααΆβααααΆααβα‘αΎαα
- βaddamb=cap_net_bind_service β αααααβααΆαβαααααβαααααααΆαβαααβααΆαααααααβαααααΆααβααΈβααααΌαβααΈβαααα root α
- -c "./capabilities" - ααααΆααααααααΎαααΆααααααα·ααΈα
αααααααΆαααααΆααααΊααΆαααααααααααααααΆααα·ααααααααααΌαααΆαααα½αααααααααααααα·ααΈαα»ααΆα αα αααααααααααα·ααΈαα αα α»ααααααααααα·ααααα·αα½αααΆαααααααΎ exeve()α ααΆαβααβαααααααΆαβαααβααααΌαβααΆαβα’αα»ααααΆαβα±ααβααΆααβααΆααααααα α¬βαα·ααΆαβαααααΆαβαααβααΆβααΆβαααααααΆαβααα·ααααΆαβα’αΆα βααααΌαβααΆαβααα½αβααααα
α’ααααααα ααααΆαααααααΆααΎ +eip ααΆαααααααΆαααΆαααααΆααααΈαααααΆαααααααααΆααα αααα»ααααααΎα --capsα αααααΆαααααααααΌαααΆαααααΎααΎααααΈαααααααΆαααααααΆαα
- ααααΌαααααααΎα±ααααααα (αα);
- ααΆααααααΆααααααΎααααΆαα (α’ααΈ);
α’αΆα ααααΌαααΆαααα½ααααααααααααΎαααΆααα»ααΆα (i) α
αααααΆαααΎαα ααααααΎ cap_net_bind_service ααΎαααααΌαααααΎααΆαααααααΎααα e α αααααΆααααααΎαααΉαααΎαααααα αααα»αααΆααααααααΆα ααΆααΉαααααΎαααΆααααααααααααααΈααααααααΆα α αΎαααΎαααααΌααααααΆααααΆαααααα i α ααΆα α»αααααα ααΎαα ααααΎααα»αααΆαααα (ααΎαααΆαααααΎααΆααααα·αααααΆααααααΌα UID) ααΆαα½αααα ααΆααΎααα ααΌα ααΆ cap_net_bind_service+eip α
α’αααα’αΆα αα·αα·αααααΎααααααααααααααΎ ss α ααΌαβααΆααβαα·αααααβα±ααβααααΈβααααα·α βααΎααααΈβα±ααβααβααΉαβααααα ααα»ααααβααΆβααΉαβαααα αΆαβα αααβαααβααΆααβααΆααααβαα·αβαααβαααααΆααβα’αααβααααΎβαααααβααΈ 0 αααα»αβααααΈβααα 65α
# ss -tulpn -e -H | cut -d' ' -f17-
128 *:80 *:*
users:(("capabilities",pid=30040,fd=3)) uid:65534 ino:11311579 sk:2c v6only:0
αααα»αα§ααΆα αααααα ααΎαααΆαααααΎ capsh ααα»ααααα’αααα’αΆα αααααααααααααααΎ libcap α αααααΆααααααααΆααααααα ααΌαααΎα man 3 libcap α
αα αααααααααααααα·ααΈ ααΆααΉαααΆααα’αααα’αα·αααααααα·αααΉαααΆαα»αααΌααααααααα·αααααΆααα’ααααααααααα·ααΈααααΌαααΆααα αααααααΎαααΆαα ααΎαααΈααα αα»αααΆαααΆαααααα’αΆα ααααΆααααααΌααα αααα»αααααααααΈα
ααΎααααΈαααααΆααααα αααΆααααΈαααααααΆααααααααα·ααΈααααααΎα ααΎαα’αΆα ααα§ααααααααααΆααααααααΆα BCC αααααααα kprobe αααααΆαααα»αααΆαααΊααα cap_capableα
/usr/share/bcc/tools/capable
TIME UID PID TID COMM CAP NAME AUDIT
10:12:53 0 424 424 systemd-udevd 12 CAP_NET_ADMIN 1
10:12:57 0 1103 1101 timesync 25 CAP_SYS_TIME 1
10:12:57 0 19545 19545 capabilities 10 CAP_NET_BIND_SERVICE 1
ααΎαα’αΆα αααααα ααΆαααΌαααΏαααΌα ααααΆαααααααΎ bpftrace ααΆαα½αααΉα kprobe αα½ααααααΆαααααα»ααα»αααΆαααΊααα cap_capableα
bpftrace -e
'kprobe:cap_capable {
time("%H:%M:%S ");
printf("%-6d %-6d %-16s %-4d %dn", uid, pid, comm, arg2, arg3);
}'
| grep -i capabilities
ααΆβααΉαβα ααβααααααβααΌα βααΆαβααααα ααααα·αααΎβαααααααΆαβαααααα·ααΈβααααβααΎαβααααΌαβααΆαβααΎαβαααααΆααβααΈ kprobeα
12:01:56 1000 13524 capabilities 21 0
12:01:56 1000 13524 capabilities 21 0
12:01:56 1000 13524 capabilities 21 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 12 0
12:01:56 1000 13524 capabilities 10 1
αα½αααΈααααΆαααΊααΆαααααααΆααααααααΎαααΆαααααΌαααΆα α αΎαα αΆααααΆααααΈααααααααααα½ααααα αΌαααααΉαααα·ααΆαααααααα·ααααααΆααααααα ααΎαααΎαααΆααααα½ααα·αα·αααααααα·ααααααΆαααααααααΆααα’αα α αΎαααΈαααα»ααααααααΆααααααααΌαααΆαααΆαα½αααΉααααααααααα (α α»αααααααα αααα»ααααααα) ααααααα 1. αααααααΆαα αα½ααααααΎαα αΆααα’αΆααααααααΊ CAP_NET_BIND_SERVICE ααΆααααΌαααΆααααααααΆααΆααααα αααα»αααΌααααααααΊααααααα»αα―αααΆααα½αααΆα/uapi/linux/ability.h ααΆαα½αααααααααΆαα 10α
/* Allows binding to TCP/UDP sockets below 1024 */
/* Allows binding to ATM VCIs below 32 */
#define CAP_NET_BIND_SERVICE 10<source lang="go">
αααααααΆαααααΌαααΆαααΎαααΆααΉαααΆαααα αααααααΎαααΆααααααΆαααα»αααΊαααααΌα ααΆ runC α¬ Docker ααΎααααΈα’αα»ααααΆαα±αααα½αααΆααααΎαααΆααααα»ααααααα·αααΆααα·αααα· ααα»αααααα½αααααααΌαααΆαα’αα»ααααΆαααααΉααααααααααΆααααααααΌαααΆαααΎααααΈααααΎαααΆααααααα·ααΈααΆαα αααΎαααα»αααααα αα αααααααααααα·ααΈααΆαααΆααααααααΆαααΆααααΆαα Docker α’αΆα αααααα±αααα½ααααααααααΎ --cap-add:
docker run -it --rm --cap-add=NET_ADMIN ubuntu ip link add dummy0 type dummy
ααΆααααααααΆαααααΉααααααα±αααα»αααΊαααααΌααααααααΆα CAP_NET_ADMIN αααα’αα»ααααΆαα±ααααΆααααααα ααΆαααααααααααααααΆαααααααΆαααΎααααΈααααααα ααα»α αααααΆαα dummy0 α
ααααααααααΆαααααα αΆαααΈααααααααΎαααααααα·αααααΌα ααΆααΆααααα ααα»ααααααΆαααααΎαα αα αααααααααααααα’αα»ααααΆαα±ααααΎαα’αα»αααααααααα·ααΈαααααααααΆαααααα½αααααααΎαα
Seccomp
Seccomp ααααΆαα±αα Secure Computing αα·αααΆαααααΆαααα»ααααα·ααΆααααααααΌαααΆαα’αα»αααααα αααα»αααΊαααααΈαα»α αααα’αα»ααααΆαα±ααα’αααα’αα·ααααααααααααΆαα α ααΆααααααααααα½αα ααα½αα αααααΈααΆ Seccomp α’αΆα αααααααααααααααΆααα ααΉαααΈαα»α ααααα αααααααΆαααααααΆαααα»αααΆααααααααααααΆαα α ααΆααααααααααα½αα ααα½αααααΎα±ααααΆααΆαααΆαααααααααΆαααΎαααααααααα ααΉααα½αααα
αααααααα·ααα Seccomp αα·α Linux ααΊαα·αααααΆα ααα»ααα αα·ααα αα α αΎαααΆααΏααααααΌαααΆαααααααΎααΆαα½αααααΆααΎααααΈααα½αααΆαα’αααααααααααααΈαα·ααΈααΆαααααααΆααααΈαα ααΆα§ααΆα ααα α’ααααααα ααααΆα αααααααααααΎαααΆαααΌααααααααΆα CAP_NET_ADMIN ααα»αααααα·αα’αα»ααααΆαα±ααααΆααα½αααααΆαααααΆαααααα ααΆααΆααααΆαααα½α αα·αααα½αααΆαα α ααΌααααααααααααα 4 ααα
αα·ααΈααΆαααααα ααααα Seccomp ααΊααα’ααααΎααααα BPF αααααααΎαααΆααααα»ααααα SECOMP_MODE_FILTER α αΎαααΆαααααααΆαα α ααΆαααααααααααααΌαααΆαα’αα»ααααααΆαααααααΌα ααααΆααΉααααα ααααααααΆααααα
ααααα Seccomp ααααΌαααΆααααα»ααααααααΎ prctl ααΆααααααααα·ααααα·ααΆα PR_SET_SECOMP α αααααααΆααααααααααααααααααααα·ααΈ BPF αααααααΌαααΆαααααα·ααααα·αααααΆαααααα αα Seccomp ααΈαα½αααααααααΆαααααα ααΆαααααααα seccomp_data α αα ααΆαααααααααααΆαααααΆααααααααααα α ααα’α»ααα ααΆαααααΆαααααααααΎαααΆααα αααα α αααααααα αα·αα’αΆαα»αααααααΆαα α ααααααααα’αα·ααααΆα ααα½αααααΆααα½α ααααααα αΆαααΆ uint64 α
αααααΆα’αααΈααααα ααΆαααααααα seccomp_data ααΎααα ααΌα ααΈααΌααααααααΊααααα αααα»αα―αααΆα linux/seccomp.hα
struct seccomp_data {
int nr;
__u32 arch;
__u64 instruction_pointer;
__u64 args[6];
};
ααΌα αααα’αααα’αΆα ααΎαααΎαααΈαα ααΆααααααααααα ααΎαα’αΆα αααααααααΆαα α αααααααα α’αΆαα»αααααααααααΆ α¬ααΆααα½ααααα αΌαααααΆααααΆααααΈαα
αααααΆααααΈααα½αααΆααααα αα Seccomp ααΈαα½αα αααααααααΌαααααααΎαααΆαααΎααααΈααααΎααΆααααααα α α·αααα α»αααααα α αΎαααααΆααααΊαααα’αααΈαααααααΌαααααΎαααααΆαααααα ααΆααααααα α α·αααα α»ααααααααααΌαααΆααααα αΆααααααααααα½αααααΆααααα‘αααααα·α (αααααΌαααααΆαααΆα) α
- SECOMP_RET_KILL_PROCESS - αααααΆααααααΎαααΆαααΆααααΌαααααΆαααααααΆααααΈααααααΆαα α ααΆαααααααααααααα·αααααΌαααΆαααααα·ααααα·αααααΆαααααΏααααα
- SECOMP_RET_KILL_THREAD - αααα αααααααααα‘αΆααα αα α»ααααααααααΆαααααααΆααααΈααααααΆαα α ααααααααααααα·αααααΌαααΆαααααα·ααααα·αααααΆαααααΏααααα
β SECOMP_RET_KILL β ααααααααααααααΆααααααΆαα SECOMP_RET_KILL_THREAD αα»ααααααΆααααΆαααααααΆαααααααα
- SECOMP_RET_TRAP - ααΆαα α ααΆαααααααααααααΌαααΆαα αΆαααΆαα α αΎααααααΆ SIGSYS (Bad System Call) ααααΌαααΆααααααΌααα αα·α αα ααΆααααα α ααΆα
- SECOMP_RET_ERRNO - ααΆαα α αααααααααα·αααααΌαααΆαααααα·ααααα·αα α αΎααααααααααααααααα‘ααααααα SECOMP_RET_DATA ααααΌαααΆααααααΌααα α αααααα’αααααααΎααααΆααααΆααααα errno α α’αΆαααααααΎααΌαα ααα»ααααα α»α ααααα errno αααααααααΆααααΌαααΆααααα‘ααα αααααΈαααααα α»αααααΌαααΆααααααααΌααα ααααααααααΆααα
- SECOMP_RET_TRACE - ααααΎααΎααααΈααΌαααααΉααααα’αααααΆαααΆα ptrace αααααααΎ - PTRACE_O_TRACESECCOMP ααΎααααΈααααΆααα αΆαααα ααααααααΆαα α ααΆαααααααααααααΌαααΆαααααα·ααααα· ααΎααααΈααΎα αα·ααααααααααααααΎαααΆααααα ααααα·αααΎα§αααααααΆαααΆααα·αααααΌαααΆαααααΆαααα ααα α»ααα½αααααΌαααΆααααααααααα·α errno ααααΌαααΆαααααααα -ENOSYS α αΎαααΆαα α αααααααααα·αααααΌαααΆαααααα·ααααα·ααα
- SECOMP_RET_LOG - ααΆαα α ααΆαααααααααααααΌαααΆααααααααΆα αα·αα αΌαα
- SECOMP_RET_ALLOW - ααΆαα α ααΆαααααααααααααΌαααΆαα’αα»ααααΆααααΆαααΆααααα
ptrace ααΊααΆααΆαα α ααααααααααΎααααΈα’αα»ααααααααααΆαααΆαααΆααα αααα»αααααΎαααΆααααα α ααΆ tracee αααααΆααααααααΆααααα½ααα·αα·ααα αα·ααααααααααααΆαααααα·ααααα·ααααααΎαααΆααααα αααααα·ααΈααΆαααΆαα’αΆα ααΆαα₯αααα·ααααΎααΆαααααα·ααααα· αα·αααααααααΆαα α»ααααααααα·αααα tracee α αα αααα»αααα·αα Seccomp ptrace ααααΌαααΆαααααΎαα ααααααααααα‘αΎαααααααααΌαααααΆαααΆα SECOMP_RET_TRACE ααΌα αααα tracer α’αΆα ααΆαααΆαααΆαα α ααααααααααΈααΆαααααα·ααααα· αα·αα’αα»αααααααααα·ααααΆααααΆαααααα½αααααααΆα
ααα α»α Seccomp
ααΈααααα½ααα ααααα½α ααααααααααΎααΆαααΆαα½α Seccomp α’αααααΉααα½αααααααααα αΆαααααα αααααααΌαααΆααααααα’ααααααααΆααααααααααααα‘αααααα·ααααααααα SECOMP_RET_ERRNO α ααΎααααΈααΆαααΆαααααΈααα α»α ααΆαα α αααααααα seccomp ααΉααααα‘αα -1 αααα½αα±αα 0α
ααα α»αααΆααααααα’αΆα ααααΎαα ααΆαα
- EACCESS - α’αααα α ααΌαααααααα·αααααΌαααΆαα’αα»ααααΆαα±ααααααΎααΆαα α ααΆαααααααααααα ααΆααΆααααααΆααΎαα‘αΎααααααΆαααααΆαα·αααΆααα·αααα· CAP_SYS_ADMIN α¬ no_new_privs αα·αααααΌαααΆαααααααααααααΎ prctl (ααΎαααΉααα·ααΆαα’αααΈααΆαα αααααααα);
- EFAULT β α’αΆαα»ααααααααααΆαα’αα»ααα (args αα αααα»ααα ααΆαααααααα seccomp_data) αα·αααΆαα’αΆααααααΆαααααΉαααααΌαααα
- EINVAL - ααΆα’αΆα ααΆαα ααα»αααα½ααααΆααα ααΈαααα
- ααααα·ααααα·ααΆααααααΆαααααΎααΊαα·αααααΆαα α¬αα·αααααΌαααΆαααΆαααααααααΊααααααα»αααΆαααααααα ααΆαααααααααα αα α»ααααααα
-ααααααααΆααααααΆααααΊαα·αααααΉαααααΌααααααΆααααααα·ααααα·ααΆααααααΆαααααΎαα»αα
-operation αα½ααααα αΌα BPF_ABS ααα»ααααααΆααααα αΆααΆαα½αααΉαα’α»α αααα·ααααααΆααααααΆαααααα’αΆα ααΎαααΈααα ααααα ααΆαααααααα seccomp_data α
- α ααα½αααΆαααααΆααααααΆααααααΌααα αααααααΎαααΈα’αα·ααααΆα
β ENOMEM β αα·αβααΆαβα’αααβα αα αΆαβαααααααααΆααβααΎααααΈβααααα·ααααα·βαααααα·ααΈ
- EOPNOTSUPP - ααααα·ααααα·ααΆαααΆααααα αΆαααΆααΆαα½αααΉα SECOMP_GET_ACTION_AVAIL αααααααΆαααΊα’αΆα ααααΎααΆα ααα»ααααααΊααααα·αααΆααααααΆααααα‘αααααα·ααα αααα»αα’αΆαα»αααααααα
- ESRCH β αααα αΆαα½αααΆαααΎαα‘αΎααα αααααααΎααααΆαααααααααααΈααα½αααααααααα
- ENOSYS - αα·αααΆαααΆααααααααΆαααα ααΉααααααααΆα SECOMP_RET_TRACE ααα
prctl ααΊααΆααΆαα α ααΆααααααααααααα’αα»ααααΆαα±αααααααα·ααΈααα α’αααααααΎααααΆαααααα α (ααααα αα·αααα½αααΆα) αα·αααααΆαααΆααααΆααααααααΎαααΆααα½α ααΌα ααΆααΆααααα ααααααα, ααααααααααααα‘αΆα, ααααααααΆαα»ααααα·ααΆα (Secomp), αα·αααα·, ααααΉαααα·ααΆααα Perf ααΆααΎαα
Seccomp α αΆααααΌα ααΆαα αα αααα·ααααΆ Sandbox αααααΆααα’ααα ααα»ααααααΆαα·ααααααα Seccomp ααΊααΆα§αααααααααΎααααΆαααααα’αα»ααααΆαα±ααα’αααααααΎαααααΎαααααααΆα sandbox α α₯α‘αΌααααααΌααααα‘ααααΎαααΈααααααααααααα·ααΈα’ααααααααα’αααααααΎααααΆααααααΌαααΆααααααΎααααααααΎααααααααα α αααααααΆαααααααΆαα α αααααααα Seccomp α
α§ααΆα αααααααα BPF Seccomp
ααΆααααααααα ααΎααααα»αααΉααααα αΆαααΈαααααααα αΌαααααΆααΌααααααααΆαααΆααααΈααααααΆααα·ααΆααααΆααΈαα»αααΊα
β ααΎαβααΉαβαααααβαααααα·ααΈ Seccomp BPF αααβααΉαβααααΌαβααΆαβααααΎβααΆβαααααβααΆαα½αβααΉαβααΌαβαααα‘ααβαα»αβααααΆβα’αΆαααααβααΎβααΆαβαααααα βα α·αααβαααβααΆαβααααΎα
- αααα»αααααααααααααΎ prctl α
ααααΌαα’αααααααΌαααΆαααααααΆααΈαααααΆααααααααααΆα αα·αααΊαααααΈαα»α α
#include <errno.h>
#include <linux/audit.h>
#include <linux/bpf.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
#include <linux/unistd.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
#include <unistd.h>
αα»ααααααΆαααααα§ααΆα αααααα ααΎαααααΌαααΆααΆααΆααΊαααααααΌαααΆαα αααααααα CONFIG_SECCOMP αα·α CONFIG_SECOMP_FILTER ααααααα ααΆ y α αα ααΎαααΆαααΈαααααΎααΆα α’αααα’αΆα αα·αα·αααααΎαααΌα αααα
cat /proc/config.gz| zcat | grep -i CONFIG_SECCOMP
ααΌαααααα αααααΊααΆαα»αααΆα install_filter ααΈααααααα αααααααΈαα½αααΆααααααΈααΆαααααΆαα’αααΈααααα BPF ααααααΎαα
static int install_filter(int nr, int arch, int error) {
struct sock_filter filter[] = {
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, arch))),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch, 0, 3),
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1),
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (error & SECCOMP_RET_DATA)),
BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW),
};
ααΆαααααΆαααααΌαααΆαααααααααααααΎαααΆααααΌ BPF_STMT αα·α BPF_JUMP αααααΆαααααααααα»αα―αααΆα linux/filter.h α
α
αΌαααΎαααααααΆααααΆαααααΆαα
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, arch)))) - αααααααααααα»α αα·ααααααΌααααα»αααΈ BPF_LD αααα»αααααααααΆααα BPF_W αα·αααααααααα ααααααααΆαααΆαααΈααΆαααα α’α»α αααα·αααα BPF_ABS α
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch, 0, 3) - αα·αα·ααααααααααΎ BPF_JEQ ααΆααΎαααααααααΆαααααααααα αααα»α BPF_K accumulator αααααααΎααΉα arch α ααΎααΌα αααα ααααα α’α»α αααα·α 0 αα ααΆααααΆαααααΆααααααΆαα ααΎαα·αααΌα αααααα ααααα α’α»α αααα·α 3 (αααα»αααααΈααα) ααΎααααΈαααααα α»αααααα arch αα·ααααΈααααΆα
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, nr)))) - αααα»α αα·ααααααΌααααα»αααΈ BPF_LD αααα»αααααααααΆααα BPF_W αααααΆαααα α αααααααααααααααααΆααααα»αα’α»α αααα·αααααα BPF_ABSα
β BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1) β αααααααααααα α ααααααααααΆαα½αααΉααααααααα’ααα nr α ααααα·αααΎαα½αααΆααααΎααααΆ ααΌααααααα ααΆαααααΆααααααΆαα α αΎααα·αααΆαα α ααΆααααααααα ααΎαα·αααΌα ααααααα’αα»ααααΆαα±ααααΆαα α ααααααααααΆαα½α SECOMP_RET_ALLOW α
- BPF_STMT(BPF_RET + BPF_K, SECOMP_RET_ERRNO | (error & SECOMP_RET_DATA)) - αααα αααααααα·ααΈααΆαα½α BPF_RET α αΎαααΆαααααααααααΎαααα α»α SECOMP_RET_ERRNO ααΆαα½αααΉααααααΈ err variableα
- BPF_STMT(BPF_RET + BPF_K, SECOMP_RET_ALLOW) - αααα αααααααα·ααΈααΆαα½α BPF_RET αα·αα’αα»ααααΆαα±ααααΆαα α ααααααααααααΎαααΆααααααααΎ SECOMP_RET_ALLOW α
SECOMP ααΊ CBPF
α’ααααααα ααααΆαααααααΆα ααα»α’αααΈααΆαααΆαααααΈααΆαααααΆαααααΌαααΆαααααΎαααα½αα±ααααααα» ELF αααααΆαα ααααα α¬αααααα·ααΈ C αααααΆαα ααααα JIT αααΆαα ααα»ααααΈααααααΆααααΏααααα
β’ ααΈαα½α Seccomp ααααΎ cBPF (classic BPF) αα·ααα·αααα eBPF αααααΆααααααΆα ααΆαα·αααΆαααΆαα α»αααααααα ααα»ααααααΆααα accumulator ααΎααααΈαααααΆαα»αααααααααααΆα α»αααααα ααΌα αααα’αΆα ααΎαααΎααα αααα»αα§ααΆα αααα
β’ ααΈααΈα Seccomp ααα½αααααααα·α αα½ααα ααΆααα’αΆααααααΆαααααΆα BPF αααααααΆαα α αΎαααααΆαα’αααΈααααααααααα αααΆααααΌαααααΎαααΆαααααΎααααΆαααααα½ααααααΆααααΆαααααΆαααΆαααααααΆααα·ααΈαααααΆααααα½ααααααΆααα’αααααααααααααα·ααΈα
ααααα·αααΎα’αααααααΌαααΆααααα½ααααααααααααΎααααΈαααααΈααΆααα½αααααα»αααααΆααα ααΌααα·α αΆαααΆ pseudocode αααααααΎααΌα ααααΆαααα
if (arch != AUDIT_ARCH_X86_64) {
return SECCOMP_RET_ALLOW;
}
if (nr == __NR_write) {
return SECCOMP_RET_ERRNO;
}
return SECCOMP_RET_ALLOW;
αααααΆααααΈαααααααΌαααααααα αααα»ααα ααΆαααααααα socket_filter α’αααααααΌαααααα sock_fprog αααααΆααααααΌα αα·ααααααααααααΆαααααΆαααααααα αα ααΆαααααααααα·αααααααααααΊααααΌαααΆαααΆα’αΆαα»ααααααααααΆαααααααΆαααααΎαααΆαααΎααααΈααααΎαααΆααα ααααααααα
struct sock_fprog prog = {
.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
.filter = filter,
};
ααΆαααΏααααα½αααααααααααΌαααααΎαα αααα»ααα»αααΆα install_filter - αααα»ααααααα·ααΈααααααα½αα―α! ααΎααααΈααααΎααΌα αααααΎαααααΎ prctl ααααα PR_SET_SECOMP ααΆαααααΎααα½αααΎααααΈαααα αΌααααααα»αααααΌααααααααΆααα»ααααα·ααΆαα αααααΆααααααΎαααααΆααααΈαααααααα»αααααααααααααΎ SECOMP_MODE_FILTER αααααΆααα αααα»α prog variable αααααααα sock_fprogα
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
perror("prctl(PR_SET_SECCOMP)");
return 1;
}
return 0;
}
ααΆα α»αααααα ααΎαα’αΆα ααααΎαα»αααΆα install_filter ααααααΎα ααα»αααααα»αααα ααΎαααααΌαααααΎ prctl ααΎααααΈααααα PR_SET_NO_NEW_PRIVS αααααΆααααΆαααααα·ααααα·αα αα α»αααααα α αΎααααα ααα»ααααααααΆαααααΆαααΆααααααααΎαααΆααα»ααΆαααα½αααΆααα·αααα·α αααΎαααΆααͺαα»αααααΆααααααα½αααα ααΆαα½αααα ααΎαα’αΆα ααααΎααΆαα α prctl ααΆαααααααα αααα»ααα»αααΆα install_filter ααααα·αααΆααα·αααα·ααΆ root α
α₯α‘αΌααααααΎαα’αΆα α α αα»αααΆα install_filter α α αΌαααΆααΆααααΆαα α ααααααααααΆααα’αααααααΆααααααΉαααααΆαααααααα X86-64 α αΎαααααΆαααααααααααΆαα’αα»ααααΆααααααΆααΆααααΆαααα»ααααααΆααα’ααα αααααΆααααΈααα‘αΎαααααα ααΎαααααααααα·ααααα·αααααααΎα’αΆαα»αααααααΈαα½αα
int main(int argc, char const *argv[]) {
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
perror("prctl(NO_NEW_PRIVS)");
return 1;
}
install_filter(__NR_write, AUDIT_ARCH_X86_64, EPERM);
return system(argv[1]);
}
αααβα αΆααααααΎαα ααΎααααΈα ααααααααααα·ααΈααααααΎα ααΎαα’αΆα ααααΎ clang α¬ gcc ααΆααα·ααΈααΆααααα ααΆααααΆααααα αααααα―αααΆα main.c αααααααΆααααααΎααα·αααα
clang main.c -o filter-write
ααΌα αααααΆαααααααααΆαα ααΎαααΆααα·αααΆααααΆαα»αα αααα»ααααααα·ααΈα ααΎααααΈααΆαααααααα α’αααααααΌαααΆααααααα·ααΈααααααααααααααα’αααΈαα½α - ls α αΆααααΌα ααΆαααααααααααα’α αααααΆαααααααααΆαααΆααααααΆααΆαα₯αα·ααΆααα
ls -la
total 36
drwxr-xr-x 2 fntlnz users 4096 Apr 28 21:09 .
drwxr-xr-x 4 fntlnz users 4096 Apr 26 13:01 ..
-rwxr-xr-x 1 fntlnz users 16800 Apr 28 21:09 filter-write
-rw-r--r-- 1 fntlnz users 19 Apr 28 21:09 .gitignore
-rw-r--r-- 1 fntlnz users 1282 Apr 28 21:08 main.c
α’ααα αΆαααααα! αααααΆα’αααΈαααααΆαααααΎααααΆαααααααα·ααΈαα»αααααααΎαααΎααα ααΌα α ααΎαααααΆααααααααααΆαααααααα·ααΈαααααΎαα ααααΆαααααααΆα’αΆαα»αααααααΈαα½αα
./filter-write "ls -la"
αα αααααααα·ααααα· αααααα·ααΈααααααααΎααααααααααααΆαααααα»αα ααααααΆαααΆααααα ααΎαα’αΆα ααααΎααααααΎααααΈααΎαα’αααΈααααααα»αααΎαα‘αΎαα
strace -f ./filter-write "ls -la"
ααααααααααΆαααΆαααααΌαααΆαααΆααααααααααΆαααααΆαα ααα»ααααααααααααααααΌαααααΆααααααΆαααα αΆαααΆ αααααααααΆααααΌαααΆαααΆααΆααααΆαα½αααΉαααα α»α EPERM - ααΌα ααααΆαααααΎαααΆαααααααα ααΆααααααααα αααααΆααααααΆαααααα·ααΈαα·ααααα ααα’αααΈαααααααααΆαα·αα’αΆα α αΌαααααΎαααΆαααΆαα α αααααααααααααα
[pid 25099] write(2, "ls: ", 4) = -1 EPERM (Operation not permitted)
[pid 25099] write(2, "write error", 11) = -1 EPERM (Operation not permitted)
[pid 25099] write(2, "n", 1) = -1 EPERM (Operation not permitted)
α₯α‘αΌααααα’ααααααααΈααααααα Seccomp BPF ααααΎαααΆαα αΎαααΆααααα·αααα’α’αααΈα’αααΈαααα’αααα’αΆα ααααΎααΆαααΆαα½αααΆα ααα»ααααααΎα’ααααα·αα αααααααα ααΆαααΌαααΏαααΌα ααααΆααΆαα½α eBPF αααα½αα±αα cBPF ααΎααααΈααΆαααααΆαααααααααααααααΆαα?
αα ααααα·αα’αααΈαααααα·ααΈ eBPF ααα»αααααΆαα αααΎααα·αααΆαα½αααααααΆαααααααααααΆ α αΎααααα»ααα½αααΆααΆαα½αααΉααα·αααα·ααΆα’ααααααααααααα αααααααααααα ααααΈαααααααΆααααααααΆααΆααα·αααΆααΌαα ααΊαααα’αα»αααααααα»αααααααααΆαααΎααααΈααΆαααΆαααααα» eBPF αα ααααα·αααααααα ααααααΆαααΆαααααααααΌαααΆαααα α ααΆα’ααααΆαα BPF LSM α
α’ααααΆαα BPF LSM
ααΎααααΈαααααααΆααααα½ααα·αα·ααααααα―αααΆαααααααΆααααααααααααααΉαααα·ααΆααααααααααα LSM α’αα»αααααααα·αααα’ααααΆααα ααΆαα α ααΆααααααααΆααααααααα αα ααααααααααααα ααΉαααΆαα α ααΆααααααααα ααα»ααααααΆααααααααα―αααΆααα αα·ααα½ααααα αΌαααΆαα½αα αααααΆαα ααΆααααααααα LSM αααααααΌααααα·αααααΈαα½αααααααααΆααα’ααΌααΈα’αΆα αα½ααααααΆααααα αΆαααααΆααα½αααααααα ααααααααααΆαααΆαα½αααΆαα α ααααααααααΎααααΆααααααααααααααααααΆα
αα αααααααα ααΊαααααΆααααααα ααα½αααααΆαααΈααααααααΆααααΆαα½ααααααα·ααΈ BPF α αΎα SELinux ααΊααΆ LSM αααααΆαααααΆαααααα½αααααααα’αα»αααααα½αααΆα
ααΌαααααααααααΆααα’ααααΆααααΆαααΈααΆαααα αααα»ααααααΆαααΊααααααα»αα―αααΆααα½αααΆα/linux/security.h:
extern int security_bpf(int cmd, union bpf_attr *attr, unsigned int size);
extern int security_bpf_map(struct bpf_map *map, fmode_t fmode);
extern int security_bpf_prog(struct bpf_prog *prog);
extern int security_bpf_map_alloc(struct bpf_map *map);
extern void security_bpf_map_free(struct bpf_map *map);
extern int security_bpf_prog_alloc(struct bpf_prog_aux *aux);
extern void security_bpf_prog_free(struct bpf_prog_aux *aux);
αα½αααααααΆαααααΉαααααΌαααΆαα α αα ααααΆααααΆααααααααααΆααααΆαααααα·ααααα·α
- security_bpf β ααααΎααΆααααα½ααα·αα·αααααααΌαααααΆαα α αααααααα BPF αααααΆαααααα·ααααα·α
- security_bpf_map - αα·αα·αααααΎααα ααααααααΊααααααα‘ααα―αααΆααα·αααααΆαααααΆαααααααΈα
- security_bpf_prog - αα·αα·αααααΎααα ααααααααΊααααααα‘ααα’ααααα·αααααΆα―αααΆααααααΆαααααααα·ααΈ eBPF α
β security_bpf_map_alloc β αα·αα·αααααΎαααΆααΎααΆααα»ααααα·ααΆααα αααα»ααααααΈ BPF ααααΌαααΆαα αΆααααααΎαα¬α’αα
- security_bpf_map_free - αα·αα·αααααΎαααΆααΎααΆααα»ααααα·ααΆαααααΌαααΆαααααααα αααα»ααααααΈ BPF αααα¬ααα
- security_bpf_prog_alloc β αα·αα·αααααΎαααΆααΎααΆααα»ααααα·ααΆαααααΌαααΆαα αΆααααααΎααα αααα»ααααααα·ααΈ BPF αααα¬ααα
- security_bpf_prog_free - αα·αα·αααααΎαααΆααΎααΆααα»ααααα·ααΆαααααΌαααΆααααα’αΆααα ααΆααααα»ααααααα·ααΈ BPF αααα¬ααα
α₯α‘αΌαααα αααααΎαααΎαα’αααΈαααΆααα’ααααα ααΎααααα αααα·ααα ααΈαααααα§αααααααααΆααα αΆαα LSM BPF ααΊααΆαα½αααα’αΆα αααααααΆαααΆαααΆαααααααααααααα» eBPF αααααΆααΆααΆααΆαααα’ααααααααΆααα·αααα·ααααααααα»ααααααααα’αΆα ααααΎααααα·ααααα·ααΆαααΎααΆα αα·ααααααα·ααΈααΆαα
αααααα
αα»ααααα·ααΆααα·ααααααΆα’αααΈαααα’αααα’αΆα α’αα»αααααααα»αααα ααα½ααααααααΆααα’αααΈααααααααΆααααα’αααα ααααΆαααΆααααααα ααΆααΆαααΆααααααΆααααΆαααααα»αααΆαααΆαααΆααααααααααα ααααα·αααααααααααΆ αα·αααΆααα·ααΈααααααααααΆα ααΏα¬αα·αααΏ αα·ααΈααα’αααα»ααααα»αααΆαααΆααΆααααααααααΊαααα αααααα·αααααΆαααΆαααΆαααΈαα»ααααααααααααααααΆ ααΌα ααααααΆαααΆααααααααα»ααααα·ααΆααα½αααααα·ααα·αα’αα»ααααΆαα±ααα αΌαααααΎααααααααααΆααααΌαααα α’αααα’αα·ααααααααααΌαααΆαααααΎααΆαααΆαααα’ααα αΆααααααα»αααΆααααααα±ααααΎαααΌααααα»ααααααααΆαα αα·αα ααα»α αααααααααααααΆα ααΎααααααΉαααΆ ααΎαααΆααααααα±ααα’αααααΌαααΆααααααΉαααααα’α’αααΈα’αααΈαααααΆαααααΆαα αα·αααααααααΎααααΆαααααααα·ααΈ BPF ααΎααααΈααααΎααΆαααΆαα½ααα½αααα
α’αααΈα’ααααα·αααα
ααα David Calavera ααΊααΆ CTO αα Netlify α ααΆααααΆαααααΎααΆααα αααα»ααααααααΆαααα Docker αα·αααΆααα½αα αααααααα»αααΆαα’αα·ααααααα§ααααα Runc, Go αα·α BCC ααααΌα ααΆαααααααααααααΎαα αα ααααααααα ααααΌαααΆαααααααΆαααααααΆααααΆαααΆαααααααΆααααΎαααααα Docker αα·αααΆαα’αα·ααααααααααααααα’αααΌαααααα·ααΈαααα½α Docker α David ααΆαβα ααααβααααΆααβα ααααβααααΆα ααβααααΎα α αΎαβαααααβαααααΉαβααβααΆαβαααααΎαβααααα·αααααΆαβααααα·ααααα·ααΆαα
Lorenzo Fontana ααααΎααΆαααΎαααα»ααααααααΎαα αα αα Sysdig ααΆαααααααααααΆαααααααααΆα ααααααΎ Falco αααααΆαααααα Cloud Native Computing Foundation αααααααααα»ααααα·ααΆααααααααΎαααΆααα»αααΊααα αα·αααΆαααααΎαααΆααα·αααααααΆααΆαααααααΌαα»αααΊααα αα·α eBPF α ααΆαααααααΆααααααααααα ααα αΆα αααααΆαααααααααααα·ααΈ ααΈαα»α ααΊααα αα·αααΆααα·ααΆαααααΎαααΆαα
Β» ααααααΆαααα’α·αα’αααΈααααα
α’αΆα
ααααΆααα
Β»
Β»
αααααΆαα Khabrozhiteley ααΆααααα α»αααααα 25% αααααααΎααααα - Linux
αα
αααααααααααααααΆα ααααα
α’αα‘α·α
ααααΌαα·α
ααΉαααααΌαααΆαααααΎααΆαα’ααΈαααα
ααααα: www.habr.com