Leabhar "BPF airson Linux Monitoring"

Leabhar "BPF airson Linux Monitoring"Halo, luchd-còmhnaidh Khabro! Is e inneal brìgheil BPF aon de na pàirtean as cudromaiche den kernel Linux. Leigidh a chleachdadh ceart le innleadairean siostam sgàinidhean a lorg agus eadhon na duilgheadasan as iom-fhillte fhuasgladh. Ionnsaichidh tu mar a sgrìobhas tu prògraman a bhios a’ cumail sùil air agus ag atharrachadh giùlan an kernel, mar a chuireas tu còd an gnìomh gu sàbhailte gus sùil a chumail air tachartasan san kernel, agus mòran a bharrachd. Cuidichidh Dàibhidh Calavera agus Lorenzo Fontana thu gus cumhachd BPF fhuasgladh. Leudaich an eòlas agad air optimization dèanadais, lìonrachadh, tèarainteachd. - Cleachd BPF gus sùil a chumail air agus atharrachadh giùlan an kernel Linux. - Cuir a-steach còd gus sùil a chumail gu tèarainte air tachartasan kernel gun a bhith agad ris an kernel ath-chruinneachadh no an siostam ath-thòiseachadh. - Cleachd eisimpleirean còd goireasach ann an C, Go no Python. - Gabh smachd le bhith a’ sealbhachadh cearcall-beatha prògram BPF.

Tèarainteachd Kernel Linux, na feartan aige agus Seccomp

Tha BPF a’ toirt seachad dòigh chumhachdach airson an kernel a leudachadh gun a bhith ag ìobairt seasmhachd, tèarainteachd no astar. Air an adhbhar seo, bha an luchd-leasachaidh kernel den bheachd gum biodh e na dheagh bheachd a bhith a ’cleachdadh a sùbailteachd gus iomallachd pròiseas a leasachadh ann an Seccomp le bhith a’ buileachadh sìoltachain Seccomp le taic bho phrògraman BPF, ris an canar cuideachd Seccomp BPF. Anns a’ chaibideil seo mìnichidh sinn dè a th’ ann an Seccomp agus mar a thèid a chleachdadh. An uairsin ionnsaichidh tu mar a sgrìobhas tu sìoltachain Seccomp a’ cleachdadh prògraman BPF. Às deidh sin, seallaidh sinn ris na dubhan BPF togte a tha air an toirt a-steach don kernel airson modalan tèarainteachd Linux.

Tha Modalan Tèarainteachd Linux (LSM) nam frèam a bheir seachad seata de ghnìomhan a dh'fhaodar a chleachdadh gus diofar mhodalan tèarainteachd a chuir an gnìomh ann an dòigh àbhaisteach. Faodar LSM a chleachdadh gu dìreach anns a’ chraobh stòr kernel, leithid Apparmor, SELinux agus Tomoyo.

Feuch an tòisich sinn le bhith a’ bruidhinn mu chomasan Linux.

Feartan

Is e brìgh comasan Linux gum feum thu cead pròiseas neo-leasaichte a thoirt seachad gus gnìomh sònraichte a choileanadh, ach gun a bhith a’ cleachdadh suids airson an adhbhair sin, no am pròiseas a dhèanamh sochaireach, a’ lughdachadh comas ionnsaigh agus a’ leigeil leis a’ phròiseas gnìomhan sònraichte a choileanadh. Mar eisimpleir, ma dh’ fheumas an t-iarrtas agad port sochair fhosgladh, can 80, an àite a bhith a’ ruith a’ phròiseas mar fhreumh, faodaidh tu dìreach an comas CAP_NET_BIND_SERVICE a thoirt dha.

Beachdaich air prògram Go air a bheil main.go:

package main
import (
            "net/http"
            "log"
)
func main() {
     log.Fatalf("%v", http.ListenAndServe(":80", nil))
}

Bidh am prògram seo a’ frithealadh frithealaiche HTTP air port 80 (is e port sochair a tha seo). Mar as trice bidh sinn ga ruith dìreach às deidh an cruinneachadh:

$ go build -o capabilities main.go
$ ./capabilities

