کتاب "د لینکس څارنې لپاره BPF"

کتاب "د لینکس څارنې لپاره BPF"سلامونه دخبرو اوسیدونکو! د BPF مجازی ماشین د لینکس کرنل یو له خورا مهم برخو څخه دی. د دې سمه کارول به د سیسټم انجینرانو ته اجازه ورکړي چې نیمګړتیاوې ومومي او حتی خورا پیچلې ستونزې حل کړي. تاسو به زده کړئ چې څنګه هغه پروګرامونه ولیکئ چې د کرنل چلند څارنه او تعدیل کوي، څنګه په خوندي توګه کوډ پلي کول ترڅو په کرنل کې د پیښو څارنه وکړي، او نور ډیر څه. ډیویډ کالاویرا او لورینزو فونټانا به تاسو سره د BPF ځواک خلاصولو کې مرسته وکړي. د فعالیت اصلاح کولو ، شبکې جوړولو ، امنیت په اړه خپله پوهه پراخه کړئ. - د لینکس کرنل چلند څارلو او بدلولو لپاره BPF وکاروئ. - کوډ داخل کړئ ترڅو د کرنل پیښې په خوندي ډول وڅارئ پرته لدې چې د کرنل بیا تنظیم کړئ یا سیسټم ریبوټ کړئ. - په C، Go یا Python کې د مناسب کوډ مثالونه وکاروئ. - د BPF برنامې ژوند دورې په مالکیت سره کنټرول واخلئ.

د لینکس کرنل امنیت، د هغې ځانګړتیاوې او سیکومپ

BPF د ثبات، امنیت، یا سرعت قرباني کولو پرته د کرنل پراخولو لپاره پیاوړې لار وړاندې کوي. د دې دلیل لپاره، د کرنل پراختیا کونکو فکر کاوه چې دا به ښه نظر وي چې د BPF پروګرامونو لخوا مالتړ شوي Seccomp فلټرونو پلي کولو سره چې د Seccomp BPF په نوم هم پیژندل کیږي په Seccomp کې د پروسې انزوا ته وده ورکولو لپاره د دې استقامت څخه کار واخلئ. پدې فصل کې به موږ تشریح کړو چې Seccomp څه شی دی او څنګه کارول کیږي. بیا به تاسو د BPF برنامو په کارولو سره د Seccomp فلټرونو لیکلو څرنګوالی زده کړئ. له هغې وروسته، موږ به جوړ شوي BPF هکونه وګورو چې د لینکس امنیت ماډلونو لپاره په کرنل کې شامل دي.

د لینکس امنیت ماډلونه (LSM) یو چوکاټ دی چې د دندو یو سیټ چمتو کوي چې په معیاري ډول د مختلف امنیت ماډلونو پلي کولو لپاره کارول کیدی شي. LSM په مستقیم ډول د کرنل سرچینې ونې کې کارول کیدی شي، لکه Apparmor، SELinux او Tomoyo.

راځئ چې د لینکس د وړتیاوو په اړه بحث پیل کړو.

ځانګړتیاوې

د لینکس د وړتیاوو جوهر دا دی چې تاسو اړتیا لرئ د یو ځانګړي کار ترسره کولو لپاره د غیرمستقیم پروسې اجازه ورکړئ ، مګر پرته له دې چې د دې هدف لپاره سوډ وکاروئ ، یا بل ډول پروسې ته امتیاز ورکړئ ، د برید احتمال کم کړئ او پروسې ته اجازه ورکړئ چې ځینې دندې ترسره کړي. د مثال په توګه ، که ستاسو غوښتنلیک د امتیاز لرونکي بندر خلاصولو ته اړتیا ولري ، نو 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 — موږ غواړو نصب شوي وړتیاوې وساتو کله چې د روټ حساب څخه تیریږي.
  • - کارن = "هیڅ څوک" - وروستی کارونکی چې برنامه پرمخ وړي هیڅوک به نه وي.
  • —addamb=cap_net_bind_service — د روټ حالت څخه د بدلولو وروسته د اړونده وړتیاو پاکول تنظیم کړئ.
  • - -c "./capabilities" - یوازې برنامه پرمخ وړئ.

