রুট সুবিধাগুলি সহ কোনও প্রোগ্রামে প্রোগ্রামালিমে লেখার সবচেয়ে নিরাপদ উপায় কী?


35

একটি বিশাল অ্যাপ্লিকেশনটির প্রয়োজন হয় একটি নির্দিষ্ট সময়ে, একটি ফাইলের জন্য সংখ্যক লেখার সম্পাদনের জন্য যার জন্য রুট অনুমতি প্রয়োজন। এটি আসলে কোনও ফাইল নয় তবে একটি হার্ডওয়্যার ইন্টারফেস যা একটি ফাইল হিসাবে লিনাক্সের কাছে প্রকাশিত।

পুরো অ্যাপ্লিকেশনটিকে মূল সুযোগগুলি এড়াতে, আমি একটি বাশ স্ক্রিপ্ট লিখেছিলাম যা সমালোচনামূলক কাজ করে। উদাহরণস্বরূপ, নিম্নলিখিত স্ক্রিপ্টটি আউটপুট হিসাবে হার্ডওয়্যার ইন্টারফেসের পোর্ট 17 সক্ষম করবে:

echo "17" > /sys/class/gpio/export
echo "out" > /sys/class/gpio/gpio17/direction

তবে, যেমনটি suidআমার সিস্টেমে বাশ স্ক্রিপ্টগুলির জন্য অক্ষম রয়েছে তাই আমি আশ্চর্য হয়েছি এটি অর্জনের সর্বোত্তম উপায় কী is

  1. এখানে উপস্থাপিত কিছু workaround ব্যবহার করুন

  2. স্ক্রিপ্টটি কল করার sudoসময় কোনও পাসওয়ার্ডের প্রয়োজন এড়াতে মূল অ্যাপ্লিকেশনটি দিয়ে স্ক্রিপ্টটি কল করুন এবং সেই অনুসারে সূডার তালিকা সম্পাদনা করুন। আমি সুডোর সুবিধাগুলি দিতে কিছুটা অস্বস্তি করছি echo

  3. কেবল একটি সি প্রোগ্রাম লিখুন fprintf, এবং এটি sued রুটে সেট করুন। স্ট্রিং এবং ফাইলের নামগুলি হার্ডকোড করুন এবং নিশ্চিত করুন যে কেবল রুট এটি সম্পাদনা করতে পারে। বা কোনও পাঠ্য ফাইল থেকে স্ট্রিংগুলি পড়ুন, একইভাবে নিশ্চিত করে নিন যে কেউ ফাইল সম্পাদনা করতে পারে না।

  4. কিছু অন্যান্য সমাধান যা আমার কাছে ঘটে না এবং এটি নিরাপদে বা সরল তবে উপরের উপস্থাপনাগুলি?


10
আপনি কেবল রুট সুবিধাগুলি দিয়ে আপনার প্রোগ্রামটি শুরু করবেন না, ফাইলটি খোলেন এবং সুযোগ-সুবিধাগুলি ছেড়ে যান না কেন? প্রতিটি ওয়েবসারভার বা এ জাতীয় সকেটগুলির জন্য এটি করে। কার্যকরভাবে, আপনি রুট হিসাবে চালাচ্ছেন না, বা সহায়ক কোনও প্রয়োজনও নেই।
দামন

উত্তর:


33

আপনার sudoঅ্যাক্সেস দেওয়ার দরকার নেই echo। প্রকৃতপক্ষে, এটি অর্থহীন কারণ, উদাহরণস্বরূপ sudo echo foo > bar, পুনঃনির্দেশটি মূল ব্যবহারকারী হিসাবে করা হয়, মূল হিসাবে নয়।

এর সাথে ছোট স্ক্রিপ্টটি কল করুন sudo, NOPASSWD:কেবলমাত্র সেই স্ক্রিপ্টটিতে (এবং অন্য কোনও অনুরূপ স্ক্রিপ্টগুলি) ব্যবহারকারী (গুলি) এর অ্যাক্সেসের প্রয়োজন রয়েছে it

