์šฐ๋ฆฌ๋Š” XDP์— ๋Œ€ํ•œ DDoS ๊ณต๊ฒฉ์— ๋Œ€ํ•œ ๋ณดํ˜ธ ๊ธฐ๋Šฅ์„ ์ž‘์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•ต ๋ถ€๋ถ„

eXpress Data Path(XDP) ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๋ฉด ํŒจํ‚ท์ด ์ปค๋„ ๋„คํŠธ์›Œํฌ ์Šคํƒ์— ๋“ค์–ด๊ฐ€๊ธฐ ์ „์— Linux ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์ž„์˜ ํŠธ๋ž˜ํ”ฝ ์ฒ˜๋ฆฌ๊ฐ€ ์ˆ˜ํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. XDP ์ ์šฉ - DDoS ๊ณต๊ฒฉ(CloudFlare), ๋ณต์žกํ•œ ํ•„ํ„ฐ, ํ†ต๊ณ„ ์ˆ˜์ง‘(Netflix)์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•ฉ๋‹ˆ๋‹ค. XDP ํ”„๋กœ๊ทธ๋žจ์€ eBPF ๊ฐ€์ƒ ๋จธ์‹ ์— ์˜ํ•ด ์‹คํ–‰๋˜๋ฏ€๋กœ ํ•„ํ„ฐ ์œ ํ˜•์— ๋”ฐ๋ผ ์ฝ”๋“œ์™€ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปค๋„ ๊ธฐ๋Šฅ ๋ชจ๋‘์— ์ œํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ธฐ์‚ฌ๋Š” XDP์˜ ์ˆ˜๋งŽ์€ ์ž๋ฃŒ์˜ ๋‹จ์ ์„ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ฒซ์งธ, XDP์˜ ๊ธฐ๋Šฅ์„ ์ฆ‰์‹œ ์šฐํšŒํ•˜๋Š” ๊ธฐ์„ฑ ์ฝ”๋“œ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ฒ€์ฆ์„ ์œ„ํ•ด ์ค€๋น„๋˜์—ˆ๊ฑฐ๋‚˜ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค๊ธฐ์—๋Š” ๋„ˆ๋ฌด ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ฒ˜์Œ๋ถ€ํ„ฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์ผ๋ฐ˜์ ์ธ ์˜ค๋ฅ˜๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ์ง€ ์ „ํ˜€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‘˜์งธ, ์ž์ฒด์ ์ธ ํ•จ์ •์ด ์žˆ์Œ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  VM ๋ฐ ํ•˜๋“œ์›จ์–ด ์—†์ด ๋กœ์ปฌ์—์„œ XDP๋ฅผ ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ํ…์ŠคํŠธ๋Š” ๋„คํŠธ์›Œํ‚น ๋ฐ Linux์— ์ต์ˆ™ํ•˜๊ณ  XDP ๋ฐ eBPF์— ๊ด€์‹ฌ์ด ์žˆ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ถ€๋ถ„์—์„œ๋Š” XDP ํ•„ํ„ฐ๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ตฌ์„ฑ๋˜๊ณ  ํ…Œ์ŠคํŠธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ž์„ธํžˆ ์ดํ•ดํ•œ ๋‹ค์Œ ํŒจํ‚ท ์ฒ˜๋ฆฌ ์ˆ˜์ค€์—์„œ ์ž˜ ์•Œ๋ ค์ง„ SYN ์ฟ ํ‚ค ๋ฉ”์ปค๋‹ˆ์ฆ˜์˜ ๊ฐ„๋‹จํ•œ ๋ฒ„์ „์„ ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์•„์ง "ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ"๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค
๊ฒ€์ฆ๋œ ํด๋ผ์ด์–ธํŠธ, ์นด์šดํ„ฐ ์œ ์ง€ ๋ฐ ํ•„ํ„ฐ ๊ด€๋ฆฌ - ์ถฉ๋ถ„ํ•œ ๋กœ๊ทธ.

์šฐ๋ฆฌ๋Š” C๋กœ ์ž‘์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์œ ํ–‰์€ ์•„๋‹ˆ์ง€๋งŒ ์‹ค์šฉ์ ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฝ”๋“œ๋Š” ๋งˆ์ง€๋ง‰ ๋งํฌ๋ฅผ ํ†ตํ•ด GitHub์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ธฐ์‚ฌ์— ์„ค๋ช…๋œ ๋‹จ๊ณ„์— ๋”ฐ๋ผ ์ปค๋ฐ‹์œผ๋กœ ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.

๋ถ€์ธ ์„ฑ๋ช…. ์ด ๊ธฐ์‚ฌ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ DDoS ๊ณต๊ฒฉ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋ฏธ๋‹ˆ ์†”๋ฃจ์…˜์„ ๊ฐœ๋ฐœํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” XDP์™€ ์ œ ์ „๋ฌธ ๋ถ„์•ผ์— ๋Œ€ํ•œ ํ˜„์‹ค์ ์ธ ์ž‘์—…์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ฃผ์š” ๋ชฉํ‘œ๋Š” ๊ธฐ์ˆ ์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด๋ฉฐ ์ด๋Š” ๊ธฐ์„ฑ ๋ณดํ˜ธ ์žฅ์น˜๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ๋Œ€ํ•œ ์ง€์นจ์ด ์•„๋‹™๋‹ˆ๋‹ค. ํŠœํ† ๋ฆฌ์–ผ ์ฝ”๋“œ๋Š” ์ตœ์ ํ™”๋˜์ง€ ์•Š์•˜์œผ๋ฉฐ ์•ฝ๊ฐ„์˜ ๋‰˜์•™์Šค๊ฐ€ ์ƒ๋žต๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

XDP ๊ฐœ์š”

๋ฌธ์„œ์™€ ๊ธฐ์กด ๊ธฐ์‚ฌ๊ฐ€ ์ค‘๋ณต๋˜์ง€ ์•Š๋„๋ก ํ•ต์‹ฌ ์‚ฌํ•ญ๋งŒ ๊ฐ„๋žตํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ํ•„ํ„ฐ ์ฝ”๋“œ๊ฐ€ ์ปค๋„์— ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ๋“ค์–ด์˜ค๋Š” ํŒจํ‚ท์€ ํ•„ํ„ฐ๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ•„ํ„ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ์ •์„ ๋‚ด๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํŒจํ‚ท์„ ์ปค๋„๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค(XDP_PASS), ํŒจํ‚ท ์‚ญ์ œ(XDP_DROP) ๋˜๋Š” ๋‹ค์‹œ ๋ณด๋‚ด์‹ญ์‹œ์˜ค(XDP_TX). ํ•„ํ„ฐ๋Š” ํŒจํ‚ค์ง€๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ํŠนํžˆ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ์— ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค. XDP_TX. ํ”„๋กœ๊ทธ๋žจ์„ ์ค‘๋‹จํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค(XDP_ABORTED) ํŒจํ‚ค์ง€๋ฅผ ์žฌ์„ค์ •ํ•˜์ง€๋งŒ ์ด๋Š” ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. assert(0) - ๋””๋ฒ„๊น…์„ ์œ„ํ•ด.

eBPF(extended Berkley Packet Filter) ๊ฐ€์ƒ ๋จธ์‹ ์€ ์ฝ”๋“œ๊ฐ€ ๋ฐ˜๋ณต๋˜์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ์‚ฌ๋žŒ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์†์ƒ์‹œํ‚ค์ง€ ์•Š๋Š”์ง€ ์ปค๋„์ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ์˜๋„์ ์œผ๋กœ ๋‹จ์ˆœํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ๋ˆ„์  ์ œํ•œ ๋ฐ ๊ฒ€์‚ฌ:

  • ๋ฃจํ”„(์—ญ๋ฐฉํ–ฅ)๋Š” ๊ธˆ์ง€๋ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ์šฉ ์Šคํƒ์€ ์žˆ์ง€๋งŒ ํ•จ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค(๋ชจ๋“  C ํ•จ์ˆ˜๋Š” ์ธ๋ผ์ธ๋˜์–ด์•ผ ํ•จ).
  • ์Šคํƒ ๋ฐ ํŒจํ‚ท ๋ฒ„ํผ ์™ธ๋ถ€์˜ ๋ฉ”๋ชจ๋ฆฌ ์•ก์„ธ์Šค๋Š” ๊ธˆ์ง€๋ฉ๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ํฌ๊ธฐ๋Š” ์ œํ•œ๋˜์–ด ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๊ทธ๋‹ค์ง€ ์ค‘์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ํŠน์ˆ˜ ์ปค๋„ ํ•จ์ˆ˜(eBPF ๋„์šฐ๋ฏธ)์— ๋Œ€ํ•œ ํ˜ธ์ถœ๋งŒ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค.