لینک شوي وړتیاوې یو ځانګړي ډول وړتیاوې دي چې د ماشومانو برنامو لخوا په میراث پاتې دي کله چې اوسنی برنامه دوی د execve() په کارولو سره اجرا کوي. یوازې هغه وړتیاوې چې د تړلو اجازه لري، یا په بل عبارت، د چاپیریال وړتیاوو په توګه، میراث کیدی شي.

تاسو شاید حیران یاست چې په --caps اختیار کې د وړتیا مشخص کولو وروسته +eip څه معنی لري. دا بیرغونه د دې وړتیا معلومولو لپاره کارول کیږي:

- باید فعال شي (p)؛

- د کارونې لپاره شتون لري (e)؛

- د ماشوم د پروسو له لارې په میراث پاتې کیدی شي (i).

څرنګه چې موږ غواړو cap_net_bind_service وکاروو، موږ باید دا د ای بیرغ سره ترسره کړو. بیا به موږ په کمانډ کې شیل پیل کړو. دا به وړتیاوې بائنری پرمخ وړي او موږ اړتیا لرو چې دا د i پرچم سره په نښه کړو. په نهایت کې ، موږ غواړو چې دا فیچر فعال شي (موږ دا د UID بدلولو پرته ترسره کړل) د p سره. داسې ښکاري لکه 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

پدې مثال کې موږ کیپش کارولی ، مګر تاسو کولی شئ د libcap په کارولو سره شیل ولیکئ. د لا زیاتو معلوماتو لپاره، man 3 libcap وګورئ.

کله چې برنامه لیکئ ، ډیری وختونه پراختیا کونکی دمخه نه پوهیږي ټول هغه ځانګړتیاوې چې برنامه د چلولو په وخت کې ورته اړتیا لري؛ سربیره پردې، دا ځانګړتیاوې ممکن په نوي نسخو کې بدلون ومومي.

زموږ د پروګرام د وړتیاوو د ښه پوهیدو لپاره، موږ کولی شو د BCC وړ وسیله واخلو، کوم چې د cap_capable kernel فعالیت لپاره kprobe ټاکي:

/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 دی، دا په فایل کې د کرنل سرچینې کوډ کې د ثابت په توګه تعریف شوی دی include/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 لپاره د چلولو په وخت کې فعال کیږي ترڅو دوی ته اجازه ورکړي چې په غیر مراعات شوي حالت کې پرمخ بوځي، مګر دوی یوازې د ډیری غوښتنلیکونو چلولو لپاره اړین وړتیاو ته اجازه ورکوي. کله چې یو غوښتنلیک ځینې وړتیاو ته اړتیا لري، ډاکر کولی شي دوی د --cap-add په کارولو سره چمتو کړي:

docker run -it --rm --cap-add=NET_ADMIN ubuntu ip link add dummy0 type dummy

دا کمانډ به کانټینر ته د CAP_NET_ADMIN وړتیا ورکړي، دا اجازه ورکوي چې د dummy0 انٹرفیس اضافه کولو لپاره د شبکې لینک تنظیم کړي.

بله برخه ښیي چې څنګه ځانګړتیاوې لکه فلټر کول، مګر د یو مختلف تخنیک کارول چې موږ ته اجازه راکوي چې په پروګرام کې خپل فلټرونه پلي کړو.

Seccomp

Seccomp د خوندي کمپیوټر لپاره ولاړ دی او یو امنیتي پرت دی چې په لینکس کرنل کې پلي کیږي چې پراختیا کونکو ته اجازه ورکوي چې ځینې سیسټم زنګونه فلټر کړي. که څه هم Seccomp د لینوکس سره په وړتیاو کې د پرتلې وړ دی، د ځینې سیسټم کالونو اداره کولو وړتیا دا د دوی په پرتله خورا انعطاف وړ کوي.

د Seccomp او لینکس ځانګړتیاوې په دوه اړخیزه توګه ځانګړي ندي او ډیری وختونه د دواړو طریقو څخه د ګټې اخیستنې لپاره یوځای کارول کیږي. د مثال په توګه، تاسو ممکن غواړئ یو پروسې ته د CAP_NET_ADMIN وړتیا ورکړئ مګر اجازه مه ورکوئ چې د ساکټ اتصالونه ومني، د منلو او منلو 4 سیسټم زنګونه بند کړئ.