এই সবসময় শ্রেষ্ঠ / সবচেয়ে নিরাপদ ব্যবহার করতে উপায় sudo। স্বতন্ত্র স্ক্রিপ্ট (গুলি) -এর জন্য রুট সুবিধাগুলির প্রয়োজন এমন সংখ্যার কমান্ডকে আলাদা করুন এবং অবিশ্বস্ত বা আংশিক-বিশ্বস্ত ব্যবহারকারীকে কেবল স্ক্রিপ্টটিকে রুট হিসাবে চালানোর অনুমতি দিন।

ক্ষুদ্র- sudoসক্ষম স্ক্রিপ্ট (গুলি) ব্যবহারকারীর কাছ থেকে আরগ (বা ইনপুট) গ্রহণ করা উচিত নয় (যেমন এটি কল করে এমন কোনও প্রোগ্রামের হার্ড-কোডিং বিকল্প এবং আরোগুলি থাকা উচিত) অথবা এটি খুব সাবধানে কোনও যুক্তি / ইনপুট যা যা করতে হবে তা যাচাই করা উচিত ব্যবহারকারীর কাছ থেকে গ্রহণ।

বৈধতার মধ্যে ভৌগল হয়ে থাকুন - বাদ দেওয়ার জন্য 'জ্ঞাত খারাপ' জিনিসগুলি অনুসন্ধান করার পরিবর্তে কেবল 'জ্ঞাত ভাল' জিনিসগুলিকে মঞ্জুরি দিন এবং যেকোনও অমিল বা ত্রুটি বা দূরবর্তী স্থানে সন্দেহজনক কোনও কিছুকেই বাতিল করুন।

বৈধতা যত তাড়াতাড়ি সম্ভব স্ক্রিপ্টের মধ্যে হওয়া উচিত (এটি মূলের মতো আরও কিছু করার আগে )।


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

যে পরিবেশের সম্ভাব্য (যেমন ব্যবহারকারী দ্বারা নিয়ন্ত্রিত অন্তর্ভুক্ত "$PATH", "$HOME", "$USER"ইত্যাদি এবং স্পষ্টভাবে সহ "$QUERY_STRING"এবং "HTTP_USER_AGENT"ইত্যাদি একটি সিজিআই লিপিতে)। আসলে, তাদের সব উদ্ধৃত করুন। যদি আপনাকে একাধিক তর্ক যুক্ত করে একটি কমান্ড লাইন তৈরি করতে হয়, আরোগুলি তালিকা তৈরি করতে একটি অ্যারে ব্যবহার করুন এবং উক্ত উদ্ধৃতিটি - "${myarray[@]}"

আমি কি এখনও "যথেষ্ট পরিমাণে" তাদের উদ্ধৃতি দিয়েছি? এটা মনে রেখ. এটা কর.


18
আপনি উল্লেখ করতে ভুলে গেছেন যে স্ক্রিপ্টটি নিজেই 500 এর অনুমতি সহ রুটের মালিকানাধীন উচিত
ওয়াইল্ডকার্ড

13
কমপক্ষে লেখার অনুমতিগুলি সৎকর্মের জন্য সরিয়ে ফেলুন। সত্যিই আমার বিষয়টি ছিল। বাকীটি কেবল কঠোর হচ্ছে।
ওয়াইল্ডকার্ড

10
একটি চিন্তামূলকভাবে লিখিত সি প্রোগ্রামে শেল স্ক্রিপ্টের চেয়ে ছোট আক্রমণের পৃষ্ঠ থাকবে।
ব্যবহারকারী 253751

7
@ এমমিবিস, সম্ভবত। তবে এটি শেল স্ক্রিপ্টের চেয়ে লেখার এবং ডিবাগ করতে অনেক বেশি সময় লাগবে। এবং একটি সি সংকলক (যা কিছু উত্পাদন সার্ভারে আক্রমণকারীদের শোষণগুলি সঙ্কলন করা আরও শক্ত করে সুরক্ষার ঝুঁকি হ্রাস করতে নিষিদ্ধ) প্রয়োজন। এছাড়াও, ইন্টারমিডিয়েট লেভেল সিসাদমিন বা প্রোগ্রামারকে একজন নবজাতক দ্বারা লিখিত একটি শেল স্ক্রিপ্ট আইএমও অনুরূপ দক্ষতার দ্বারা লিখিত কোনও সি প্রোগ্রামের তুলনায় শোষণযোগ্য হওয়ার সম্ভাবনা কম - বিশেষত যদি এটি ব্যবহারকারীর সরবরাহিত ডেটা গ্রহণ এবং বৈধ করতে হয়।
ক্যাস