ํ•„ํ„ฐ๋ฅผ ์„ค๊ณ„ํ•˜๊ณ  ์„ค์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ์†Œ์Šค ์ฝ”๋“œ(์˜ˆ: kernel.c)๋Š” ๊ฐ์ฒด(kernel.o) eBPF ๊ฐ€์ƒ ๋จธ์‹  ์•„ํ‚คํ…์ฒ˜์˜ ๊ฒฝ์šฐ. 2019๋…„ 10.1์›” ํ˜„์žฌ eBPF ์ปดํŒŒ์ผ์€ Clang์—์„œ ์ง€์›๋˜๋ฉฐ GCC XNUMX์—์„œ ์•ฝ์†๋ฉ๋‹ˆ๋‹ค.
  2. ์ด ๊ฐœ์ฒด ์ฝ”๋“œ์— ์ปค๋„ ๊ตฌ์กฐ(์˜ˆ: ํ…Œ์ด๋ธ” ๋ฐ ์นด์šดํ„ฐ)์— ๋Œ€ํ•œ ํ˜ธ์ถœ์ด ํฌํ•จ๋œ ๊ฒฝ์šฐ ํ•ด๋‹น ID๋Š” XNUMX์œผ๋กœ ๋Œ€์ฒด๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ•ด๋‹น ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ปค๋„์— ๋กœ๋“œํ•˜๊ธฐ ์ „์— ์ด๋Ÿฌํ•œ XNUMX์„ ์ปค๋„ ํ˜ธ์ถœ(์ฝ”๋“œ ๋งํฌ)์„ ํ†ตํ•ด ์ƒ์„ฑ๋œ ํŠน์ • ๊ฐœ์ฒด์˜ ID๋กœ ๋ฐ”๊ฟ”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์™ธ๋ถ€ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ๊ณ  ํŠน์ • ํ•„ํ„ฐ๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  ๋กœ๋“œํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ์ปค๋„์€ ๋กœ๋“œ๋œ ํ”„๋กœ๊ทธ๋žจ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ฃผ๊ธฐ๊ฐ€ ์—†๊ณ  ํŒจํ‚ท ๋ฐ ์Šคํƒ ๊ฒฝ๊ณ„๋ฅผ ์ดˆ๊ณผํ•˜์ง€ ๋ชปํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ฒ€์ฆ์ž๊ฐ€ ์ฝ”๋“œ๊ฐ€ ์ •ํ™•ํ•˜๋‹ค๋Š” ๊ฒƒ์„ ์ฆ๋ช…ํ•  ์ˆ˜ ์—†์œผ๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ๊ฑฐ๋ถ€๋ฉ๋‹ˆ๋‹ค. ๊ฒ€์ฆ์ž๋ฅผ ๊ธฐ์˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  4. ์„ฑ๊ณต์ ์œผ๋กœ ๊ฒ€์ฆ๋œ ํ›„ ์ปค๋„์€ eBPF ์•„ํ‚คํ…์ฒ˜ ๊ฐœ์ฒด ์ฝ”๋“œ๋ฅผ ์‹œ์Šคํ…œ ์•„ํ‚คํ…์ฒ˜์šฉ ๊ธฐ๊ณ„์–ด ์ฝ”๋“œ(์ ์‹œ)๋กœ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค.
  5. ํ”„๋กœ๊ทธ๋žจ์ด ์ธํ„ฐํŽ˜์ด์Šค์— ์—ฐ๊ฒฐ๋˜๊ณ  ํŒจํ‚ท ์ฒ˜๋ฆฌ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

XDP๋Š” ์ปค๋„์—์„œ ์‹คํ–‰๋˜๋ฏ€๋กœ ์ถ”์  ๋กœ๊ทธ์™€ ์‹ค์ œ๋กœ ํ”„๋กœ๊ทธ๋žจ์ด ํ•„ํ„ฐ๋งํ•˜๊ฑฐ๋‚˜ ์ƒ์„ฑํ•˜๋Š” ํŒจํ‚ท์„ ์‚ฌ์šฉํ•˜์—ฌ ๋””๋ฒ„๊น…์ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ eBPF๋Š” ๋‹ค์šด๋กœ๋“œํ•œ ์ฝ”๋“œ๊ฐ€ ์‹œ์Šคํ…œ์— ๋Œ€ํ•ด ์•ˆ์ „ํ•œ์ง€ ํ™•์ธํ•˜๋ฏ€๋กœ ๋กœ์ปฌ Linux์—์„œ ์ง์ ‘ XDP๋ฅผ ์‹คํ—˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ™˜๊ฒฝ ์ค€๋น„

์กฐ๋ฆฝ

Clang์€ eBPF ์•„ํ‚คํ…์ฒ˜์— ๋Œ€ํ•œ ๊ฐ์ฒด ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ํ”„๋กœ์„ธ์Šค๋Š” ๋‹ค์Œ ๋‘ ๋‹จ๊ณ„๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค.

  1. C ์ฝ”๋“œ๋ฅผ LLVM ๋ฐ”์ดํŠธ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผํ•ฉ๋‹ˆ๋‹ค(clang -emit-llvm).
  2. ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ eBPF ๊ฐ์ฒด ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜(llc -march=bpf -filetype=obj).

ํ•„ํ„ฐ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ๋ณด์กฐ ๊ธฐ๋Šฅ๊ณผ ๋งคํฌ๋กœ๊ฐ€ ํฌํ•จ๋œ ๋ช‡ ๊ฐœ์˜ ํŒŒ์ผ์ด ์œ ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ปค๋„ ํ…Œ์ŠคํŠธ์—์„œ. ์ปค๋„ ๋ฒ„์ „(KVER). ๋‹ค์Œ ์œ„์น˜์— ๋‹ค์šด๋กœ๋“œํ•˜์„ธ์š”. helpers/:

export KVER=v5.3.7
export BASE=https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/plain/tools/testing/selftests/bpf
wget -P helpers --content-disposition "${BASE}/bpf_helpers.h?h=${KVER}" "${BASE}/bpf_endian.h?h=${KVER}"
unset KVER BASE

Arch Linux์šฉ Makefile(์ปค๋„ 5.3.7):

CLANG ?= clang
LLC ?= llc

KDIR ?= /lib/modules/$(shell uname -r)/build
ARCH ?= $(subst x86_64,x86,$(shell uname -m))

CFLAGS = 
    -Ihelpers 
    
    -I$(KDIR)/include 
    -I$(KDIR)/include/uapi 
    -I$(KDIR)/include/generated/uapi 
    -I$(KDIR)/arch/$(ARCH)/include 
    -I$(KDIR)/arch/$(ARCH)/include/generated 
    -I$(KDIR)/arch/$(ARCH)/include/uapi 
    -I$(KDIR)/arch/$(ARCH)/include/generated/uapi 
    -D__KERNEL__ 
    
    -fno-stack-protector -O2 -g

xdp_%.o: xdp_%.c Makefile
    $(CLANG) -c -emit-llvm $(CFLAGS) $< -o - | 
    $(LLC) -march=bpf -filetype=obj -o $@

.PHONY: all clean

all: xdp_filter.o

