লিনাক্সে নতুন ফাইল বর্ণনাকারী খোলার প্রক্রিয়াটিকে আটকাও তবে সকেটের মাধ্যমে ফাইল বর্ণনাকারী গ্রহণের অনুমতি দিন


9

আমি বর্তমানে এমন একটি প্রকল্পে কাজ করছি যেখানে আমার পিতামাতার প্রক্রিয়া রয়েছে যা একটি সকেটপায়ার সেট করে, কাঁটাচামচ করে এবং তারপরে যোগাযোগের জন্য এই সকেটপেইরটি ব্যবহার করে। শিশু, যদি এটি কোনও ফাইল (বা অন্য কোনও ফাইল বর্ণনাকারী ভিত্তিক সংস্থান) খুলতে চায় তবে সর্বদা পিতামাতার কাছে যেতে হবে, fdউত্সটির জন্য অনুরোধ করতে হবে এবং সকেটপেইরের মাধ্যমে প্রেরণ করা উচিত। তদুপরি আমি শিশুটিকে নিজেই কোনও ফাইল বিবরণী খুলতে বাধা দিতে চাই to

আমি হোঁচট খেয়েছি setrlimitযা সফলভাবে শিশুটিকে নতুন ফাইল বর্ণনাকারী খোলার থেকে আটকাচ্ছে, তবে এটি প্রাথমিক সকেট সংযোগের মাধ্যমে প্রেরিত কোনও ফাইল বর্ণনাকারীকেও অবৈধ বলে মনে হচ্ছে। লিনাক্সে এমন কোন পদ্ধতি রয়েছে যা একটি একক প্রক্রিয়াটিকে কোনও ফাইল খোলার অনুমতি দেয়, তার ফাইল বিবরণকারীকে অন্য প্রক্রিয়াগুলিতে প্রেরণ করে এবং তাদের দ্বারা এই ফাইলগুলি কোনও ফাইল বিবরণকারী খোলার অনুমতি না দিয়ে তাদের ব্যবহার করতে দেয়?

আমার ব্যবহারের ক্ষেত্রে যা কোনও কার্নেল কনফিগারেশন, সিস্টেম কল ইত্যাদি হতে পারে যতক্ষণ না এটি কাঁটাচামচ পরে প্রয়োগ করা যেতে পারে এবং যতক্ষণ না এটি সমস্ত ফাইল বর্ণনাকারীর ক্ষেত্রে প্রযোজ্য (কেবল ফাইল নয় সকেট, সকেটপেইস ইত্যাদি)।


1
আপনি সেক কম্পিউটারে আগ্রহী হতে পারেন।
ব্যবহারকারী 253751

উত্তর:


6

আপনার এখানে যা আছে তা হ'ল সেকম্পম্প ব্যবহারের ক্ষেত্রে ।

সেকম্পম্প ব্যবহার করে, আপনি বিভিন্ন উপায়ে সিস্কলগুলি ফিল্টার করতে পারেন। আপনি কি এই অবস্থায় কাজ করতে চান পরে হয়, fork()একটি ইনস্টল করার seccompফিল্টার যে ব্যবহার নামঞ্জুর করে open(2), openat(2), socket(2)(এবং আরও অনেক কিছু)। এটি সম্পাদন করতে, আপনি নিম্নলিখিতগুলি করতে পারেন:

  1. প্রথমে seccomp_init(3)এর ডিফল্ট আচরণ ব্যবহার করে একটি সেকম্পম্প প্রসঙ্গ তৈরি করুন SCMP_ACT_ALLOW
  2. তারপরে seccomp_rule_add(3)প্রতিটি সিস্কেল যা আপনি অস্বীকার করতে চান তা ব্যবহার করে প্রসঙ্গে একটি নিয়ম যুক্ত করুন । আপনি ব্যবহার করতে পারেন SCMP_ACT_KILL, যদি প্রাপ্ত syscall চেষ্টা করা হয় প্রক্রিয়া হত্যা করার SCMP_ACT_ERRNO(val)করতে নির্দিষ্ট ফিরে প্রাপ্ত syscall ব্যর্থ errnoমান, বা অন্য কোন actionমান ম্যানুয়েল পৃষ্ঠা সংজ্ঞায়িত।
  3. প্রসঙ্গটি seccomp_load(3)কার্যকর করার জন্য ব্যবহার করে লোড করুন ।

চালিয়ে যাওয়ার আগে, দ্রষ্টব্য যে শ্বেতলিস্ট পদ্ধতির চেয়ে ব্ল্যাকলিস্ট পদ্ধতির মতো সাধারণভাবে দুর্বল। এটি এমন কোনও সিস্কেলকে অনুমতি দেয় যা স্পষ্টভাবে অস্বীকৃত নয় এবং এর ফলে ফিল্টারটি বাইপাসে যেতে পারে । আপনি যদি বিশ্বাস করেন যে আপনি যে শিশু প্রক্রিয়াটি সম্পাদন করতে চান তা ফিল্টারটি এড়িয়ে যাওয়ার চেষ্টা করতে পারে, বা যদি আপনি ইতিমধ্যে জানেন যে কোন সিস্টেমে বাচ্চাদের প্রয়োজন হবে, একটি শ্বেত তালিকাটি আরও ভাল, এবং আপনার উপরের বিপরীতটি করা উচিত: এর ডিফল্ট ক্রিয়া সহ ফিল্টার তৈরি করুন SCMP_ACT_KILLএবং এর সাথে প্রয়োজনীয় সিস্টেমে অনুমতি দিন SCMP_ACT_ALLOW। কোডের ক্ষেত্রে পার্থক্যটি ন্যূনতম (হোয়াইটলিস্ট সম্ভবত দীর্ঘতর, তবে পদক্ষেপগুলি একই)।