3
@ জোনাস উইলিকি - আমি মনে করি আমরা এখন সত্যের চেয়ে সত্য এবং সত্যই মতামতের ক্ষেত্রের মধ্যে আছি। আপনি শেল বা সি (বা পার্ল বা পাইথন বা অ্যাজক ইত্যাদি) এর জন্য বৈধ যুক্তি তুলতে পারেন হয় কম-বেশি শোষণমূলক ভুল হওয়ার ঝুঁকিতে পড়ে। সত্যই, এটি বেশিরভাগ প্রোগ্রামারের দক্ষতা এবং বিশদ (এবং ক্লান্তি, তাত্ক্ষণিকতা, সতর্কতা ইত্যাদি) এর দিকে মনোনিবেশ করার উপর নির্ভর করে। এটি সত্য, যদিও, নিম্ন স্তরের ভাষাগুলিতে উচ্চ স্তরের ভাষাগুলিতে আরও কম সংখ্যক লাইন-কোড-কোডে কী করা যায় তা অর্জনের জন্য আরও কোড লেখার প্রয়োজন হয় .... এবং প্রতিটি এলওসি একটির জন্য আরেকটি সুযোগ ভুল করা হবে।
ক্যাস

16

জিপিও ফাইলগুলিতে মালিককে পরীক্ষা করুন:

ls -l /sys/class/gpio/

সম্ভবত, আপনি খুঁজে পাবেন যে এগুলি গ্রুপের মালিকানাধীন gpio:

-rwxrwx--- 1 root     gpio     4096 Mar  8 10:50 export
...

সেক্ষেত্রে gpioসুডো ছাড়াই অ্যাক্সেস দেওয়ার জন্য আপনি কেবল নিজের ব্যবহারকারীকে গোষ্ঠীতে যুক্ত করতে পারেন:

sudo usermod -aG gpio myusername

পরিবর্তনটি কার্যকর হওয়ার জন্য আপনাকে তার পরে লগআউট এবং পুনরায় লগ ইন করতে হবে।


এটি কাজ করে না। প্রকৃতপক্ষে, সমস্ত কিছুর গোষ্ঠী মালিক /sys/class/gpio/জিপিও, তবে নিজেকে সেই গোষ্ঠীতে যুক্ত করার পরেও আমি যখনই সেখানে কিছু লেখার চেষ্টা করি তখনও আমি "অনুমতি অস্বীকার" পাই।
vsz

1
সমস্যাটি হ'ল ফাইলগুলি /sys/class/gpio/আসলে /sys/devices/platform/soc/<some temporary name>/gpioমালিক এবং গোষ্ঠী উভয়ই মূল যেখানে সেখানে কেবলমাত্র প্রতিলিঙ্ক ।
vsz