Ach, leis nach eil sinn a’ toirt seachad sochairean freumha, tilgidh an còd seo mearachd nuair a cheanglas sinn am port:

2019/04/25 23:17:06 listen tcp :80: bind: permission denied
exit status 1

capsh (manaidsear slige) na inneal a bhios a’ ruith slige le seata sònraichte de chomasan.

Anns a 'chùis seo, mar a chaidh ainmeachadh roimhe, an àite a bhith a' toirt seachad làn chòraichean bunaiteach, faodaidh tu ceangal port sochair a chomasachadh le bhith a 'toirt seachad an comas cap_net_bind_service còmhla ris a h-uile càil eile a tha sa phrògram mu thràth. Gus seo a dhèanamh, is urrainn dhuinn ar prògram a chur ann an 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"

Tuigidh sinn an sgioba seo beagan.

  • capsh - cleachd capsh mar shlige.
  • —caps='cap_net_bind_service+eip cap_setpcap, cap_setuid, cap_setgid+ep' - leis gu feum sinn an cleachdaiche atharrachadh (chan eil sinn airson ruith mar fhreumh), sònraichidh sinn cap_net_bind_service agus an comas an ID cleachdaiche atharrachadh bho freumh do dhuine sam bith, is e sin cap_setuid agus cap_setgid.
  • —keep=1 - tha sinn airson na comasan stàlaichte a chumail nuair a thionndaidheas tu bhon chunntas freumh.
  • —user=“chan eil duine” - cha bhi an cleachdaiche deireannach a' ruith a' phrògraim na dhuine.
  • —addamb=cap_net_bind_service - suidhich glanadh nan comasan co-cheangailte ris an dèidh tionndadh bhon mhodh freumh.
  • - -c "./comasan" - dìreach ruith am prògram.

Tha comasan ceangailte nan seòrsa sònraichte de chomasan a tha air an sealbhachadh le prògraman cloinne nuair a bhios am prògram gnàthach gan cur an gnìomh a’ cleachdadh execve(). Chan fhaod ach comasan a tha ceadaichte a bhith co-cheangailte, no ann am faclan eile, mar chomasan àrainneachd, a bhith air an sealbhachadh.

Is dòcha gu bheil thu a’ faighneachd dè tha +eip a’ ciallachadh às deidh dhut an comas a shònrachadh san roghainn --caps. Tha na brataichean sin air an cleachdadh gus dearbhadh gu bheil an comas:

-must a bhith air a ghnìomhachadh (p);

- ri fhaighinn airson a chleachdadh (e);

-can a bhith air an sealbhachadh le pròiseasan cloinne (i).

Leis gu bheil sinn airson cap_net_bind_service a chleachdadh, feumaidh sinn seo a dhèanamh leis a’ bhratach e. An uairsin tòisichidh sinn an t-slige anns an àithne. Ruithidh seo na comasan binary agus feumaidh sinn a chomharrachadh leis a’ bhratach i. Mu dheireadh, tha sinn airson gum bi am feart air a chomasachadh (rinn sinn seo gun a bhith ag atharrachadh an UID) le p. Tha e coltach ri cap_net_bind_service+eip.

Faodaidh tu an toradh a sgrùdadh le bhith a’ cleachdadh ss. Nach giorraich sinn an toradh beagan gus a bhith iomchaidh air an duilleag, ach seallaidh e am port co-cheangailte agus ID neach-cleachdaidh a bharrachd air 0, sa chùis seo 65:

# ss -tulpn -e -H | cut -d' ' -f17-
128 *:80 *:*
users:(("capabilities",pid=30040,fd=3)) uid:65534 ino:11311579 sk:2c v6only:0

San eisimpleir seo chleachd sinn capsh, ach faodaidh tu slige a sgrìobhadh a’ cleachdadh libcap. Airson tuilleadh fiosrachaidh, faic Man 3 libcap.

Nuair a bhios iad a’ sgrìobhadh phrògraman, gu math tric chan eil fios aig an leasaiche ro-làimh air na feartan uile a dh’ fheumas am prògram aig àm ruith; A bharrachd air an sin, faodaidh na feartan sin atharrachadh ann an dreachan ùra.