clean:
    rm -f ./*.o

KDIR ์ปค๋„ ํ—ค๋”์— ๋Œ€ํ•œ ๊ฒฝ๋กœ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ARCH - ์‹œ์Šคํ…œ ๊ตฌ์กฐ. ๊ฒฝ๋กœ์™€ ๋„๊ตฌ๋Š” ๋ฐฐํฌํŒ๋งˆ๋‹ค ์•ฝ๊ฐ„ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Debian 10(์ปค๋„ 4.19.67)์˜ ์ฐจ์ด์  ์˜ˆ

# ะดั€ัƒะณะฐั ะบะพะผะฐะฝะดะฐ
CLANG ?= clang
LLC ?= llc-7

# ะดั€ัƒะณะพะน ะบะฐั‚ะฐะปะพะณ
KDIR ?= /usr/src/linux-headers-$(shell uname -r)
ARCH ?= $(subst x86_64,x86,$(shell uname -m))

# ะดะฒะฐ ะดะพะฟะพะปะฝะธั‚ะตะปัŒะฝั‹ั… ะบะฐั‚ะฐะปะพะณะฐ -I
CFLAGS = 
    -Ihelpers 
    
    -I/usr/src/linux-headers-4.19.0-6-common/include 
    -I/usr/src/linux-headers-4.19.0-6-common/arch/$(ARCH)/include 
    # ะดะฐะปะตะต ะฑะตะท ะธะทะผะตะฝะตะฝะธะน

CFLAGS ๋ณด์กฐ ํ—ค๋”๊ฐ€ ์žˆ๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ ์ปค๋„ ํ—ค๋”๊ฐ€ ์žˆ๋Š” ์—ฌ๋Ÿฌ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ƒ์ง• __KERNEL__ ํ•„ํ„ฐ๊ฐ€ ์ปค๋„์—์„œ ์‹คํ–‰๋˜๋ฏ€๋กœ UAPI(์‚ฌ์šฉ์ž ๊ณต๊ฐ„ API) ํ—ค๋”๊ฐ€ ์ปค๋„ ์ฝ”๋“œ์— ์ •์˜๋˜์–ด ์žˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์Šคํƒ ๋ณดํ˜ธ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(-fno-stack-protector), eBPF ์ฝ”๋“œ ๊ฒ€์ฆ๊ธฐ๋Š” ์—ฌ์ „ํžˆ ์Šคํƒ ๋ฒ”์œ„ ์œ„๋ฐ˜ ์œ„๋ฐ˜์„ ํ™•์ธํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. eBPF ๋ฐ”์ดํŠธ์ฝ”๋“œ์˜ ํฌ๊ธฐ๊ฐ€ ์ œํ•œ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ฆ‰์‹œ ์ตœ์ ํ™”๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋ชจ๋“  ํŒจํ‚ท์„ ํ†ต๊ณผํ•˜๊ณ  ์•„๋ฌด ์ž‘์—…๋„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๋Š” ํ•„ํ„ฐ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

#include <uapi/linux/bpf.h>

#include <bpf_helpers.h>

SEC("prog")
int xdp_main(struct xdp_md* ctx) {
    return XDP_PASS;
}

char _license[] SEC("license") = "GPL";

ํŒ€ make ์ˆ˜์ง‘ํ•˜๋‹ค xdp_filter.o. ์ง€๊ธˆ ์–ด๋””์—์„œ ์‹œํ—˜ํ•ด ๋ณผ ์ˆ˜ ์žˆ๋‚˜์š”?

ํ…Œ์ŠคํŠธ ๋ฒค์น˜

์Šคํƒ ๋“œ์—๋Š” ํ•„ํ„ฐ๊ฐ€ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค์™€ ํŒจํ‚ท์ด ์ „์†ก๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค ๋‘ ๊ฐœ๊ฐ€ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ•„ํ„ฐ์™€ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด ์ž์ฒด IP๋ฅผ ๊ฐ–์ถ˜ ์™„์ „ํ•œ Linux ์žฅ์น˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

veth(๊ฐ€์ƒ ์ด๋”๋„ท) ์œ ํ˜•์˜ ์žฅ์น˜๋Š” ์šฐ๋ฆฌ์—๊ฒŒ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์„œ๋กœ ์ง์ ‘ "์—ฐ๊ฒฐ๋œ" ๊ฐ€์ƒ ๋„คํŠธ์›Œํฌ ์ธํ„ฐํŽ˜์ด์Šค ์Œ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ด ์„น์…˜์—์„œ๋Š” ๋ชจ๋“  ๋ช…๋ น์„ ip ์—์„œ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค root):

ip link add xdp-remote type veth peer name xdp-local

์—ฌ๊ธฐ์— xdp-remote ะธ xdp-local โ€” ์žฅ์น˜ ์ด๋ฆ„. ~์— xdp-local (192.0.2.1/24) ํ•„ํ„ฐ๊ฐ€ ๋ถ€์ฐฉ๋ฉ๋‹ˆ๋‹ค. xdp-remote (192.0.2.2/24) ๋“ค์–ด์˜ค๋Š” ํŠธ๋ž˜ํ”ฝ์ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋™์ผํ•œ ์‹œ์Šคํ…œ์— ์žˆ๊ณ  Linux๋Š” ๋‹ค๋ฅธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๋‘˜ ์ค‘ ํ•˜๋‚˜๋กœ ํŠธ๋ž˜ํ”ฝ์„ ๋ณด๋‚ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊นŒ๋‹ค๋กœ์šด ๊ทœ์น™์œผ๋กœ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. iptables, ๊ทธ๋Ÿฌ๋‚˜ ํŒจํ‚ค์ง€๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๋””๋ฒ„๊น…์ด ๋ถˆํŽธํ•ฉ๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ๋„ค์ž„์ŠคํŽ˜์ด์Šค(์ดํ•˜ netns)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์ข‹์Šต๋‹ˆ๋‹ค.

๋„คํŠธ์›Œํฌ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—๋Š” ๋‹ค๋ฅธ netns์˜ ์œ ์‚ฌํ•œ ๊ฐœ์ฒด์™€ ๊ฒฉ๋ฆฌ๋œ ์ผ๋ จ์˜ ์ธํ„ฐํŽ˜์ด์Šค, ๋ผ์šฐํŒ… ํ…Œ์ด๋ธ” ๋ฐ NetFilter ๊ทœ์น™์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ ์‹คํ–‰๋˜๋ฉฐ ํ•ด๋‹น netns์˜ ๊ฐœ์ฒด์—๋งŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹œ์Šคํ…œ์—๋Š” ๋ชจ๋“  ๊ฐœ์ฒด์— ๋Œ€ํ•œ ๋‹จ์ผ ๋„คํŠธ์›Œํฌ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ Linux์—์„œ ์ž‘์—…ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ netns์— ๋Œ€ํ•ด์„œ๋Š” ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ƒˆ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. xdp-test ๊ทธ๋ฆฌ๊ณ  ๊ฑฐ๊ธฐ๋กœ ์˜ฎ๊ฒจ xdp-remote.

ip netns add xdp-test
ip link set dev xdp-remote netns xdp-test

๊ทธ๋Ÿฐ ๋‹ค์Œ ์‹คํ–‰์ค‘์ธ ํ”„๋กœ์„ธ์Šค xdp-test, "๋ณด์ง€" ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค xdp-local (๊ธฐ๋ณธ์ ์œผ๋กœ netns์— ๋‚จ์•„ ์žˆ์Šต๋‹ˆ๋‹ค.) 192.0.2.1๋กœ ํŒจํ‚ท์„ ๋ณด๋‚ผ ๋•Œ ์ด๋ฅผ ํ†ต๊ณผํ•ฉ๋‹ˆ๋‹ค. xdp-remote์ด๋Š” ์ด ํ”„๋กœ์„ธ์Šค์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” 192.0.2.0/24์˜ ์œ ์ผํ•œ ์ธํ„ฐํŽ˜์ด์Šค์ด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฐ˜๋Œ€ ๋ฐฉํ–ฅ์œผ๋กœ๋„ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

netns ์‚ฌ์ด๋ฅผ ์ด๋™ํ•  ๋•Œ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋‹ค์šด๋˜๊ณ  ์ฃผ์†Œ๊ฐ€ ์†์‹ค๋ฉ๋‹ˆ๋‹ค. netns์—์„œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋ ค๋ฉด ๋‹ค์Œ์„ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ip ... ์ด ๋ช…๋ น ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ ip netns exec:

ip netns exec xdp-test 
    ip address add 192.0.2.2/24 dev xdp-remote
ip netns exec xdp-test 
    ip link set xdp-remote up

๋ณด์‹œ๋‹ค์‹œํ”ผ ์„ค์ •๊ณผ ๋‹ค๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. xdp-local ๊ธฐ๋ณธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ:

    ip address add 192.0.2.1/24 dev xdp-local
    ip link set xdp-local up

๋‹น์‹ ์ด ์‹คํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ tcpdump -tnevi xdp-local, ๋‹ค์Œ์—์„œ ๋ณด๋‚ธ ํŒจํ‚ท์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. xdp-test, ์ด ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

ip netns exec xdp-test   ping 192.0.2.1

์‰˜์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. xdp-test. ์ €์žฅ์†Œ์—๋Š” ์Šคํƒ ๋“œ ์ž‘์—…์„ ์ž๋™ํ™”ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํƒ ๋“œ๋ฅผ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. sudo ./stand up ๊ทธ๋ฆฌ๊ณ  ์‚ญ์ œํ•ด sudo ./stand down.

ํŠธ๋ ˆ์ด์‹ฑ

ํ•„ํ„ฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์žฅ์น˜์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

ip -force link set dev xdp-local xdp object xdp_filter.o verbose

์—ด์‡  -force ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์ด ์ด๋ฏธ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ์ƒˆ ํ”„๋กœ๊ทธ๋žจ์„ ์—ฐ๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. โ€œ๋ฌด์†Œ์‹์€ ์ข‹์€ ์†Œ์‹์ด๋‹คโ€๋Š” ์ด ๋ช…๋ น์— ๊ด€ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ฉฐ, ์–ด์จŒ๋“  ๊ฒฐ๋ก ์€ ๋ฐฉ๋Œ€ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜ํƒ€๋‚ด๋‹ค verbose ์„ ํƒ ์‚ฌํ•ญ์ด์ง€๋งŒ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์–ด์…ˆ๋ธ”๋ฆฌ ๋ชฉ๋ก๊ณผ ํ•จ๊ป˜ ์ฝ”๋“œ ๊ฒ€์ฆ๊ธฐ ์ž‘์—…์— ๋Œ€ํ•œ ๋ณด๊ณ ์„œ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

Verifier analysis:

0: (b7) r0 = 2
1: (95) exit

์ธํ„ฐํŽ˜์ด์Šค์—์„œ ํ”„๋กœ๊ทธ๋žจ ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

ip link set dev xdp-local xdp off

์Šคํฌ๋ฆฝํŠธ์—์„œ ๋‹ค์Œ์€ ๋ช…๋ น์ž…๋‹ˆ๋‹ค. sudo ./stand attach ะธ sudo ./stand detach.

ํ•„ํ„ฐ๋ฅผ ๋ถ€์ฐฉํ•˜๋ฉด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ping ๊ณ„์† ์‹คํ–‰๋˜์ง€๋งŒ ํ”„๋กœ๊ทธ๋žจ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๊นŒ? ๋กœ๊ทธ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ bpf_trace_printk() ๋น„์Šทํ•˜๋‹ค printf()์ด์ง€๋งŒ ํŒจํ„ด ์™ธ์— ์ตœ๋Œ€ XNUMX๊ฐœ์˜ ์ธ์ˆ˜์™€ ์ œํ•œ๋œ ์ง€์ •์ž ๋ชฉ๋ก๋งŒ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋งคํฌ๋กœ bpf_printk() ํ†ตํ™”๋ฅผ ๋‹จ์ˆœํ™”ํ•ฉ๋‹ˆ๋‹ค.

   SEC("prog")
   int xdp_main(struct xdp_md* ctx) {
+      bpf_printk("got packet: %pn", ctx);
       return XDP_PASS;
   }

์ถœ๋ ฅ์€ ํ™œ์„ฑํ™”๋˜์–ด์•ผ ํ•˜๋Š” ์ปค๋„ ์ถ”์  ์ฑ„๋„๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

echo -n 1 | sudo tee /sys/kernel/debug/tracing/options/trace_printk

๋ฉ”์‹œ์ง€ ์Šค๋ ˆ๋“œ ๋ณด๊ธฐ:

cat /sys/kernel/debug/tracing/trace_pipe

์ด ๋‘ ๋ช…๋ น ๋ชจ๋‘ ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. sudo ./stand log.

์ด์ œ Ping์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

<...>-110930 [004] ..s1 78803.244967: 0: got packet: 00000000ac510377

๊ฒ€์ฆ๊ธฐ์˜ ์ถœ๋ ฅ์„ ์ž์„ธํžˆ ์‚ดํŽด๋ณด๋ฉด ์ด์ƒํ•œ ๊ณ„์‚ฐ์„ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

0: (bf) r3 = r1
1: (18) r1 = 0xa7025203a7465
3: (7b) *(u64 *)(r10 -8) = r1
4: (18) r1 = 0x6b63617020746f67
6: (7b) *(u64 *)(r10 -16) = r1
7: (bf) r1 = r10
8: (07) r1 += -16
9: (b7) r2 = 16
10: (85) call bpf_trace_printk#6
<...>

์‚ฌ์‹ค eBPF ํ”„๋กœ๊ทธ๋žจ์—๋Š” ๋ฐ์ดํ„ฐ ์„น์…˜์ด ์—†์œผ๋ฏ€๋กœ ํ˜•์‹ ๋ฌธ์ž์—ด์„ ์ธ์ฝ”๋”ฉํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ VM ๋ช…๋ น์˜ ์ฆ‰๊ฐ์ ์ธ ์ธ์ˆ˜์ž…๋‹ˆ๋‹ค.

$ python -c "import binascii; print(bytes(reversed(binascii.unhexlify('0a7025203a74656b63617020746f67'))))"
b'got packet: %pn'

์ด๋Ÿฌํ•œ ์ด์œ ๋กœ ๋””๋ฒ„๊ทธ ์ถœ๋ ฅ์€ ๊ฒฐ๊ณผ ์ฝ”๋“œ๋ฅผ ํฌ๊ฒŒ ๋ถ€ํ’€๋ฆฝ๋‹ˆ๋‹ค.

XDP ํŒจํ‚ท ๋ณด๋‚ด๊ธฐ

ํ•„ํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  ํŒจํ‚ท์„ ๋‹ค์‹œ ๋ณด๋‚ด๋„๋ก ํ•˜์„ธ์š”. ํ—ค๋”์˜ ์ฃผ์†Œ๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋„คํŠธ์›Œํฌ ๊ด€์ ์—์„œ๋Š” ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์ง€๋งŒ ์ด์ œ ์›์น™์ ์œผ๋กœ ์ž‘์—…์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

       bpf_printk("got packet: %pn", ctx);
-      return XDP_PASS;
+      return XDP_TX;
   }

์‹œ์ž‘ํ•˜๋‹ค tcpdump ์— xdp-remote. ๋™์ผํ•œ ๋ฐœ์‹  ๋ฐ ์ˆ˜์‹  ICMP ์—์ฝ” ์š”์ฒญ์„ ํ‘œ์‹œํ•˜๊ณ  ICMP ์—์ฝ” ์‘๋‹ต ํ‘œ์‹œ๋ฅผ ์ค‘์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ์ผ์„ ์œ„ํ•ด ๋ฐํ˜€์กŒ์Šต๋‹ˆ๋‹ค XDP_TX ์— ์žˆ๋Š” ํ”„๋กœ๊ทธ๋žจ์—์„œ xdp-local ํ•ด์•ผ์Œ ์ธํ„ฐํŽ˜์ด์Šค๋กœ xdp-remote ๋น„์–ด ์žˆ์–ด๋„ ํ”„๋กœ๊ทธ๋žจ๋„ ํ• ๋‹น๋˜์–ด ์ž๋ž์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์ด๊ฑธ ์–ด๋–ป๊ฒŒ ์•Œ์•˜์ง€?

์ปค๋„์—์„œ ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ ์ถ”์  ๊ทธ๋Ÿฐ๋ฐ ์„ฑ๋Šฅ ์ด๋ฒคํŠธ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋™์ผํ•œ ๊ฐ€์ƒ ๋จธ์‹ ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, eBPF๋ฅผ ์‚ฌ์šฉํ•œ ๋””์Šค์–ด์…ˆ๋ธ”๋ฆฌ์— eBPF๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์•…์—์„œ ์„ ์„ ์ฐพ์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์•…์—์„œ ์„ ์„ ์ด๋Œ์–ด๋‚ผ ๋‹ค๋ฅธ ๊ฒƒ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

$ sudo perf trace --call-graph dwarf -e 'xdp:*'
   0.000 ping/123455 xdp:xdp_bulk_tx:ifindex=19 action=TX sent=0 drops=1 err=-6
                                     veth_xdp_flush_bq ([veth])
                                     veth_xdp_flush_bq ([veth])
                                     veth_poll ([veth])
                                     <...>

์ฝ”๋“œ 6์ด๋ž€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

$ errno 6
ENXIO 6 No such device or address

๊ธฐ๋Šฅ veth_xdp_flush_bq() ์—์„œ ์˜ค๋ฅ˜ ์ฝ”๋“œ๋ฅผ ๋ฐ›์Šต๋‹ˆ๋‹ค. veth_xdp_xmit(), ์—ฌ๊ธฐ์„œ ๊ฒ€์ƒ‰ ENXIO ๊ทธ๋ฆฌ๊ณ  ๋Œ“๊ธ€์„ ์ฐพ์•„๋ณด์„ธ์š”.

์ตœ์†Œ ํ•„ํ„ฐ๋ฅผ ๋ณต์›ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค(XDP_PASS) ํŒŒ์ผ์— ์žˆ์Œ xdp_dummy.c, Makefile์— ์ถ”๊ฐ€ํ•˜๊ณ  ๋ฐ”์ธ๋”ฉํ•˜์‹ญ์‹œ์˜ค. xdp-remote:

ip netns exec remote 
    ip link set dev int xdp object dummy.o

์ง€๊ธˆ tcpdump ์˜ˆ์ƒ๋˜๋Š” ๋‚ด์šฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

62:57:8e:70:44:64 > 26:0e:25:37:8f:96, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 13762, offset 0, flags [DF], proto ICMP (1), length 84)
    192.0.2.2 > 192.0.2.1: ICMP echo request, id 46966, seq 1, length 64
62:57:8e:70:44:64 > 26:0e:25:37:8f:96, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 13762, offset 0, flags [DF], proto ICMP (1), length 84)
    192.0.2.2 > 192.0.2.1: ICMP echo request, id 46966, seq 1, length 64

๋Œ€์‹  ARP๋งŒ ํ‘œ์‹œ๋˜๋Š” ๊ฒฝ์šฐ ํ•„ํ„ฐ๋ฅผ ์ œ๊ฑฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. sudo ./stand detach), ๊ฐ€์ž ping์„ ํƒญํ•œ ๋‹ค์Œ ํ•„ํ„ฐ๋ฅผ ์„ค์ •ํ•˜๊ณ  ๋‹ค์‹œ ์‹œ๋„ํ•˜์„ธ์š”. ๋ฌธ์ œ๋Š” ํ•„ํ„ฐ๊ฐ€ XDP_TX ARP์™€ ์Šคํƒ ๋ชจ๋‘ ์œ ํšจํ•ฉ๋‹ˆ๋‹ค.
๋„ค์ž„์ŠคํŽ˜์ด์Šค xdp-test MAC ์ฃผ์†Œ 192.0.2.1์„ "์žŠ์–ด ๋ฒ„๋ฆฌ๋ฉด" ์ด IP๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ ์„ฑ๋ช…

๋ช…์‹œ๋œ ์ž‘์—…์œผ๋กœ ๋„˜์–ด๊ฐ€๊ฒ ์Šต๋‹ˆ๋‹ค. XDP์— SYN ์ฟ ํ‚ค ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

SYN Flood๋Š” ์—ฌ์ „ํžˆ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” DDoS ๊ณต๊ฒฉ์œผ๋กœ, ๊ทธ ๋ณธ์งˆ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ์„ค์ •๋˜๋ฉด(TCP ํ•ธ๋“œ์…ฐ์ดํฌ) ์„œ๋ฒ„๋Š” SYN์„ ์ˆ˜์‹ ํ•˜๊ณ  ํ–ฅํ›„ ์—ฐ๊ฒฐ์„ ์œ„ํ•ด ๋ฆฌ์†Œ์Šค๋ฅผ ํ• ๋‹นํ•˜๊ณ  SYNACK ํŒจํ‚ท์œผ๋กœ ์‘๋‹ตํ•˜๊ณ  ACK๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ๊ณต๊ฒฉ์ž๋Š” ์ˆ˜์ฒœ ๊ฐœ์˜ ๊ฐ•๋ ฅํ•œ ๋ด‡๋„ท์— ์žˆ๋Š” ๊ฐ ํ˜ธ์ŠคํŠธ์˜ ์Šคํ‘ธํ•‘๋œ ์ฃผ์†Œ์—์„œ ์ดˆ๋‹น ์ˆ˜์ฒœ ๊ฐœ์˜ SYN ํŒจํ‚ท์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ํŒจํ‚ท์ด ๋„์ฐฉํ•˜์ž๋งˆ์ž ๊ฐ•์ œ๋กœ ์ž์›์„ ํ• ๋‹นํ•˜์ง€๋งŒ, ์‹œ๊ฐ„์ด ๋งŽ์ด ์ดˆ๊ณผ๋œ ํ›„์— ์ž์›์„ ํ•ด์ œํ•˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ๋‚˜ ์ œํ•œ์ด ๋ชจ๋‘ ์†Œ๋ชจ๋˜๊ณ  ์ƒˆ๋กœ์šด ์—ฐ๊ฒฐ์ด ํ—ˆ์šฉ๋˜์ง€ ์•Š์œผ๋ฉฐ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

SYN ํŒจํ‚ท์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์ž์›์„ ํ• ๋‹นํ•˜์ง€ ์•Š๊ณ  SYNACK ํŒจํ‚ท์œผ๋กœ๋งŒ ์‘๋‹ตํ•œ๋‹ค๋ฉด ๋‚˜์ค‘์— ๋„์ฐฉํ•œ ACK ํŒจํ‚ท์ด ์ €์žฅ๋˜์ง€ ์•Š์€ SYN ํŒจํ‚ท์ž„์„ ์„œ๋ฒ„๋Š” โ€‹โ€‹์–ด๋–ป๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒ ๋Š”๊ฐ€? ๊ฒฐ๊ตญ ๊ณต๊ฒฉ์ž๋Š” ๊ฐ€์งœ ACK๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. SYN ์ฟ ํ‚ค์˜ ์š”์ ์€ ์ด๋ฅผ ์ธ์ฝ”๋”ฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. seqnum ์ฃผ์†Œ, ํฌํŠธ ๋ฐ ์†”ํŠธ ๋ณ€๊ฒฝ์˜ ํ•ด์‹œ์ธ ์—ฐ๊ฒฐ ๋งค๊ฐœ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค. ์†”ํŠธ๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ธฐ ์ „์— ACK๊ฐ€ ๋„์ฐฉํ–ˆ๋‹ค๋ฉด ํ•ด์‹œ๋ฅผ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. acknum. ๋…ธ acknum ์†”ํŠธ์—๋Š” ๋น„๋ฐ€์ด ํฌํ•จ๋˜์–ด ์žˆ๊ณ  ์ œํ•œ๋œ ์ฑ„๋„๋กœ ์ธํ•ด ์ด๋ฅผ ๋ถ„๋ฅ˜ํ•  ์‹œ๊ฐ„์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ณต๊ฒฉ์ž๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

SYN ์ฟ ํ‚ค๋Š” ์˜ค๋žซ๋™์•ˆ Linux ์ปค๋„์—์„œ ๊ตฌํ˜„๋˜์–ด ์™”์œผ๋ฉฐ SYN์ด ๋„ˆ๋ฌด ๋นจ๋ฆฌ ๋Œ€๋Ÿ‰์œผ๋กœ ๋„์ฐฉํ•˜๋Š” ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ ํ™œ์„ฑํ™”๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

TCP ํ•ธ๋“œ์…ฐ์ดํฌ ๊ต์œก ํ”„๋กœ๊ทธ๋žจ

TCP๋Š” ๋ฐ์ดํ„ฐ ์ „์†ก์„ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด HTTP ์š”์ฒญ์€ TCP๋ฅผ ํ†ตํ•ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ์ŠคํŠธ๋ฆผ์€ ํŒจํ‚ท์˜ ์กฐ๊ฐ์œผ๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  TCP ํŒจํ‚ท์—๋Š” ๋…ผ๋ฆฌ์  ํ”Œ๋ž˜๊ทธ์™€ 32๋น„ํŠธ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ”Œ๋ž˜๊ทธ์˜ ์กฐํ•ฉ์— ๋”ฐ๋ผ ํŠน์ • ํŒจํ‚ค์ง€์˜ ์—ญํ• ์ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค. SYN ํ”Œ๋ž˜๊ทธ๋Š” ์ด๊ฒƒ์ด ์—ฐ๊ฒฐ์—์„œ ๋ณด๋‚ธ ์‚ฌ๋žŒ์˜ ์ฒซ ๋ฒˆ์งธ ํŒจํ‚ท์ž„์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ACK ํ”Œ๋ž˜๊ทธ๋Š” ๋ณด๋‚ธ ์‚ฌ๋žŒ์ด ํ•ด๋‹น ๋ฐ”์ดํŠธ๊นŒ์ง€์˜ ๋ชจ๋“  ์—ฐ๊ฒฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ–ˆ์Œ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. acknum. ํŒจํ‚ท์—๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”Œ๋ž˜๊ทธ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ SYNACK ํŒจํ‚ท๊ณผ ๊ฐ™์ด ํ•ด๋‹น ํ”Œ๋ž˜๊ทธ์˜ ์กฐํ•ฉ์œผ๋กœ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

  • ์‹œํ€€์Šค ๋ฒˆํ˜ธ(seqnum)๋Š” ์ด ํŒจํ‚ท์—์„œ ์ „์†ก๋˜๋Š” ์ฒซ ๋ฒˆ์งธ ๋ฐ”์ดํŠธ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์˜ ์˜คํ”„์…‹์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด X๋ฐ”์ดํŠธ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ์ฒซ ๋ฒˆ์งธ ํŒจํ‚ท์—์„œ ์ด ์ˆซ์ž๊ฐ€ N์ธ ๊ฒฝ์šฐ ์ƒˆ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ๋‹ค์Œ ํŒจํ‚ท์—์„œ๋Š” N+X๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ์‹œ์ž‘๋  ๋•Œ ๊ฐ ์ธก์€ ์ด ๋ฒˆํ˜ธ๋ฅผ ๋ฌด์ž‘์œ„๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  • ์Šน์ธ ๋ฒˆํ˜ธ(acknum) - seqnum๊ณผ ๋™์ผํ•œ ์˜คํ”„์…‹์ด์ง€๋งŒ ์ „์†ก๋˜๋Š” ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ฐœ์‹ ์ž๊ฐ€ ๋ณด์ง€ ๋ชปํ•œ ์ˆ˜์‹ ์ž์˜ ์ฒซ ๋ฒˆ์งธ ๋ฐ”์ดํŠธ ์ˆ˜๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ์ด ์‹œ์ž‘๋  ๋•Œ ๋‹น์‚ฌ์ž๋“ค์€ ๋™์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. seqnum ะธ acknum. ํด๋ผ์ด์–ธํŠธ๋Š” ์ž์‹ ์˜ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ SYN ํŒจํ‚ท์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. seqnum = X. ์„œ๋ฒ„๋Š” SYNACK ํŒจํ‚ท์œผ๋กœ ์‘๋‹ตํ•˜๋ฉฐ, ์—ฌ๊ธฐ์— ํ•ด๋‹น ๋‚ด์šฉ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. seqnum = Y ๊ทธ๋ฆฌ๊ณ  ๋…ธ์ถœํ•œ๋‹ค acknum = X + 1. ํด๋ผ์ด์–ธํŠธ๋Š” ACK ํŒจํ‚ท์œผ๋กœ SYNACK์— ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค. seqnum = X + 1, acknum = Y + 1. ๊ทธ ํ›„ ์‹ค์ œ ๋ฐ์ดํ„ฐ ์ „์†ก์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.

ํ”ผ์–ด๊ฐ€ ํŒจํ‚ท ์ˆ˜์‹ ์„ ํ™•์ธํ•˜์ง€ ์•Š์œผ๋ฉด TCP๋Š” ์‹œ๊ฐ„ ์ดˆ๊ณผ ํ›„ ํŒจํ‚ท์„ ๋‹ค์‹œ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

SYN ์ฟ ํ‚ค๊ฐ€ ํ•ญ์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ฒซ์งธ, SYNACK ๋˜๋Š” ACK๊ฐ€ ์†์‹ค๋˜๋ฉด ๋‹ค์‹œ ์ „์†ก๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ ์„ค์ • ์†๋„๊ฐ€ ๋Š๋ ค์ง‘๋‹ˆ๋‹ค. ๋‘˜์งธ, SYN ํŒจํ‚ค์ง€์—๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค! โ€” ์—ฐ๊ฒฐ์˜ ์ถ”๊ฐ€ ์ž‘์—…์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ์—ฌ๋Ÿฌ ์˜ต์…˜์ด ์ „์†ก๋ฉ๋‹ˆ๋‹ค. ๋“ค์–ด์˜ค๋Š” SYN ํŒจํ‚ท์„ ๊ธฐ์–ตํ•˜์ง€ ์•Š์œผ๋ฉด ์„œ๋ฒ„๋Š” ์ด๋Ÿฌํ•œ ์˜ต์…˜์„ ๋ฌด์‹œํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ๋Š” ๋‹ค์Œ ํŒจํ‚ท์—์„œ ํ•ด๋‹น ์˜ต์…˜์„ ๋ณด๋‚ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ TCP๊ฐ€ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ ์–ด๋„ ์ดˆ๊ธฐ ๋‹จ๊ณ„์—์„œ๋Š” ์—ฐ๊ฒฐ ํ’ˆ์งˆ์ด ์ €ํ•˜๋ฉ๋‹ˆ๋‹ค.

ํŒจํ‚ค์ง€ ๊ด€์ ์—์„œ XDP ํ”„๋กœ๊ทธ๋žจ์€ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SYNACK์œผ๋กœ SYN์— ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.
  • RST(์—ฐ๊ฒฐ ํ•ด์ œ)๋กœ ACK์— ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.
  • ๋‚˜๋จธ์ง€ ํŒจํ‚ท์„ ํ๊ธฐํ•ฉ๋‹ˆ๋‹ค.

ํŒจํ‚ค์ง€ ๊ตฌ๋ฌธ ๋ถ„์„๊ณผ ํ•จ๊ป˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์˜์‚ฌ ์ฝ”๋“œ:

ะ•ัะปะธ ัั‚ะพ ะฝะต Ethernet,
    ะฟั€ะพะฟัƒัั‚ะธั‚ัŒ ะฟะฐะบะตั‚.
ะ•ัะปะธ ัั‚ะพ ะฝะต IPv4,
    ะฟั€ะพะฟัƒัั‚ะธั‚ัŒ ะฟะฐะบะตั‚.
ะ•ัะปะธ ะฐะดั€ะตั ะฒ ั‚ะฐะฑะปะธั†ะต ะฟั€ะพะฒะตั€ะตะฝะฝั‹ั…,               (*)
        ัƒะผะตะฝัŒัˆะธั‚ัŒ ัั‡ะตั‚ั‡ะธะบ ะพัั‚ะฐะฒัˆะธั…ัั ะฟั€ะพะฒะตั€ะพะบ,
        ะฟั€ะพะฟัƒัั‚ะธั‚ัŒ ะฟะฐะบะตั‚.
ะ•ัะปะธ ัั‚ะพ ะฝะต TCP,
    ัะฑั€ะพัะธั‚ัŒ ะฟะฐะบะตั‚.     (**)
ะ•ัะปะธ ัั‚ะพ SYN,
    ะพั‚ะฒะตั‚ะธั‚ัŒ SYN-ACK ั cookie.
ะ•ัะปะธ ัั‚ะพ ACK,
    ะตัะปะธ ะฒ acknum ะปะตะถะธั‚ ะฝะต cookie,
        ัะฑั€ะพัะธั‚ัŒ ะฟะฐะบะตั‚.
    ะ—ะฐะฝะตัั‚ะธ ะฒ ั‚ะฐะฑะปะธั†ัƒ ะฐะดั€ะตั ั N ะพัั‚ะฐะฒัˆะธั…ัั ะฟั€ะพะฒะตั€ะพะบ.    (*)
    ะžั‚ะฒะตั‚ะธั‚ัŒ RST.   (**)
ะ’ ะพัั‚ะฐะปัŒะฝั‹ั… ัะปัƒั‡ะฐัั… ัะฑั€ะพัะธั‚ัŒ ะฟะฐะบะตั‚.

ํ•˜๋‚˜ (*) ์‹œ์Šคํ…œ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์ง€์ ์ด ํ‘œ์‹œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ๋Š” SYN ์ฟ ํ‚ค๋ฅผ seqnum์œผ๋กœ ์ƒ์„ฑํ•˜์—ฌ TCP ํ•ธ๋“œ์…ฐ์ดํฌ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ์ด๋Ÿฌํ•œ ์ง€์  ์—†์ด๋„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฅ์—์„œ (**), ํ…Œ์ด๋ธ”์ด ์—†์œผ๋ฉด ํŒจํ‚ท์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.

TCP ํ•ธ๋“œ์…ฐ์ดํฌ ๊ตฌํ˜„

ํŒจํ‚ค์ง€ ๊ตฌ๋ฌธ ๋ถ„์„ ๋ฐ ์ฝ”๋“œ ํ™•์ธ

๋„คํŠธ์›Œํฌ ํ—ค๋” ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค: ์ด๋”๋„ท(uapi/linux/if_ether.h), IPv4(uapi/linux/ip.h) ๋ฐ TCP(uapi/linux/tcp.h). ๋‹ค์Œ๊ณผ ๊ด€๋ จ๋œ ์˜ค๋ฅ˜๋กœ ์ธํ•ด ํ›„์ž๋ฅผ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. atomic64_t, ํ•„์š”ํ•œ ์ •์˜๋ฅผ ์ฝ”๋“œ์— ๋ณต์‚ฌํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€๋…์„ฑ์„ ์œ„ํ•ด C๋กœ ๊ฐ•์กฐ ํ‘œ์‹œ๋œ ๋ชจ๋“  ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœ ์‹œ์ ์— ์ธ๋ผ์ธ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ปค๋„์˜ eBPF ๊ฒ€์ฆ์ž๊ฐ€ ์—ญ์ถ”์ , ์ฆ‰ ์‹ค์ œ๋กœ ๋ฃจํ”„ ๋ฐ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ๊ธˆ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

#define INTERNAL static __attribute__((always_inline))

๋งคํฌ๋กœ LOG() ๋ฆด๋ฆฌ์Šค ๋นŒ๋“œ์—์„œ ์ธ์‡„๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ๊ทธ๋žจ์€ ๊ธฐ๋Šฅ์˜ ์ปจ๋ฒ ์ด์–ด์ž…๋‹ˆ๋‹ค. ๊ฐ๊ฐ์€ ํ•ด๋‹น ๋ ˆ๋ฒจ ํ—ค๋”๊ฐ€ ๊ฐ•์กฐ ํ‘œ์‹œ๋œ ํŒจํ‚ท์„ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, process_ether() ์ฑ„์›Œ์งˆ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ ether. ํ•„๋“œ ๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์ด ๊ธฐ๋Šฅ์€ ํŒจํ‚ท์„ ๋” ๋†’์€ ์ˆ˜์ค€์œผ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋Š” XDP ์ž‘์—…์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ๋กœ์„œ๋Š” SYN ๋ฐ ACK ์ฒ˜๋ฆฌ๊ธฐ๊ฐ€ ๋ชจ๋“  ํŒจํ‚ท์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

struct Packet {
    struct xdp_md* ctx;

    struct ethhdr* ether;
    struct iphdr* ip;
    struct tcphdr* tcp;
};

INTERNAL int process_tcp_syn(struct Packet* packet) { return XDP_PASS; }
INTERNAL int process_tcp_ack(struct Packet* packet) { return XDP_PASS; }
INTERNAL int process_tcp(struct Packet* packet) { ... }
INTERNAL int process_ip(struct Packet* packet) { ... }

INTERNAL int
process_ether(struct Packet* packet) {
    struct ethhdr* ether = packet->ether;

    LOG("Ether(proto=0x%x)", bpf_ntohs(ether->h_proto));

    if (ether->h_proto != bpf_ntohs(ETH_P_IP)) {
        return XDP_PASS;
    }

    // B
    struct iphdr* ip = (struct iphdr*)(ether + 1);
    if ((void*)(ip + 1) > (void*)packet->ctx->data_end) {
        return XDP_DROP; /* malformed packet */
    }

    packet->ip = ip;
    return process_ip(packet);
}