4
@vsz আপনি কি চেষ্টা করেছেন chgrp gpio /sys/devices/platform/soc/*/gpio? সম্ভবত এর মতো কিছু একটি স্টার্টআপ ফাইলে রাখা যেতে পারে।
jpa

হ্যাঁ, তবে এটি এত সহজ নয়। তারা সবসময় অন্যভাবে তৈরি হয় হিসেবে আমি ভালো কিছু ব্যবহার ছিলchgrp gpio `readlink -f /sys/class/gpio/gpio18`/*
vsz

7

এর একটি সমাধান (বিশেষত লিনাক্স ডেস্কটপে ব্যবহৃত হয় তবে অন্যান্য ক্ষেত্রে এটি প্রযোজ্য) ডি-বাস ব্যবহার করে অনুমোদনের জন্য রুট এবং পোলকিট হিসাবে চলমান একটি ছোট পরিষেবা সক্রিয় করতে। এটিই মূলত যা পলকিতের জন্য ডিজাইন করা হয়েছিল ; এর সূচনা ডকুমেন্টেশন থেকে :

পোলকিট একটি অনুমোদনপ্রাপ্ত এপিআই সরবরাহ করে যা সুবিধাপ্রাপ্ত প্রোগ্রামগুলি ("MECHANISMS") সুবিধাপ্রাপ্ত প্রোগ্রামগুলিকে ("ক্লায়েন্টস") অফার করে পরিষেবা ব্যবহার করে। সিস্টেম আর্কিটেকচার এবং বড় ছবির জন্য পোলকিট ম্যানুয়াল পৃষ্ঠাটি দেখুন।

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

আমি ডি-বাসের মাধ্যমে যোগাযোগের জন্য একটি ভাল বেসিক নিবন্ধটি পেয়েছি এবং আমি এটি পরীক্ষা না করে এটি মিশ্রণে পোলকিট যুক্ত করার একটি প্রাথমিক উদাহরণ বলে মনে হয়

এই পদ্ধতির ক্ষেত্রে, কোনও কিছুর জন্য সেটআপের চিহ্ন চিহ্নিত করার দরকার নেই।


5

এটি করার একটি উপায় হ'ল সিতে লিখিত একটি সেটুইড-রুট প্রোগ্রাম তৈরি করা যা কেবলমাত্র যা প্রয়োজন তা করে এবং আরও কিছু না। আপনার ক্ষেত্রে এটি কোনও ব্যবহারকারীর ইনপুটকে মোটেই দেখতে হবে না।

#include <unistd.h>
#include <string.h>
#include <stdio.h>  // for perror(3)
// #include ...  more stuff for open(2)

static void write_str_to_file(const char*fn, const char*str) {
    int fd = open(fn, O_WRONLY)
    if (-1 == fd) {
        perror("opening device file");  // make this a CPP macro instead of function so you can use string concat to get the filename into the error msg
        exit(1);
    }
    int err = write(fd, str, strlen(str));
    // ... error check
    err = close(fd);
    // ... error check
}

int main(int argc, char**argv) {
    write_string_to_file("/sys/class/gpio/export", "17");
    write_string_to_file("/sys/class/gpio/gpio17/direction", "out");
    return 0;
}

পরিবেশের ভেরিয়েবল বা যে কোনও কিছুর মাধ্যমে এটিকে বিকৃত করার কোনও উপায় নেই, কারণ এটি কেবল কয়েকটি সিস্টেমে কল করা।

ডাউনসাইড: আপনার প্রতিটি কলের রিটার্নের মানটি পরীক্ষা করা উচিত।

পার্শ্ববর্তী: ত্রুটি পরীক্ষা করা সত্যিই সহজ: যদি কিছুতেই ত্রুটি থাকে তবে ন্যায়বিচার perrorও জামিন আউট: অ-শূন্য স্থিতি সহ প্রস্থান করুন। যদি কোনও ত্রুটি থাকে তবে তদন্ত করুন strace। সত্যিই দুর্দান্ত ত্রুটি বার্তা দেওয়ার জন্য আপনার নিজের এই প্রোগ্রামটির দরকার নেই।


2
দ্বিতীয়টির অনুপস্থিতি থেকে রক্ষা পেতে কোনও কিছু লেখার আগেই আমি উভয় ফাইল খোলার প্রলোভনে পড়তে পারি। এবং আমি এই প্রোগ্রামটি চালাতে পারি sudoযাতে এটি নিজেই সেটআপ করার দরকার হয় না। ঘটনাচক্রে, এটি <fcntl.h>জন্য open()
জোনাথন লেফলার

3

সুডোর প্রতিধ্বনির পরিবর্তে আশীর্বাদ করা হ'ল এমন পরিস্থিতিতে পৌঁছানোর এক সাধারণ উপায় যা আপনাকে রুট পারম সীমাবদ্ধ করতে হবে। / Dev / null এ পুনঃনির্দেশ হ'ল কোনও আউটপুট ফাঁস হওয়া বন্ধ করা - টি আপনি যা চান তা করে।

echo "17" | sudo tee /sys/class/gpio/export > /dev/null
echo "out" | sudo tee /sys/class/gpio/gpio17/direction > /dev/null

5
যদি আপনি teeচালনা করার অনুমতি দেন তবে sudoআপনি যে কোনও ফাইলকে ওভাররাইট বা সংযুক্তকরণের অনুমতি দিচ্ছেন (উদাহরণস্বরূপ, /etc/passwd- কেবলমাত্র একটি নতুন uid = 0 অ্যাকাউন্ট যুক্ত করুন)। আপনি ভাল হিসাবে all কমান্ড চালানো যাবে অনুমতি দিতে পারে sudo(BTW /etc/sudoersসেট জন্যে 'যে কোন ফাইল' তাই ওভাররাইট সঙ্গে হতে পারে sudo tee)
CA গুলির

2
স্পষ্টতই, আপনি পৃথক প্রশ্নে এই উত্তরেtee বর্ণিত ফাইলগুলিতে সীমাবদ্ধ করতে পারেন to কেবল নিশ্চিত হয়ে নিন যে আপনি মন্তব্যগুলিও পড়েছেন, কারণ কিছু লোকের ব্যবহৃত মূল সিনট্যাক্স নিয়ে সমস্যা ছিল এবং সেই সমস্যার সমাধানের পরামর্শ দেয়।
অ্যালেক্স

1
@ অ্যালেক্স, হ্যাঁ, আপনি sudo- তে যে কোনও কমান্ড দিয়ে এটি করতে পারেন - অনুমতিযোগ্য আরগগুলি সীমাবদ্ধ করুন। আপনি যদি teeপ্রচুর ফাইল ব্যবহার করতে চান বা যা কিছু করতে চান তবে কনফিগারেশনটি খুব দীর্ঘ এবং জটিল হয়ে উঠতে পারে sudo
ক্যাস

0

আপনি একটি স্ক্রিপ্ট তৈরি করতে পারেন যা আপনার পছন্দসই কাজটি সম্পাদন করে। তারপরে, একটি নতুন ব্যবহারকারীর অ্যাকাউন্ট তৈরি করুন যা কেবলমাত্র ওপেনএসএইচএইচ দ্বারা ব্যবহৃত কী সরবরাহ করে লগ ইন করতে পারে।

দ্রষ্টব্য: যে কী ফাইল আছে তা যদি কেউ স্ক্রিপ্টটি চালাতে সক্ষম হবেন, সুতরাং নিশ্চিত করুন যে ওপেনএসএসএইচ কী ফাইলটি কারও দ্বারা পঠনযোগ্য নয় যা আপনি কাজটি সম্পাদন করতে বাধা দিতে চান।

ওপেনএসএসএইচ কনফিগারেশনে (অনুমোদিত_কিগুলি ফাইলে) কীটি নির্দিষ্ট করার আগে একটি "কমান্ড (একটি স্থান দ্বারা অনুসরণ করা) নির্দিষ্ট করুন, এই" উদাহরণ "পাঠ্যে বর্ণিত:

command="myscript" keydata optionalComment

এই কনফিগারেশন বিকল্পটি কেবলমাত্র একটি নির্দিষ্ট কমান্ড চালানোর জন্য সেই ওপেনএসএইচ কীটিকে সীমাবদ্ধ করতে পারে। এখন আপনার কাছে অনুমতি মঞ্জুর করার সুযোগ রয়েছে তবে ওপেনএসএসএইচ কনফিগারেশন হ'ল সেই সমাধানটির অংশ যা ব্যবহারকারীর কী করতে সক্ষম তা সীমাবদ্ধ / সীমাবদ্ধ করতে ব্যবহার করা হচ্ছে, যাতে ব্যবহারকারী অন্যান্য কমান্ডগুলি চালাচ্ছে না। এটিতে "সুডো" কনফিগারেশন ফাইলের মতো জটিলতাও নেই, সুতরাং আপনি যদি ওপেনবিএসডি ব্যবহার করেন বা ওপেনবিএসডি-র নতুন "দোস" ("হিসাবে করুন") আরও জনপ্রিয় হতে শুরু করে (আপনি যে কোনও অপারেটিং সিস্টেম ব্যবহার করেন ভবিষ্যতের সংস্করণ সহ) , sudo কনফিগারেশনে আপনার খুব জটিলতার দ্বারা চ্যালেঞ্জের প্রয়োজন হবে না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.