د Seccomp فلټر کولو میتود د BPF فلټرونو پراساس دی چې په SECOMP_MODE_FILTER حالت کې کار کوي ، او د سیسټم کال فلټر کول په ورته ډول د پاکټونو په څیر ترسره کیږي.

د Seccomp فلټرونه د PR_SET_SECCOMP عملیاتو له لارې د prctl په کارولو سره بار شوي. دا فلټرونه د BPF پروګرام بڼه اخلي چې د هر Seccomp پاکټ لپاره اجرا کیږي چې د seccomp_data جوړښت لخوا استازیتوب کیږي. دا جوړښت د حوالې جوړښت لري، د سیسټم زنګ په وخت کې د پروسیسر لارښوونو ته اشاره کوي، او د سیسټم کال ډیری دلیلونه، چې د uint64 په توګه څرګند شوي.

دا هغه څه دي چې د seccomp_data جوړښت د لینکس/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 (خراب سیسټم کال) سیګنال هغه کار ته لیږل کیږي چې ورته زنګ وهي.

- SECOMP_RET_ERRNO - د سیسټم زنګ نه دی اجرا شوی، او د SECOMP_RET_DATA فلټر بیرته ستنیدو ارزښت یوه برخه د کارونکي ځای ته د غلط ارزښت په توګه لیږدول کیږي. د غلطۍ د علت پورې اړه لري، مختلف غلط ارزښتونه بیرته راستانه شوي. په راتلونکې برخه کې د غلطۍ شمیرې لیست چمتو شوی.

- SECOMP_RET_TRACE - د PTRACE_O_TRACESECCOMP په کارولو سره د ptrace ټرسر ته خبرتیا ورکولو لپاره کارول کیږي کله چې د سیسټم کال اجرا کیږي د پروسې لیدلو او کنټرول لپاره. که یو ټرسر وصل نه وي، یوه تېروتنه بیرته راستانه شوې، errno -ENOSYS ته ټاکل شوی، او د سیسټم کال نه اجرا کیږي.

- SECOMP_RET_LOG - د سیسټم کال حل شوی او لاګ شوی.

- SECOMP_RET_ALLOW - د سیسټم کال په ساده ډول اجازه لري.

ptrace یو سیسټم دی چې د tracee په نوم پروسې کې د تعقیب میکانیزم پلي کولو لپاره د پروسې اجرا کولو نظارت او کنټرول وړتیا سره. د ټریس برنامه کولی شي په مؤثره توګه په اجرا کولو اغیزه وکړي او د ټریسي حافظې راجسترونه بدل کړي. د Seccomp په شرایطو کې، ptrace کارول کیږي کله چې د SECOMP_RET_TRACE حالت کوډ لخوا پیل شي، نو ټرسر کولی شي د سیسټم کال د اجرا کولو مخه ونیسي او خپل منطق پلي کړي.

د Seccomp تېروتنې

وخت په وخت، د Seccomp سره د کار کولو په وخت کې، تاسو به د مختلفو غلطیو سره مخ شئ، کوم چې د SECOMP_RET_ERRNO ډول د بیرته ستنیدو ارزښت لخوا پیژندل شوي. د یوې غلطۍ راپور ورکولو لپاره، د seccomp سیسټم کال به د 1 پرځای -0 بیرته راشي.

لاندې تېروتنې ممکن دي:

- EACCESS - زنګ وهونکي ته اجازه نه ورکول کیږي چې سیسټم ته زنګ ووهي. دا معمولا پیښیږي ځکه چې دا د CAP_SYS_ADMIN امتیازات نلري یا no_new_privs د prctl په کارولو سره تنظیم شوي ندي (موږ به پدې اړه وروسته خبرې وکړو)؛

— EFAULT — منظور شوي دلیلونه (args په seccomp_data جوړښت کې) د اعتبار وړ پته نلري؛

- EINVAL - دلته څلور دلیلونه کیدی شي:

- غوښتل شوي عملیات نامعلوم دي یا په اوسني ترتیب کې د کرنل لخوا نه ملاتړ کیږي؛

- ټاکل شوي بیرغونه د غوښتل شوي عملیاتو لپاره اعتبار نلري؛

- په عملیاتو کې BPF_ABS شامل دي، مګر د ټاکل شوي آفسیټ سره ستونزې شتون لري، کوم چې ممکن د seccomp_data جوړښت له اندازې څخه زیات وي؛