SEC("prog")
int xdp_main(struct xdp_md* ctx) {
    struct Packet packet;
    packet.ctx = ctx;

    // A
    struct ethhdr* ether = (struct ethhdr*)(void*)ctx->data;
    if ((void*)(ether + 1) > (void*)ctx->data_end) {
        return XDP_PASS;
    }

    packet.ether = ether;
    return process_ether(&packet);
}

A์™€ B๋กœ ํ‘œ์‹œ๋œ ํ™•์ธ ์‚ฌํ•ญ์— ์ฃผ๋ชฉํ•˜์„ธ์š”. A๋ฅผ ์ฃผ์„ ์ฒ˜๋ฆฌํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์ด ๋นŒ๋“œ๋˜์ง€๋งŒ ๋กœ๋“œ ์‹œ ํ™•์ธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Verifier analysis:

<...>
11: (7b) *(u64 *)(r10 -48) = r1
12: (71) r3 = *(u8 *)(r7 +13)
invalid access to packet, off=13 size=1, R7(id=0,off=0,r=0)
R7 offset is outside of the packet
processed 11 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0

Error fetching program/map!

ํ‚ค ๋ฌธ์ž์—ด invalid access to packet, off=13 size=1, R7(id=0,off=0,r=0): ๋ฒ„ํผ ์‹œ์ž‘๋ถ€ํ„ฐ 12๋ฒˆ์งธ ๋ฐ”์ดํŠธ๊ฐ€ ํŒจํ‚ท ์™ธ๋ถ€์ผ ๋•Œ ์‹คํ–‰ ๊ฒฝ๋กœ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชฉ๋ก์—์„œ ์šฐ๋ฆฌ๊ฐ€ ๋งํ•˜๋Š” ์ค„์„ ์ดํ•ดํ•˜๊ธฐ๋Š” ์–ด๋ ต์ง€๋งŒ ๋ช…๋ น ๋ฒˆํ˜ธ(XNUMX)์™€ ์†Œ์Šค ์ฝ”๋“œ ์ค„์„ ๋ณด์—ฌ์ฃผ๋Š” ๋””์Šค์–ด์…ˆ๋ธ”๋Ÿฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