Gus tuigse nas fheàrr fhaighinn air comasan a’ phrògraim againn, is urrainn dhuinn an inneal comasach BCC a ghabhail, a tha a’ suidheachadh an kprobe airson a’ ghnìomh cap_capable kernel:

/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

Is urrainn dhuinn an aon rud a choileanadh le bhith a’ cleachdadh bpftrace le kprobe aon-loidhne anns a’ ghnìomh cap_capable kernel:

bpftrace -e 
   'kprobe:cap_capable {
      time("%H:%M:%S ");
      printf("%-6d %-6d %-16s %-4d %dn", uid, pid, comm, arg2, arg3);
    }' 
    | grep -i capabilities

Bheir seo a-mach rudeigin mar na leanas ma tha comasan a’ phrògraim againn air an comasachadh às deidh 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

Is e an còigeamh colbh na comasan a dh’ fheumas am pròiseas, agus leis gu bheil an toradh seo a’ toirt a-steach tachartasan neo-sgrùdaidh, chì sinn a h-uile sgrùdadh neo-sgrùdadh agus mu dheireadh an comas a tha a dhìth leis a’ bhratach sgrùdaidh (mu dheireadh san toradh) air a shuidheachadh gu 1. Comas. is e fear anns a bheil ùidh againn CAP_NET_BIND_SERVICE, tha e air a mhìneachadh mar sheasmhach ann an còd stòr kernel san fhaidhle a’ toirt a-steach /uapi/linux/ability.h le aithnichear 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">

Bidh comasan gu tric air an comasachadh aig àm ruith airson soithichean leithid runC no Docker gus leigeil leotha ruith ann am modh gun bhuannachd, ach chan eil cead aca ach na comasan a tha a dhìth gus a’ mhòr-chuid de thagraidhean a ruith. Nuair a dh’ fheumas tagradh comasan sònraichte, faodaidh Docker an toirt seachad le bhith a’ cleachdadh --cap-add:

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

Bheir an àithne seo comas CAP_NET_ADMIN don ghobhar, a’ leigeil leis ceangal lìonraidh a rèiteachadh gus an eadar-aghaidh dummy0 a chur ris.

Tha an ath earrann a’ sealltainn mar a chleachdas tu feartan leithid sìoladh, ach a’ cleachdadh dòigh eadar-dhealaichte a leigeas leinn na sìoltachain againn fhèin a chuir an gnìomh gu prògramach.

Seccomp

Tha Seccomp a’ seasamh airson Coimpiutaireachd Thèarainte agus tha e na ìre tèarainteachd air a chuir an gnìomh anns an kernel Linux a leigeas le luchd-leasachaidh gairmean siostam sònraichte a shìoladh. Ged a tha comas aig Seccomp ri Linux ann an comasan, tha a chomas air cuid de ghlainnean siostaim a riaghladh ga dhèanamh tòrr nas sùbailte an coimeas riutha.

Chan eil feartan Seccomp agus Linux eadar-dhealaichte bho chèile agus gu tric bidh iad air an cleachdadh còmhla gus buannachd fhaighinn bhon dà dhòigh-obrach. Mar eisimpleir, is dòcha gum biodh tu airson comas CAP_NET_ADMIN a thoirt do phròiseas ach gun a bhith a’ leigeil leis gabhail ri ceanglaichean socaid, a’ bacadh gairmean siostam gabhail is gabhail ri4.

Tha an dòigh sìolaidh Seccomp stèidhichte air sìoltachain BPF a tha ag obair sa mhodh SECCOMP_MODE_FILTER, agus thathas a’ sìoladh gairm siostam san aon dòigh ri pacaidean.

Bithear a’ luchdachadh sìoltachain Seccomp a’ cleachdadh prctl tron ​​obair PR_SET_SECCOMP. Tha na sìoltachain sin ann an cruth prògram BPF a thèid a chuir gu bàs airson gach pacaid Seccomp air a riochdachadh leis an structar seccomp_data. Anns an structar seo tha an ailtireachd iomraidh, comharradh air stiùireadh pròiseasar aig àm gairm an t-siostaim, agus sia argamaidean gairm siostam aig a’ char as àirde, air an cur an cèill mar uint64.

