Linux ์ปค๋ ๋ณด์, ๊ธฐ๋ฅ ๋ฐ Seccomp
BPF๋ ์์ ์ฑ, ๋ณด์ ๋๋ ์๋๋ฅผ ํฌ์ํ์ง ์๊ณ ์ปค๋์ ํ์ฅํ ์ ์๋ ๊ฐ๋ ฅํ ๋ฐฉ๋ฒ์ ์ ๊ณตํฉ๋๋ค. ์ด๋ฌํ ์ด์ ๋ก ์ปค๋ ๊ฐ๋ฐ์๋ Seccomp BPF๋ผ๊ณ ๋ ์๋ ค์ง BPF ํ๋ก๊ทธ๋จ์์ ์ง์ํ๋ Seccomp ํํฐ๋ฅผ ๊ตฌํํ์ฌ Seccomp์ ํ๋ก์ธ์ค ๊ฒฉ๋ฆฌ๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด ๋ค์ํ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ ์๊ฐ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ์ด ์ฅ์์๋ Seccomp๊ฐ ๋ฌด์์ด๋ฉฐ ์ด๋ป๊ฒ ์ฌ์ฉ๋๋์ง ์ค๋ช ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ BPF ํ๋ก๊ทธ๋จ์ ์ฌ์ฉํ์ฌ Seccomp ํํฐ๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์์๋ด ๋๋ค. ๊ทธ๋ฐ ๋ค์ Linux ๋ณด์ ๋ชจ๋์ฉ ์ปค๋์ ํฌํจ๋ ๋ด์ฅ BPF ํํฌ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
LSM(Linux ๋ณด์ ๋ชจ๋)์ ํ์คํ๋ ๋ฐฉ์์ผ๋ก ๋ค์ํ ๋ณด์ ๋ชจ๋ธ์ ๊ตฌํํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ฅ ์ธํธ๋ฅผ ์ ๊ณตํ๋ ํ๋ ์์ํฌ์ ๋๋ค. LSM์ Apparmor, SELinux ๋ฐ Tomoyo์ ๊ฐ์ ์ปค๋ ์์ค ํธ๋ฆฌ์์ ์ง์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
Linux์ ๊ธฐ๋ฅ์ ๋ํด ๋ ผ์ํ๋ ๊ฒ๋ถํฐ ์์ํ๊ฒ ์ต๋๋ค.
๊ธฐ๋ฅ
Linux ๊ธฐ๋ฅ์ ํต์ฌ์ ํน์ ์์ ์ ์ํํ๊ธฐ ์ํด ๊ถํ์ด ์๋ ํ๋ก์ธ์ค ๊ถํ์ ๋ถ์ฌํด์ผ ํ์ง๋ง ํด๋น ๋ชฉ์ ์ผ๋ก suid๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ํ๋ก์ธ์ค์ ๊ถํ์ ๋ถ์ฌํ์ฌ ๊ณต๊ฒฉ ๊ฐ๋ฅ์ฑ์ ์ค์ด๊ณ ํ๋ก์ธ์ค๊ฐ ํน์ ์์ ์ ์ํํ ์ ์๋๋ก ํ์ฉํด์ผ ํ๋ค๋ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค์ด, ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ฃจํธ๋ก ํ๋ก์ธ์ค๋ฅผ ์คํํ๋ ๋์ ๊ถํ ์๋ ํฌํธ(์: 80)๋ฅผ ์ด์ด์ผ ํ๋ ๊ฒฝ์ฐ ๊ฐ๋จํ CAP_NET_BIND_SERVICE ๊ธฐ๋ฅ์ ์ ๊ณตํ ์ ์์ต๋๋ค.
main.go๋ผ๋ Go ํ๋ก๊ทธ๋จ์ ์๊ฐํด ๋ณด์ธ์.
package main
import (
"net/http"
"log"
)
func main() {
log.Fatalf("%v", http.ListenAndServe(":80", nil))
}
์ด ํ๋ก๊ทธ๋จ์ ํฌํธ 80(ํน๊ถ ํฌํธ)์์ HTTP ์๋ฒ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ปดํ์ผ ์งํ์ ์คํํฉ๋๋ค.
$ go build -o capabilities main.go
$ ./capabilities
๊ทธ๋ฌ๋ ๋ฃจํธ ๊ถํ์ ๋ถ์ฌํ์ง ์๊ธฐ ๋๋ฌธ์ ์ด ์ฝ๋๋ ํฌํธ๋ฅผ ๋ฐ์ธ๋ฉํ ๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
2019/04/25 23:17:06 listen tcp :80: bind: permission denied
exit status 1
capsh(์ ๊ด๋ฆฌ์)๋ ํน์ ๊ธฐ๋ฅ ์ธํธ๋ฅผ ์ฌ์ฉํ์ฌ ์์ ์คํํ๋ ๋๊ตฌ์ ๋๋ค.
์ด ๊ฒฝ์ฐ ์ด๋ฏธ ์ธ๊ธํ ๊ฒ์ฒ๋ผ ์ ์ฒด ๋ฃจํธ ๊ถํ์ ๋ถ์ฌํ๋ ๋์ ์ด๋ฏธ ํ๋ก๊ทธ๋จ์ ์๋ ๋ค๋ฅธ ๋ชจ๋ ๊ธฐ๋ฅ๊ณผ ํจ๊ป 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' - ์ฌ์ฉ์๋ฅผ ๋ณ๊ฒฝํด์ผ ํ๊ธฐ ๋๋ฌธ์(๋ฃจํธ๋ก ์คํํ๊ณ ์ถ์ง ์์) cap_net_bind_service์ ์ค์ ๋ก ์ฌ์ฉ์ ID๋ฅผ ๋ณ๊ฒฝํ ์ ์๋ ๊ธฐ๋ฅ์ ๋ค์์์ ์ง์ ํฉ๋๋ค. ์๋ฌด๋, ์ฆ cap_setuid ๋ฐ cap_setgid์ ๋ฃจํธ๊ฐ ์์ต๋๋ค.
- โkeep=1 โ ๋ฃจํธ ๊ณ์ ์์ ์ ํํ ๋ ์ค์น๋ ๊ธฐ๋ฅ์ ์ ์งํ๋ ค๊ณ ํฉ๋๋ค.
- โuser=โnobodyโ โ ํ๋ก๊ทธ๋จ์ ์คํํ๋ ์ต์ข ์ฌ์ฉ์๋ ๋๊ตฌ๋ ์๋๋๋ค.
- โaddamb=cap_net_bind_service โ ๋ฃจํธ ๋ชจ๋์์ ์ ํํ ํ ๊ด๋ จ ๊ธฐ๋ฅ ์ง์ฐ๊ธฐ๋ฅผ ์ค์ ํฉ๋๋ค.
- - -c "./capability" - ํ๋ก๊ทธ๋จ์ ์คํํ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.
์ฐ๊ฒฐ๋ ๊ธฐ๋ฅ์ ํ์ฌ ํ๋ก๊ทธ๋จ์ด execve()๋ฅผ ์ฌ์ฉํ์ฌ ํ์ ํ๋ก๊ทธ๋จ์ ์คํํ ๋ ํ์ ํ๋ก๊ทธ๋จ์ ์์๋๋ ํน๋ณํ ์ข ๋ฅ์ ๊ธฐ๋ฅ์ ๋๋ค. ์ฐ๊ฒฐ์ด ํ์ฉ๋ ๊ธฐ๋ฅ, ์ฆ ํ๊ฒฝ ๊ธฐ๋ฅ๋ง ์์๋ ์ ์์ต๋๋ค.
--caps ์ต์ ์์ ๊ธฐ๋ฅ์ ์ง์ ํ ํ +eip๊ฐ ๋ฌด์์ ์๋ฏธํ๋์ง ๊ถ๊ธํ ๊ฒ์ ๋๋ค. ์ด๋ฌํ ํ๋๊ทธ๋ ๋ค์ ๊ธฐ๋ฅ์ ๊ฒฐ์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
-ํ์ฑํ๋์ด์ผ ํฉ๋๋ค(p).
- ์ฌ์ฉ ๊ฐ๋ฅ(e)
-์์ ํ๋ก์ธ์ค์ ์ํด ์์๋ ์ ์์ต๋๋ค(i).
cap_net_bind_service๋ฅผ ์ฌ์ฉํ๊ณ ์ถ๊ธฐ ๋๋ฌธ์ e ํ๋๊ทธ๋ฅผ ์ฌ์ฉํ์ฌ ์ด ์์ ์ ์ํํด์ผ ํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ช ๋ น์์ ์ ธ์ ์์ํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ๊ธฐ๋ฅ ๋ฐ์ด๋๋ฆฌ๊ฐ ์คํ๋๋ฉฐ ์ด๋ฅผ i ํ๋๊ทธ๋ก ํ์ํด์ผ ํฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก p๋ฅผ ์ฌ์ฉํ์ฌ ๊ธฐ๋ฅ์ ํ์ฑํํ๋ ค๊ณ ํฉ๋๋ค(UID๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ์ด ์์ ์ ์ํํ์ต๋๋ค). cap_net_bind_service+eip์ฒ๋ผ ๋ณด์ ๋๋ค.
ss๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค. ํ์ด์ง์ ๋ง๊ฒ ์ถ๋ ฅ์ ์กฐ๊ธ ์ค์ด๋ฉด 0์ด ์๋ ๊ด๋ จ ํฌํธ์ ์ฌ์ฉ์ ID(์ด ๊ฒฝ์ฐ 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์ ์ฐธ์กฐํ์ธ์.
ํ๋ก๊ทธ๋จ์ ์์ฑํ ๋ ๊ฐ๋ฐ์๋ ๋ฐํ์ ์ ํ๋ก๊ทธ๋จ์ ํ์ํ ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ฏธ๋ฆฌ ์์ง ๋ชปํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๋ํ ์ด๋ฌํ ๊ธฐ๋ฅ์ ์ ๋ฒ์ ์์ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.
ํ๋ก๊ทธ๋จ์ ๊ธฐ๋ฅ์ ๋ ์ ์ดํดํ๊ธฐ ์ํด cap_capable ์ปค๋ ๊ธฐ๋ฅ์ ๋ํ kprobe๋ฅผ ์ค์ ํ๋ BCC ์ง์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
/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
cap_capable ์ปค๋ ํจ์์์ ๋จ์ผ ๋ผ์ด๋ kprobe์ ํจ๊ป bpftrace๋ฅผ ์ฌ์ฉํ์ฌ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์ต๋๋ค.
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์ ๋๋ค. ์ด๋ ์๋ณ์ 10์ ๊ฐ๋ include/uapi/linux/ability.h ํ์ผ์ ์ปค๋ ์์ค ์ฝ๋์์ ์์๋ก ์ ์๋ฉ๋๋ค.
/* 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๋ ๋ณด์ ์ปดํจํ (Secure Computing)์ ์๋ฏธํ๋ฉฐ ๊ฐ๋ฐ์๊ฐ ํน์ ์์คํ ํธ์ถ์ ํํฐ๋งํ ์ ์๋๋ก Linux ์ปค๋์ ๊ตฌํ๋ ๋ณด์ ๊ณ์ธต์ ๋๋ค. Seccomp์ ๊ธฐ๋ฅ์ Linux์ ๋น์ทํ์ง๋ง ํน์ ์์คํ ํธ์ถ์ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ์ผ๋ก ์ธํด Linux์ ๋นํด ํจ์ฌ ๋ ์ ์ฐํด์ก์ต๋๋ค.
Seccomp์ Linux ๊ธฐ๋ฅ์ ์ํธ ๋ฐฐํ์ ์ด์ง ์์ผ๋ฉฐ ๋ ์ ๊ทผ ๋ฐฉ์์ ์ด์ ์ ์ป๊ธฐ ์ํด ํจ๊ป ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ์๋ฅผ ๋ค์ด ํ๋ก์ธ์ค์ CAP_NET_ADMIN ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง๋ง ์์ผ ์ฐ๊ฒฐ์ ํ์ฉํ์ง ์๊ณ accept ๋ฐ accept4 ์์คํ ํธ์ถ์ ์ฐจ๋จํ ์ ์์ต๋๋ค.
Seccomp ํํฐ๋ง ๋ฐฉ์์ SECCOMP_MODE_FILTER ๋ชจ๋๋ก ๋์ํ๋ BPF ํํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฉฐ, ์์คํ ์ฝ ํํฐ๋ง์ ํจํท๊ณผ ๋์ผํ๊ฒ ์ํ๋๋ค.
Seccomp ํํฐ๋ PR_SET_SECCOMP ์์ ์ ํตํด prctl์ ์ฌ์ฉํ์ฌ ๋ก๋๋ฉ๋๋ค. ์ด๋ฌํ ํํฐ๋ seccomp_data ๊ตฌ์กฐ๋ก ํ์๋๋ ๊ฐ Seccomp ํจํท์ ๋ํด ์คํ๋๋ BPF ํ๋ก๊ทธ๋จ์ ํํ๋ฅผ ์ทจํฉ๋๋ค. ์ด ๊ตฌ์กฐ์๋ ์ฐธ์กฐ ์ํคํ ์ฒ, ์์คํ ํธ์ถ ์ ํ๋ก์ธ์ ๋ช ๋ น์ ๋ํ ํฌ์ธํฐ, uint64๋ก ํ์๋๋ ์ต๋ XNUMX๊ฐ์ ์์คํ ํธ์ถ ์ธ์๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
linux/seccomp.h ํ์ผ์ ์ปค๋ ์์ค ์ฝ๋์์ seccomp_data ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
struct seccomp_data {
int nr;
__u32 arch;
__u64 instruction_pointer;
__u64 args[6];
};
์ด ๊ตฌ์กฐ์์ ๋ณผ ์ ์๋ฏ์ด ์์คํ ํธ์ถ, ์ธ์ ๋๋ ๋์ ์กฐํฉ์ ๊ธฐ์ค์ผ๋ก ํํฐ๋งํ ์ ์์ต๋๋ค.
๊ฐ Seccomp ํจํท์ ์์ ํ ํ ํํฐ๋ ์ต์ข ๊ฒฐ์ ์ ๋ด๋ฆฌ๊ณ ์ปค๋์ ๋ค์์ ์ํํ ์์ ์ ์๋ ค์ฃผ๋ ์ฒ๋ฆฌ๋ฅผ ์ํํด์ผ ํฉ๋๋ค. ์ต์ข ๊ฒฐ์ ์ ๋ฐํ ๊ฐ(์ํ ์ฝ๋) ์ค ํ๋๋ก ํํ๋ฉ๋๋ค.
- SECCOMP_RET_KILL_PROCESS - ์ด๋ก ์ธํด ์คํ๋์ง ์๋ ์์คํ ํธ์ถ์ ํํฐ๋งํ ํ ์ฆ์ ์ ์ฒด ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃํฉ๋๋ค.
- SECCOMP_RET_KILL_THREAD - ์ด๋ก ์ธํด ์คํ๋์ง ์๋ ์์คํ ํธ์ถ์ ํํฐ๋งํ ํ ์ฆ์ ํ์ฌ ์ค๋ ๋๋ฅผ ์ข ๋ฃํฉ๋๋ค.
โ SECCOMP_RET_KILL โ SECCOMP_RET_KILL_THREAD์ ๋ณ์นญ, ์ด์ ๋ฒ์ ๊ณผ์ ํธํ์ฑ์ ์ํด ๋จ๊ฒจ๋์์ต๋๋ค.
- SECCOMP_RET_TRAP - ์์คํ ํธ์ถ์ด ๊ธ์ง๋๋ฉฐ ์ด๋ฅผ ํธ์ถํ๋ ์์ ์ SIGSYS(Bad System Call) ์ ํธ๊ฐ ์ ์ก๋ฉ๋๋ค.
- SECCOMP_RET_ERRNO - ์์คํ ํธ์ถ์ด ์คํ๋์ง ์๊ณ SECCOMP_RET_DATA ํํฐ ๋ฐํ ๊ฐ ์ค ์ผ๋ถ๊ฐ errno ๊ฐ์ผ๋ก ์ฌ์ฉ์ ๊ณต๊ฐ์ ์ ๋ฌ๋ฉ๋๋ค. ์ค๋ฅ์ ์์ธ์ ๋ฐ๋ผ ๋ค๋ฅธ errno ๊ฐ์ด ๋ฐํ๋ฉ๋๋ค. ์ค๋ฅ ๋ฒํธ ๋ชฉ๋ก์ ๋ค์ ์น์ ์ ์ ๊ณต๋ฉ๋๋ค.
- SECCOMP_RET_TRACE - ํด๋น ํ๋ก์ธ์ค๋ฅผ ๋ณด๊ณ ์ ์ดํ๊ธฐ ์ํด ์์คํ ํธ์ถ์ด ์คํ๋ ๋ PTRACE_O_TRACESECCOMP๋ฅผ ์ฌ์ฉํ์ฌ ptrace ์ถ์ ์์๊ฒ ์๋ฆฌ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ถ์ ํ๋ก๊ทธ๋จ์ด ์ฐ๊ฒฐ๋์ด ์์ง ์์ผ๋ฉด ์ค๋ฅ๊ฐ ๋ฐํ๋๊ณ errno๋ -ENOSYS๋ก ์ค์ ๋๋ฉฐ ์์คํ ํธ์ถ์ ์คํ๋์ง ์์ต๋๋ค.
- SECCOMP_RET_LOG - ์์คํ ํธ์ถ์ด ํด๊ฒฐ๋๊ณ ๊ธฐ๋ก๋ฉ๋๋ค.
- SECCOMP_RET_ALLOW - ์์คํ ํธ์ถ์ด ํ์ฉ๋ฉ๋๋ค.
ptrace๋ ํ๋ก์ธ์ค ์คํ์ ๋ชจ๋ํฐ๋งํ๊ณ ์ ์ดํ๋ โโ๊ธฐ๋ฅ์ ๊ฐ์ถ ์ถ์ ๋ฉ์ปค๋์ฆ์ Tracee๋ผ๋ ํ๋ก์ธ์ค์ ๊ตฌํํ๊ธฐ ์ํ ์์คํ ํธ์ถ์ ๋๋ค. ์ถ์ ํ๋ก๊ทธ๋จ์ ์คํ์ ํจ๊ณผ์ ์ผ๋ก ์ํฅ์ ๋ฏธ์น๊ณ ํผ์ถ์ ์์ ๋ฉ๋ชจ๋ฆฌ ๋ ์ง์คํฐ๋ฅผ ์์ ํ ์ ์์ต๋๋ค. Seccomp ์ปจํ ์คํธ์์๋ SECCOMP_RET_TRACE ์ํ ์ฝ๋์ ์ํด ํธ๋ฆฌ๊ฑฐ๋ ๋ ptrace๊ฐ ์ฌ์ฉ๋๋ฏ๋ก ์ถ์ ํ๋ก๊ทธ๋จ์ ์์คํ ํธ์ถ์ด ์คํ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ณ ์์ฒด ๋ ผ๋ฆฌ๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค.
Seccomp ์ค๋ฅ
๋๋๋ก Seccomp๋ก ์์ ํ๋ ๋์ SECCOMP_RET_ERRNO ์ ํ์ ๋ฐํ ๊ฐ์ผ๋ก ์๋ณ๋๋ ๋ค์ํ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค. ์ค๋ฅ๋ฅผ ๋ณด๊ณ ํ๊ธฐ ์ํด seccomp ์์คํ ํธ์ถ์ 1 ๋์ -0์ ๋ฐํํฉ๋๋ค.
๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
- EACCESS - ํธ์ถ์๋ ์์คํ ํธ์ถ์ ํ ์ ์์ต๋๋ค. ์ด๋ ์ผ๋ฐ์ ์ผ๋ก CAP_SYS_ADMIN ๊ถํ์ด ์๊ฑฐ๋ prctl์ ์ฌ์ฉํ์ฌ no_new_privs๊ฐ ์ค์ ๋์ง ์์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํฉ๋๋ค(์ด์ ๋ํด์๋ ๋์ค์ ์ค๋ช ํ๊ฒ ์ต๋๋ค).
โ EFAULT โ ์ ๋ฌ๋ ์ธ์(seccomp_data ๊ตฌ์กฐ์ ์ธ์)์ ์ ํจํ ์ฃผ์๊ฐ ์์ต๋๋ค.
โ EINVAL โ ์ฌ๊ธฐ์๋ ๋ค ๊ฐ์ง ์ด์ ๊ฐ ์์ ์ ์์ต๋๋ค.
-์์ฒญํ ์์ ์ด ์ ์ ์๊ฑฐ๋ ํ์ฌ ๊ตฌ์ฑ์ ์ปค๋์์ ์ง์๋์ง ์์ต๋๋ค.
-์ง์ ๋ ํ๋๊ทธ๊ฐ ์์ฒญ๋ ์์ ์ ๋ํด ์ ํจํ์ง ์์ต๋๋ค.
-์์ ์๋ BPF_ABS๊ฐ ํฌํจ๋์ด ์์ง๋ง ์ง์ ๋ ์คํ์ ์ ๋ฌธ์ ๊ฐ ์์ด seccomp_data ๊ตฌ์กฐ์ ํฌ๊ธฐ๋ฅผ ์ด๊ณผํ ์ ์์ต๋๋ค.
-ํํฐ์ ์ ๋ฌ๋ ๋ช ๋ น ์๊ฐ ์ต๋๊ฐ์ ์ด๊ณผํฉ๋๋ค.
โ ENOMEM โ ํ๋ก๊ทธ๋จ์ ์คํํ๊ธฐ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํฉ๋๋ค.
- EOPNOTSUPP - SECCOMP_GET_ACTION_AVAIL์ ์ฌ์ฉํ์ฌ ์์ ์ ์ฌ์ฉํ ์ ์์์ ๋ํ๋ด๋ ์์ ์ด์ง๋ง ์ปค๋์ ์ธ์ ๋ฐํ์ ์ง์ํ์ง ์์ต๋๋ค.
โ ESRCH โ ๋ค๋ฅธ ์คํธ๋ฆผ์ ๋๊ธฐํํ ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
- ENOSYS - SECCOMP_RET_TRACE ์์ ์ ์ฐ๊ฒฐ๋ ์ถ์ ํ๋ก๊ทธ๋จ์ด ์์ต๋๋ค.
prctl์ ์ฌ์ฉ์ ๊ณต๊ฐ ํ๋ก๊ทธ๋จ์ด ๋ฐ์ดํธ ์๋์, ์ค๋ ๋ ์ด๋ฆ, ๋ณด์ ๊ณ์ฐ ๋ชจ๋(Seccomp), ๊ถํ, Perf ์ด๋ฒคํธ ๋ฑ๊ณผ ๊ฐ์ ํ๋ก์ธ์ค์ ํน์ ์ธก๋ฉด์ ์กฐ์(์ค์ ๋ฐ ๊ฐ์ ธ์ค๊ธฐ)ํ ์ ์๋๋ก ํ๋ ์์คํ ํธ์ถ์ ๋๋ค.
Seccomp๋ ์๋๋ฐ์ค ๊ธฐ์ ์ฒ๋ผ ๋ณด์ผ ์๋ ์์ง๋ง ๊ทธ๋ ์ง ์์ต๋๋ค. Seccomp๋ ์ฌ์ฉ์๊ฐ ์๋๋ฐ์ค ๋ฉ์ปค๋์ฆ์ ๊ฐ๋ฐํ ์ ์๋ ์ ํธ๋ฆฌํฐ์ ๋๋ค. ์ด์ Seccomp ์์คํ ํธ์ถ์ ์ํด ์ง์ ํธ์ถ๋๋ ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์ ์ํธ ์์ฉ ํ๋ก๊ทธ๋จ์ด ์ด๋ป๊ฒ ์์ฑ๋๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
BPF Seccomp ํํฐ ์
์ฌ๊ธฐ์๋ ์์์ ์ค๋ช ํ ๋ ๊ฐ์ง ์์ ์ ๊ฒฐํฉํ๋ ๋ฐฉ๋ฒ, ์ฆ ๋ค์์ ๋ณด์ฌ์ค๋๋ค.
โ ์ฐ๋ฆฌ๋ ๋ด๋ฆฐ ๊ฒฐ์ ์ ๋ฐ๋ผ ๋ค๋ฅธ ๋ฐํ ์ฝ๋๋ฅผ ๊ฐ๋ ํํฐ๋ก ์ฌ์ฉ๋ Seccomp BPF ํ๋ก๊ทธ๋จ์ ์์ฑํ ๊ฒ์ ๋๋ค.
โ prctl์ ์ฌ์ฉํ์ฌ ํํฐ๋ฅผ ๋ก๋ํฉ๋๋ค.
๋จผ์ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ Linux ์ปค๋์ ํค๋๊ฐ ํ์ํฉ๋๋ค.
#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_SECCOMP_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),
};
์ง์นจ์ linux/filter.h ํ์ผ์ ์ ์๋ BPF_STMT ๋ฐ BPF_JUMP ๋งคํฌ๋ก๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ๋ฉ๋๋ค.
์ง์นจ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, arch))) - ์์คํ ์ BPF_W๋ผ๋ ๋จ์ด์ ํํ๋ก BPF_LD์์ ๋ก๋ ๋ฐ ๋์ ๋๋ฉฐ, ํจํท ๋ฐ์ดํฐ๋ ๊ณ ์ ์คํ์ BPF_ABS์ ์์นํฉ๋๋ค.
- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch, 0, 3) - ๋์ฐ๊ธฐ ์์ BPF_K์ ์ํคํ ์ฒ ๊ฐ์ด arch์ ๊ฐ์์ง BPF_JEQ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ธํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์คํ์ 0์์ ๋ค์ ๋ช ๋ น์ด๋ก ์ ํํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด ์คํ์ 3์์ ์ ํํ์ฌ(์ด ๊ฒฝ์ฐ) ์์น๊ฐ ์ผ์นํ์ง ์๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
- BPF_STMT(BPF_LD + BPF_W + BPF_ABS (offsetof(struct seccomp_data, nr))) - BPF_ABS์ ๊ณ ์ ์คํ์ ์ ํฌํจ๋ ์์คํ ํธ์ถ ๋ฒํธ์ธ BPF_W๋ผ๋ ๋จ์ด ํํ๋ก BPF_LD์์ ๋ก๋ ๋ฐ ๋์ ๋ฉ๋๋ค.
โ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1) โ ์์คํ ํธ์ถ ๋ฒํธ๋ฅผ nr ๋ณ์์ ๊ฐ๊ณผ ๋น๊ตํฉ๋๋ค. ๋์ผํ๋ฉด ๋ค์ ๋ช ๋ น์ด๋ก ์ด๋ํ์ฌ ์์คํ ํธ์ถ์ ๋นํ์ฑํํ๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด SECCOMP_RET_ALLOW๋ฅผ ์ฌ์ฉํ์ฌ ์์คํ ํธ์ถ์ ํ์ฉํฉ๋๋ค.
- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (์ค๋ฅ & SECCOMP_RET_DATA)) - BPF_RET๋ก ํ๋ก๊ทธ๋จ์ ์ข ๋ฃํ๊ณ ๊ฒฐ๊ณผ์ ์ผ๋ก err ๋ณ์์ ์ซ์์ ํจ๊ป SECCOMP_RET_ERRNO ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW) - BPF_RET๋ก ํ๋ก๊ทธ๋จ์ ์ข ๋ฃํ๊ณ SECCOMP_RET_ALLOW๋ฅผ ์ฌ์ฉํ์ฌ ์์คํ ํธ์ถ์ด ์คํ๋๋๋ก ํ์ฉํฉ๋๋ค.
SECCOMP๋ CBPF์ ๋๋ค.
์ปดํ์ผ๋ ELF ๊ฐ์ฒด๋ JIT ์ปดํ์ผ๋ C ํ๋ก๊ทธ๋จ ๋์ ๋ช ๋ น ๋ชฉ๋ก์ด ์ฌ์ฉ๋๋ ์ด์ ๊ฐ ๊ถ๊ธํ ์ ์์ต๋๋ค.์ฌ๊ธฐ์๋ ๋ ๊ฐ์ง ์ด์ ๊ฐ ์์ต๋๋ค.
โข ์ฒซ์งธ, Seccomp๋ eBPF๊ฐ ์๋ cBPF(ํด๋์ BPF)๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ฆ, ๋ ์ง์คํฐ๋ ์์ง๋ง ์์ ์์ ๋ณผ ์ ์๋ฏ์ด ๋ง์ง๋ง ๊ณ์ฐ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๋ ๋์ฐ๊ธฐ๋ง ์์ต๋๋ค.
โข ๋์งธ, Seccomp๋ BPF ๋ช ๋ น์ด ๋ฐฐ์ด์ ๋ํ ํฌ์ธํฐ๋ฅผ ์ง์ ๋ฐ์๋ค์ด๊ณ ๋ค๋ฅธ ์ด๋ค ๊ฒ๋ ๋ฐ์๋ค์ด์ง ์์ต๋๋ค. ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ๋งคํฌ๋ก๋ ํ๋ก๊ทธ๋๋จธ ์นํ์ ์ธ ๋ฐฉ์์ผ๋ก ์ด๋ฌํ ๋ช ๋ น์ ์ง์ ํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค.
์ด ์ด์ ๋ธ๋ฆฌ๋ฅผ ์ดํดํ๋ ๋ฐ ๋์์ด ๋ ํ์ํ๋ฉด ๋์ผํ ์์ ์ ์ํํ๋ ์์ฌ์ฝ๋๋ฅผ ๊ณ ๋ คํ์ธ์.
if (arch != AUDIT_ARCH_X86_64) {
return SECCOMP_RET_ALLOW;
}
if (nr == __NR_write) {
return SECCOMP_RET_ERRNO;
}
return SECCOMP_RET_ALLOW;
์์ผ_ํํฐ ๊ตฌ์กฐ์์ ํํฐ ์ฝ๋๋ฅผ ์ ์ํ ํ ์ฝ๋์ ๊ณ์ฐ๋ ํํฐ ๊ธธ์ด๋ฅผ ํฌํจํ๋ sock_fprog๋ฅผ ์ ์ํด์ผ ํฉ๋๋ค. ์ด ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ ๋์ค์ ์คํํ ํ๋ก์ธ์ค๋ฅผ ์ ์ธํ๊ธฐ ์ํ ์ธ์๋ก ํ์ํฉ๋๋ค.
struct sock_fprog prog = {
.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
.filter = filter,
};
install_filter ํจ์์์ ํด์ผ ํ ์ผ์ ๋จ ํ๋๋ฟ์ ๋๋ค. ํ๋ก๊ทธ๋จ ์์ฒด๋ฅผ ๋ก๋ํ๋ ๊ฒ์ ๋๋ค! ์ด๋ฅผ ์ํด ๋ณด์ ์ปดํจํ ๋ชจ๋๋ก ๋ค์ด๊ฐ๊ธฐ ์ํ ์ต์ ์ผ๋ก PR_SET_SECCOMP๋ฅผ ์ฌ์ฉํ์ฌ prctl์ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ sock_fprog ์ ํ์ prog ๋ณ์์ ํฌํจ๋ SECCOMP_MODE_FILTER๋ฅผ ์ฌ์ฉํ์ฌ ํํฐ๋ฅผ ๋ก๋ํ๋๋ก ๋ชจ๋์ ์ง์ํฉ๋๋ค.
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๋ฅผ ์ค์ ํด์ผ ํ๋ฉฐ ์ด๋ฅผ ํตํด ํ์ ํ๋ก์ธ์ค๊ฐ ์์ ํ๋ก์ธ์ค๋ณด๋ค ๋ ๋ง์ ๊ถํ์ ๋ฐ๋ ์ํฉ์ ๋ฐฉ์งํด์ผ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ๋ฃจํธ ๊ถํ ์์ด install_filter ํจ์์์ ๋ค์ prctl ํธ์ถ์ ์ํํ ์ ์์ต๋๋ค.
์ด์ 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๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๊ณ ์๋์ง ํ์ธํ ์ ์์ต๋๋ค.
strace -f ./filter-write "ls -la"
์์ ๊ฒฐ๊ณผ๋ ๋ง์ด ๋จ์ถ๋์์ผ๋ ํด๋น ๋ถ๋ถ์์๋ ์ฐ๋ฆฌ๊ฐ ์ค์ ํ ๊ฒ๊ณผ ๋์ผํ EPERM ์ค๋ฅ๋ก ๊ธฐ๋ก์ด ์ฐจ๋จ๋ ๊ฒ์ผ๋ก ๋ํ๋ฌ์ต๋๋ค. ์ด๋ ํ๋ก๊ทธ๋จ์ด write ์์คํ ํธ์ถ์ ์ ๊ทผํ ์ ์๊ธฐ ๋๋ฌธ์ ์๋ฌด๊ฒ๋ ์ถ๋ ฅํ์ง ์๋๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค:
[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์ ์๋ ๋ฐฉ์์ ์ดํดํ๊ณ ์ด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌด์์ ํ ์ ์๋์ง์ ๋ํ ์ข์ ์์ด๋์ด๋ฅผ ์ป์์ต๋๋ค. ํ์ง๋ง cBPF ๋์ eBPF๋ฅผ ์ฌ์ฉํ์ฌ ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ป๊ณ ์ต๋ ์ฑ๋ฅ์ ํ์ฉํ๊ณ ์ถ์ง ์์ผ์ญ๋๊น?
eBPF ํ๋ก๊ทธ๋จ์ ์๊ฐํ ๋ ๋๋ถ๋ถ์ ์ฌ๋๋ค์ ๋จ์ํ ํ๋ก๊ทธ๋จ์ ์์ฑํ๊ณ ๊ด๋ฆฌ์ ๊ถํ์ผ๋ก ๋ก๋ํ๋ค๊ณ ์๊ฐํฉ๋๋ค. ์ด ์ค๋ช ์ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ค์ด์ง๋ง ์ปค๋์ ๋ค์ํ ์์ค์์ eBPF ๊ฐ์ฒด๋ฅผ ๋ณดํธํ๊ธฐ ์ํ ์ผ๋ จ์ ๋ฉ์ปค๋์ฆ์ ๊ตฌํํฉ๋๋ค. ์ด๋ฌํ ๋ฉ์ปค๋์ฆ์ BPF LSM ํธ๋ฉ์ด๋ผ๊ณ ํฉ๋๋ค.
BPF LSM ํธ๋ฉ
์์คํ ์ด๋ฒคํธ์ ๋ํ ์ํคํ ์ฒ ๋ ๋ฆฝ์ ๋ชจ๋ํฐ๋ง์ ์ ๊ณตํ๊ธฐ ์ํด LSM์ ํธ๋ฉ ๊ฐ๋ ์ ๊ตฌํํฉ๋๋ค. ํํฌ ํธ์ถ์ ๊ธฐ์ ์ ์ผ๋ก ์์คํ ํธ์ถ๊ณผ ์ ์ฌํ์ง๋ง ์์คํ ๋ ๋ฆฝ์ ์ด๋ฉฐ ์ธํ๋ผ์ ํตํฉ๋ฉ๋๋ค. LSM์ ์ถ์ํ ๊ณ์ธต์ด ๋ค์ํ ์ํคํ ์ฒ์์ ์์คํ ํธ์ถ์ ์ฒ๋ฆฌํ ๋ ๋ฐ์ํ๋ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ด ๋ ์ ์๋ ์๋ก์ด ๊ฐ๋ ์ ์ ๊ณตํฉ๋๋ค.
์ด ๊ธ์ ์ฐ๋ ์์ ์์ ์ปค๋์๋ BPF ํ๋ก๊ทธ๋จ๊ณผ ๊ด๋ จ๋ XNUMX๊ฐ์ ํํฌ๊ฐ ์์ผ๋ฉฐ SELinux๋ ์ด๋ฅผ ๊ตฌํํ๋ ์ ์ผํ ๋ด์ฅ LSM์ ๋๋ค.
ํธ๋ฉ์ ์์ค ์ฝ๋๋ ์ปค๋ ํธ๋ฆฌ์ include/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 ํ๋ก๊ทธ๋จ์ ์ฌ์ฉํ์ฌ ์์ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ ์ดํดํ์ จ๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
์ ์ ์๊ฐ
๋ฐ์ด๋น๋ ์นผ๋ผ๋ฒ ๋ผ Netlify์ CTO์ ๋๋ค. ๊ทธ๋ Docker ์ง์ ๋ถ์ผ์์ ์ผํ์ผ๋ฉฐ Runc, Go, BCC ๋๊ตฌ ๋ฐ ๊ธฐํ ์คํ ์์ค ํ๋ก์ ํธ ๊ฐ๋ฐ์ ๊ธฐ์ฌํ์ต๋๋ค. Docker ํ๋ก์ ํธ ์์ ๊ณผ Docker ํ๋ฌ๊ทธ์ธ ์ํ๊ณ ๊ฐ๋ฐ๋ก ์ ๋ช ํฉ๋๋ค. David๋ Flame ๊ทธ๋ํ์ ๋งค์ฐ ์ด์ ์ ์ด๋ฉฐ ํญ์ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ๋ชจ์ํ๊ณ ์์ต๋๋ค.
๋ก๋ ์กฐ ํฐํ๋ Sysdig์ ์คํ ์์ค ํ์์ ์ผํ๋ฉฐ ์ฃผ๋ก ์ปค๋ ๋ชจ๋๊ณผ eBPF๋ฅผ ํตํด ์ปจํ ์ด๋ ๋ฐํ์ ๋ณด์๊ณผ ์ด์ ํ์ง๋ฅผ ์ ๊ณตํ๋ Cloud Native Computing Foundation ํ๋ก์ ํธ์ธ Falco์ ์ค์ ์ ๋๊ณ ์์ต๋๋ค. ๊ทธ๋ ๋ถ์ฐ ์์คํ , ์ํํธ์จ์ด ์ ์ ๋คํธ์ํน, Linux ์ปค๋ ๋ฐ ์ฑ๋ฅ ๋ถ์์ ์ด์ ์ ๊ฐ๊ณ ์์ต๋๋ค.
ยป ์ฑ
์ ๋ํ ์์ธํ ๋ด์ฉ์ ๋ค์์์ ํ์ธํ ์ ์์ต๋๋ค.
ยป
ยป
Khabrozhiteley์ ๊ฒฝ์ฐ ์ฟ ํฐ์ ์ฌ์ฉํ์ฌ 25% ํ ์ธ์ ๋ฐ์ผ์ธ์ - Linux
์ข
์ด์ฑ
์ ๊ฒฐ์ ํ์๋ฉด ์ ์์ฑ
์ด ์ด๋ฉ์ผ๋ก ๋ฐ์ก๋ฉ๋๋ค.
์ถ์ฒ : habr.com