llvm-objdump -S xdp_filter.o | less

์ด ๊ฒฝ์šฐ์—๋Š” ์„ ์„ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

LOG("Ether(proto=0x%x)", bpf_ntohs(ether->h_proto));

๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ๋ถ„๋ช…ํžˆ ํ•ด์ค๋‹ˆ๋‹ค. ether. ํ•ญ์ƒ ์ด๋Ÿฐ ์‹์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ต์žฅํ•˜๋‹ค SYN

์ด ๋‹จ๊ณ„์˜ ๋ชฉํ‘œ๋Š” ๊ณ ์ •๋œ SYNACK ํŒจํ‚ท์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. seqnum, ์ด๋Š” ํ–ฅํ›„ SYN ์ฟ ํ‚ค๋กœ ๋Œ€์ฒด๋  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ๋‹ค์Œ์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. process_tcp_syn() ๊ทธ๋ฆฌ๊ณ  ์ฃผ๋ณ€ ์ง€์—ญ.

ํŒจํ‚ค์ง€ ํ™•์ธ

์ด์ƒํ•˜๊ฒŒ๋„ ๊ฐ€์žฅ ์ฃผ๋ชฉํ• ๋งŒํ•œ ๋Œ€์‚ฌ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

/* Required to verify checksum calculation */
const void* data_end = (const void*)ctx->data_end;