Seo mar a tha structar seccomp_data coltach bhon chòd stòr kernel san fhaidhle linux/seccomp.h:

struct seccomp_data {
int nr;
      __u32 arch;
      __u64 instruction_pointer;
      __u64 args[6];
};

Mar a chì thu bhon structar seo, is urrainn dhuinn sìoladh le gairm an t-siostaim, na h-argamaidean aige, no measgachadh den dà chuid.

Às deidh dha gach pasgan Seccomp fhaighinn, feumaidh an sìoltachan giullachd a dhèanamh gus co-dhùnadh deireannach a dhèanamh agus innse don kernel dè an ath rud a nì thu. Tha an co-dhùnadh deireannach air a chuir an cèill le aon de na luachan tilleadh (còdan inbhe).

- SECCOMP_RET_KILL_PROCESS - a’ marbhadh a’ phròiseis gu lèir sa bhad às deidh dhut gairm siostam a shìoladh nach tèid a chuir gu bàs air sgàth seo.

- SECCOMP_RET_KILL_THREAD - crìoch a chur air an t-snàthainn gnàthach sa bhad às deidh dhut gairm siostam a shìoladh nach deach a chuir gu bàs air sgàth seo.

— SECCOMP_RET_KILL - alias airson SECCOMP_RET_KILL_THREAD, air fhàgail airson co-fhreagarrachd air ais.

- SECCOMP_RET_TRAP - tha gairm an t-siostaim toirmisgte, agus thèid an comharra SIGSYS (Droch Call System) a chuir chun ghnìomh a tha ga ghairm.

- SECCOMP_RET_ERRNO - Chan eil gairm an t-siostaim air a chuir gu bàs, agus thèid pàirt de luach tilleadh sìoltachain SECCOMP_RET_DATA a chuir gu àite luchd-cleachdaidh mar luach errno. A rèir adhbhar na mearachd, tha luachan errno eadar-dhealaichte air an tilleadh. Tha liosta de na h-àireamhan mearachd anns an ath earrann.

- SECCOMP_RET_TRACE - Air a chleachdadh gus fios a chuir chun rianadair ptrace a’ cleachdadh - PTRACE_O_TRACESECCOMP gus casg a chuir air nuair a thèid gairm siostaim a chuir gu bàs gus am pròiseas sin fhaicinn agus smachd a chumail air. Mura h-eil rianadair ceangailte, thèid mearachd a thilleadh, tha errno air a shuidheachadh gu -ENOSYS, agus chan eil gairm an t-siostaim air a chuir gu bàs.

- SECCOMP_RET_LOG - tha gairm an t-siostaim air a rèiteachadh agus air a chlàradh.

- SECCOMP_RET_ALLOW - tha gairm an t-siostaim dìreach ceadaichte.

Is e gairm siostam a th’ ann am ptrace gus dòighean lorg a chuir an gnìomh ann am pròiseas ris an canar tracee, leis a’ chomas sùil a chumail air agus smachd a chumail air coileanadh a’ phròiseis. Faodaidh am prògram lorg buaidh èifeachdach a thoirt air coileanadh agus clàran cuimhne tracee atharrachadh. Ann an co-theacsa Seccomp, thathas a’ cleachdadh ptrace nuair a thèid a bhrosnachadh leis a’ chòd inbhe SECCOMP_RET_TRACE, gus an urrainn don rianadair casg a chuir air gairm an t-siostaim bho bhith a’ coileanadh agus a’ cur an gnìomh a loidsig fhèin.

Seccomp mearachdan

Bho àm gu àm, fhad ‘s a bhios tu ag obair le Seccomp, thig thu tarsainn air grunn mhearachdan, a tha air an comharrachadh le luach tilleadh den t-seòrsa SECCOMP_RET_ERRNO. Gus cunntas a thoirt air mearachd, tillidh an gairm siostam seccomp -1 an àite 0.

Tha na mearachdan a leanas comasach:

- EACCESS - Chan eil cead aig an neach-fios gairm siostam a dhèanamh. Bidh seo mar as trice a’ tachairt leis nach eil sochairean CAP_SYS_ADMIN aige no chan eil no_new_privs air a shuidheachadh le prctl (bruidhnidh sinn mu dheidhinn seo nas fhaide air adhart);

- EFAULT - chan eil seòladh dligheach aig na h-argamaidean a chaidh aontachadh (args ann an structar seccomp_data);

- EINVAL - faodaidh ceithir adhbharan a bhith an seo:

- chan eil fios air an obrachadh a chaidh iarraidh no chan eil e a’ faighinn taic bhon kernel san rèiteachadh làithreach;

- chan eil na brataichean ainmichte dligheach airson an obrachaidh a chaidh iarraidh;

-Operation gabhail a-steach BPF_ABS, ach tha duilgheadasan ann leis an t-suim a chaidh a shònrachadh, a dh'fhaodadh a bhith nas àirde na meud an seccomp_data structar;

- tha an àireamh de stiùiridhean a chaidh a thoirt don chriathrag nas àirde na an ìre as àirde;

- ENOMEM - chan eil cuimhne gu leòr ann airson am prògram a chuir an gnìomh;

- EOPNOTSUPP - chomharraich an t-obrachadh gun robh an gnìomh ri làimh le SECCOMP_GET_ACTION_AVAIL, ach chan eil an kernel a' cur taic ri tilleadh ann an argamaidean;

- ESRCH - thachair duilgheadas nuair a chaidh sruth eile a shioncronachadh;

- ENOSYS - Chan eil lorgair sam bith ceangailte ris a’ ghnìomh SECCOMP_RET_TRACE.

Is e gairm siostam a th’ ann am prctl a leigeas le prògram àite-cleachdaidh taobhan sònraichte de phròiseas a làimhseachadh (a shuidheachadh agus fhaighinn), leithid buanseasmhachd byte, ainmean snàithlean, modh àireamhachaidh tèarainte (Seccomp), sochairean, tachartasan Perf, msaa.

Is dòcha gu bheil Seccomp coltach ri teicneòlas bogsa gainmhich dhut, ach chan eil. Is e goireas a th’ ann an Seccomp a leigeas le luchd-cleachdaidh uidheamachd bogsa gainmhich a leasachadh. A-nis leig dhuinn sùil a thoirt air mar a tha prògraman eadar-obrachadh luchd-cleachdaidh air an cruthachadh a ’cleachdadh criathrag ris an canar gu dìreach le gairm siostam Seccomp.

Eisimpleir Filter Seccomp BPF

An seo seallaidh sinn mar a chuireas tu an dà ghnìomh a chaidh a dheasbad na bu thràithe còmhla, is iad sin:

- sgrìobhaidh sinn prògram Seccomp BPF, a thèid a chleachdadh mar shìoltachain le còdan tilleadh eadar-dhealaichte a rèir nan co-dhùnaidhean a chaidh a dhèanamh;

- luchdaich an sìoltachan a’ cleachdadh prctl.

An toiseach feumaidh tu cinn-cinn bhon leabharlann àbhaisteach agus an kernel 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>

Mus feuch sinn ris an eisimpleir seo, feumaidh sinn dèanamh cinnteach gu bheil an kernel air a chur ri chèile le CONFIG_SECCOMP agus CONFIG_SECCOMP_FILTER set to y. Air inneal obrach faodaidh tu seo a sgrùdadh mar seo:

cat /proc/config.gz| zcat | grep -i CONFIG_SECCOMP

Tha an còrr den chòd na ghnìomh install_filter dà-phàirt. Anns a’ chiad phàirt tha an liosta againn de stiùiridhean sìolaidh 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),
  };

Tha an stiùireadh air a shuidheachadh a’ cleachdadh na macros BPF_STMT agus BPF_JUMP a tha air am mìneachadh anns an fhaidhle linux/filter.h.
Rachamaid tro na stiùiridhean.

- BPF_STMT (BPF_LD + BPF_W + BPF_ABS (offsetof (struct seccomp_data, bogha)))) - bidh an siostam a’ luchdachadh agus a’ cruinneachadh bho BPF_LD ann an cruth an fhacail BPF_W, tha dàta pacaid suidhichte aig ìre stèidhichte BPF_ABS.

- BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, bogha, 0, 3) - dèan sgrùdadh le bhith a’ cleachdadh BPF_JEQ a bheil luach na h-ailtireachd ann an seasmhach cruinneachaidh BPF_K co-ionann ri bogha. Ma tha, leum aig co-chothromachadh 0 chun an ath stiùireadh, air neo leumaidh tu aig co-chothromachadh 3 (sa chùis seo) gus mearachd a thilgeil leis nach eil bogha a’ freagairt.

- BPF_STMT (BPF_LD + BPF_W + BPF_ABS (offsetof (struct seccomp_data, nr))) - A’ luchdachadh agus a’ cruinneachadh bho BPF_LD ann an cruth an fhacail BPF_W, is e sin àireamh gairm an t-siostaim a tha ann an co-dhùnadh stèidhichte BPF_ABS.

— BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, nr, 0, 1) - a’ dèanamh coimeas eadar àireamh gairm an t-siostaim agus luach an caochladair nr. Ma tha iad co-ionann, gluais air adhart chun ath stiùireadh agus cuir à comas gairm an t-siostaim, air neo leigidh sin le gairm an t-siostaim le SECCOMP_RET_ALLOW.

- BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (mearachd & SECCOMP_RET_DATA)) - a’ crìochnachadh a’ phrògraim le BPF_RET agus mar thoradh air sin a’ toirt a-mach mearachd SECCOMP_RET_ERRNO leis an àireamh bhon chaochladair mearachd.

- BPF_STMT (BPF_RET + BPF_K, SECCOMP_RET_ALLOW) - crìoch a chur air a’ phrògram le BPF_RET agus a’ ceadachadh gairm an t-siostaim a chuir gu bàs a’ cleachdadh SECCOMP_RET_ALLOW.

Is e SECCOMP CBPF
Is dòcha gu bheil thu a’ faighneachd carson a thathas a’ cleachdadh liosta stiùiridh an àite rud ELF cruinnichte no prògram C air a chur ri chèile le JIT.

Tha dà adhbhar ann airson seo.

• An toiseach, bidh Seccomp a’ cleachdadh cBPF (BPF clasaigeach) agus chan e eBPF, a tha a’ ciallachadh: chan eil clàran ann, ach dìreach inneal-cruinneachaidh gus an toradh àireamhachaidh mu dheireadh a stòradh, mar a chithear san eisimpleir.

• San dàrna h-àite, tha Seccomp a’ gabhail ri puing gu sreath de stiùiridhean BPF gu dìreach agus gun dad eile. Tha na macros a chleachd sinn dìreach a 'cuideachadh le bhith a' comharrachadh an stiùiridh seo ann an dòigh a tha furasta a chleachdadh le prògramadair.

Ma tha feum agad air barrachd cuideachaidh a’ tuigsinn a’ cho-chruinneachaidh seo, smaoinich air a’ chòd-brèige a nì an aon rud:

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

Às deidh dhut an còd sìoltachain a mhìneachadh anns an structar socket_filter, feumaidh tu sock_fprog a mhìneachadh anns a bheil an còd agus fad àireamhaichte a’ chriathrag. Tha feum air an structar dàta seo mar argamaid airson a bhith ag ainmeachadh gum bi am pròiseas a’ ruith nas fhaide air adhart:

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

Chan eil ach aon rud ri dhèanamh sa ghnìomh install_filter - luchdaich am prògram fhèin! Gus seo a dhèanamh, bidh sinn a’ cleachdadh prctl, a’ gabhail PR_SET_SECOMP mar roghainn a dhol a-steach gu modh coimpiutaireachd tèarainte. An uairsin innisidh sinn don mhodh an criathrag a luchdachadh a’ cleachdadh SECCOMP_MODE_FILTER, a tha anns a’ chaochladair prog de seòrsa sock_fprog:

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