- فلټر ته د لارښوونو شمیر له اعظمي حد څخه ډیر دی؛

- ENOMEM - د پروګرام اجرا کولو لپاره کافي حافظه نه ده؛

- EOPNOTSUPP - عملیاتو اشاره وکړه چې د SECOMP_GET_ACTION_AVAIL سره عمل شتون درلود، مګر کرنل په دلیلونو کې د بیرته راستنیدو ملاتړ نه کوي؛

- ESRCH - یوه ستونزه رامینځته شوه کله چې د بل جریان همغږي کول؛

- ENOSYS - د SECOMP_RET_TRACE عمل سره هیڅ ټرسر نشته.

prctl یو سیسټم کال دی چې د کارونکي ځای پروګرام ته اجازه ورکوي چې د پروسې ځانګړي اړخونه سمبال کړي (سیټ او ترلاسه کړي) لکه د بایټ پایښت، د تار نومونه، د خوندي محاسبې حالت (Seccomp)، امتیازات، Perf پیښې، او نور.

Seccomp ممکن تاسو ته د سینڈ باکس ټیکنالوژۍ په څیر ښکاري، مګر دا نده. Seccomp یو افادیت دی چې کاروونکو ته اجازه ورکوي چې د سینڈ باکس میکانیزم رامینځته کړي. اوس راځئ وګورو چې څنګه د کارونکي متقابل عمل برنامې د فلټر په کارولو سره رامینځته کیږي چې مستقیم د 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_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),
  };

لارښوونې د 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 کې د جوړښت ارزښت د آرچ سره مساوي دی. که داسې وي، راتلونکي لارښوونې ته په آفسیټ 0 کې کود کړئ، که نه نو په آفسټ 3 کې کود وکړئ (په دې حالت کې) د تېروتنې غورځولو لپاره ځکه چې آرک سره سمون نه خوري.

- 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 | (غلطي او SECOMP_RET_DATA)) - برنامه د BPF_RET سره پای ته رسوي او په پایله کې د غلط متغیر شمیرې سره SECOMP_RET_ERRNO یوه تېروتنه رامینځته کوي.

- BPF_STMT(BPF_RET + BPF_K, SECOMP_RET_ALLOW) - برنامه د BPF_RET سره پای ته رسوي او د سیسټم کال ته اجازه ورکوي چې د SECCOMP_RET_ALLOW په کارولو سره اجرا شي.

SECOMP CBPF دی
تاسو شاید حیران یاست چې ولې د لارښوونو لیست د تالیف شوي ELF څیز یا د JIT مرتب شوي C برنامې پرځای کارول کیږي.

د دې لپاره دوه لاملونه شتون لري.

• لومړی، Seccomp cBPF (کلاسیک BPF) کاروي نه eBPF، پدې معنی چې: دا هیڅ راجستر نلري، مګر یوازې د محاسبې وروستۍ پایلې ذخیره کولو لپاره یو جمع کونکی، لکه څنګه چې په مثال کې لیدل کیدی شي.

• دوهم، Seccomp په مستقیم ډول د BPF لارښوونو لړۍ ته اشاره کوي او بل څه نه. هغه میکرو چې موږ یې کارولي دي په ساده ډول د دې لارښوونو په ټاکلو کې د پروګرامر-دوستانه طریقې سره مرسته کوي.

که تاسو د دې مجلس په پوهیدو کې ډیرې مرستې ته اړتیا لرئ، سیډوکوډ ته پام وکړئ چې ورته کار کوي:

if (arch != AUDIT_ARCH_X86_64) {
    return SECCOMP_RET_ALLOW;
}
if (nr == __NR_write) {
    return SECCOMP_RET_ERRNO;
}
return SECCOMP_RET_ALLOW;

د ساکټ_فلټر جوړښت کې د فلټر کوډ تعریف کولو وروسته ، تاسو اړتیا لرئ د ساک_فپروګ تعریف کړئ چې کوډ پکې وي او د فلټر محاسبه شوي اوږدوالی. د دې معلوماتو جوړښت ته اړتیا ده چې د پروسې اعلانولو لپاره د دلیل په توګه وروسته پرمخ بوځي:

struct sock_fprog prog = {
   .len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
   .filter = filter,
};