์ฒซ ๋ฒˆ์งธ ๋ฒ„์ „์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ 5.1 ์ปค๋„์ด ์‚ฌ์šฉ๋˜์—ˆ์œผ๋ฉฐ ๊ฒ€์ฆ์ž์—๊ฒŒ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฐจ์ด๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. data_end ะธ (const void*)ctx->data_end. ์ด ๊ธ€์„ ์“ฐ๋Š” ์‹œ์ ์—๋Š” ์ปค๋„ 5.3.1์—๋Š” ์ด ๋ฌธ์ œ๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•„๋“œ์™€ ๋‹ค๋ฅด๊ฒŒ ์ง€์—ญ ๋ณ€์ˆ˜์— ์•ก์„ธ์Šคํ–ˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตํ›ˆ: ์ค‘์ฒฉ ๊ทœ๋ชจ๊ฐ€ ํด ๊ฒฝ์šฐ ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๋Š” ๊ฒƒ์ด ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๊ฒ€์ฆ์ž์˜ ์˜๊ด‘์„ ์œ„ํ•œ ์ผ์ƒ์ ์ธ ๊ธธ์ด ํ™•์ธ์ž…๋‹ˆ๋‹ค. ์˜ํ˜• MAX_CSUM_BYTES ์•„๋ž˜์—.