Mu dheireadh, is urrainn dhuinn ar gnìomh install_filter a chleachdadh, ach ron sin feumaidh sinn prctl a chleachdadh gus PR_SET_NO_NEW_PRIVS a shuidheachadh airson an cur gu bàs an-dràsta agus mar sin an suidheachadh a sheachnadh far am faigh pròiseasan cloinne barrachd shochairean na am pàrantan. Le seo, is urrainn dhuinn na gairmean prctl a leanas a dhèanamh anns a’ ghnìomh install_filter gun chòraichean freumha a bhith againn.

A-nis is urrainn dhuinn an gnìomh install_filter a ghairm. Nach cuir sinn casg air a h-uile gairm siostam sgrìobhaidh co-cheangailte ri ailtireachd X86-64 agus dìreach thoir cead a chuireas casg air gach oidhirp. Às deidh dhuinn an criathrag a chuir a-steach, leanaidh sinn oirnn le bhith a’ cleachdadh a’ chiad argamaid:

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]);
 }

Feuch an tòisich sinn. Gus am prògram againn a chur ri chèile is urrainn dhuinn clang no gcc a chleachdadh, an dara dòigh tha e dìreach a’ cur ri chèile am faidhle main.c gun roghainnean sònraichte:

clang main.c -o filter-write

Mar a chaidh ainmeachadh, tha sinn air casg a chuir air a h-uile tagradh sa phrògram. Gus seo a dhearbhadh feumaidh tu prògram a bheir a-mach rudeigin - tha e coltach gur e deagh thagraiche a th’ ann. Seo mar a bhios i mar as trice a’ giùlan:

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

Sgoinneil! Seo cò ris a bhios cleachdadh ar prògram pasgain coltach: Bidh sinn dìreach a’ dol seachad air a’ phrògram a tha sinn airson a dhearbhadh mar a’ chiad argamaid:

./filter-write "ls -la"

Nuair a thèid a chuir gu bàs, bidh am prògram seo a’ toirt a-mach toradh gu tur falamh. Ach, faodaidh sinn strace a chleachdadh gus faicinn dè tha dol air adhart:

strace -f ./filter-write "ls -la"

Tha toradh na h-obrach air a ghiorrachadh gu mòr, ach tha am pàirt co-fhreagarrach dheth a’ sealltainn gu bheil clàran air am bacadh le mearachd EPERM - an aon fhear a shuidhich sinn. Tha seo a’ ciallachadh nach bi am prògram a’ toirt a-mach dad leis nach urrainn dha cothrom fhaighinn air gairm an t-siostam sgrìobhaidh:

[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)

A-nis tha thu a 'tuigsinn mar a tha Seccomp BPF ag obair agus tha deagh bheachd agad air dè as urrainn dhut a dhèanamh leis. Ach nach bu toil leat an aon rud a choileanadh le eBPF an àite cBPF gus a làn chumhachd a chleachdadh?

Nuair a smaoinicheas iad air prògraman eBPF, tha a’ mhòr-chuid den bheachd gu bheil iad dìreach gan sgrìobhadh agus gan luchdachadh le sochairean rianadair. Ged a tha an aithris seo fìor san fharsaingeachd, tha an kernel a’ cur an gnìomh seata de dhòighean gus nithean eBPF a dhìon aig diofar ìrean. Canar ribeachan BPF LSM ris na h-innealan sin.

BPF LSM ribe

Gus sgrùdadh neo-eisimeileach air ailtireachd a thoirt seachad air tachartasan siostam, bidh LSM a’ cur an gnìomh bun-bheachd ribe. Tha gairm dubhan gu teicnigeach coltach ri gairm siostam, ach tha e neo-eisimeileach bhon t-siostam agus amalaichte leis a’ bhun-structar. Tha LSM a’ toirt seachad bun-bheachd ùr anns am faod còmhdach tarraing-às cuideachadh le bhith a’ seachnadh dhuilgheadasan a thig orra nuair a thathar a’ dèiligeadh ri fiosan siostam air diofar ailtireachd.

Aig àm sgrìobhaidh, tha seachd dubhan aig an kernel co-cheangailte ri prògraman BPF, agus is e SELinux an aon LSM togte a bhios gan cur an gnìomh.