د install_filter فنکشن کې کولو لپاره یوازې یو شی پاتې دی - برنامه پخپله پورته کړئ! د دې کولو لپاره، موږ prctl کاروو، د خوندي کمپیوټري حالت ته د ننوتلو لپاره PR_SET_SECCOMP د اختیار په توګه واخلو. بیا موږ موډ ته وایو چې د SECOMP_MODE_FILTER په کارولو سره فلټر پورته کړئ، کوم چې د sock_fprog ډول پروګ متغیر کې شتون لري:

  if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {
    perror("prctl(PR_SET_SECCOMP)");
    return 1;
  }
  return 0;
}

په نهایت کې، موږ کولی شو زموږ د install_filter فعالیت وکاروو، مګر مخکې له دې چې موږ د اوسني اجرا کولو لپاره PR_SET_NO_NEW_PRIVS ترتیبولو لپاره prctl وکاروو او په دې توګه د هغه وضعیت څخه مخنیوی وکړو چې د ماشوم پروسې د دوی د والدینو په پرتله ډیر امتیازات ترلاسه کوي. د دې سره، موږ کولی شو د انسټالټ فلټر فنکشن کې لاندې 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]);
 }

راځه چي پیل یی کړو. زموږ د برنامه تالیف کولو لپاره موږ کولی شو کلینګ یا 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 کار کوي او ښه نظر لرئ چې تاسو ورسره څه کولی شئ. مګر ایا تاسو نه غواړئ د CBPF پرځای د eBPF سره ورته شی ترلاسه کړئ ترڅو خپل بشپړ ځواک وکاروي؟

کله چې د eBPF برنامو په اړه فکر کوئ ، ډیری خلک فکر کوي چې دوی په ساده ډول دوی لیکي او د مدیر امتیازاتو سره یې باروي. پداسې حال کې چې دا بیان عموما ریښتیا وي، کرنل په مختلفو کچو کې د eBPF شیانو د ساتنې لپاره د میکانیزمونو سیټ پلي کوي. دا میکانیزمونه د BPF LSM جالونه بلل کیږي.

BPF LSM جالونه

د سیسټم پیښو د جوړښت څخه خپلواکه نظارت چمتو کولو لپاره، LSM د جال مفهوم پلي کوي. د هک کال په تخنیکي ډول د سیسټم کال ته ورته دی، مګر سیسټم خپلواک دی او د زیربنا سره مدغم دی. LSM یو نوی مفهوم وړاندې کوي په کوم کې چې د خلاصون پرت کولی شي د ستونزو څخه مخنیوي کې مرسته وکړي کله چې په مختلف جوړښتونو کې د سیسټم تلیفونونو سره معامله کوي.

د لیکلو په وخت کې، کرنل د BPF برنامو سره تړلی اوه هکونه لري، او 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 دی. هغه د ډاکر مالتړ کې کار کړی او د Runc، Go او BCC وسیلو، او همدارنګه د نورو خلاصې سرچینې پروژو پراختیا کې یې مرسته کړې. د ډاکر پروژو او د ډاکر پلگ ان ایکوسیستم پراختیا کې د هغه د کار لپاره پیژندل شوی. ډیویډ د شعاع ګرافونو په اړه خورا لیواله دی او تل د فعالیت غوره کولو په لټه کې دی.

لورینزو فونټانا په سیسډیګ کې د خلاصې سرچینې ټیم کې کار کوي ، چیرې چې هغه په ​​​​لومړني ډول په Falco متمرکز دی ، د کلاوډ اصلي کمپیوټري بنسټ پروژه چې د کانټینر چلولو امنیت او د کرنل ماډل او eBPF له لارې د انډولۍ کشف چمتو کوي. هغه د توزیع شوي سیسټمونو، سافټویر تعریف شوي شبکې، د لینکس کرنل، او د فعالیت تحلیل په اړه لیوالتیا لري.

» د کتاب په اړه نور جزئیات دلته موندلی شئ د خپرونکي ویب پاڼه
» فهرست
» اقتباس

د Khabrozhiteley لپاره 25% تخفیف د کوپن په کارولو سره - لینوکس

د کتاب د کاغذي نسخې په تادیه کولو سره، یو بریښنایی کتاب به د بریښنالیک له لارې لیږل کیږي.

سرچینه: www.habr.com

Add a comment