BPF(Berkeley Packet Filters)๋ ๋ช ๋
๋์ ์์ด ๊ธฐ์ ๊ฐํ๋ฌผ์ ์ฒซ ํ์ด์ง์ ๋ฑ์ฅํ Linux ์ปค๋ ๊ธฐ์ ์
๋๋ค. ์ปจํผ๋ฐ์ค๋ BPF์ ์ฌ์ฉ ๋ฐ ๊ฐ๋ฐ์ ๋ํ ๋ณด๊ณ ์๋ก ๊ฐ๋ ์ฐจ ์์ต๋๋ค. Linux ๋คํธ์ํฌ ํ์ ์์คํ
๊ด๋ฆฌ์์ธ David Miller๊ฐ Linux Plumbers 2018์์ ์ฐ์คํฉ๋๋ค.
Habrรฉ์๋ BPF์ ๋ํ ์ฒด๊ณ์ ์ธ ์ค๋ช
์ด ์์ง ์์ผ๋ฏ๋ก ์ผ๋ จ์ ๊ธฐ์ฌ์์ ๊ธฐ์ ์ ์ญ์ฌ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์ํคํ
์ฒ ๋ฐ ๊ฐ๋ฐ ๋๊ตฌ๋ฅผ ์ค๋ช
ํ๋ฉฐ BPF ์ฌ์ฉ์ ์ ์ฉ ๋ฐ ์คํ ์์ญ์ ๊ฐ๋ตํ๊ฒ ์ค๋ช
ํ๋ ค๊ณ ํฉ๋๋ค. ์๋ฆฌ์ฆ์ ์ ๋ก ๊ธฐ์ฌ์์๋ ํด๋์ BPF์ ์ญ์ฌ์ ์ํคํ
์ฒ๋ฅผ ์ค๋ช
ํ๊ณ ์๋ ์๋ฆฌ์ ๋น๋ฐ๋ ๊ณต๊ฐํฉ๋๋ค. tcpdump
, seccomp
, strace
, ๊ทธ๋ฆฌ๊ณ ํจ์ฌ ๋.
BPF์ ๊ฐ๋ฐ์ Linux ๋คํธ์ํน ์ปค๋ฎค๋ํฐ์ ์ํด ์ ์ด๋๋ฉฐ, BPF์ ์ฃผ์ ๊ธฐ์กด ์ ํ๋ฆฌ์ผ์ด์
์ ๋คํธ์ํฌ์ ๊ด๋ จ๋์ด ์์ผ๋ฏ๋ก ํ๊ฐ๋ฅผ ๋ฐ์ต๋๋ค.
BPF ์ญ์ฌ์ ๋ํ ๋จ๊ธฐ ๊ฐ์ข(c)
์ต์ BPF ๊ธฐ์ ์ ๋์ผํ ์ด๋ฆ์ ๊ฐ์ง ๊ธฐ์กด ๊ธฐ์ ์ ๊ฐ์ ํ๊ณ ํ์ฅํ ๋ฒ์ ์ผ๋ก, ํ์ฌ๋ ํผ๋์ ํผํ๊ธฐ ์ํด ํด๋์ BPF๋ผ๊ณ ํฉ๋๋ค. ์ ์๋ ค์ง ์ ํธ๋ฆฌํฐ๋ ํด๋์ BPF๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ง๋ค์ด์ก์ต๋๋ค. tcpdump
, ๋ฉ์ปค๋์ฆ seccomp
, ๋ ์๋ ค์ง ๋ชจ๋ xt_bpf
์ iptables
๋ฐ ๋ถ๋ฅ๊ธฐ cls_bpf
. ์ต์ Linux์์๋ ํด๋์ BPF ํ๋ก๊ทธ๋จ์ด ์๋์ผ๋ก ์๋ก์ด ํ์์ผ๋ก ๋ณํ๋์ง๋ง ์ฌ์ฉ์ ๊ด์ ์์ ๋ณผ ๋ API๋ ๊ทธ๋๋ก ์ ์ง๋์์ผ๋ฉฐ ์ด ๊ธฐ์ฌ์์ ๋ณผ ์ ์๋ฏ์ด ํด๋์ BPF์ ์๋ก์ด ์ฉ๋๊ฐ ์ฌ์ ํ ๋ฐ๊ฒฌ๋๊ณ ์์ต๋๋ค. ์ด๋ฌํ ์ด์ ๋ก, ๊ทธ๋ฆฌ๊ณ Linux์์ ํด๋์ BPF ๊ฐ๋ฐ์ ์ญ์ฌ๋ฅผ ๋ฐ๋ผ๊ฐ๋ฉด ๊ทธ๊ฒ์ด ์ด๋ป๊ฒ ๊ทธ๋ฆฌ๊ณ ์ ํ๋์ ์ธ ํํ๋ก ์งํํ๋์ง๊ฐ ๋ ๋ช
ํํด์ง ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋๋ ํด๋์ BPF์ ๋ํ ๊ธฐ์ฌ๋ถํฐ ์์ํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
์ง๋ ์ธ๊ธฐ XNUMX๋ ๋ ๋ง, ์ ๋ช ํ ๋ก๋ ์ค ๋ฒํด๋ฆฌ ์ฐ๊ตฌ์(Lawrence Berkeley Laboratory)์ ์์ง๋์ด๋ค์ ์ง๋ ์ธ๊ธฐ XNUMX๋ ๋ ํ๋ฐ์ ํ๋ํ๋ ํ๋์จ์ด์์ ๋คํธ์ํฌ ํจํท์ ์ ์ ํ๊ฒ ํํฐ๋งํ๋ ๋ฐฉ๋ฒ์ ๋ํ ์ง๋ฌธ์ ๊ด์ฌ์ ๊ฐ๊ฒ ๋์์ต๋๋ค. ์๋ CSPF(CMU/Stanford Packet Filter) ๊ธฐ์ ๋ก ๊ตฌํ๋ ํํฐ๋ง์ ๊ธฐ๋ณธ ์์ด๋์ด๋ ๋ถํ์ํ ํจํท์ ์ต๋ํ ๋นจ๋ฆฌ ํํฐ๋งํ๋ ๊ฒ์ด์์ต๋๋ค. ์ด๋ ์ปค๋ ๊ณต๊ฐ์์ ๋ถํ์ํ ๋ฐ์ดํฐ๊ฐ ์ฌ์ฉ์ ๊ณต๊ฐ์ ๋ณต์ฌ๋๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ปค๋ ๊ณต๊ฐ์์ ์ฌ์ฉ์ ์ฝ๋๋ฅผ ์คํํ๊ธฐ ์ํ ๋ฐํ์ ๋ณด์์ ์ ๊ณตํ๊ธฐ ์ํด ์๋๋ฐ์ค ๊ฐ์ ๋จธ์ ์ด ์ฌ์ฉ๋์์ต๋๋ค.
๊ทธ๋ฌ๋ ๊ธฐ์กด ํํฐ์ ๊ฐ์ ๋จธ์ ์ ์คํ ๊ธฐ๋ฐ ๋จธ์ ์์ ์คํ๋๋๋ก ์ค๊ณ๋์์ผ๋ฉฐ ์ต์ RISC ๋จธ์ ์์๋ ํจ์จ์ ์ผ๋ก ์คํ๋์ง ์์์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก Berkeley Labs์ ์์ง๋์ด๋ค์ ๋
ธ๋ ฅ์ ํตํด ์๋ก์ด BPF(Berkeley Packet Filters) ๊ธฐ์ ์ด ๊ฐ๋ฐ๋์์ผ๋ฉฐ, ๊ทธ ๊ฐ์ ๋จธ์ ์ํคํ
์ฒ๋ ๋ค์๊ณผ ๊ฐ์ ์ ์๋ ค์ง ์ ํ์ ์ฃผ๋ ฅ ์ ํ์ธ Motorola 6502 ํ๋ก์ธ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ค๊ณ๋์์ต๋๋ค.
BPF ๋จธ์ ์ํคํ ์ฒ
์ฌ๋ก๋ฅผ ๋ถ์ํ๋ฉด์ ์ค์ ์ ์ธ ๋ฐฉ์์ผ๋ก ์ํคํ
์ฒ์ ๋ํด ์์ ๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ฐ์ ๋จธ์ ์ ์ฌ์ฉ์๊ฐ ์ก์ธ์คํ ์ ์๋ ๋ ๊ฐ์ 32๋นํธ ๋ ์ง์คํฐ, ์ฆ ๋์ฐ๊ธฐ๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. A
๋ฐ ์ธ๋ฑ์ค ๋ ์ง์คํฐ X
, ์ฐ๊ธฐ ๋ฐ ํ์ ์ฝ๊ธฐ์ ์ฌ์ฉํ ์ ์๋ 64๋ฐ์ดํธ ๋ฉ๋ชจ๋ฆฌ(16์๋) ๋ฐ ์ด๋ฌํ ๊ฐ์ฒด ์์
์ ์ํ ์์ ๋ช
๋ น ์์คํ
์
๋๋ค. ์กฐ๊ฑด์์ ๊ตฌํํ๊ธฐ ์ํ ์ ํ ๋ช
๋ น๋ ํ๋ก๊ทธ๋จ์์ ์ฌ์ฉํ ์ ์์์ง๋ง ํ๋ก๊ทธ๋จ์ ์ ์ ์๋ฃ๋ฅผ ๋ณด์ฅํ๊ธฐ ์ํด ์์ผ๋ก๋ง ์ ํํ ์ ์์์ต๋๋ค. ์ฆ, ํนํ ๋ฃจํ๋ฅผ ๋ง๋๋ ๊ฒ์ด ๊ธ์ง๋์์ต๋๋ค.
๊ธฐ๊ณ๋ฅผ ์์ํ๋ ์ผ๋ฐ์ ์ธ ๊ณํ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ฌ์ฉ์๋ BPF ์ํคํ ์ฒ์ฉ ํ๋ก๊ทธ๋จ์ ์์ฑํ๊ณ ๋ค์์ ์ฌ์ฉํฉ๋๋ค. ์ฝ๊ฐ ์ปค๋ ๋ฉ์ปค๋์ฆ(์: ์์คํ ํธ์ถ)์ ํ๋ก๊ทธ๋จ์ ๋ก๋ํ๊ณ ์ฐ๊ฒฐํฉ๋๋ค. ์ด๋ค ์ฌ๋๋ค์๊ฒ๋ ์ปค๋์ ์ด๋ฒคํธ ์์ฑ๊ธฐ(์: ์ด๋ฒคํธ๋ ๋คํธ์ํฌ ์นด๋์ ๋ค์ ํจํท์ด ๋์ฐฉํ๋ ๊ฒ)์ ๋๋ค. ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ์ปค๋์ ํ๋ก๊ทธ๋จ์ ์คํํ๊ณ (์: ์ธํฐํ๋ฆฌํฐ์์) ๋จธ์ ๋ฉ๋ชจ๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ด๋ค ์ฌ๋๋ค์๊ฒ๋ ์ปค๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ(์: ์์ ํจํท์ ๋ฐ์ดํฐ)
์์ ๋ด์ฉ์ผ๋ก ์์ ๋ฅผ ์ดํด๋ณด๊ธฐ์ ์ถฉ๋ถํฉ๋๋ค. ํ์์ ๋ฐ๋ผ ์์คํ
๋ฐ ๋ช
๋ น ํ์์ ๋ํด ์์ ๋ณด๊ฒ ์ต๋๋ค. ๊ฐ์ ๋จธ์ ์ ๋ช
๋ น ์์คํ
์ ์ฆ์ ์ฐ๊ตฌํ๊ณ ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ํด ๋ฐฐ์ฐ๊ณ ์ถ๋ค๋ฉด ์๋ณธ ๊ธฐ์ฌ๋ฅผ ์ฝ์ผ์ญ์์ค. libpcap
: ํจํท ์บก์ฒ๋ฅผ ์ํ ์ํคํ
์ฒ ๋ฐ ์ต์ ํ ๋ฐฉ๋ฒ๋ก libpcap
.
Linux์์ ํด๋์ BPF๋ฅผ ์ฌ์ฉํ๋ ๋ชจ๋ ์ค์ํ ์๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. tcpdump
(libpcap
), ์ด์ปด, xt_bpf
, cls_bpf
.
TCP ๋คํ
BPF ๊ฐ๋ฐ์ ์ ์๋ ค์ง ์ ํธ๋ฆฌํฐ์ธ ํจํท ํํฐ๋ง์ ์ํ ํ๋ฐํธ์๋ ๊ฐ๋ฐ๊ณผ ๋ณํํ์ฌ ์ํ๋์์ต๋๋ค. tcpdump
. ๊ทธ๋ฆฌ๊ณ ์ด๊ฒ์ ๋ง์ ์ด์ ์ฒด์ ์์ ์ฌ์ฉํ ์ ์๋ ํด๋์ BPF๋ฅผ ์ฌ์ฉํ๋ ๊ฐ์ฅ ์ค๋๋๊ณ ์ ๋ช
ํ ์์ด๋ฏ๋ก ์ด ๊ธฐ์ ์ ๋ํ ์ฐ๊ตฌ๋ฅผ ์์ํ๊ฒ ์ต๋๋ค.
(์ ๋ ์ด ๊ธ์ ๋ชจ๋ ์์ ๋ฅผ Linux์์ ์คํํ์ต๋๋ค. 5.6.0-rc6
. ๋ ๋์ ๊ฐ๋
์ฑ์ ์ํด ์ผ๋ถ ๋ช
๋ น์ ์ถ๋ ฅ์ด ํธ์ง๋์์ต๋๋ค.)
์: IPv6 ํจํท ๊ด์ฐฐ
์ธํฐํ์ด์ค์ ๋ชจ๋ IPv6 ํจํท์ ๋ณด๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค. eth0
. ์ด๋ฅผ ์ํด ์ฐ๋ฆฌ๋ ํ๋ก๊ทธ๋จ์ ์คํํ ์ ์์ต๋๋ค tcpdump
๊ฐ๋จํ ํํฐ๋ก ip6
:
$ sudo tcpdump -i eth0 ip6
์ด ๊ฒฝ์ฐ, tcpdump
ํํฐ๋ฅผ ์ปดํ์ผํฉ๋๋ค ip6
BPF ์ํคํ
์ฒ ๋ฐ์ดํธ์ฝ๋๋ก ๋ณํํ์ฌ ์ปค๋๋ก ๋ณด๋
๋๋ค(์์ธํ ๋ด์ฉ์ ์น์
์ฐธ์กฐ). eth0
. ํํฐ๊ฐ XNUMX์ด ์๋ ๊ฐ์ ๋ฐํํ๋ ๊ฒฝ์ฐ n
, ๊ทธ ๋ค์์๋ ์ต๋ n
ํจํท์ ๋ฐ์ดํธ๊ฐ ์ฌ์ฉ์ ๊ณต๊ฐ์ ๋ณต์ฌ๋๊ณ ์ถ๋ ฅ์์ โโ๋ณผ ์ ์์ต๋๋ค. tcpdump
.
์ด๋ค ๋ฐ์ดํธ์ฝ๋๊ฐ ์ปค๋๋ก ์ ์ก๋์๋์ง ์ฝ๊ฒ ์์๋ผ ์ ์๋ค๋ ๊ฒ์ด ๋ฐํ์ก์ต๋๋ค. tcpdump
์ ๋์์ผ๋ก tcpdump
, ์ต์
์ ์ฌ์ฉํ์ฌ ์คํํ๋ฉด -d
:
$ sudo tcpdump -i eth0 -d ip6
(000) ldh [12]
(001) jeq #0x86dd jt 2 jf 3
(002) ret #262144
(003) ret #0
XNUMX๋ฒ์งธ ์ค์์ ๋ค์ ๋ช
๋ น์ ์คํํฉ๋๋ค. ldh [12]
, ์ด๋ "๋ ์ง์คํฐ์ ๋ก๋"๋ฅผ ์๋ฏธํฉ๋๋ค. A
์ฃผ์ 16โ์ ๋ฐ ๋จ์ด(12๋นํธ)๊ฐ ์๊ณ ์ ์ผํ ์ง๋ฌธ์ ์ฐ๋ฆฌ๊ฐ ์ด๋ค ์ข
๋ฅ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์์ต๋๊น? ๋๋ต์ ์ ์์ต๋๋ค. x
์์ํ๋ค (x+1)
๋ถ์๋ ๋คํธ์ํฌ ํจํท์ ๋ฒ์งธ ๋ฐ์ดํธ์
๋๋ค. ์ด๋๋ท ์ธํฐํ์ด์ค์์ ํจํท์ ์ฝ์ต๋๋ค. eth0
๊ทธ๋ฆฌ๊ณ ์ด
6 6 2
|Destination MAC|Source MAC|Ether Type|...|
๊ทธ๋์ ๋ช
๋ น์ ์คํํ ํ ldh [12]
๊ธฐ๋ก๋ถ์ A
๋คํ์ด ์์ ๊ฑฐ์ผ Ether Type
โ ์ด ์ด๋๋ท ํ๋ ์์์ ์ ์ก๋ ํจํท ์ ํ. 1๋ฒ์งธ ์ค์์๋ ๋ ์ง์คํฐ์ ๋ด์ฉ์ ๋น๊ตํฉ๋๋ค. A
(ํจํค์งํ) ๋ค 0x86dd
๊ทธ๋ฆฌ๊ณ ์ด jt 2
ะธ jf 3
โ ๋น๊ต๊ฐ ์ฑ๊ณตํ ๊ฒฝ์ฐ ์ด๋ํด์ผ ํ ํ์(A == 0x86dd
) ์คํจํ์ต๋๋ค. ๋ฐ๋ผ์ ์ฑ๊ณต์ ์ธ ๊ฒฝ์ฐ(IPv6)์์๋ 2ํ์ผ๋ก ์ด๋ํ๊ณ , ์คํจํ ๊ฒฝ์ฐ์๋ 3ํ์ผ๋ก ์ด๋ํฉ๋๋ค. 3ํ์์ ํ๋ก๊ทธ๋จ์ ์ฝ๋ 0(ํจํท ๋ณต์ฌ ์ ํจ)์ผ๋ก ์ข
๋ฃ๋๊ณ , 2ํ์์ ํ๋ก๊ทธ๋จ์ ์ฝ๋๋ก ์ข
๋ฃ๋ฉ๋๋ค. 262144(์ต๋ 256KB ํจํค์ง๋ฅผ ๋ณต์ฌํ์ธ์).
๋ ๋ณต์กํ ์: ๋์ ํฌํธ๋ณ๋ก TCP ํจํท์ ์ดํด๋ด ๋๋ค.
๋์ ํฌํธ 666์ ์ฌ์ฉํ์ฌ ๋ชจ๋ TCP ํจํท์ ๋ณต์ฌํ๋ ํํฐ์ ๋ชจ์์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. IPv4 ์ฌ๋ก๊ฐ ๋ ๊ฐ๋จํ๋ฏ๋ก IPv6 ์ฌ๋ก๋ฅผ ๊ณ ๋ คํด ๋ณด๊ฒ ์ต๋๋ค. ์ด ์์ ๋ฅผ ์ฐ๊ตฌํ ํ ์ฐ์ต์ผ๋ก IPv6 ํํฐ๋ฅผ ์ง์ ํ์ํ ์ ์์ต๋๋ค(ip6 and tcp dst port 666
) ๋ฐ ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ์ ๋ํ ํํฐ(tcp dst port 666
). ๋ฐ๋ผ์ ์ฐ๋ฆฌ๊ฐ ๊ด์ฌ ์๋ ํํฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
$ sudo tcpdump -i eth0 -d ip and tcp dst port 666
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 10
(002) ldb [23]
(003) jeq #0x6 jt 4 jf 10
(004) ldh [20]
(005) jset #0x1fff jt 10 jf 6
(006) ldxb 4*([14]&0xf)
(007) ldh [x + 16]
(008) jeq #0x29a jt 9 jf 10
(009) ret #262144
(010) ret #0
์ฐ๋ฆฌ๋ 0ํ๊ณผ 1ํ์ด ๋ฌด์์ ํ๋์ง ์ด๋ฏธ ์๊ณ ์์ต๋๋ค. 2๋ฒ์งธ ์ค์์ ์ฐ๋ฆฌ๋ ์ด๊ฒ์ด IPv4 ํจํท์ธ์ง๋ฅผ ์ด๋ฏธ ํ์ธํ์ต๋๋ค(Ether Type = 0x800
) ๋ ์ง์คํฐ์ ๋ก๋ํฉ๋๋ค. A
ํจํท์ 24๋ฒ์งธ ๋ฐ์ดํธ์
๋๋ค. ์ฐ๋ฆฌ ํจํค์ง๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค
14 8 1 1
|ethernet header|ip fields|ttl|protocol|...|
์ด๋ ์ฐ๋ฆฌ๊ฐ ๋ ์ง์คํฐ์ ๋ก๋ํ๋ค๋ ์๋ฏธ์
๋๋ค. A
IP ํค๋์ ํ๋กํ ์ฝ ํ๋๋ ๋
ผ๋ฆฌ์ ์
๋๋ค. TCP ํจํท๋ง ๋ณต์ฌํ๋ ค๊ณ ํ๊ธฐ ๋๋ฌธ์
๋๋ค. ์ฐ๋ฆฌ๋ ํ๋กํ ์ฝ์ ๋ค์๊ณผ ๋น๊ตํฉ๋๋ค. 0x6
(IPPROTO_TCP
๋ผ์ธ 4์ 5์์๋ ์ฃผ์ 20์ ์๋ ํํ์๋๋ฅผ ๋ก๋ํ๊ณ ๋ค์ ๋ช
๋ น์ ์ฌ์ฉํฉ๋๋ค. jset
์ธ ๊ฐ์ง ์ค ํ๋๊ฐ ์ค์ ๋์ด ์๋์ง ํ์ธํ์ญ์์ค. jset
๊ฐ์ฅ ์ค์ํ ์ธ ๋นํธ๊ฐ ์ง์์ง๋๋ค. XNUMX๊ฐ์ ๋นํธ ์ค XNUMX๊ฐ๋ ํจํท์ด ์กฐ๊ฐํ๋ IP ํจํท์ ์ผ๋ถ์ธ์ง ์ฌ๋ถ๋ฅผ ์๋ ค์ฃผ๊ณ , ๊ทธ๋ ๋ค๋ฉด ๋ง์ง๋ง ์กฐ๊ฐ์ธ์ง ์ฌ๋ถ๋ฅผ ์๋ ค์ค๋๋ค. ์ธ ๋ฒ์งธ ๋นํธ๋ ์์ฝ๋์ด ์์ผ๋ฉฐ XNUMX์ด์ด์ผ ํฉ๋๋ค. ๋ถ์์ ํ๊ฑฐ๋ ์์๋ ํจํท์ ํ์ธํ๊ณ ์ถ์ง ์์ผ๋ฏ๋ก ์ธ ๋นํธ๋ฅผ ๋ชจ๋ ํ์ธํฉ๋๋ค.
์ด ๋ชฉ๋ก์์ ๊ฐ์ฅ ํฅ๋ฏธ๋ก์ด ๊ฒ์ 6๋ฒ์งธ ์ค์
๋๋ค. ํํ ldxb 4*([14]&0xf)
๋ ์ง์คํฐ์ ๋ก๋ํ๋ค๋ ์๋ฏธ์
๋๋ค. X
ํจํท์ 4๋ฒ์งธ ๋ฐ์ดํธ์ ์ตํ์ XNUMX๋นํธ์ XNUMX๋ฅผ ๊ณฑํ ๊ฒ์
๋๋ค. XNUMX๋ฒ์งธ ๋ฐ์ดํธ์ ์ตํ์ XNUMX๋นํธ๋ ํ๋์
๋๋ค. 4*([14]&0xf)
์ด ํ์๊ณผ ๋ ์ง์คํฐ์๋ง ์ฌ์ฉํ ์ ์๋ ํน์ ์ฃผ์ ์ง์ ์ฒด๊ณ์ ๋ํ ์ง์ ์
๋๋ค. X
, ์ฆ. ์ฐ๋ฆฌ๋ ๋งํ ์ ์์ด ldb 4*([14]&0xf)
๋ ldxb 5*([14]&0xf)
(๋ค๋ฅธ ์คํ์
๋ง ์ง์ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ldxb 4*([16]&0xf)
). ์ด ์ฃผ์ ์ง์ ๋ฐฉ์์ด BPF์ ์ ํํ๊ฒ ์ถ๊ฐ๋ ๊ฒ์ ๋ถ๋ช
ํฉ๋๋ค. X
(์ธ๋ฑ์ค ๋ ์ง์คํฐ) IPv4 ํค๋ ๊ธธ์ด์
๋๋ค.
๊ทธ๋์ 7๋ฒ์งธ ์ค์์ ์ฐ๋ฆฌ๋ ๋จ์ด์ ์ ๋ฐ์ ๋ก๋ํ๋ ค๊ณ ํฉ๋๋ค. (X+16)
. ์ด๋๋ท ํค๋๊ฐ 14๋ฐ์ดํธ๋ฅผ ์ฐจ์งํ๋ค๋ ์ ์ ๊ธฐ์ตํ๊ณ , X
IPv4 ํค๋์ ๊ธธ์ด๊ฐ ํฌํจ๋์ด ์์ผ๋ฏ๋ก A
TCP ๋์ ํฌํธ๊ฐ ๋ก๋๋์์ต๋๋ค.
14 X 2 2
|ethernet header|ip header|source port|destination port|
๋ง์ง๋ง์ผ๋ก 8ํ์์๋ ๋์ ํฌํธ๋ฅผ ์ํ๋ ๊ฐ๊ณผ ๋น๊ตํ๊ณ 9ํ ๋๋ 10ํ์์๋ ํจํท์ ๋ณต์ฌํ ์ง ์ฌ๋ถ์ ๋ํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
Tcpdump: ๋ก๋ ์ค
์ด์ ์์ ์์๋ ํจํท ํํฐ๋ง์ ์ํด BPF ๋ฐ์ดํธ์ฝ๋๋ฅผ ์ปค๋์ ์ ํํ ๋ก๋ํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์ธํ ์ค๋ช
ํ์ง ์์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋งํ๋ฉด, tcpdump
๋ง์ ์์คํ
์ผ๋ก ํฌํ
๋์์ผ๋ฉฐ ํํฐ ์์
์ ์ํด tcpdump
libpcap
libpcap
, ๋ค์์ ์ํํด์ผ ํฉ๋๋ค.
- ์ ํ ์ค๋ช
์ ๋ง๋ค๊ธฐ
pcap_t
์ธํฐํ์ด์ค ์ด๋ฆ์์: ,pcap_create
- ์ธํฐํ์ด์ค ํ์ฑํ:
,pcap_activate
- ์ปดํ์ผ ํํฐ:
,pcap_compile
- ์ฐ๊ฒฐ ํํฐ:
.pcap_setfilter
๊ธฐ๋ฅ์ด ์ด๋ป๊ฒ ๋๋์ง ๋ณด๋ ค๋ฉด pcap_setfilter
Linux์์ ๊ตฌํ๋ ๊ฒฝ์ฐ strace
(์ผ๋ถ ์ค์ด ์ ๊ฑฐ๋์์ต๋๋ค):
$ sudo strace -f -e trace=%network tcpdump -p -i eth0 ip
socket(AF_PACKET, SOCK_RAW, 768) = 3
bind(3, {sa_family=AF_PACKET, sll_protocol=htons(ETH_P_ALL), sll_ifindex=if_nametoindex("eth0"), sll_hatype=ARPHRD_NETROM, sll_pkttype=PACKET_HOST, sll_halen=0}, 20) = 0
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, {len=4, filter=0xb00bb00bb00b}, 16) = 0
...
์ถ๋ ฅ์ ์ฒ์ ๋ ์ค์์ ์ฐ๋ฆฌ๋ eth0
. ๋ถํฐ ip
XNUMX๊ฐ์ BPF ๋ช
๋ น์ด๋ก ๊ตฌ์ฑ๋๋ฉฐ ์ธ ๋ฒ์งธ ์ค์์๋ ์ต์
์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ์ค๋๋ค. SO_ATTACH_FILTER
setsockopt
๊ธธ์ด๊ฐ 4์ธ ํํฐ๋ฅผ ๋ก๋ํ๊ณ ์ฐ๊ฒฐํฉ๋๋ค. ์ด๊ฒ์ด ํํฐ์
๋๋ค.
ํด๋์ BPF์์๋ ํํฐ ๋ก๋ ๋ฐ ์ฐ๊ฒฐ์ด ํญ์ ์์์ฑ ์์ ์ผ๋ก ๋ฐ์ํ์ง๋ง ์ ๋ฒ์ ์ BPF์์๋ ํ๋ก๊ทธ๋จ ๋ก๋ ๋ฐ ์ด๋ฒคํธ ์์ฑ๊ธฐ์ ๋ฐ์ธ๋ฉํ๋ ์์ ์ด ์๊ฐ์ ์ผ๋ก ๋ถ๋ฆฌ๋๋ค๋ ์ ์ ์ฃผ๋ชฉํ ๊ฐ์น๊ฐ ์์ต๋๋ค.
์จ๊ฒจ์ง ์ง์ค
์ฝ๊ฐ ๋ ์์ ํ ๋ฒ์ ์ ์ถ๋ ฅ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
$ sudo strace -f -e trace=%network tcpdump -p -i eth0 ip
socket(AF_PACKET, SOCK_RAW, 768) = 3
bind(3, {sa_family=AF_PACKET, sll_protocol=htons(ETH_P_ALL), sll_ifindex=if_nametoindex("eth0"), sll_hatype=ARPHRD_NETROM, sll_pkttype=PACKET_HOST, sll_halen=0}, 20) = 0
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, {len=1, filter=0xbeefbeefbeef}, 16) = 0
recvfrom(3, 0x7ffcad394257, 1, MSG_TRUNC, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
setsockopt(3, SOL_SOCKET, SO_ATTACH_FILTER, {len=4, filter=0xb00bb00bb00b}, 16) = 0
...
์์์ ์ธ๊ธํ๋ฏ์ด ํํฐ๋ฅผ ๋ก๋ํ๊ณ 5๋ฒ ๋ผ์ธ์ ์์ผ์ ์ฐ๊ฒฐํฉ๋๋ค. ํ์ง๋ง 3๋ฒ ๋ผ์ธ๊ณผ 4๋ฒ ๋ผ์ธ์์๋ ์ด๋ค ์ผ์ด ๋ฐ์ํฉ๋๊น? ์ด๊ฒ์ด ๋ฐํ์ก์ต๋๋ค libpcap
์ฐ๋ฆฌ๋ฅผ ๋๋ด
๋๋ค. ํํฐ์ ์ถ๋ ฅ์ ํํฐ๋ฅผ ๋ง์กฑํ์ง ์๋ ํจํท์ด ํฌํจ๋์ง ์๋๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ ret #0
(๋ชจ๋ ํจํท ์ญ์ ) ์์ผ์ ๋น์ฐจ๋จ ๋ชจ๋๋ก ์ ํํ๊ณ ์ด์ ํํฐ์์ ๋จ์ ์์ ์ ์๋ ๋ชจ๋ ํจํท์ ๋นผ๋ ค๊ณ ์๋ํฉ๋๋ค.
์ ์ฒด์ ์ผ๋ก ํด๋์ BPF๋ฅผ ์ฌ์ฉํ์ฌ Linux์์ ํจํค์ง๋ฅผ ํํฐ๋งํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ ํํ์ ํํฐ๊ฐ ํ์ํฉ๋๋ค. struct sock_fprog
๊ฐ๋ฐฉํ ์์ผ, ๊ทธ ํ ์์คํ
ํธ์ถ์ ์ฌ์ฉํ์ฌ ํํฐ๋ฅผ ์์ผ์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค. setsockopt
.
ํฅ๋ฏธ๋กญ๊ฒ๋ ํํฐ๋ ์์ ์์ผ๋ฟ๋ง ์๋๋ผ ๋ชจ๋ ์์ผ์ ๋ถ์ฐฉ๋ ์ ์์ต๋๋ค. ์ฌ๊ธฐ
์ฌ์ฉ์ ๋ํ ์์ธํ ๋ด์ฉ setsockopt
ํํฐ ์ฐ๊ฒฐ์ ๋ํด์๋ ์ฐธ์กฐ struct sock_fprog
๋์์์ด tcpdump
์ฐ๋ฆฌ๋ ์น์
์์ ์ด์ผ๊ธฐ ํ ๊ฒ์
๋๋ค
ํด๋์ BPF์ XNUMX์ธ๊ธฐ
BPF๋ 1997๋
Linux์ ํฌํจ๋์์ผ๋ฉฐ ์ค๋ซ๋์ ์ฃผ๋ ฅ์ผ๋ก ๋จ์ ์์ต๋๋ค. libpcap
ํน๋ณํ ๋ณ๊ฒฝ ์์ด(Linux ๊ด๋ จ ๋ณ๊ฒฝ์ ๋ฌผ๋ก , x86_64
์ํธ.
JIT ์ปดํ์ผ๋ฌ๋ 2012๋
์ ์ผ๋ จ์ ๋ณํ ์ค ์ฒซ ๋ฒ์งธ์์ต๋๋ค. xt_bpf
, ์ด๋ฅผ ํตํด ๋ค์์ ๋ํ ๊ท์น์ ์์ฑํ ์ ์์ต๋๋ค. iptables
BPF์ ๋์์ผ๋ก 2013๋
XNUMX์์ cls_bpf
, BPF๋ฅผ ์ฌ์ฉํ์ฌ ํธ๋ํฝ ๋ถ๋ฅ์๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
์ด ๋ชจ๋ ์์ ๋ฅผ ๊ณง ๋ ์์ธํ ์ดํด๋ณด๊ฒ ์ง๋ง ๋จผ์ BPF์ฉ ์์ ํ๋ก๊ทธ๋จ์ ์์ฑํ๊ณ ์ปดํ์ผํ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ฐ๋ ๊ฒ์ด ์ ์ฉํ ๊ฒ์
๋๋ค. libpcap
์ ํ์ (๊ฐ๋จํ ์: ํํฐ ์์ฑ๋จ) libpcap
0 ๋๋ 0x40000์ ๋ ๊ฐ์ง ๊ฐ๋ง ๋ฐํํ ์ ์์) ๋๋ ์ผ๋ฐ์ ์ผ๋ก seccomp์ ๊ฒฝ์ฐ์ ๊ฐ์ด ์ ์ฉํ ์ ์์ต๋๋ค.
์ฐ๋ฆฌ ์์ผ๋ก BPF ํ๋ก๊ทธ๋๋ฐํ๊ธฐ
BPF ๋ช ๋ น์ด์ ๋ฐ์ด๋๋ฆฌ ํ์์ ๋ํด ์์๋ด ์๋ค. ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค.
16 8 8 32
| code | jt | jf | k |
๊ฐ ๋ช
๋ น์ด๋ 64๋นํธ๋ฅผ ์ฐจ์งํ๋ฉฐ ์ฒ์ 16๋นํธ๋ ๋ช
๋ น์ด ์ฝ๋์ด๊ณ ๊ทธ ๋ค์์๋ XNUMX๋นํธ ๋ค์ฌ์ฐ๊ธฐ๊ฐ XNUMX๊ฐ ์์ต๋๋ค. jt
ะธ jf
๋ฐ ์ธ์์ ๊ฒฝ์ฐ 32๋นํธ K
, ๊ทธ ๋ชฉ์ ์ ๋ช
๋ น๋ง๋ค ๋ค๋ฆ
๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์ ๋ช
๋ น์ ret
, ํ๋ก๊ทธ๋จ์ ์ข
๋ฃํ๋ ์ฝ๋์๋ 6
, ๋ฐํ ๊ฐ์ ์์์์ ๊ฐ์ ธ์ต๋๋ค. K
. C์์๋ ๋จ์ผ BPF ๋ช
๋ น์ด๊ฐ ๊ตฌ์กฐ๋ก ํํ๋ฉ๋๋ค.
struct sock_filter {
__u16 code;
__u8 jt;
__u8 jf;
__u32 k;
}
์ ์ฒด ํ๋ก๊ทธ๋จ์ ๊ตฌ์กฐ ํํ์ ๋๋ค.
struct sock_fprog {
unsigned short len;
struct sock_filter *filter;
}
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ์ด๋ฏธ ํ๋ก๊ทธ๋จ์ ์์ฑํ ์ ์์ต๋๋ค(์๋ฅผ ๋ค์ด, ๋ช
๋ น์ด ์ฝ๋๋ฅผ ์๊ณ ์์ต๋๋ค). ip6
์ผ๋ก
struct sock_filter code[] = {
{ 0x28, 0, 0, 0x0000000c },
{ 0x15, 0, 1, 0x000086dd },
{ 0x06, 0, 0, 0x00040000 },
{ 0x06, 0, 0, 0x00000000 },
};
struct sock_fprog prog = {
.len = ARRAY_SIZE(code),
.filter = code,
};
ํ๋ก๊ทธ๋จ prog
์ฐ๋ฆฌ๋ ํตํ์์ ํฉ๋ฒ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค
setsockopt(sk, SOL_SOCKET, SO_ATTACH_FILTER, &prog, sizeof(prog))
๊ธฐ๊ณ์ด ํํ๋ก ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ ๊ฒ์ ๊ทธ๋ฆฌ ํธ๋ฆฌํ์ง๋ ์์ง๋ง ๋๋ก๋ ํ์ํ ๋๋ ์์ต๋๋ค(์: ๋๋ฒ๊น
, ๋จ์ ํ
์คํธ ์์ฑ, Habrรฉ์ ๋ํ ๊ธฐ์ฌ ์์ฑ ๋ฑ). ํธ์์ ํ์ผ์ <linux/filter.h>
๋์ฐ๋ฏธ ๋งคํฌ๋ก๊ฐ ์ ์๋์์ต๋๋ค. ์์ ๋์ผํ ์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๋ค์ ์์ฑํ ์ ์์ต๋๋ค.
struct sock_filter code[] = {
BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 12),
BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, ETH_P_IPV6, 0, 1),
BPF_STMT(BPF_RET|BPF_K, 0x00040000),
BPF_STMT(BPF_RET|BPF_K, 0),
}
๊ทธ๋ฌ๋ ์ด ์ต์
์ ๊ทธ๋ค์ง ํธ๋ฆฌํ์ง ์์ต๋๋ค. ์ด๊ฒ์ด Linux ์ปค๋ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ถ๋ก ํ ๊ฒ์ด๋ฏ๋ก ๋๋ ํ ๋ฆฌ์ ์์ต๋๋ค. tools/bpf
์ด์
๋ธ๋ฆฌ ์ธ์ด๋ ๋๋ฒ๊ทธ ์ถ๋ ฅ๊ณผ ๋งค์ฐ ์ ์ฌํฉ๋๋ค. tcpdump
, ๊ทธ๋ฌ๋ ์ถ๊ฐ๋ก ๊ธฐํธ ๋ ์ด๋ธ์ ์ง์ ํ ์๋ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ๋ค์์ TCP/IPv4๋ฅผ ์ ์ธํ ๋ชจ๋ ํจํท์ ์ญ์ ํ๋ ํ๋ก๊ทธ๋จ์
๋๋ค.
$ cat /tmp/tcp-over-ipv4.bpf
ldh [12]
jne #0x800, drop
ldb [23]
jneq #6, drop
ret #-1
drop: ret #0
๊ธฐ๋ณธ์ ์ผ๋ก ์ด์
๋ธ๋ฌ๋ ๋ค์ ํ์์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค. <ะบะพะปะธัะตััะฒะพ ะธะฝััััะบัะธะน>,<code1> <jt1> <jf1> <k1>,...
, TCP๋ฅผ ์ฌ์ฉํ ์์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
$ tools/bpf/bpf_asm /tmp/tcp-over-ipv4.bpf
6,40 0 0 12,21 0 3 2048,48 0 0 23,21 0 1 6,6 0 0 4294967295,6 0 0 0,
C ํ๋ก๊ทธ๋๋จธ์ ํธ์๋ฅผ ์ํด ๋ค๋ฅธ ์ถ๋ ฅ ํ์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
$ tools/bpf/bpf_asm -c /tmp/tcp-over-ipv4.bpf
{ 0x28, 0, 0, 0x0000000c },
{ 0x15, 0, 3, 0x00000800 },
{ 0x30, 0, 0, 0x00000017 },
{ 0x15, 0, 1, 0x00000006 },
{ 0x06, 0, 0, 0xffffffff },
{ 0x06, 0, 0, 0000000000 },
์ด ํ
์คํธ๋ ์ ํ ๊ตฌ์กฐ ์ ์์ ๋ณต์ฌ๋ ์ ์์ต๋๋ค. struct sock_filter
, ์ด ์น์
์ ์์ ๋ถ๋ถ์์ ๊ทธ๋ฌ๋ ๊ฒ์ฒ๋ผ.
Linux ๋ฐ netsniff-ng ํ์ฅ
ํ์ค BPF ์ธ์๋ Linux ๋ฐ tools/bpf/bpf_asm
์ง์๊ณผ struct sk_buff
, ์ปค๋์ ๋คํธ์ํฌ ํจํท์ ์ค๋ช
ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ค๋ฅธ ์ ํ์ ๋์ฐ๋ฏธ ๋ช
๋ น๋ ์์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ldw cpu
๋ ์ง์คํฐ์ ๋ก๋๋ฉ๋๋ค A
์ปค๋ ํจ์ ์คํ ๊ฒฐ๊ณผ raw_smp_processor_id()
. (BPF์ ์ ๋ฒ์ ์์๋ ์ด๋ฌํ ๋นํ์ค ํ์ฅ์ด ํ์ฅ๋์ด ๋ฉ๋ชจ๋ฆฌ, ๊ตฌ์กฐ์ ์ก์ธ์คํ๊ณ ์ด๋ฒคํธ๋ฅผ ์์ฑํ๊ธฐ ์ํ ์ปค๋ ๋์ฐ๋ฏธ ์ธํธ๋ฅผ ํ๋ก๊ทธ๋จ์ ์ ๊ณตํฉ๋๋ค.) ๋ค์์ ํํฐ์ ํฅ๋ฏธ๋ก์ด ์์
๋๋ค. ํ์ฅ์ ์ฌ์ฉํ์ฌ ํจํท ํค๋๋ฅผ ์ฌ์ฉ์ ๊ณต๊ฐ์ผ๋ก poff
, ํ์ด๋ก๋ ์คํ์
:
ld poff
ret a
BPF ํ์ฅ์ ๋ค์์์ ์ฌ์ฉํ ์ ์์ต๋๋ค. tcpdump
, ๊ทธ๋ฌ๋ ์ด๊ฒ์ด ์ ํธ๋ฆฌํฐ ํจํค์ง์ ๋ํด ์์๊ฐ๋ ์ข์ ์ด์ ์
๋๋ค. netsniff-ng
netsniff-ng
, BPF๋ฅผ ์ฌ์ฉํ ํํฐ๋ง ์ธ์๋ ํจ๊ณผ์ ์ธ ํธ๋ํฝ ์์ฑ๊ธฐ๊ฐ ํฌํจ๋์ด ์์ผ๋ฉฐ tools/bpf/bpf_asm
, BPF ์ด์
๋ธ๋ฌ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. bpfc
. ํจํค์ง์๋ ๋งค์ฐ ์์ธํ ๋ฌธ์๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ๊ธฐ์ฌ ๋ง์ง๋ง์ ์๋ ๋งํฌ๋ ์ฐธ์กฐํ์ธ์.
์ด์ปด
๋ฐ๋ผ์ ์ฐ๋ฆฌ๋ ์์์ ๋ณต์ก์ฑ์ ์ง๋ BPF ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์ด๋ฏธ ์๊ณ ์์ผ๋ฉฐ ์๋ก์ด ์์ ๋ฅผ ๋ณผ ์ค๋น๊ฐ ๋์์ต๋๋ค. ๊ทธ ์ค ์ฒซ ๋ฒ์งธ๋ BPF ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ ์์คํ ํธ์ถ ์ธ์ ์ธํธ ๋ฐ ์ธํธ๋ฅผ ๊ด๋ฆฌํ ์ ์๋ seccomp ๊ธฐ์ ์ ๋๋ค. ์ฃผ์ด์ง ํ๋ก์ธ์ค์ ๊ทธ ์์.
seccomp์ ์ฒซ ๋ฒ์งธ ๋ฒ์ ์ 2005๋
์ ์ปค๋์ ์ถ๊ฐ๋์์ง๋ง ๊ทธ๋ค์ง ์ธ๊ธฐ๊ฐ ์์์ต๋๋ค. ํ๋ก์ธ์ค์์ ์ฌ์ฉํ ์ ์๋ ์์คํ
ํธ์ถ ์งํฉ์ ๋ค์์ผ๋ก ์ ํํ๋ ๋จ์ผ ์ต์
๋ง ์ ๊ณตํ๊ธฐ ๋๋ฌธ์
๋๋ค. read
, write
, exit
ะธ sigreturn
, ๊ท์น์ ์๋ฐํ ํ๋ก์ธ์ค๋ ๋ค์์ ์ฌ์ฉํ์ฌ ์ข
๋ฃ๋์์ต๋๋ค. SIGKILL
. ๊ทธ๋ฌ๋ 2012๋
์ seccomp์๋ BPF ํํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์ด ํ์ฉ๋๋ ์์คํ
ํธ์ถ ์งํฉ์ ์ ์ํ๊ณ ํด๋น ์ธ์์ ๋ํ ๊ฒ์ฌ๋ ์ํํ ์ ์์ต๋๋ค. (ํฅ๋ฏธ๋กญ๊ฒ๋ Chrome์ ์ด ๊ธฐ๋ฅ์ ์ต์ด ์ฌ์ฉ์ ์ค ํ๋์์ผ๋ฉฐ Chrome ์ง์์ ํ์ฌ BPF์ ์ ๋ฒ์ ์ ๊ธฐ๋ฐ์ผ๋ก KRSI ๋ฉ์ปค๋์ฆ์ ๊ฐ๋ฐํ๊ณ Linux ๋ณด์ ๋ชจ๋์ ์ฌ์ฉ์ ์ ์๋ฅผ ํ์ฉํ๊ณ ์์ต๋๋ค.) ์ถ๊ฐ ๋ฌธ์์ ๋ํ ๋งํฌ๋ ๋์์ ์ฐพ์ ์ ์์ต๋๋ค. ๊ธฐ์ฌ์.
seccomp ์ฌ์ฉ์ ๋ํ ๊ธฐ์ฌ๊ฐ ์ด๋ฏธ ํ๋ธ์ ์์ผ๋ฏ๋ก ๋ค์ ํ์ ์น์
์ ์ฝ๊ธฐ ์ ์(๋๋ ๋์ ) ์ฝ์ด๋ณด๊ณ ์ถ์ดํ ์๋ ์์ต๋๋ค. ๊ธฐ์ฌ์์
๋ค์์ผ๋ก ํํฐ๋ฅผ ์์ฑํ๊ณ ๋ก๋ํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค. seccomp
๋ฒ ์ด C์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฌ์ฉ libseccomp
๊ฐ ์ต์
์ ์ฅ๋จ์ ์ ๋ฌด์์ด๋ฉฐ, ๋ง์ง๋ง์ผ๋ก ํ๋ก๊ทธ๋จ์์ seccomp๊ฐ ์ด๋ป๊ฒ ์ฌ์ฉ๋๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค. strace
.
seccomp์ฉ ํํฐ ์์ฑ ๋ฐ ๋ก๋
์ฐ๋ฆฌ๋ ์ด๋ฏธ BPF ํ๋ก๊ทธ๋จ์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์์ผ๋ฏ๋ก ๋จผ์ seccomp ํ๋ก๊ทธ๋๋ฐ ์ธํฐํ์ด์ค๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ํ๋ก์ธ์ค ์์ค์์ ํํฐ๋ฅผ ์ค์ ํ ์ ์์ผ๋ฉฐ ๋ชจ๋ ํ์ ํ๋ก์ธ์ค๋ ์ ํ ์ฌํญ์ ์์ํฉ๋๋ค. ์ด๋ ์์คํ
ํธ์ถ์ ์ฌ์ฉํ์ฌ ์ํ๋ฉ๋๋ค. seccomp(2)
seccomp(SECCOMP_SET_MODE_FILTER, flags, &filter)
์ด๋์์ &filter
- ์ด๊ฒ์ ์ฐ๋ฆฌ์๊ฒ ์ด๋ฏธ ์น์ํ ๊ตฌ์กฐ์ ๋ํ ํฌ์ธํฐ์
๋๋ค. struct sock_fprog
, ์ฆ. BPF ํ๋ก๊ทธ๋จ.
seccomp ํ๋ก๊ทธ๋จ์ ์์ผ ํ๋ก๊ทธ๋จ๊ณผ ์ด๋ป๊ฒ ๋ค๋ฆ ๋๊น? ์ ์ก๋ ์ปจํ ์คํธ. ์์ผ์ ๊ฒฝ์ฐ ํจํท์ ํฌํจํ๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด ์ฃผ์ด์ก๊ณ seccomp์ ๊ฒฝ์ฐ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๊ฐ ์ฃผ์ด์ก์ต๋๋ค.
struct seccomp_data {
int nr;
__u32 arch;
__u64 instruction_pointer;
__u64 args[6];
};
์ฌ๊ธฐ์ nr
์์ํ ์์คํ
ํธ์ถ์ ๋ฒํธ์
๋๋ค. arch
- ํ์ฌ ์ํคํ
์ฒ(์์ธํ ๋ด์ฉ์ ์๋ ์ฐธ์กฐ) args
- ์ต๋ XNUMX๊ฐ์ ์์คํ
ํธ์ถ ์ธ์ instruction_pointer
์์คํ
ํธ์ถ์ ์ํํ ์ฌ์ฉ์ ๊ณต๊ฐ ๋ช
๋ น์ ๋ํ ํฌ์ธํฐ์
๋๋ค. ๋ฐ๋ผ์ ์๋ฅผ ๋ค์ด ์์คํ
ํธ์ถ ๋ฒํธ๋ฅผ ๋ ์ง์คํฐ์ ๋ก๋ํ๋ ค๋ฉด A
์ฐ๋ฆฌ๋ ๋งํด์ผ
ldw [0]
seccomp ํ๋ก๊ทธ๋จ์๋ ๋ค๋ฅธ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ์ปจํ
์คํธ๋ 32๋นํธ ์ ๋ ฌ๋ก๋ง ์ก์ธ์คํ ์ ์์ผ๋ฉฐ ํํฐ๋ฅผ ๋ก๋ํ๋ ค๊ณ ํ ๋ ๋ฐ ๋จ์ด ๋๋ ๋ฐ์ดํธ๋ฅผ ๋ก๋ํ ์ ์์ต๋๋ค. ldh [0]
์์คํ
ํธ์ถ seccomp
๋์์ฌ ๊ฒ์ด๋ค EINVAL
. ์ด ํจ์๋ ๋ก๋๋ ํํฐ๋ฅผ ํ์ธํฉ๋๋ค. seccomp_check_filter()
mod
(๋๋๊ธฐ ๋๋จธ์ง) ์ถ๊ฐ ์ดํ seccomp BPF ํ๋ก๊ทธ๋จ์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ฐ๋ฆฌ๋ seccomp ํ๋ก๊ทธ๋จ์ ์์ฑํ๊ณ ์ฝ๋ ๋ฐ ํ์ํ ๋ชจ๋ ๊ฒ์ ์ด๋ฏธ ์๊ณ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ํ๋ก๊ทธ๋จ ๋ก์ง์ ์์คํ ํธ์ถ์ ํ์ดํธ ๋๋ ๋ธ๋ ๋ฆฌ์คํธ๋ก ๋ฐฐ์ด๋ฉ๋๋ค.
ld [0]
jeq #304, bad
jeq #176, bad
jeq #239, bad
jeq #279, bad
good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */
bad: ret #0
304, 176, 239, 279๋ฒ์ผ๋ก ๋ฒํธ๊ฐ ๋งค๊ฒจ์ง XNUMX๊ฐ์ ์์คํ
ํธ์ถ์ ๋ธ๋๋ฆฌ์คํธ๋ฅผ ํ์ธํฉ๋๋ค. ์ด ์์คํ
ํธ์ถ์ ๋ฌด์์
๋๊น? ํ๋ก๊ทธ๋จ์ด ์ด๋ค ์ํคํ
์ฒ๋ฅผ ์ํด ์์ฑ๋์๋์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ํ์คํ ๋งํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ seccomp์ ์ ์๋ arch
๊ตฌ์กฐ struct seccomp_data
). ์ํคํ
์ฒ๋ฅผ ํ์ธํ ๊ฒฝ์ฐ ์์ ์ ์์ ๋ถ๋ถ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
ld [4]
jne #0xc000003e, bad_arch ; SCMP_ARCH_X86_64
๊ทธ๋ฌ๋ฉด ์์คํ ํธ์ถ ๋ฒํธ๊ฐ ํน์ ๊ฐ์ ์ป๊ฒ ๋ฉ๋๋ค.
๋ค์์ ์ฌ์ฉํ์ฌ seccomp์ ๋ํ ํํฐ๋ฅผ ์์ฑํ๊ณ ๋ก๋ํฉ๋๋ค. libseccomp
๋ค์ดํฐ๋ธ ์ฝ๋ ๋๋ BPF ์ด์
๋ธ๋ฆฌ์ ํํฐ๋ฅผ ์์ฑํ๋ฉด ๊ฒฐ๊ณผ๋ฅผ ์์ ํ ์ ์ดํ ์ ์์ง๋ง ๋์์ ์ด์ ๊ฐ๋ฅํ๊ณ /๋๋ ์ฝ์ ์ ์๋ ์ฝ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ๋์ ๊ฒฝ์ฐ๋ ์์ต๋๋ค. ๋์๊ด์ด ์ฐ๋ฆฌ๋ฅผ ๋์์ค ๊ฑฐ์์
์๋ฅผ ๋ค์ด, ์ด์ ์ ์์คํ
ํธ์ถ ๋ธ๋๋ฆฌ์คํธ๋ฅผ ์ค์นํ ํ ์ฌ์ฉ์๊ฐ ์ ํํ ๋ฐ์ด๋๋ฆฌ ํ์ผ์ ์คํํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
#include <seccomp.h>
#include <unistd.h>
#include <err.h>
static int sys_numbers[] = {
__NR_mount,
__NR_umount2,
// ... ะตัะต 40 ัะธััะตะผะฝัั
ะฒัะทะพะฒะพะฒ ...
__NR_vmsplice,
__NR_perf_event_open,
};
int main(int argc, char **argv)
{
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
for (size_t i = 0; i < sizeof(sys_numbers)/sizeof(sys_numbers[0]); i++)
seccomp_rule_add(ctx, SCMP_ACT_TRAP, sys_numbers[i], 0);
seccomp_load(ctx);
execvp(argv[1], &argv[1]);
err(1, "execlp: %s", argv[1]);
}
๋จผ์ ๋ฐฐ์ด์ ์ ์ํฉ๋๋ค. sys_numbers
์ฐจ๋จํ ์์คํ
ํธ์ถ ๋ฒํธ๊ฐ 40๊ฐ ์ด์์
๋๋ค. ๊ทธ๋ฐ ๋ค์ ์ปจํ
์คํธ๋ฅผ ์ด๊ธฐํํฉ๋๋ค. ctx
๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๊ฐ ๋ฌด์์ ํ์ฉํ๊ณ ์ถ์์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ ค์ฃผ์ธ์(SCMP_ACT_ALLOW
) ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ ์์คํ
ํธ์ถ(๋ธ๋๋ฆฌ์คํธ๋ฅผ ์์ฑํ๋ ๊ฒ์ด ๋ ์ฝ์ต๋๋ค). ๊ทธ๋ฐ ๋ค์ ๋ธ๋๋ฆฌ์คํธ์ ๋ชจ๋ ์์คํ
ํธ์ถ์ ํ๋์ฉ ์ถ๊ฐํฉ๋๋ค. ๋ชฉ๋ก์ ์์คํ
ํธ์ถ์ ๋ํ ์๋ต์ผ๋ก ์ฐ๋ฆฌ๋ ๋ค์์ ์์ฒญํฉ๋๋ค. SCMP_ACT_TRAP
, ์ด ๊ฒฝ์ฐ seccomp๋ ํ๋ก์ธ์ค์ ์ ํธ๋ฅผ ๋ณด๋
๋๋ค. SIGSYS
์ด๋ค ์์คํ
ํธ์ถ์ด ๊ท์น์ ์๋ฐํ๋์ง์ ๋ํ ์ค๋ช
๊ณผ ํจ๊ป. ๋ง์ง๋ง์ผ๋ก ๋ค์์ ์ฌ์ฉํ์ฌ ํ๋ก๊ทธ๋จ์ ์ปค๋์ ๋ก๋ํฉ๋๋ค. seccomp_load
, ํ๋ก๊ทธ๋จ์ ์ปดํ์ผํ๊ณ ์์คํ
ํธ์ถ์ ์ฌ์ฉํ์ฌ ํ๋ก์ธ์ค์ ์ฐ๊ฒฐํฉ๋๋ค. seccomp(2)
.
์ฑ๊ณต์ ์ธ ์ปดํ์ผ์ ์ํด์๋ ํ๋ก๊ทธ๋จ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฐ๊ฒฐ๋์ด์ผ ํฉ๋๋ค. libseccomp
์ :
cc -std=c17 -Wall -Wextra -c -o seccomp_lib.o seccomp_lib.c
cc -o seccomp_lib seccomp_lib.o -lseccomp
์ฑ๊ณต์ ์ธ ์ถ์์ ์:
$ ./seccomp_lib echo ok
ok
์ฐจ๋จ๋ ์์คํ ํธ์ถ์ ์:
$ sudo ./seccomp_lib mount -t bpf bpf /tmp
Bad system call
์ฐ๋ฆฌ๋ ์ฌ์ฉ strace
์์ธํ ๋ด์ฉ์ ๋ค์์ ์ฐธ์กฐํ์ธ์.
$ sudo strace -e seccomp ./seccomp_lib mount -t bpf bpf /tmp
seccomp(SECCOMP_SET_MODE_FILTER, 0, {len=50, filter=0x55d8e78428e0}) = 0
--- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, si_call_addr=0xboobdeadbeef, si_syscall=__NR_mount, si_arch=AUDIT_ARCH_X86_64} ---
+++ killed by SIGSYS (core dumped) +++
Bad system call
๋ถ๋ฒ์ ์ธ ์์คํ
ํธ์ถ๋ก ์ธํด ํ๋ก๊ทธ๋จ์ด ์ข
๋ฃ๋์๋์ง ์ด๋ป๊ฒ ์ ์ ์๋์? mount(2)
.
๊ทธ๋์ ์ฐ๋ฆฌ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ํํฐ๋ฅผ ์์ฑํ์ต๋๋ค. libseccomp
, ์ฌ์ํ์ง ์์ ์ฝ๋๋ฅผ ๋ค ์ค์ ๋ง์ถ๋ ๊ฒ์
๋๋ค. ์์ ์์์ ์์คํ
ํธ์ถ์ด ๋ง์ ๊ฒฝ์ฐ์๋ ๋น๊ต ๋ชฉ๋ก์ ๋ถ๊ณผํ๋ฏ๋ก ์คํ ์๊ฐ์ด ๋์ ๋๊ฒ ์ค์ด๋ค ์ ์์ต๋๋ค. ์ต์ ํ๋ฅผ ์ํด libseccomp๋ ์ต๊ทผ SCMP_FLTATR_CTL_OPTIMIZE
. ์ด ์์ฑ์ 2๋ก ์ค์ ํ๋ฉด ํํฐ๊ฐ ์ด์ง ๊ฒ์ ํ๋ก๊ทธ๋จ์ผ๋ก ๋ณํ๋ฉ๋๋ค.
์ด์ง ๊ฒ์ ํํฐ๊ฐ ์ด๋ป๊ฒ ์๋ํ๋์ง ๋ณด๋ ค๋ฉด ๋ค์์ ์ดํด๋ณด์ธ์.
$ echo 1 3 6 8 13 | ./generate_bin_search_bpf.py
ld [0]
jeq #6, bad
jgt #6, check8
jeq #1, bad
jeq #3, bad
ret #0x7fff0000
check8:
jeq #8, bad
jeq #13, bad
ret #0x7fff0000
bad: ret #0
BPF ํ๋ก๊ทธ๋จ์ ๋ค์ฌ์ฐ๊ธฐ ์ ํ๋ฅผ ์ํํ ์ ์๊ธฐ ๋๋ฌธ์ ํจ์ฌ ๋ ๋น ๋ฅด๊ฒ ์์ฑํ ์๋ ์์ต๋๋ค(์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์์ต๋๋ค). jmp A
๋๋ jmp [label+X]
) ๋ฐ๋ผ์ ๋ชจ๋ ์ ํ์ ์ ์ ์
๋๋ค.
seccomp ๋ฐ strace
๋ชจ๋๊ฐ ์ ํธ๋ฆฌํฐ๋ฅผ ์๊ณ ์์ต๋๋ค. strace
Linux์์ ํ๋ก์ธ์ค์ ๋์์ ์ฐ๊ตฌํ๋ ๋ฐ ์์ด์๋ ์๋ ๋๊ตฌ์
๋๋ค. ๊ทธ๋ฌ๋ ๋ง์ ์ฌ๋๋ค์ด strace
์ฌ์ฉํ์ฌ ๊ตฌํ ptrace(2)
, ์ด ๋ฉ์ปค๋์ฆ์์๋ ํ๋ก์ธ์ค๋ฅผ ์ค์งํ๋ ๋ฐ ํ์ํ ์์คํ
ํธ์ถ ์ธํธ(์: ๋ช
๋ น)๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค.
$ time strace du /usr/share/ >/dev/null 2>&1
real 0m3.081s
user 0m0.531s
sys 0m2.073s
ะธ
$ time strace -e open du /usr/share/ >/dev/null 2>&1
real 0m2.404s
user 0m0.193s
sys 0m1.800s
๋ ๋ฒ์งธ ๊ฒฝ์ฐ์๋ ๋จ ํ๋์ ์์คํ ํธ์ถ๋ง ์ถ์ ํ๋ ค๊ณ ํ์ง๋ง ๊ฑฐ์ ๋์์ ์ฒ๋ฆฌ๋ฉ๋๋ค.
์๋ก์ด ์ต์
--seccomp-bpf
์ ์ถ๊ฐ strace
๋ฒ์ 5.3์ ์ฌ์ฉํ๋ฉด ํ๋ก์ธ์ค ์๋๋ฅผ ์ฌ๋ฌ ๋ฒ ๋์ผ ์ ์์ผ๋ฉฐ ํ๋์ ์์คํ
ํธ์ถ ์ถ์ ์ ๋ฐ๋ฅธ ์์ ์๊ฐ์ ์ด๋ฏธ ์ผ๋ฐ ์์ ์๊ฐ๊ณผ ๋น์ทํฉ๋๋ค.
$ time strace --seccomp-bpf -e open du /usr/share/ >/dev/null 2>&1
real 0m0.148s
user 0m0.017s
sys 0m0.131s
$ time du /usr/share/ >/dev/null 2>&1
real 0m0.140s
user 0m0.024s
sys 0m0.116s
(๋ฌผ๋ก ์ฌ๊ธฐ์๋ ์ด ๋ช
๋ น์ ๊ธฐ๋ณธ ์์คํ
ํธ์ถ์ ์ถ์ ํ์ง ์๋๋ค๋ ์ ์์ ์ฝ๊ฐ์ ์์์๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, newfsstat
, ๊ทธ๋ฐ ๋ค์ strace
์๋ ๊ฒ๋งํผ ์ธ๊ฒ ๋ธ๋ ์ดํฌ๋ฅผ ๋ฐ์ ๊ฒ์ด๋ค --seccomp-bpf
.)
์ด ์ต์
์ ์ด๋ป๊ฒ ์๋ํ๋์? ๊ทธ๋
์์ด strace
ํ๋ก์ธ์ค์ ์ฐ๊ฒฐํ๊ณ ๋ค์์ ์ฌ์ฉํ์ฌ ์์ํฉ๋๋ค. PTRACE_SYSCALL
. ๊ด๋ฆฌ๋๋ ํ๋ก์ธ์ค๊ฐ (๋ชจ๋ ) ์์คํ
ํธ์ถ์ ๋ฐํํ๋ฉด ์ ์ด๊ฐ ๋ค์ ํ๋ก์ธ์ค๋ก ์ด์ ๋ฉ๋๋ค. strace
, ์์คํ
ํธ์ถ์ ์ธ์๋ฅผ ์ดํด๋ณด๊ณ ๋ค์๊ณผ ๊ฐ์ด ์คํํฉ๋๋ค. PTRACE_SYSCALL
. ์ผ์ ์๊ฐ์ด ์ง๋ ํ ํ๋ก์ธ์ค๋ ์์คํ
ํธ์ถ์ ์๋ฃํ๊ณ ์ข
๋ฃํ๋ฉด ์ ์ด๊ฐ ๋ค์ ์ ์ก๋ฉ๋๋ค. strace
, ๋ฐํ ๊ฐ์ ๋ณด๊ณ ๋ค์์ ์ฌ์ฉํ์ฌ ํ๋ก์ธ์ค๋ฅผ ์์ํฉ๋๋ค. PTRACE_SYSCALL
, ๋ฑ๋ฑ.
๊ทธ๋ฌ๋ seccomp๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ํ๋ก์ธ์ค๋ฅผ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋๋ก ์ ํํ๊ฒ ์ต์ ํํ ์ ์์ต๋๋ค. ์ฆ, ์์คํ
์ฝ๋ง ๋ณด๊ณ ์ถ๋ค๋ฉด X
, ๊ทธ๋ฐ ๋ค์ BPF ํํฐ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. X
๊ฐ์ ๋ฐํ SECCOMP_RET_TRACE
, ๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ์๊ฒ ๊ด์ฌ์ด ์๋ ์ ํ์ ๊ฒฝ์ฐ - SECCOMP_RET_ALLOW
:
ld [0]
jneq #X, ignore
trace: ret #0x7ff00000
ignore: ret #0x7fff0000
์ด ๊ฒฝ์ฐ strace
์ฒ์์๋ ๋ค์๊ณผ ๊ฐ์ด ํ๋ก์ธ์ค๋ฅผ ์์ํฉ๋๋ค. PTRACE_CONT
, ์์คํ
ํธ์ถ์ด ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ ํํฐ๋ ๊ฐ ์์คํ
ํธ์ถ์ ๋ํด ์ฒ๋ฆฌ๋ฉ๋๋ค. X
, ํ๋ก์ธ์ค๋ ๊ณ์ ์คํ๋์ง๋ง, X
, seccomp๊ฐ ์ ์ด๊ถ์ ์ด์ ํฉ๋๋ค. strace
์ธ์๋ฅผ ๋ณด๊ณ ๋ค์๊ณผ ๊ฐ์ ํ๋ก์ธ์ค๋ฅผ ์์ํฉ๋๋ค. PTRACE_SYSCALL
(seccomp์๋ ์์คํ
ํธ์ถ ์ข
๋ฃ ์ ํ๋ก๊ทธ๋จ์ ์คํํ ์ ์๋ ๊ธฐ๋ฅ์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค.) ์์คํ
ํธ์ถ์ด ๋ฐํ๋๋ฉด strace
๋ค์์ ์ฌ์ฉํ์ฌ ํ๋ก์ธ์ค๋ฅผ ๋ค์ ์์ํฉ๋๋ค. PTRACE_CONT
seccomp์ ์ ๋ฉ์์ง๋ฅผ ๊ธฐ๋ค๋ฆฝ๋๋ค.
์ต์
์ฌ์ฉ์ --seccomp-bpf
๋ ๊ฐ์ง ์ ํ ์ฌํญ์ด ์์ต๋๋ค. ์ฒซ์งธ, ์ด๋ฏธ ์กด์ฌํ๋ ํ๋ก์ธ์ค์ ์ฐธ์ฌํ ์ ์์ต๋๋ค(์ต์
-p
ํ๋ก๊ทธ๋จ strace
), ์ด๋ seccomp์์ ์ง์๋์ง ์๊ธฐ ๋๋ฌธ์
๋๋ค. ๋์งธ, ๊ฐ๋ฅ์ฑ์ด ์๋ค ์๋ ํ์ ํ๋ก์ธ์ค๋ฅผ ์ดํด๋ณด์ญ์์ค. seccomp ํํฐ๋ ์ด๋ฅผ ๋นํ์ฑํํ ์ ์๋ ๊ธฐ๋ฅ ์์ด ๋ชจ๋ ํ์ ํ๋ก์ธ์ค์ ์ํด ์์๋๊ธฐ ๋๋ฌธ์
๋๋ค.
์ ํํ ์ด๋ป๊ฒ ๋๋์ง ์ข ๋ ์์ธํ strace
์ ์ผํ๋ค seccomp
์์ ์ฐพ์ ์ ์์ต๋๋ค
xt_bpf
์ด์ ๋คํธ์ํฌ์ ์ธ๊ณ๋ก ๋์๊ฐ ๋ณด๊ฒ ์ต๋๋ค.
๋ฐฐ๊ฒฝ: ์ค๋์ ์ธ 2007๋
์ ํต์ฌ์ xt_u32
๋ทํํฐ์ฉ. ํจ์ฌ ๋ ์ค๋๋ ํธ๋ํฝ ๋ถ๋ฅ๊ธฐ์ ์ ์ฌํ๊ฒ ์์ฑ๋์์ต๋๋ค. cls_u32
๋ค์๊ณผ ๊ฐ์ ๊ฐ๋จํ ์์
์ ์ฌ์ฉํ์ฌ iptables์ ๋ํ ์์์ ์ด์ง ๊ท์น์ ์์ฑํ ์ ์์ต๋๋ค. ํจํค์ง์์ 32๋นํธ๋ฅผ ๋ก๋ํ๊ณ ์ด์ ๋ํด ์ผ๋ จ์ ์ฐ์ ์์
์ ์ํํฉ๋๋ค. ์๋ฅผ ๋ค์ด,
sudo iptables -A INPUT -m u32 --u32 "6&0xFF=1" -j LOG --log-prefix "seen-by-xt_u32"
ํจ๋ฉ 32๋ถํฐ ์์ํ์ฌ IP ํค๋์ 6๋นํธ๋ฅผ ๋ก๋ํ๊ณ ์ฌ๊ธฐ์ ๋ง์คํฌ๋ฅผ ์ ์ฉํฉ๋๋ค. 0xFF
(๋ฎ์ ๋ฐ์ดํธ๋ฅผ ์ทจํจ) ์ด ํ๋ protocol
IP ํค๋๋ฅผ 1(ICMP)๊ณผ ๋น๊ตํฉ๋๋ค. ์ฌ๋ฌ ๊ฒ์ฌ๋ฅผ ํ๋์ ๊ท์น์ผ๋ก ๊ฒฐํฉํ ์ ์์ผ๋ฉฐ ์ฐ์ฐ์๋ฅผ ์คํํ ์๋ ์์ต๋๋ค. @
โ X๋ฐ์ดํธ๋ฅผ ์ค๋ฅธ์ชฝ์ผ๋ก ์ด๋ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๊ท์น
iptables -m u32 --u32 "6&0xFF=0x6 && 0>>22&0x3C@4=0x29"
TCP ์ํ์ค ๋ฒํธ๊ฐ ๊ฐ์ง ์์์ง ํ์ธํฉ๋๋ค. 0x29
. ๊ทธ๋ฌํ ๊ท์น์ ์ง์ ์์ฑํ๋ ๊ฒ์ด ๊ทธ๋ค์ง ํธ๋ฆฌํ์ง ์๋ค๋ ๊ฒ์ด ์ด๋ฏธ ๋ถ๋ช
ํ๊ธฐ ๋๋ฌธ์ ๋ ์์ธํ ์ค๋ช
ํ์ง ์๊ฒ ์ต๋๋ค. ๊ธฐ์ฌ์์ xt_u32
. ์ด ๊ธ ๋ง์ง๋ง์ ์๋ ๋งํฌ๋ ์ฐธ์กฐํ์ธ์.
2013๋
๋ถํฐ ๋ชจ๋ ๋์ ๋ชจ๋ xt_u32
BPF ๊ธฐ๋ฐ ๋ชจ๋์ ์ฌ์ฉํ ์ ์์ต๋๋ค xt_bpf
. ์ฌ๊ธฐ๊น์ง ์ฝ์ ์ฌ๋์ด๋ผ๋ฉด ๋๊ตฌ๋ BPF ๋ฐ์ดํธ์ฝ๋๋ฅผ iptables ๊ท์น์ผ๋ก ์คํํ๋ ์๋ ์๋ฆฌ์ ๋ํด ์ด๋ฏธ ๋ช
ํํ๊ฒ ์๊ณ ์์ ๊ฒ์
๋๋ค. ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ด ์ ๊ท์น์ ๋ง๋ค ์ ์์ต๋๋ค.
iptables -A INPUT -m bpf --bytecode <ะฑะฐะนัะบะพะด> -j LOG
์ฌ๊ธฐ์ <ะฑะฐะนัะบะพะด>
- ์ด๊ฒ์ ์ด์
๋ธ๋ฌ ์ถ๋ ฅ ํ์์ ์ฝ๋์
๋๋ค. bpf_asm
์๋ฅผ ๋ค์ด ๊ธฐ๋ณธ์ ์ผ๋ก
$ cat /tmp/test.bpf
ldb [9]
jneq #17, ignore
ret #1
ignore: ret #0
$ bpf_asm /tmp/test.bpf
4,48 0 0 9,21 0 1 17,6 0 0 1,6 0 0 0,
# iptables -A INPUT -m bpf --bytecode "$(bpf_asm /tmp/test.bpf)" -j LOG
์ด ์์์๋ ๋ชจ๋ UDP ํจํท์ ํํฐ๋งํฉ๋๋ค. ๋ชจ๋์ BPF ํ๋ก๊ทธ๋จ์ ๋ํ ์ปจํ
์คํธ xt_bpf
๋ ๋ฌผ๋ก iptables์ ๊ฒฝ์ฐ IPv4 ํค๋์ ์์ ๋ถ๋ถ์ ๊ฐ๋ฆฌํค๋ ํจํท ๋ฐ์ดํฐ๋ฅผ ๊ฐ๋ฆฌํต๋๋ค. BPF ํ๋ก๊ทธ๋จ์ ๋ฐํ ๊ฐ false
ํจํท์ด ์ผ์นํ์ง ์์์ ์๋ฏธํฉ๋๋ค.
๋ชจ๋์ด ๋ถ๋ช
ํฉ๋๋ค. xt_bpf
์์ ์๋ณด๋ค ๋ ๋ณต์กํ ํํฐ๋ฅผ ์ง์ํฉ๋๋ค. Cloudfare์ ์ค์ ์ฌ๋ก๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์ต๊ทผ๊น์ง ๊ทธ๋ค์ ๋ชจ๋์ ์ฌ์ฉํ์ต๋๋ค. xt_bpf
DDoS ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ณดํธํฉ๋๋ค. ๊ธฐ์ฌ์์ bpfgen
์ด๋ฆ์ ๋ํ DNS ์ฟผ๋ฆฌ์ ์ผ์นํ๋ BPF ํ๋ก๊ทธ๋จ์ ๋ง๋ค ์ ์์ต๋๋ค habr.com
:
$ ./bpfgen --assembly dns -- habr.com
ldx 4*([0]&0xf)
ld #20
add x
tax
lb_0:
ld [x + 0]
jneq #0x04686162, lb_1
ld [x + 4]
jneq #0x7203636f, lb_1
ldh [x + 8]
jneq #0x6d00, lb_1
ret #65535
lb_1:
ret #0
ํ๋ก๊ทธ๋จ์์ ๋จผ์ ๋ ์ง์คํฐ์ ๋ก๋ํฉ๋๋ค. X
์ค ์ฃผ์์ ์์ x04habrx03comx00
UDP ๋ฐ์ดํฐ๊ทธ๋จ ๋ด๋ถ์์ ์์ฒญ์ ํ์ธํฉ๋๋ค. 0x04686162 <-> "x04hab"
๊ธฐํ
์ ์ ํ Cloudfare๋ p0f -> BPF ์ปดํ์ผ๋ฌ ์ฝ๋๋ฅผ ๊ฒ์ํ์ต๋๋ค. ๊ธฐ์ฌ์์
$ ./bpfgen p0f -- 4:64:0:0:*,0::ack+:0
39,0 0 0 0,48 0 0 8,37 35 0 64,37 0 34 29,48 0 0 0,
84 0 0 15,21 0 31 5,48 0 0 9,21 0 29 6,40 0 0 6,
...
ํ์ฌ ๋ ์ด์ Cloudfare๋ฅผ ์ฌ์ฉํ์ง ์์ต๋๋ค. xt_bpf
, ์๋ก์ด ๋ฒ์ ์ BPF๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ์ต์
์ค ํ๋์ธ XDP๋ก ์ด๋ํ๊ธฐ ๋๋ฌธ์ ์ฐธ์กฐํ์ธ์.
cls_bpf
์ปค๋์์ ํด๋์ BPF๋ฅผ ์ฌ์ฉํ๋ ๋ง์ง๋ง ์๋ ๋ถ๋ฅ์์
๋๋ค. cls_bpf
Linux์ ํธ๋ํฝ ์ ์ด ํ์ ์์คํ
์ฉ์ผ๋ก 2013๋
๋ง์ Linux์ ์ถ๊ฐ๋์์ผ๋ฉฐ ๊ฐ๋
์ ์ผ๋ก ๊ณ ๋ ํ์ ์์คํ
์ ๋์ฒดํฉ๋๋ค. cls_u32
.
ํ์ง๋ง ์ง๊ธ์ ์ํ์ ๋ํด ์ค๋ช
ํ์ง ์๊ฒ ์ต๋๋ค. cls_bpf
, ํด๋์ BPF์ ๋ํ ์ง์์ ๊ด์ ์์ ๋ณผ ๋ ์ด๊ฒ์ ์ฐ๋ฆฌ์๊ฒ ์๋ฌด๊ฒ๋ ์ ๊ณตํ์ง ์๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๋ ์ด๋ฏธ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ต์ํด์ก์ต๋๋ค. ๋ํ ํ์ฅ BPF์ ๋ํด ์ค๋ช
ํ๋ ํ์ ๊ธฐ์ฌ์์๋ ์ด ๋ถ๋ฅ์๋ฅผ ๋ ๋ฒ ์ด์ ๋ง๋ ๊ฒ์
๋๋ค.
ํด๋์ BPF c ์ฌ์ฉ์ ๋ํด ์ด์ผ๊ธฐํ์ง ์๋ ๋ ๋ค๋ฅธ ์ด์ cls_bpf
๋ฌธ์ ๋ ํ์ฅ BPF์ ๋น๊ตํ ๋ ์ด ๊ฒฝ์ฐ ์ ์ฉ ๋ฒ์๊ฐ ๊ทผ๋ณธ์ ์ผ๋ก ์ข์์ง๋ค๋ ๊ฒ์
๋๋ค. ๊ธฐ์กด ํ๋ก๊ทธ๋จ์ ํจํค์ง์ ๋ด์ฉ์ ๋ณ๊ฒฝํ ์ ์์ผ๋ฉฐ ํธ์ถ ๊ฐ์ ์ํ๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค.
์ด์ ํด๋์ BPF์ ์๋ณ์ ๊ณ ํ๊ณ ๋ฏธ๋๋ฅผ ๋ฐ๋ผ๋ณผ ๋์ ๋๋ค.
ํด๋์ BPF์ ์๋ณ
์ฐ๋ฆฌ๋ 32๋
๋ ์ด๋ฐ์ ๊ฐ๋ฐ๋ BPF ๊ธฐ์ ์ด ์ด๋ป๊ฒ 64๋
๋์ ์ฑ๊ณต์ ์ผ๋ก ์ด์๋จ์๊ณ ๋ง์ง๋ง๊น์ง ์๋ก์ด ์์ฉ ๋ถ์ผ๋ฅผ ์ฐพ์๋์ง ์ดํด๋ณด์์ต๋๋ค. ๊ทธ๋ฌ๋ ์คํ ๋จธ์ ์์ RISC๋ก์ ์ ํ์ด ํด๋์ BPF ๊ฐ๋ฐ์ ์๋๋ ฅ์ด ๋์๋ ๊ฒ์ฒ๋ผ, XNUMX๋
๋์๋ XNUMX๋นํธ ๋จธ์ ์์ XNUMX๋นํธ ๋จธ์ ์ผ๋ก์ ์ ํ์ด ์์๊ณ ํด๋์ BPF๋ ์ธ๋ชจ์๊ฒ ๋๊ธฐ ์์ํ์ต๋๋ค. ๋ํ ํด๋์ BPF์ ๊ธฐ๋ฅ์ ๋งค์ฐ ์ ํ์ ์ด๋ฉฐ ์ค๋๋ ์ํคํ
์ฒ ์ธ์๋ BPF ํ๋ก๊ทธ๋จ ํธ์ถ ์ฌ์ด์ ์ํ๋ฅผ ์ ์ฅํ๋ ๊ธฐ๋ฅ์ด ์์ผ๋ฉฐ ์ง์ ์ ์ธ ์ฌ์ฉ์ ์ํธ ์์ฉ ๊ฐ๋ฅ์ฑ์ด ์์ผ๋ฉฐ ์ํธ ์์ฉํ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค. ์ ํ๋ ์์ ๊ตฌ์กฐ ํ๋๋ฅผ ์ฝ๋ ๊ฒ์ ์ ์ธํ๊ณ ์ปค๋๊ณผ ํจ๊ป sk_buff
๊ฐ์ฅ ๊ฐ๋จํ ๋์ฐ๋ฏธ ๊ธฐ๋ฅ์ ์คํํ๋ฉด ํจํท์ ๋ด์ฉ์ ๋ณ๊ฒฝํ๊ณ ๋ฆฌ๋๋ ์
ํ ์ ์์ต๋๋ค.
์ค์ ๋ก ํ์ฌ Linux์ ๋จ์ ์๋ ํด๋์ BPF๋ API ์ธํฐํ์ด์ค๋ฟ์ ๋๋ค. ์ปค๋ ๋ด๋ถ์์๋ ์์ผ ํํฐ๋ seccomp ํํฐ ๋ฑ ๋ชจ๋ ํด๋์ ํ๋ก๊ทธ๋จ์ด ์๋์ผ๋ก ์๋ก์ด ํ์์ธ ํ์ฅ BPF๋ก ๋ณํ๋ฉ๋๋ค. (์ด๊ฒ์ด ์ด๋ป๊ฒ ๋ฐ์ํ๋์ง์ ๋ํด์๋ ๋ค์ ๊ธฐ์ฌ์์ ์์ธํ ์ค๋ช ํ๊ฒ ์ต๋๋ค.)
์๋ก์ด ์ํคํ
์ฒ๋ก์ ์ ํ์ Alexey Starovoitov๊ฐ BPF ์
๋ฐ์ดํธ ์ฒด๊ณ๋ฅผ ์ ์ํ 2013๋
์ ์์๋์์ต๋๋ค. 2014๋
์ ํด๋น ํจ์น
์ด ์๋ฆฌ์ฆ์ ์ถ๊ฐ ๊ธฐ์ฌ์์๋ ์ฒ์์๋ ๋ด๋ถ BPF, ํ์ฅ BPF, ์ง๊ธ์ ๋จ์ํ BPF๋ก ์๋ ค์ง ์๋ก์ด ๊ธฐ์ ์ ์ํคํ ์ฒ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค๋ฃฐ ๊ฒ์ ๋๋ค.
์ฐธ์กฐ
- Steven McCanne ๋ฐ Van Jacobson, "BSD ํจํท ํํฐ: ์ฌ์ฉ์ ์์ค ํจํท ์บก์ฒ๋ฅผ ์ํ ์๋ก์ด ์ํคํ
์ฒ",
https://www.tcpdump.org/papers/bpf-usenix93.pdf
- Steven McCanne, "libpcap: ํจํท ์บก์ฒ๋ฅผ ์ํ ์ํคํ
์ฒ ๋ฐ ์ต์ ํ ๋ฐฉ๋ฒ๋ก ",
https://sharkfestus.wireshark.org/sharkfest.11/presentations/McCanne-Sharkfest'11_Keynote_Address.pdf
tcpdump
,libpcap
:https://www.tcpdump.org/ IPtable U32 ๊ฒฝ๊ธฐ ํํ ๋ฆฌ์ผ .- BPF - ์ํ์ง ๋ฐ์ดํธ์ฝ๋:
https://blog.cloudflare.com/bpf-the-forgotten-bytecode/
- BPF ๋๊ตฌ ์๊ฐ:
https://blog.cloudflare.com/introducing-the-bpf-tools/
bpf_cls
:http://man7.org/linux/man-pages/man8/tc-bpf.8.html
- seccomp ๊ฐ์:
https://lwn.net/Articles/656307/
https://github.com/torvalds/linux/blob/master/Documentation/userspace-api/seccomp_filter.rst
habr: ์ปจํ ์ด๋ ๋ฐ ๋ณด์: seccomp habr: systemd๋ก ๋ฐ๋ชฌ์ ๊ฒฉ๋ฆฌํ๊ฑฐ๋ "์ด ์์ ์๋ Docker๊ฐ ํ์ํ์ง ์์ต๋๋ค!" - Paul Chaignon, "strace --seccomp-bpf: ๋ด๋ถ ์ดํด๋ณด๊ธฐ",
https://fosdem.org/2020/schedule/event/debugging_strace_bpf/
netsniff-ng
:http://netsniff-ng.org/
์ถ์ฒ : habr.com