const u32 ip_len = ip->ihl * 4;
if ((void*)ip + ip_len > data_end) {
    return XDP_DROP; /* malformed packet */
}
if (ip_len > MAX_CSUM_BYTES) {
    return XDP_ABORTED; /* implementation limitation */
}

const u32 tcp_len = tcp->doff * 4;
if ((void*)tcp + tcp_len > (void*)ctx->data_end) {
    return XDP_DROP; /* malformed packet */
}
if (tcp_len > MAX_CSUM_BYTES) {
    return XDP_ABORTED; /* implementation limitation */
}

ํŒจํ‚ค์ง€ ํŽผ์น˜๊ธฐ

์ž‘์„ฑ seqnum ะธ acknum, ACK๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค(SYN์ด ์ด๋ฏธ ์„ค์ •๋˜์–ด ์žˆ์Œ).

const u32 cookie = 42;
tcp->ack_seq = bpf_htonl(bpf_ntohl(tcp->seq) + 1);
tcp->seq = bpf_htonl(cookie);
tcp->ack = 1;

TCP ํฌํŠธ, IP ์ฃผ์†Œ, MAC ์ฃผ์†Œ๋ฅผ ๊ตํ™˜ํ•ฉ๋‹ˆ๋‹ค. ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” XDP ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ memcpy() โ€” Clang ๋‚ด์žฅ ๊ธฐ๋Šฅ์„ ์ˆจ๊ธฐ๋Š” ๋งคํฌ๋กœ์ž…๋‹ˆ๋‹ค.

const u16 temp_port = tcp->source;
tcp->source = tcp->dest;
tcp->dest = temp_port;

const u32 temp_ip = ip->saddr;
ip->saddr = ip->daddr;
ip->daddr = temp_ip;

struct ethhdr temp_ether = *ether;
memcpy(ether->h_dest, temp_ether.h_source, ETH_ALEN);
memcpy(ether->h_source, temp_ether.h_dest, ETH_ALEN);

์ฒดํฌ์„ฌ ์žฌ๊ณ„์‚ฐ

IPv4 ๋ฐ TCP ์ฒดํฌ์„ฌ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ—ค๋”์— ๋ชจ๋“  16๋น„ํŠธ ๋‹จ์–ด๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•˜๋ฉฐ ํ—ค๋”์˜ ํฌ๊ธฐ๊ฐ€ ์—ฌ๊ธฐ์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ปดํŒŒ์ผ ์‹œ๊ฐ„์—๋Š” ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๊ฒ€์ฆ์ž๊ฐ€ ๊ฒฝ๊ณ„ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ผ๋ฐ˜ ๋ฃจํ”„๋ฅผ ๊ฑด๋„ˆ๋›ฐ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ—ค๋”์˜ ํฌ๊ธฐ๋Š” ๊ฐ๊ฐ ์ตœ๋Œ€ 64๋ฐ”์ดํŠธ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ๊ณ ์ •๋œ ๋ฐ˜๋ณต ํšŸ์ˆ˜๋กœ ๋ฃจํ”„๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ์ผ์ฐ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์žˆ์Œ์„ ์ฐธ๊ณ ํ•ฉ๋‹ˆ๋‹ค RFC 1624 ํŒจํ‚ค์ง€์˜ ๊ณ ์ • ๋‹จ์–ด๋งŒ ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ ์ฒดํฌ์„ฌ์„ ๋ถ€๋ถ„์ ์œผ๋กœ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋ฐฉ๋ฒ•์€ ๋ณดํŽธ์ ์ด์ง€ ์•Š์œผ๋ฉฐ ๊ตฌํ˜„์„ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๊ธฐ๊ฐ€ ๋” ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

์ฒดํฌ์„ฌ ๊ณ„์‚ฐ ๊ธฐ๋Šฅ:

#define MAX_CSUM_WORDS 32
#define MAX_CSUM_BYTES (MAX_CSUM_WORDS * 2)

INTERNAL u32
sum16(const void* data, u32 size, const void* data_end) {
    u32 s = 0;
#pragma unroll
    for (u32 i = 0; i < MAX_CSUM_WORDS; i++) {
        if (2*i >= size) {
            return s; /* normal exit */
        }
        if (data + 2*i + 1 + 1 > data_end) {
            return 0; /* should be unreachable */
        }
        s += ((const u16*)data)[i];
    }
    return s;
}

ํ•˜์ง€๋งŒ size ํ˜ธ์ถœ ์ฝ”๋“œ์— ์˜ํ•ด ๊ฒ€์ฆ๋˜๋ฉด ๊ฒ€์ฆ์ž๊ฐ€ ๋ฃจํ”„ ์™„๋ฃŒ๋ฅผ ์ฆ๋ช…ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‘ ๋ฒˆ์งธ ์ข…๋ฃŒ ์กฐ๊ฑด์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

