
لغة ومكتبة لتحديد سياسات تصفية استدعاءات النظام.
كايفل هي لغة ومكتبة لتحديد سياسات تصفية استدعاءات النظام. يتم تجميع السياسات إلى كود BPF يمكن استخدامه مع seccomp-filter.
هذا ليس منتجًا رسميًا من Google.
struct sock_fprog prog;
kafel_ctxt_t ctxt = kafel_ctxt_create();
kafel_set_input_string(ctxt, seccomp_policy);
if (kafel_compile(ctxt, &prog)) {
fprintf(stderr, "policy compilation failed: %s", kafel_error_msg(ctxt));
kafel_ctxt_destroy(&ctxt);
exit(-1);
}
kafel_ctxt_destroy(&ctxt);
prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
free(prog.filter);
struct sock_fprog prog;
if (kafel_compile_string(seccomp_policy, &prog)) {
fputs("policy compilation failed", stderr);
exit(-1);
}
prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
free(prog.filter);
يتم استخدام لغة بسيطة لتعريف السياسات.
ملف السياسة يتكون من تعليمات.
يمكن أن تكون التعليمات:
سيتم إضافة تعليمات تعريف السياسة الموضوعة في نطاق الملف إلى سياسة المستوى الأعلى الضمنية. سيتم تجميع سياسة المستوى الأعلى هذه.
DEFAULT the_action
تحدد أن الإجراء the_action يجب اتخاذه عندما لا تتطابق أي قاعدة.
يجب تحديد الإجراء الافتراضي مرة واحدة فقط.
إذا لم يحدد ملف السياسة أي إجراءات افتراضية، سيكون الإجراء الافتراضي هو KILL
يدعم كايفل ترميزات الأرقام التالية:
420xfa107770b10101يمكنك تعريف ثوابت رقمية لجعل سياساتك أكثر قابلية للقراءة. يمكن وضع تعريفات الثوابت في أي مكان تقريبًا في ملف السياسة. لا يمكن وضع تعريف ثابت داخل تعريف سياسة. يمكن بعد ذلك استخدام الثوابت المعرفة في أي مكان يُتوقع فيه وجود رقم.
#define MYCONST 123
تعريف السياسة هو قائمة من كتل الإجراءات وتعليمات الاستخدام مفصولة بفواصل.
samples/ يحتوي على بعض الأمثلة السياسية التي توضح الميزات المدعومة.
يعمل USE someOtherPolicy كما لو تم لصق محتوى someOtherPolicy في مكانها. يمكنك فقط استخدام السياسات المعرفة قبل تعليمة الاستخدام.
باستخدام تعليمات الاستخدام، يمكنك إنشاء مجموعات ذات معنى من قواعد التصفية التي تعتبر لبنات بناء لسياسات أكبر.
تتكون كتلة الإجراءات من هدف وقائمة من قواعد مطابقة استدعاءات النظام مفصولة بفواصل.
هدف القاعدة الأولى المتطابقة هو قرار السياسة.
يسرد الجدول التالي أهداف كايفل وقيم العودة المقابلة لـ seccomp-filter.
تتكون قاعدة من اسم استدعاء النظام وقائمة اختيارية من التعبيرات المنطقية.
قائمة من التعبيرات المنطقية مفصولة بفواصل. الفاصلة مكافئة دلاليًا لـ || ولكن لها أولوية أقل، لذا قد تكون أسهل في القراءة.
عادةً ما يتم تحديد استدعاءات النظام بأسمائها كما هي معرفة في نواة لينكس. ومع ذلك، يمكنك أيضًا تصفية استدعاءات النظام المخصصة غير الموجودة في قائمة استدعاءات النظام القياسية. يمكنك إما تعريف ثابت واستخدامه بدلاً من اسم استدعاء النظام أو استخدام الكلمة المفتاحية SYSCALL.
#define mysyscall -1
POLICY my_const {
ALLOW {
mysyscall
}
}
POLICY my_literal {
ALLOW {
SYSCALL[-1]
}
}
يمكنك تقييد قاعدة استدعاء النظام لمجموعة فرعية من المعماريات باستخدام حارس ON. يقبل الحارس إما اسم معمارية واحدة أو قائمة مفصولة بفواصل ومحاطة بأقواس. تتوافق الأسماء مع الأهداف المعروفة من قبل kafel_set_target_archs (على سبيل المثال x86_64, x86, arm, aarch64, mips64, riscv64, m68k).
ALLOW {
io_uring_setup ON x86_64,
arm_fadvise64_64 ON arm
}
عند التجميع لمعمارية خارج نطاق الحارس، يتم تجاهل قاعدة استدعاء النظام، لذا لم تعد السياسات عبر المعماريات بحاجة إلى تكرار سياسات كاملة فقط لمراعاة اختلافات توفر استدعاءات النظام.
تُستخدم التعبيرات المنطقية لتصفية استدعاءات النظام بناءً على وسائطها. يشبه التعبير بناء جملة لغة C، باستثناء عدم وجود عوامل حسابية.
some_syscall(first_arg, my_arg_name) { first_arg == 42 && my_arg_name != 42 }
يمكن استخدام عاملي البت AND (&) و OR (|) لاختبار الأعلام.
mmap { (prot & PROT_EXEC) == 0 },
open { flags == O_RDONLY|O_CLOEXEC }
لا تحتاج إلى تعريف وسائط لاستدعاءات النظام المعروفة ولكن يمكنك فقط استخدام أسمائها العادية كما هو محدد في نواة لينكس وصفحات man.
write { fd == 1 }
من أجل تبسيط إعادة الاستخدام وتأليف السياسات، يوفر كايفل دعم التضمين.
#include "some_other_file.policy"
يبحث كايفل عن الملفات المضمنة فقط ضمن الدلائل المضافة صراحةً إلى مسارات البحث.
kafel_add_include_search_path(ctxt, "includes/path");
يضيف includes/path إلى مسارات البحث - سيشير توجيه التضمين المثال بعد ذلك إلى includes/path/some_other_file.policy.
يتم إنهاء توجيه التضمين بسطر جديد أو فاصلة منقوطة. يمكن تحديد ملفات متعددة، مفصولة بمسافات، في توجيه واحد.
#include "first.policy" "second.policy"; #include "third.policy"
عند استخدامه مع nsjail، يتيح الأمر التالي إنشاء بيئة مقيدة إلى حد ما لشلّك
$ ./nsjail --chroot / --seccomp_string 'POLICY a { ALLOW { write, execve, brk, access, mmap, open, newfstat, close, read, mprotect, arch_prctl, munmap, getuid, getgid, getpid, rt_sigaction, geteuid, getppid, getcwd, getegid, ioctl, fcntl, newstat, clone, wait4, rt_sigreturn, exit_group } } USE a DEFAULT KILL' -- /bin/sh -i
[2017-01-15T21:53:08+0100] Mode: STANDALONE_ONCE
[2017-01-15T21:53:08+0100] Jail parameters: hostname:'NSJAIL', chroot:'/', process:'/bin/sh', bind:[::]:0, max_conns_per_ip:0, uid:(ns:1000, global:1000), gid:(ns:1000, global:1000), time_limit:0, personality:0, daemonize:false, clone_newnet:true, clone_newuser:true, clone_newns:true, clone_newpid:true, clone_newipc:true, clonew_newuts:true, clone_newcgroup:false, keep_caps:false, tmpfs_size:4194304, disable_no_new_privs:false, pivot_root_only:false
[2017-01-15T21:53:08+0100] Mount point: src:'/' dst:'/' type:'' flags:0x5001 options:''
[2017-01-15T21:53:08+0100] Mount point: src:'(null)' dst:'/proc' type:'proc' flags:0x0 options:''
[2017-01-15T21:53:08+0100] PID: 18873 about to execute '/bin/sh' for [STANDALONE_MODE]
/bin/sh: 0: can't access tty; job control turned off
$ set
IFS='
'
OPTIND='1'
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
PPID='0'
PS1='$ '
PS2='> '
PS4='+ '
PWD='/'
$ id
Bad system call
$ exit
[2017-01-15T21:53:17+0100] PID: 18873 exited with status: 159, (PIDs left: 0)
| Kafel | seccomp-filter |
|---|
ALLOW | SECCOMP_RET_ALLOW |
LOG | SECCOMP_RET_LOG |
KILL, KILL_THREAD, DENY | SECCOMP_RET_KILL |
KILL_PROCESS | SECCOMP_RET_KILL_PROCESS |
USER_NOTIF | SECCOMP_RET_USER_NOTIF |
ERRNO(number) | SECCOMP_RET_ERRNO+number |
TRAP(number) | SECCOMP_RET_TRAP+number |
TRACE(number) | SECCOMP_RET_TRACE+number |