Tha còd stòr nan ribe suidhichte anns a’ chraobh kernel san fhaidhle a’ toirt a-steach/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);

Thèid gach fear dhiubh a ghairm aig diofar ìrean cur gu bàs:

- security_bpf - a’ dèanamh sgrùdadh tùsail air fiosan siostam BPF a chaidh a chuir gu bàs;

- security_bpf_map - sgrùdaidhean nuair a thilleas an kernel tuairisgeul faidhle airson a’ mhapa;

- security_bpf_prog - sgrùdaidhean nuair a thilleas an kernel tuairisgeul faidhle airson a’ phrògram eBPF;

- security_bpf_map_alloc - a’ sgrùdadh a bheil an raon tèarainteachd taobh a-staigh mapaichean BPF air a thòiseachadh;

- security_bpf_map_free - dèan cinnteach a bheil an raon tèarainteachd air a ghlanadh taobh a-staigh mapaichean BPF;

- security_bpf_prog_alloc - a’ sgrùdadh a bheil an raon tèarainteachd air a thòiseachadh taobh a-staigh prògraman BPF;

- security_bpf_prog_free - a’ sgrùdadh a bheil an raon tèarainteachd air a ghlanadh am broinn prògraman BPF.

A-nis, a’ faicinn seo uile, tha sinn a’ tuigsinn: is e am beachd air cùl luchd-glacaidh LSM BPF gun urrainn dhaibh dìon a thoirt do gach nì eBPF, a’ dèanamh cinnteach nach urrainn ach an fheadhainn leis na sochairean iomchaidh gnìomhachd a dhèanamh air cairtean agus prògraman.

Geàrr-chunntas

Chan e tèarainteachd rudeigin as urrainn dhut a chuir an gnìomh ann an dòigh aon-mheudach airson a h-uile dad a tha thu airson a dhìon. Tha e cudromach a bhith comasach air siostaman a dhìon aig diofar ìrean agus ann an diofar dhòighean. Creideas e no nach creid, is e an dòigh as fheàrr air siostam a dhèanamh tèarainte diofar ìrean dìon a chuir air dòigh bho dhiofar shuidheachaidhean, gus nach bi lughdachadh tèarainteachd aon ìre a’ toirt cothrom air an t-siostam gu lèir. Tha an luchd-leasachaidh bunaiteach air obair ionmholta a dhèanamh a’ toirt dhuinn seata de shreathan eadar-dhealaichte agus puingean-ceangail. Tha sinn an dòchas gu bheil sinn air tuigse mhath a thoirt dhut air dè na sreathan a th’ ann agus mar a chleachdas tu prògraman BPF gus obrachadh leotha.

Mu na h-ùghdaran

Daibhidh Calavera an CTO aig Netlify. Bha e ag obair ann an taic Docker agus chuir e ri leasachadh innealan Runc, Go agus BCC, a bharrachd air pròiseactan stòr fosgailte eile. Tha e ainmeil airson a chuid obrach air pròiseactan Docker agus leasachadh eag-shiostam plugan Docker. Tha Daibhidh gu math dìoghrasach mu ghrafaichean lasrach agus tha e an-còmhnaidh a’ coimhead ri coileanadh a bharrachadh.

Lorenzo Fontana ag obair air an sgioba le còd fosgailte aig Sysdig, far a bheil e ag amas gu sònraichte air Falco, pròiseact Cloud Native Computing Foundation a bheir seachad tèarainteachd ùine-ruith container agus lorg neo-riaghailteachd tro mhodal kernel agus eBPF. Tha e dìoghrasach mu shiostaman sgaoilte, lìonrachadh air a mhìneachadh le bathar-bog, an kernel Linux, agus mion-sgrùdadh coileanaidh.

» Gheibhear barrachd fiosrachaidh mun leabhar aig làrach-lìn foillsichear
» Clàr-innse
» Cuibhreann

Airson Khabrozhiteley lasachadh 25% a’ cleachdadh coupon - Linux

Nuair a thèid dreach pàipeir den leabhar a phàigheadh, thèid leabhar eileagtronaigeach a chuir air post-d.

Source: www.habr.com

Cuir beachd ann