32๋น„ํŠธ ๋‹จ์–ด์˜ ๊ฒฝ์šฐ ๋” ๊ฐ„๋‹จํ•œ ๋ฒ„์ „์ด ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.

INTERNAL u32
sum16_32(u32 v) {
    return (v >> 16) + (v & 0xffff);
}

์‹ค์ œ๋กœ ์ฒดํฌ์„ฌ์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๊ณ  ํŒจํ‚ท์„ ๋‹ค์‹œ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

ip->check = 0;
ip->check = carry(sum16(ip, ip_len, data_end));

u32 tcp_csum = 0;
tcp_csum += sum16_32(ip->saddr);
tcp_csum += sum16_32(ip->daddr);
tcp_csum += 0x0600;
tcp_csum += tcp_len << 8;
tcp->check = 0;
tcp_csum += sum16(tcp, tcp_len, data_end);
tcp->check = carry(tcp_csum);

return XDP_TX;

๊ธฐ๋Šฅ carry() RFC 32์— ๋”ฐ๋ผ 16๋น„ํŠธ ๋‹จ์–ด์˜ 791๋น„ํŠธ ํ•ฉ๊ณ„์—์„œ ์ฒดํฌ์„ฌ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

TCP ํ•ธ๋“œ์…ฐ์ดํฌ ํ™•์ธ

ํ•„ํ„ฐ๋Š” ๋‹ค์Œ๊ณผ์˜ ์—ฐ๊ฒฐ์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. netcat, Linux๊ฐ€ RST ํŒจํ‚ท์œผ๋กœ ์‘๋‹ตํ•œ ์ตœ์ข… ACK๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋„คํŠธ์›Œํฌ ์Šคํƒ์ด SYN์„ ์ˆ˜์‹ ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์—(SYNACK๋กœ ๋ณ€ํ™˜๋˜์–ด ๋‹ค์‹œ ์ „์†ก๋˜์—ˆ์œผ๋ฉฐ) OS ๊ด€์ ์—์„œ ๋ณด๋ฉด ์—ด๊ธฐ์™€ ๊ด€๋ จ ์—†๋Š” ํŒจํ‚ท์ด ๋„์ฐฉํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ด.

$ sudo ip netns exec xdp-test   nc -nv 192.0.2.1 6666
192.0.2.1 6666: Connection reset by peer

๋ณธ๊ฒฉ์ ์ธ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ํ™•์ธํ•˜๊ณ  ๊ด€์ฐฐํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค tcpdump ์— xdp-remote ์™œ๋ƒํ•˜๋ฉด ์˜ˆ๋ฅผ ๋“ค๋ฉด, hping3 ์ž˜๋ชป๋œ ์ฒดํฌ์„ฌ์—๋Š” ์‘๋‹ตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

XDP ๊ด€์ ์—์„œ ๋ณผ ๋•Œ ๊ฒ€์ฆ ์ž์ฒด๋Š” ์‚ฌ์†Œํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ณ„์‚ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์›์‹œ์ ์ด๋ฉฐ ์ •๊ตํ•œ ๊ณต๊ฒฉ์ž์—๊ฒŒ ์ทจ์•ฝํ•  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Linux ์ปค๋„์€ ์•”ํ˜ธํ™” SipHash๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ XDP์— ๋Œ€ํ•œ ๊ตฌํ˜„์€ ๋ถ„๋ช…ํžˆ ์ด ๊ธฐ์‚ฌ์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฉ๋‹ˆ๋‹ค.

์™ธ๋ถ€ ํ†ต์‹ ๊ณผ ๊ด€๋ จ๋œ ์ƒˆ๋กœ์šด TODO๋ฅผ ์œ„ํ•ด ๋„์ž…๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

  • XDP ํ”„๋กœ๊ทธ๋žจ์ด ์ €์žฅํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. cookie_seed (์†”ํŠธ์˜ ๋น„๋ฐ€ ๋ถ€๋ถ„) ์ „์—ญ ๋ณ€์ˆ˜์—๋Š” ์ปค๋„์— ์ €์žฅ์ด ํ•„์š”ํ•˜๋ฉฐ ๊ทธ ๊ฐ’์€ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š” ์ƒ์„ฑ๊ธฐ์—์„œ ์ฃผ๊ธฐ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ๋ฉ๋‹ˆ๋‹ค.

  • SYN ์ฟ ํ‚ค๊ฐ€ ACK ํŒจํ‚ท๊ณผ ์ผ์น˜ํ•˜๋ฉด ๋ฉ”์‹œ์ง€๋ฅผ ์ธ์‡„ํ•  ํ•„์š”๊ฐ€ ์—†์ง€๋งŒ, ํŒจํ‚ท์„ ๊ณ„์† ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด ํ™•์ธ๋œ ํด๋ผ์ด์–ธํŠธ์˜ IP๋ฅผ ๊ธฐ์–ตํ•ฉ๋‹ˆ๋‹ค.

ํ•ฉ๋ฒ•์ ์ธ ํด๋ผ์ด์–ธํŠธ ํ™•์ธ:

$ sudoip netns exec xdp-test   nc -nv 192.0.2.1 6666
192.0.2.1 6666: Connection reset by peer

๋กœ๊ทธ์—๋Š” ๊ฒ€์‚ฌ๊ฐ€ ํ†ต๊ณผ๋˜์—ˆ์Œ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค(flags=0x2 - ์ด๊ฒƒ์€ SYN์ž…๋‹ˆ๋‹ค. flags=0x10 ACK์ž…๋‹ˆ๋‹ค):

Ether(proto=0x800)
  IP(src=0x20e6e11a dst=0x20e6e11e proto=6)
    TCP(sport=50836 dport=6666 flags=0x2)
Ether(proto=0x800)
  IP(src=0xfe2cb11a dst=0xfe2cb11e proto=6)
    TCP(sport=50836 dport=6666 flags=0x10)
      cookie matches for client 20200c0

ํ™•์ธ๋œ IP ๋ชฉ๋ก์€ ์—†์ง€๋งŒ SYN ํ”Œ๋Ÿฌ๋“œ ์ž์ฒด๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ์‹œ์ž‘๋œ ACK ํ”Œ๋Ÿฌ๋“œ์— ๋Œ€ํ•œ ๋ฐ˜์‘์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

sudo ip netns exec xdp-test   hping3 --flood -A -s 1111 -p 2222 192.0.2.1

๋กœ๊ทธ ํ•ญ๋ชฉ:

Ether(proto=0x800)
  IP(src=0x15bd11a dst=0x15bd11e proto=6)
    TCP(sport=3236 dport=2222 flags=0x10)
      cookie mismatch

๊ฒฐ๋ก 

๋•Œ๋กœ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ eBPF, ํŠนํžˆ XDP๊ฐ€ ๊ฐœ๋ฐœ ํ”Œ๋žซํผ์ด๋ผ๊ธฐ๋ณด๋‹ค๋Š” ๊ณ ๊ธ‰ ๊ด€๋ฆฌ์ž ๋„๊ตฌ๋กœ ๋” ๋งŽ์ด ์ œ์‹œ๋˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ XDP๋Š” ์ปค๋„์˜ ํŒจํ‚ท ์ฒ˜๋ฆฌ๋ฅผ ๋ฐฉํ•ดํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ์ด์ง€ DPDK ๋ฐ ๊ธฐํƒ€ ์ปค๋„ ์šฐํšŒ ์˜ต์…˜๊ณผ ๊ฐ™์€ ์ปค๋„ ์Šคํƒ์˜ ๋Œ€์•ˆ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด์— XDP๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋งค์šฐ ๋ณต์žกํ•œ ๋กœ์ง์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ํŠธ๋ž˜ํ”ฝ ์ฒ˜๋ฆฌ ์ค‘๋‹จ ์—†์ด ์‰ฝ๊ฒŒ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒ€์ฆ์ž๋Š” ํฐ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ค์ง€ ์•Š์œผ๋ฉฐ ๊ฐœ์ธ์ ์œผ๋กœ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ์ฝ”๋“œ์˜ ์ผ๋ถ€์— ๋Œ€ํ•ด ์ด๋ฅผ ๊ฑฐ๋ถ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‘ ๋ฒˆ์งธ ๋ถ€๋ถ„์—์„œ๋Š” ์ฃผ์ œ๊ฐ€ ํฅ๋ฏธ๋กœ์šธ ๊ฒฝ์šฐ ํ™•์ธ๋œ ํด๋ผ์ด์–ธํŠธ ๋ฐ ์—ฐ๊ฒฐ ๋Š๊น€ ํ…Œ์ด๋ธ”์„ ์™„์„ฑํ•˜๊ณ  ์นด์šดํ„ฐ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉฐ ํ•„ํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์‚ฌ์šฉ์ž ๊ณต๊ฐ„ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋งํฌ :

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€