উপরের উদাহরণটি এখানে দেওয়া হয়েছে (আমি exit(-1)কেবল সরলতার জন্য ত্রুটির ক্ষেত্রে করছি ):

#include <stdlib.h>
#include <seccomp.h>

static void secure(void) {
    int err;
    scmp_filter_ctx ctx;

    int blacklist[] = {
        SCMP_SYS(open),
        SCMP_SYS(openat),
        SCMP_SYS(creat),
        SCMP_SYS(socket),
        SCMP_SYS(open_by_handle_at),
        // ... possibly more ...
    };

    // Create a new seccomp context, allowing every syscall by default.
    ctx = seccomp_init(SCMP_ACT_ALLOW);
    if (ctx == NULL)
        exit(-1);

    /* Now add a filter for each syscall that you want to disallow.
       In this case, we'll use SCMP_ACT_KILL to kill the process if it
       attempts to execute the specified syscall. */

    for (unsigned i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); i++) {
        err = seccomp_rule_add(ctx, SCMP_ACT_KILL, blacklist[i], 0);
        if (err)
            exit(-1);
    }

    // Load the context making it effective.
    err = seccomp_load(ctx);
    if (err)
        exit(-1);
}

এখন, আপনার প্রোগ্রামে, আপনি ঠিক ঠিক এর পরে সেকম্পম্প ফিল্টার প্রয়োগ করতে উপরের ফাংশনটিতে কল করতে পারেন fork():

child_pid = fork();
if (child_pid == -1)
    exit(-1);

if (child_pid == 0) {
    secure();

    // Child code here...

    exit(0);
} else {
    // Parent code here...
}

সেক কম্পিউটারে কয়েকটি গুরুত্বপূর্ণ নোট:

  • একটি সেকম্পম্প ফিল্টার, একবার প্রয়োগ করা হলে, প্রক্রিয়া দ্বারা সরানো বা পরিবর্তন করা যাবে না।
  • যদি fork(2)বা clone(2)ফিল্টার দ্বারা অনুমোদিত হয় তবে যে কোনও শিশু প্রক্রিয়া একই ফিল্টার দ্বারা সীমাবদ্ধ থাকবে।
  • যদি execve(2)অনুমতি দেওয়া হয় তবে বিদ্যমান ফিল্টারটি কল করার জন্য জুড়ে সংরক্ষণ করা হবে execve(2)
  • যদি prctl(2)সিস্কেল অনুমোদিত হয় তবে প্রক্রিয়াটি আরও ফিল্টার প্রয়োগ করতে সক্ষম।

2
একটি স্যান্ডবক্সের জন্য ব্ল্যাকলিস্টিং? সাধারণত একটি খারাপ ধারণা, আপনি পরিবর্তে হোয়াইটলিস্ট করতে চান।
Deduplicator

@ ডেডুকিপ্লেটর আমি জানি, তবে একটি হোয়াইটলিস্ট পদ্ধতি ওপির অবস্থার জন্য খুব ভালভাবে প্রযোজ্য না কারণ তারা কেবল নতুন ফাইল বর্ণনাকারী খোলার বিষয়টি অস্বীকার করতে চায়। আমি শেষে একটি নোট যুক্ত করব।
মার্কো বোনেলি

উত্তরের জন্য ধন্যবাদ, এটাই আমার দরকার। মূলত আমি যে অ্যাপ্লিকেশনটি চেয়েছিলাম সেটির জন্য একটি শ্বেতলিস্ট প্রকৃতপক্ষে আরও ভাল। আমি কেবল মনে রাখিনি যে কেবল ফাইল বর্ণনাকারী খোলার চেয়ে আরও বেশি কিছু সীমাবদ্ধ করা উচিত।
jklmnn

হ্যাঁ, ঠিক আছে আমি সত্যিই ভুলে গেছি এটি socket(2)একটি তৈরি করতে পারে fd, যাতে খুব ব্লক করা উচিত। আপনি যদি সন্তানের প্রক্রিয়াটি জানেন তবে একটি শ্বেত তালিকাটি আরও ভাল।
মার্কো বোনেলি

@ মারকোবোনেলি একটি শ্বেত তালিকা অবশ্যই ভাল। চট করে, creat(), dup(), এবং dup2()সব Linux সিস্টেম কল রিটার্ন ফাইল বর্ণনাকারী হয়। একটি কালো তালিকাভুক্ত করার বিভিন্ন উপায় রয়েছে ...
অ্যান্ড্রু হেনেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.