क्या लिनक्स पर "विशेषाधिकार प्राप्त" बंदरगाहों को बांधने के लिए गैर-रूट प्रक्रियाओं का एक तरीका है?


389

मेरे विकास बॉक्स पर इस सीमा को रखना बहुत कष्टप्रद है, जब मेरे अलावा कभी कोई उपयोगकर्ता नहीं होगा।

मैं मानक वर्कअराउंड के बारे में जानता हूं , लेकिन उनमें से कोई भी वैसा नहीं करता जैसा मैं चाहता हूं:

  1. ऑर्डबाइंड (डेबियन परीक्षण में संस्करण, 1.0, केवल IPv4 का समर्थन करता है)
  2. एक कम बंदरगाह को एक उच्च बंदरगाह ("nat" तालिका को ip6tables के लिए अभी तक लागू नहीं किया गया है, iptables के IPv6 संस्करण के लिए iptables REDIRECT लक्ष्य का उपयोग करके )
  3. सुडो (रूट के रूप में मैं बचने की कोशिश कर रहा हूं)
  4. SELinux (या समान)। (यह सिर्फ मेरा देव बॉक्स है, मैं बहुत सारी अतिरिक्त जटिलता का परिचय नहीं देना चाहता।)

क्या sysctlलिनक्स पर "विशेषाधिकार प्राप्त" बंदरगाहों (1024 से कम बंदरगाहों) पर बाँधने के लिए गैर-रूट प्रक्रियाओं को अनुमति देने के लिए कुछ सरल चर है, या मैं सिर्फ भाग्य से बाहर हूं?

EDIT: कुछ मामलों में, आप ऐसा करने के लिए क्षमताओं का उपयोग कर सकते हैं


5
मेरे अनुभव में, यह प्रयास करने का एक कारण अपाचे (या लाइटटपैड) का उपयोग करने के बजाय एक वेब सर्वर लिखना है।
S

मैंने अपने उत्तर के लिए सेट किया सामान लगभग समान stackoverflow.com/questions/277991/…
पॉल टॉम्बलिन

15
क्योंकि इस उदाहरण में, मैं IPv6 का उपयोग कर रहा था, यही वजह थी कि कुछ "सामान्य" वर्करॉइड्स (ऑक्टबाइंड और आईपीटैबल्स रिडायरेक्ट) ने मेरे लिए काम नहीं किया।
जेसन Creighton


1
इसे करने के कुछ तरीके हैं। गैर-रूट प्रक्रिया को 80 और 443 पोर्ट में बांधने की अनुमति दें देखें ? सुपर यूजर पर।
jww

जवाबों:


392

ठीक है, उन लोगों के लिए धन्यवाद जिन्होंने क्षमताओं प्रणाली और CAP_NET_BIND_SERVICEक्षमता को इंगित किया । यदि आपके पास हाल ही में कर्नेल है, तो गैर-रूट के रूप में सेवा शुरू करने के लिए इसका उपयोग करना संभव है, लेकिन कम बंदरगाहों को बांधें। संक्षिप्त उत्तर यह है कि आप क्या करते हैं:

setcap 'cap_net_bind_service=+ep' /path/to/program

और फिर इसके बाद कभी भी programइसे अंजाम दिया जाएगा CAP_NET_BIND_SERVICEsetcapडेबियन पैकेज में है libcap2-bin

अब चेतावनी के लिए:

  1. आपको कम से कम 2.6.24 कर्नेल की आवश्यकता होगी
  2. यदि आपकी फ़ाइल एक स्क्रिप्ट है तो यह काम नहीं करेगा। (यानी, दुभाषिया लॉन्च करने के लिए # लाइन का उपयोग करता है)। इस मामले में, जहाँ तक मैं समझता हूँ, आपको दुभाषिया के निष्पादन योग्य क्षमता को स्वयं लागू करना होगा, जो निश्चित रूप से एक सुरक्षा दुःस्वप्न है, क्योंकि उस दुभाषिए का उपयोग करने वाले किसी भी कार्यक्रम की क्षमता होगी। मैं इस समस्या को हल करने के लिए कोई भी आसान, आसान तरीका नहीं खोज पाया।
  3. लिनक्स LD_LIBRARY_PATH को ऐसे किसी भी अक्षम कर देगा, programजिसके पास विशेषाधिकार हैं जैसे setcapया suid। इसलिए यदि आपका programअपना स्वयं का उपयोग करता है .../lib/, तो आपको पोर्ट अग्रेषण जैसे किसी अन्य विकल्प पर ध्यान देना होगा।

संसाधन:

नोट: RHEL ने सबसे पहले इसे v6 में जोड़ा था


3
स्क्रिप्ट के लिए आंशिक वर्कअराउंड: इंटरप्रेटर की एक प्रति बनाएं (उदाहरण के लिए bash), इसे कैपिटलिटी दें लेकिन कॉपी को उन उपयोगकर्ताओं तक पहुंच को प्रतिबंधित करें जिन्हें इसकी आवश्यकता है। बेशक, उन उपयोगकर्ताओं पर भरोसा किया जाना चाहिए, लेकिन वे वैसे भी स्क्रिप्ट को बदल सकते हैं।
एरिच कित्जमुलेर 12

3
उपरोक्त डेबियन (बाइनरी) पैकेज के अलावा, डेवलपर की साइट friedhoff.org/posixfilecaps.html संबंधित कागजात / प्रस्तुतियाँ / आदि ...
RandomNickName42

1
Suse SLES 11.1 पर मुझे इस कार्य के लिए कर्नेल परम file_caps = 1 को grub menu.lst में जोड़ना था।
शे

2
हां @ C.Ross चूंकि इसे लागू करना /usr/bin/javaहोगा और फिर सिस्टम पर चल रहे किसी भी जावा ऐप की क्षमता को खोल देगा। प्रति उपयोगकर्ता बहुत बुरी क्षमताएं भी सेट नहीं की जा सकतीं।
joeytwiddle

5
क्या सेट की गई सेटिंग रीबूट में बनी रहती है; यदि यह नियम रखने के लिए कोई मानक स्थान नहीं है तो क्या यह सिस्टम स्टार्टअप के दौरान चलाया जाता है? है /etc/security/capability.confकिसी भी मदद Debian / Ubuntu पर?
joeytwiddle

34

आप एक पोर्ट रीडायरेक्ट कर सकते हैं। यह वही है जो मैं लिनक्स बॉक्स पर चल रहे सिल्वरलाइट पॉलिसी सर्वर के लिए करता हूं

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300

5
दुर्भाग्य से यह केवल रूट किए गए कनेक्शन के लिए काम करेगा, अर्थात स्थानीय मशीन से नहीं।
zbyszek 11

@joeytwiddle मुझे लगता है कि यह स्क्रिप्ट में है जो आपके सर्वर को चलाता है (शुरू करता है), लेकिन मैं गलत हो सकता हूं। मैं यह भी जानना चाहता हूं: पी
कैमिलो मार्टिन

@CamiloMartin फिर से देखते हुए, डेबियन प्रलेखन जो प्रश्न से जुड़ा हुआ था, उसे आपके फ़ायरवॉल स्क्रिप्ट में रखने, या उसे बनाने की सलाह देता है /etc/network/if-up.d/firewall
joeytwiddle 8

8
@zbyszek यह एक अतिरिक्त iptables नियम के साथ स्थानीय मशीन कनेक्शन के लिए काम कर सकता है: stackoverflow.com/a/31795603/1356953
00500005

पुराने कर्नेल में ऐसा लगता है कि यह IPv6 के लिए समर्थित नहीं था । लेकिन जाहिरा तौर पर यह ip6tables v1.4.18 और लिनक्स कर्नेल v3.8 में समर्थित है।
क्रेग मैकक्वीन 1

31

मानक तरीका उन्हें "सेतुविहीन" बनाना है ताकि वे जड़ के रूप में शुरू हो जाएं, और फिर वे उस मूल विशेषाधिकार को फेंक देते हैं जैसे ही वे बंदरगाह के लिए बाध्य होते हैं, लेकिन इससे पहले कि वे इसे कनेक्शन स्वीकार करना शुरू कर दें। आप Apache और INN के सोर्स कोड में इसके अच्छे उदाहरण देख सकते हैं। मुझे बताया गया है कि लाइटटैप एक और अच्छा उदाहरण है।

एक अन्य उदाहरण पोस्टफ़िक्स है, जो कई डेमॉन का उपयोग करता है जो पाइप के माध्यम से संचार करते हैं, और उनमें से केवल एक या दो (जो स्वीकार करने या बाइट को छोड़कर बहुत कम करते हैं) रूट के रूप में चलते हैं और बाकी कम विशेषाधिकार पर चलते हैं।


1
दिलचस्प बात यह है कि यह CAP_SETUID सेट के बिना लिनक्स (शायद सिर्फ उबंटू) के हाल के संस्करणों के तहत काम नहीं करता है। इसलिए यदि आपको सेतु की आवश्यकता है तो आपको इस क्षमता को वैसे भी निर्धारित करना होगा।
मैट

रूट प्राइवेट को छोड़ना ऐसा करने का सही तरीका है। हालाँकि यह आवश्यक नहीं है कि यदि आप init / upstart / systemd सेवा शुरू करते हैं तो setuid सेट करें।
माइकल हैम्पटन

2
यह मुश्किल है अगर कार्यक्रम एक व्याख्या भाषा या बायटेकोड दुभाषिया में लिखा है जैसे कि सी # (मोनो), जावा, पायथन। (स्पष्ट रूप से पर्ल ने इसे binfmt_miscऔर इसके 'सी' ध्वज के माध्यम से किया है , मैं दूसरों के बारे में निश्चित नहीं हूं।)
क्रेग मैकक्वीन

उत्सर्जन बाइट को छोड़कर बहुत कम, यह बहुत कम नहीं है।
रयान

यदि आप एक बाइनरी सेतु तय करते हैं, तो यह एक रूट प्रोसेस के रूप में चलेगा। हालांकि, सवाल यह है कि रूट प्रक्रिया के रूप में अपने बाइनरी को चलाने के बिना इसे कैसे पूरा किया जाए। यह समाधान एक अलग प्रश्न का उत्तर है, जिसका नाम है: "एक गैर-निजीकृत उपयोगकर्ता के पास एक निजीकृत पोर्ट के लिए एक प्रक्रिया कैसे हो सकती है", लेकिन यह सवाल नहीं है, IMHO?
माइकल बीयर

24

या अपना कर्नेल पैच करें और चेक निकालें।

(अंतिम उपाय का विकल्प, अनुशंसित नहीं)।

में net/ipv4/af_inet.c, पढ़ने वाली दो पंक्तियों को हटा दें

      if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
              goto out;

और कर्नेल अब विशेषाधिकार प्राप्त बंदरगाहों की जाँच नहीं करेगा।


22
कारणों की एक भीड़ के लिए एक बहुत बुरा विचार।
एडम लाससेक

24
यह बुरा विचार है। लेकिन वास्तव में काम करेगा। और यकीनन मुझे हँसाया।
Oto Brglez

23
बेशक यह एक बुरा विचार है। इसलिए मैंने अंतिम उपाय कहा। खुले स्रोत की बात यह है कि यदि आप जिस तरह से चाहते हैं वह इसे बदल नहीं सकता है।
जोशुआ

18
मुझे यकीन नहीं है कि आपको क्यों अपमानित किया गया था। मालवेयर लेखकों को परवाह नहीं है कि वे किस पोर्ट पर सुनते हैं, और वे 1024 से अधिक पोर्ट खोलने के लिए अधिक खुश हैं। मुझे ऐसा लगता है कि सभी पोर्ट को विशेषाधिकारों की आवश्यकता होनी चाहिए, या किसी पोर्ट को विशेषाधिकारों की आवश्यकता नहीं होनी चाहिए। और 1024 के नीचे एक पोर्ट खोलने के लिए रूट की आवश्यकता होती है, इसका मतलब है कि आपके पास रूट के रूप में उच्च जोखिम वाला एप्लिकेशन चल रहा है। यह मेरे लिए वास्तव में गूंगा विचार जैसा लगता है। शायद मुझे यहाँ कुछ याद आ रहा है ...
jww

9
दिन में वापस, पोर्ट <1024 यूनिक्स में UNIX प्रोटोकॉल का उपयोग किया गया था ताकि यह साबित हो सके कि दूसरे छोर पर चल रहा कोड रूट के रूप में चल रहा था। यह सामान्य सुरक्षा के साथ UNIX सर्वर के एक सेट के लिए यथोचित कार्य करता है।
जोशुआ

22

आप एक स्थानीय SSH सुरंग को सेटअप कर सकते हैं, उदाहरण के लिए यदि आप चाहते हैं कि पोर्ट 80 आपके ऐप से 3000 तक बंधे।

sudo ssh $USERNAME@localhost -L 80:localhost:3000 -N

यह स्क्रिप्ट सर्वर के साथ काम करने, और बहुत सरल होने का लाभ है।


1
मेरा व्यक्तिगत पसंदीदा। चालू और बंद करने के लिए बहुत आसान है और सिस्टम-व्यापी परिवर्तनों की आवश्यकता नहीं है। महान विचार!
डान पसारो

ये अद्भुत है। अब तक का सबसे सरल जवाब।
माइकेलवॉल्डन

1
मुझे उम्मीद है कि यह मामूली महंगा होगा और किसी भी प्रदर्शन बाध्य स्थिति में एक अच्छा विचार नहीं होगा, लेकिन मैं इसे परीक्षण के बिना सुनिश्चित नहीं कर सकता। SSH एन्क्रिप्शन में एक नॉनज़रो राशि होती है।
लह्राँ

3
यह बिना ssh ओवरहेड के netcat के साथ किया जा सकता है:sudo nc -l 80 | nc localhost 3000
बगस्टर

1
आप केवल उसी मशीन पर डेटा को दूसरे पोर्ट में स्थानांतरित करने के लिए एन्क्रिप्ट + डिक्रिप्ट कर रहे हैं? इसके अलावा, यह यूडीपी ट्रैफ़िक के लिए काम नहीं करता है।
डेनियल एफ

19

अपडेट 2017:

ऑर्किड का उपयोग करें


CAP_NET_BIND_SERVICE या कस्टम कर्नेल से बहुत बेहतर।

  • CAP_NET_BIND_SERVICE बाइनरी पर भरोसा करता है, लेकिन प्रति पोर्ट एक्सेस पर कोई नियंत्रण प्रदान नहीं करता है।
  • Authbind उपयोगकर्ता / समूह पर भरोसा करता है और प्रति पोर्ट एक्सेस पर नियंत्रण प्रदान करता है, और IPv4 और IPv6 (IPv6 समर्थन को देर से जोड़ा गया है) दोनों का समर्थन करता है।

    1. इंस्टॉल: apt-get install authbind

    2. सभी उपयोगकर्ताओं और समूहों के लिए संबंधित पोर्ट, जैसे 80 और 443 तक पहुंच कॉन्फ़िगर करें:

      सुडो टच / आदि / ऑर्टबाइंड / बायपोर्ट / 80 सुडो
      टच / आदि / ऑर्बिटबाइंड / बायपोर्ट / 443 सुडो चामोद
      777 / आदि / ऑर्बिटबाइंड / बायपोर्ट / 80 सुडो चामोद
      777 / आदि / ऑर्बिटब / बायपोर्ट / 443

    3. के माध्यम से अपने आदेश निष्पादित authbind
      (वैकल्पिक रूप से निर्दिष्ट --deepया अन्य तर्क, मैन पेज देखें):

      authbind --deep /path/to/binary command line args
      

      जैसे

      authbind --deep java -jar SomeServer.jar
      

जोशुआ के शानदार फॉलो-अप के रूप में (= अनुशंसित नहीं जब तक आपको पता नहीं है कि आप क्या करते हैं) कर्नेल को हैक करने की सिफारिश:

मैंने पहली बार इसे यहां पोस्ट किया है

सरल। एक सामान्य या पुराने कर्नेल के साथ, आप नहीं।
जैसा कि दूसरों द्वारा बताया गया है, iptables एक पोर्ट को आगे बढ़ा सकता है।
जैसा कि दूसरों द्वारा बताया गया है, CAP_NET_BIND_SERVICE भी काम कर सकती है।
बेशक CAP_NET_BIND_SERVICE विफल हो जाएगी यदि आप अपने प्रोग्राम को स्क्रिप्ट से लॉन्च करते हैं, जब तक आप शेल दुभाषिया पर टोपी सेट नहीं करते हैं, जो कि व्यर्थ है, आप बस अपनी सेवा को रूट के रूप में चला सकते हैं ...
जैसे जावा के लिए, आपको इसे लागू करना होगा। JAVA JVM को

sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/lib/jvm/java-8-openjdk/jre/bin/java

जाहिर है, इसका मतलब है कि कोई भी जावा प्रोग्राम सिस्टम पोर्ट को बांध सकता है।
मोनो / .NET के लिए डिटो।

मुझे भी पूरा यकीन है कि xinetd विचारों का सबसे अच्छा नहीं है।
लेकिन चूंकि दोनों विधियां हैक हैं, तो केवल प्रतिबंध हटाकर सीमा को क्यों नहीं बढ़ाया जाए?
किसी ने नहीं कहा कि आपको एक सामान्य कर्नेल चलाना है, इसलिए आप बस अपना स्वयं का रन बना सकते हैं।

आप बस नवीनतम कर्नेल के लिए स्रोत डाउनलोड करें (या आपके पास वर्तमान में)। बाद में, आप इस पर जाएं:

/usr/src/linux-<version_number>/include/net/sock.h:

वहां आप इस लाइन को देखें

/* Sockets 0-1023 can't be bound to unless you are superuser */
#define PROT_SOCK       1024

और इसे बदल दें

#define PROT_SOCK 0

यदि आप एक असुरक्षित ssh स्थिति नहीं चाहते हैं, तो आप इसे इस में बदल देंगे: #define PROT_S100 24

आम तौर पर, मैं सबसे कम सेटिंग का उपयोग करता हूं, जिसकी आपको आवश्यकता है, जैसे http के लिए 79, या 24 जब एसएमटीपी का उपयोग पोर्ट 25 पर किया जाता है।

यह सब पहले से ही है।
कर्नेल को संकलित करें, और इसे स्थापित करें।
रीबूट।
समाप्त - यह बेवकूफी की सीमा है, और यह स्क्रिप्ट के लिए भी काम करता है।

यहां बताया गया है कि आप कर्नेल कैसे संकलित करते हैं:

https://help.ubuntu.com/community/Kernel/Compile

# You can get the kernel-source via package linux-source, no manual download required
apt-get install linux-source fakeroot

mkdir ~/src
cd ~/src
tar xjvf /usr/src/linux-source-<version>.tar.bz2
cd linux-source-<version>

# Apply the changes to PROT_SOCK define in /include/net/sock.h

# Copy the kernel config file you are currently using
cp -vi /boot/config-`uname -r` .config

# Install ncurses libary, if you want to run menuconfig
apt-get install libncurses5 libncurses5-dev

# Run menuconfig (optional)
make menuconfig

# Define the number of threads you wanna use when compiling (should be <number CPU cores> - 1), e.g. for quad-core
export CONCURRENCY_LEVEL=3
# Now compile the custom kernel
fakeroot make-kpkg --initrd --append-to-version=custom kernel-image kernel-headers

# And wait a long long time

cd ..

संक्षेप में, iptables का उपयोग करें यदि आप सुरक्षित रहना चाहते हैं, तो कर्नेल को संकलित करें यदि आप सुनिश्चित करना चाहते हैं कि यह प्रतिबंध आपको फिर से परेशान नहीं करता है।


पतन का कोई कारण? रूट-हैटर, या कर्नेल-संकलन निर्देशों ने काम नहीं किया?
स्टेफेन स्टीगर

4
कर्नेल को संशोधित करना भविष्य के अपडेट को बहुत अधिक दर्दनाक बनाता है। मैं ऐसा नहीं करूंगा, क्योंकि मुझे पता है कि मैं अपने कर्नेल को नियमित रूप से अपडेट रखने के लिए बहुत आलसी होगा। यह अच्छा है कि यह सिद्धांत में संभव है, लेकिन बहुत सारी परिस्थितियों में यह एक व्यवहार्य विकल्प नहीं है।
क्रिटिकट्राटजी

हो सकता है कि इसे करने का एक अधिक सुरक्षित तरीका यह है कि chmod 777 / etc / orbbind / byport / 80 को chmod 544 / etc / orbbind / byport / 23 से बदल कर chown लॉगिन करें: group / etc / orbbind / byport / 23
Jérôme B

18

फ़ाइल क्षमताएं आदर्श नहीं हैं, क्योंकि वे पैकेज अपडेट के बाद टूट सकते हैं।

आदर्श समाधान, आईएमएचओ, अंतर्निहित CAP_NET_BIND_SERVICEसेट के साथ एक शेल बनाने की क्षमता होना चाहिए ।

यहाँ ऐसा करने का कुछ जटिल तरीका है:

sg $DAEMONUSER "capsh --keep=1 --uid=`id -u $DAEMONUSER` \
     --caps='cap_net_bind_service+pei' -- \
     YOUR_COMMAND_GOES_HERE"

capshउपयोगिता डेबियन / उबंटू वितरण में libcap2-bin पैकेज में पाई जा सकती है। यहाँ क्या है:

  • sgप्रभावी समूह ID को डेमन उपयोगकर्ता में बदल देता है। यह आवश्यक है क्योंकि capshजीआईडी ​​अपरिवर्तित छोड़ देता है और हम निश्चित रूप से इसे नहीं चाहते हैं।
  • बिट्स 'यूआईडी परिवर्तन पर क्षमता बनाए रखें' सेट करता है।
  • यूआईडी को बदलता है $DAEMONUSER
  • सभी कैप्स को छोड़ देता है (इस समय सभी कैप्स अभी भी मौजूद हैं --keep=1), अंतर्निहित को छोड़करcap_net_bind_service
  • अपने आदेश निष्पादित करता है ('-' एक विभाजक है)

परिणाम निर्दिष्ट उपयोगकर्ता और समूह और cap_net_bind_serviceविशेषाधिकारों के साथ एक प्रक्रिया है ।

एक उदाहरण के रूप में, ejabberdस्टार्टअप स्क्रिप्ट से एक पंक्ति :

sg $EJABBERDUSER "capsh --keep=1 --uid=`id -u $EJABBERDUSER` --caps='cap_net_bind_service+pei' -- $EJABBERD --noshell -detached"

और यह वास्तव में काम नहीं करता है। उपयोगकर्ता आईडी स्विच पर कैप्स संरक्षित नहीं हैं। यदि आप रूट के रूप में चलाना चाहते हैं तो यह काम करेगा, लेकिन सभी क्षमताओं के साथ।
साइबरक्स

अगर मैं ऐसा करने की कोशिश करता हूं, तो मुझे "बाइनरी फ़ाइल निष्पादित नहीं किया जा सकता है"। वास्तव में, या विकल्पों का उपयोग करते समय मुझे "बाइनरी फ़ाइल निष्पादित नहीं कर सकता" के अलावा कुछ भीcapsh करने के लिए नहीं मिल सकता है । मुझे आश्चर्य है कि मुझे क्या याद आ रहा है। --==
क्रेग मैकक्यून

@CraigMcQueen, के बाद सब कुछ --पर पारित कर दिया है /bin/bash, तो आप के साथ कोशिश करना चाहते हो सकता है -c 'your command'। काश, मुझे @Cyberax के रूप में एक ही समस्या का अनुभव हो रहा है, क्योंकि मुझे कोशिश करते समय "अनुमति अस्वीकृत" मिलती है bind
आमिर

फ़ाइल क्षमताओं को स्थापित किए बिना काम करने के लिए (या रूट के रूप में), आपको इस Unix.SE उत्तर में वर्णित परिवेश क्षमताओं का उपयोग करने की आवश्यकता होगी । तुम भी इस्तेमाल कर सकते हैं के बजाय (या जो सेट , और ): --gidsg--user--uid--gid--groupssudo capsh --caps='cap_net_bind_service+eip cap_setpcap,cap_setuid,cap_setgid+ep' --keep=1 --user="$service_user" --addamb=cap_net_bind_service -- -c 'exec $service $service_args'
Kevinoid

18

किसी कारण से कोई भी आपके लिए आवश्यक मूल्य तक sysctl net.ipv4.ip_unprivileged_port_start को कम करने का उल्लेख नहीं करता है। उदाहरण: हमें अपने ऐप को 443 पोर्ट पर बाँधने की आवश्यकता है।

sysctl net.ipv4.ip_unprivileged_port_start=443

कुछ लोग कह सकते हैं कि, एक संभावित सुरक्षा समस्या है: अबाधित उपयोगकर्ता अब अन्य विशेषाधिकार प्राप्त बंदरगाहों (444-1024) से जुड़ सकते हैं। लेकिन आप अन्य पोर्ट्स को ब्लॉक करके इस समस्या को आसानी से iptables के साथ हल कर सकते हैं:

iptables -I INPUT -p tcp --dport 444:1024 -j DROP
iptables -I INPUT -p udp --dport 444:1024 -j DROP

अन्य तरीकों से तुलना। यह विधि:

  • कुछ बिंदु से (IMO) CAP_NET_BIND_SERVICE / setuid को सेट करने से भी अधिक सुरक्षित है, क्योंकि कोई एप्लिकेशन बिल्कुल भी सेट नहीं करता है, आंशिक रूप से (वास्तव में क्षमताएँ)। उदाहरण के लिए, क्षमता-सक्षम अनुप्रयोग के एक coredump को पकड़ने के लिए आपको sysctl fs.suid_dumpable (जो एक और संभावित सुरक्षा समस्याओं की ओर ले जाता है) को बदलना होगा, साथ ही, जब CAP / suid सेट हो, / proc / PID निर्देशिका रूट के स्वामित्व में हो, तो आपके गैर-रूट उपयोगकर्ता के पास चलने की प्रक्रिया की पूरी जानकारी / नियंत्रण नहीं होगा, उदाहरण के लिए, उपयोगकर्ता (सामान्य स्थिति में) यह निर्धारित करने में सक्षम नहीं होगा कि कौन से कनेक्शन / proc / PID / fd / (netstat -aptn) के माध्यम से आवेदन करने हैं। पीआईडी)।
  • सुरक्षा में कमी है: जबकि आपका ऐप (या पोर्ट्स 443-1024 का उपयोग करने वाला कोई भी ऐप) किसी कारण से डाउन हो गया है, दूसरा ऐप पोर्ट ले सकता है। लेकिन यह समस्या CAP / suid पर भी लागू की जा सकती है (यदि आप इसे दुभाषिया, जैसे जावा / नोडज पर सेट करते हैं) और iptables-redirect। इस समस्या को बाहर करने के लिए सिस्टमड-सॉकेट विधि का उपयोग करें। केवल विशेष उपयोगकर्ता बाइंडिंग की अनुमति देने के लिए ऑर्बिटबिंद विधि का उपयोग करें।
  • हर बार जब आप एप्लिकेशन के नए संस्करण को तैनात करते हैं, तो CAP / suid को सेट करने की आवश्यकता नहीं होती है।
  • सिस्टम सपोर्ट-सॉकेट विधि की तरह आवेदन समर्थन / संशोधन की आवश्यकता नहीं है।
  • कर्नेल पुनर्निर्माण की आवश्यकता नहीं है (यदि रनिंग संस्करण इस sysctl सेटिंग का समर्थन करता है)
  • LD_PRELOAD को ऑर्कबिट / प्राइवेटबाइंड विधि की तरह नहीं करता है, इससे संभावित रूप से प्रदर्शन, सुरक्षा, व्यवहार प्रभावित हो सकता है (क्या यह परीक्षण नहीं किया गया है)। बाकी ऑर्बिट में वास्तव में लचीला और सुरक्षित तरीका है।
  • ओवर-परफॉर्मेंस को लागू करता है REDIRECT / DNAT मेथड, क्योंकि इसमें एड्रेस ट्रांसलेशन, कनेक्शन स्टेट ट्रैकिंग आदि की आवश्यकता नहीं होती है। यह केवल हाई-लोड सिस्टम पर ध्यान देने योग्य है।

स्थिति के आधार पर, मैं sysctl, CAP, ऑर्बिटबाइंड और iptables-redirect के बीच चयन करूंगा। और यह बहुत अच्छा है कि हमारे पास बहुत सारे विकल्प हैं।


2
शानदार जवाब के लिए धन्यवाद! ऐसा प्रतीत होता है कि यह कार्यक्षमता पहली बार अप्रैल 2017 में लिनक्स 4.11 में दिखाई दी थी , इसलिए यह 2009 के आसपास नहीं था जब मैंने पहली बार यह प्रश्न पूछा था। मैंने एक त्वरित परीक्षण भी किया, और यह आईपीवी 6 के लिए भी काम करता है, भले ही "आईपीवी 4" क्षत-विक्षत नाम में हो।
जेसन Creighton

15

दो अन्य सरल संभावनाएं:

"एक डेमॉन जो एक पुराने पोर्ट को बांधता है और आपके डेमॉन को हैंड कंट्रोल करता है" का एक पुराना (अनफैनेबल) समाधान है। इसे inetd (या xinetd) कहा जाता है। विपक्ष हैं:

  • आपके डेमॉन को stdin / stdout पर बात करने की आवश्यकता है (यदि आप डेमन को नियंत्रित नहीं करते हैं - यदि आपके पास स्रोत नहीं है - तो यह शायद एक शोस्टॉपर है, हालांकि कुछ सेवाओं में एक अयोग्य-संगतता ध्वज हो सकता है)
  • हर कनेक्शन के लिए एक नई डेमॉन प्रक्रिया को फोर्क किया गया है
  • यह श्रृंखला में एक अतिरिक्त कड़ी है

पेशेवरों:

  • किसी भी पुराने यूनिक्स पर उपलब्ध है
  • एक बार जब आपके sysadmin ने कॉन्फ़िगरेशन सेट कर दिया है, तो आप अपने विकास के बारे में जाने के लिए अच्छे हैं (जब आप अपने डेमॉन को फिर से बनाते हैं, तो क्या आप सेट की गई क्षमताओं को खो सकते हैं? और फिर आपको अपने व्यवस्थापक को वापस जाना होगा "कृपया सर .. । ")
  • डेमन को उस नेटवर्किंग सामान के बारे में चिंता करने की ज़रूरत नहीं है, बस स्टड / स्टडआउट पर बात करनी है
  • अनुरोध के अनुसार अपने डेमॉन को गैर-रूट उपयोगकर्ता के रूप में निष्पादित करने के लिए कॉन्फ़िगर कर सकते हैं

एक अन्य विकल्प: विशेषाधिकार प्राप्त पोर्ट से हैक किए गए प्रॉक्सी (नेटकैट या यहां तक ​​कि कुछ अधिक मजबूत ) से कुछ मनमाने उच्च-संख्या वाले पोर्ट जहां आप अपना लक्ष्य डेमॉन चला सकते हैं। (नेटकैट स्पष्ट रूप से उत्पादन समाधान नहीं है, लेकिन "सिर्फ मेरा देव बॉक्स", सही?)। इस तरह से आप अपने सर्वर के नेटवर्क-सक्षम संस्करण का उपयोग करना जारी रख सकते हैं, केवल प्रॉक्सी (बूट पर) शुरू करने के लिए रूट / सुडो की आवश्यकता होगी, जटिल / संभावित नाजुक क्षमताओं पर निर्भर नहीं होंगे।


1
अच्छा सुझाव। किसी कारण से मैं भी inetd का उपयोग करने के बारे में नहीं सोचा था। सिवाय इसके कि प्रश्न में सेवा यूडीपी आधारित है, इसलिए यह टीसीपी सेवाओं की तुलना में थोड़ा अधिक जटिल है। मेरे पास अभी समाधान के साथ काम करने का एक समाधान है, लेकिन मुझे यह कुछ विचार देना होगा।
जेसन क्रेयटन 3

दूसरे विकल्प के लिए, आप संभवतः inetd का उपयोग करके प्रॉक्सी शुरू कर सकते हैं ... (लेकिन IPTables संभावित कम ओवरहेड है ...)
Gert van den Berg

14

मेरा "मानक वर्कअराउंड" उपयोगकर्ता-रिडायरेक्टर के रूप में सोसाइट का उपयोग करता है:

socat tcp6-listen:80,fork tcp6:8080

खबरदार कि यह पैमाने पर नहीं होगा, फोर्किंग महंगा है, लेकिन यह जिस तरह से समाज का काम करता है।


13

लिनक्स "इस एप्लिकेशन को रूट के रूप में चलाया जाता है" की तुलना में अधिक बारीक अनुमतियों का समर्थन करने के लिए क्षमताओं का समर्थन करता है । उन क्षमताओं में से एक CAP_NET_BIND_SERVICEजो विशेषाधिकार प्राप्त बंदरगाह (<1024) के लिए बाध्यकारी है।

दुर्भाग्य से मैं यह नहीं जानता कि इसका उपयोग करने के लिए गैर-रूट के रूप में किसी एप्लिकेशन को चलाने के लिए अभी भी CAP_NET_BIND_SERVICE(शायद उपयोग कर रहा है setcap, लेकिन इसके लिए एक मौजूदा समाधान होने के लिए बाध्य है)।


स्क्रिप्ट, या व्यक्तिगत JVM / मोनो कार्यक्रमों के लिए काम नहीं करेंगे।
स्टेफेन स्टीगर

13

मुझे पता है कि यह एक पुराना सवाल है, लेकिन अब हाल ही में (> = 4.3) गुठली के साथ अंत में इस का एक अच्छा जवाब है - परिवेश क्षमताओं।

इसका त्वरित उत्तर यह है कि लेफ्टकैप के नवीनतम (अभी तक अप्रकाशित) संस्करण की एक प्रति को जिप से बाहर निकालें और उसे संकलित करें। परिणामी progs/capshबाइनरी को कहीं कॉपी करें ( /usr/local/binएक अच्छा विकल्प है)। फिर, रूट के रूप में, के साथ अपना कार्यक्रम शुरू करें

/usr/local/bin/capsh --keep=1 --user='your-service-user-name' \
    --inh='cap_net_bind_service' --addamb='cap_net_bind_service' \ 
    -- -c 'your-program'

आदेश में, हम हैं

  • घोषणा करते हुए कि जब हम उपयोगकर्ताओं को स्विच करते हैं, तो हम अपनी वर्तमान क्षमता सेट रखना चाहते हैं
  • उपयोगकर्ता और समूह को 'आपकी सेवा-उपयोगकर्ता-नाम' में बदलना
  • cap_net_bind_serviceविरासत में मिली और परिवेशीय सेटों की क्षमता को जोड़ना
  • फोर्किंग bash -c 'your-command'(चूंकि capshस्वचालित रूप से दलीलों के बाद शुरू होता है --)

यहां हुड के तहत बहुत कुछ चल रहा है।

सबसे पहले, हम रूट के रूप में चल रहे हैं, इसलिए डिफ़ॉल्ट रूप से, हमें क्षमताओं का एक पूरा सेट मिलता है। इसमें शामिल हैं setuidऔर setgidsidcalls के साथ uid और gid स्विच करने की क्षमता । हालांकि, आमतौर पर जब कोई प्रोग्राम ऐसा करता है, तो वह अपनी क्षमताओं का एक सेट खो देता है - यह इतना है कि रूट को छोड़ने का पुराना तरीका setuidअभी भी काम करता है। --keep=1ध्वज बताता capshजारी करने के लिए prctl(PR_SET_KEEPCAPS)syscall, जब उपयोगकर्ता को बदलने जो क्षमताओं के छोड़ने अक्षम करता है। उपयोगकर्ताओं का वास्तविक परिवर्तन ध्वज के capshसाथ होता है --user, जो चलता है setuidऔर setgid

अगली समस्या जिसे हमें हल करने की आवश्यकता है, वह यह है कि हम execअपने बच्चों की देखभाल किस तरह से करें । क्षमताओं की प्रणाली में हमेशा क्षमताओं का एक 'विरासत में मिला' सेट होता है, जो "एक निष्पादित (2) में संरक्षित क्षमताओं का एक सेट है" [ क्षमताएं (7) ]। जब भी यह लगता है कि यह हमारी समस्या को हल करता है (बस cap_net_bind_serviceविरासत में मिली क्षमता को सही सेट करता है?), यह वास्तव में केवल विशेषाधिकार प्राप्त प्रक्रियाओं के लिए लागू होता है - और हमारी प्रक्रिया अब विशेषाधिकार प्राप्त नहीं है, क्योंकि हमने पहले ही उपयोगकर्ता ( --userध्वज के साथ ) बदल दिया है ।

नई परिवेश क्षमता सेट इस समस्या के इर्द-गिर्द काम करती है - यह "क्षमताओं का एक सेट है जो एक प्रोग्राम के निष्पादित (2) में संरक्षित है जो विशेषाधिकार प्राप्त नहीं है।" cap_net_bind_serviceपरिवेश सेट में डालकर , जब capshहमारे सर्वर प्रोग्राम को निष्पादित करते हैं, तो हमारा प्रोग्राम इस क्षमता को विरासत में देगा और श्रोताओं को कम बंदरगाहों पर बांधने में सक्षम होगा।

यदि आप अधिक जानने के लिए इच्छुक हैं, तो क्षमताओं के मैनुअल पेज इसे बहुत विस्तार से बताते हैं। के capshमाध्यम से चल रहा straceहै भी बहुत जानकारीपूर्ण है!


--addambझंडा libcap 2.26 के साथ पेश किया गया था। मेरे सिस्टम में 2.25 थे और मुझे स्रोत से निर्माण करना था।
ngreen

12

TLDR: "उत्तर" के लिए (जैसा कि मैं इसे देखता हूं), इस उत्तर में >> TLDR << भाग पर नीचे कूदें।

ठीक है, मैंने इसे समझ लिया है (इस बार असली के लिए), इस सवाल का जवाब, और मेरा यह जवाब भी एक और जवाब (दोनों यहाँ और ट्विटर पर) को बढ़ावा देने के लिए माफी माँगने का एक तरीका है जो मुझे लगा कि "सबसे अच्छा था" ", लेकिन इसे आज़माने के बाद, मुझे पता चला कि मुझसे इस बारे में गलती हुई थी। मेरी गलती से सीखें बच्चे: जब तक आप वास्तव में इसे स्वयं नहीं आजमाते हैं, तब तक कुछ प्रचार न करें

दोबारा, मैंने यहां सभी उत्तरों की समीक्षा की। मैंने उनमें से कुछ की कोशिश की है (और दूसरों को आज़माने के लिए नहीं चुना क्योंकि मुझे समाधान पसंद नहीं आया)। मैंने सोचा था कि समाधान को systemdइसके Capabilities=और CapabilitiesBindingSet=सेटिंग्स के साथ उपयोग करना था । कुछ समय तक इसके साथ कुश्ती करने के बाद, मुझे पता चला कि यह समाधान नहीं है क्योंकि:

क्षमताओं का उद्देश्य रूट प्रक्रियाओं को प्रतिबंधित करना है!

जैसा कि ओपी ने बुद्धिमानी से कहा, यह हमेशा बचने के लिए सबसे अच्छा है (यदि संभव हो तो आपके सभी डेमों के लिए!)।

आपके साथ विकल्पों से संबंधित क्षमताओं का उपयोग नहीं कर सकते हैं User=और Group=में systemd, इकाई फ़ाइलों क्योंकि क्षमताओं कर रहे हैं हमेशा जब रीसेट execev(या जो भी कार्य है) कहा जाता है। दूसरे शब्दों में, जब systemdकांटे और उसके परमिट को गिरा देते हैं, तो क्षमताओं को रीसेट कर दिया जाता है। इसके चारों ओर कोई रास्ता नहीं है, और कर्नेल में सभी बाध्यकारी तर्क यूआईडी = 0 के आसपास बुनियादी हैं, क्षमताओं के नहीं। इसका मतलब है कि यह संभावना नहीं है कि क्षमताएं कभी भी इस प्रश्न का सही उत्तर होंगी (कम से कम किसी भी समय जल्द ही)। संयोग से setcap, जैसा कि दूसरों ने उल्लेख किया है, समाधान नहीं है। यह मेरे लिए काम नहीं करता था, यह स्क्रिप्ट के साथ अच्छी तरह से काम नहीं करता है, और जब भी फाइल बदलती है, तो वे वैसे भी रीसेट हो जाते हैं।

मेरी अल्प रक्षा में, मैंने स्टेट (टिप्पणी में अब मुझे हटा दिया गया है), कि जेम्स ' iptables सुझाव (जिसमें ओपी का भी उल्लेख है), "दूसरा सबसे अच्छा समाधान" था। :-P

>> TLDR <<

इसका समाधान इस तरह से ( DNSChain से लिया गया ) systemdऑन-द-फ्लाई iptablesकमांड के साथ संयोजन करना है :

[Unit]
Description=dnschain
After=network.target
Wants=namecoin.service

[Service]
ExecStart=/usr/local/bin/dnschain
Environment=DNSCHAIN_SYSD_VER=0.0.1
PermissionsStartOnly=true
ExecStartPre=/sbin/sysctl -w net.ipv4.ip_forward=1
ExecStartPre=-/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=-/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStartPre=/sbin/iptables -A INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=/sbin/iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStopPost=/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStopPost=/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
User=dns
Group=dns
Restart=always
RestartSec=5
WorkingDirectory=/home/dns
PrivateTmp=true
NoNewPrivileges=true
ReadOnlyDirectories=/etc

# Unfortunately, capabilities are basically worthless because they're designed to restrict root daemons. Instead, we use iptables to listen on privileged ports.
# Capabilities=cap_net_bind_service+pei
# SecureBits=keep-caps

[Install]
WantedBy=multi-user.target

यहाँ हम निम्नलिखित पूरा करते हैं:

  • डेमॉन 5333 पर सुनता है, लेकिन कनेक्शन सफलतापूर्वक 53 धन्यवाद पर स्वीकार किया जाता है iptables
  • हम यूनिट फाइल में ही कमांड्स को शामिल कर सकते हैं, और इस प्रकार हम लोगों के सिरदर्द से बचाते हैं। systemdहमारे लिए फ़ायरवॉल नियम साफ़ करता है, जब डेमॉन नहीं चल रहा होता है तो उन्हें निकालना सुनिश्चित करता है।
  • हम कभी भी जड़ के रूप में नहीं चलते हैं, और हम विशेषाधिकार वृद्धि को असंभव बनाते हैं (कम से कम systemdदावा करते हैं), माना जाता है कि भले ही डेमन समझौता करता है और सेट करता है uid=0

iptablesअभी भी, दुर्भाग्य से, काफी बदसूरत और मुश्किल से उपयोगी उपयोगिता है। उदाहरण के लिए, यदि डेमॉन eth0:0इसके बजाय सुन रहा है eth0, तो आदेश थोड़ा अलग हैं


2
किसी को भी पुरानी शैली के उपनामों का उपयोग नहीं करना चाहिए eth0:0जब तक कि उनके पास वास्तव में प्राचीन लिनक्स वितरण न हो। वे वर्षों के लिए पदावनत हो गए हैं और अंततः चले जाएंगे।
माइकल हैम्पटन

1
मुझे लगता है कि आपका मतलब OpenVZ है। (SolusVM एक कंट्रोल पैनल है।) और हां, OpenVZ बहुत सारी चीजों को गलत करता है, नेटवर्किंग सिर्फ उनमें से एक है।
माइकल हैम्पटन

1
एनएएच, मेरा मतलब है कि सोलसवीएम। / Etc / नेटवर्क / इंटरफेस से:# Generated by SolusVM
ग्रेग स्लीपक

1
अभी भी OpenVZ नहीं ... कम से कम मैं इसका उपयोग नहीं कर रहा हूँ, और न ही मेरा VPS है।
ग्रेग स्लीपप

7
Systemd की क्षमताओं की ओर इशारा करने के लिए धन्यवाद। हालाँकि, जटिल iptables की कोई आवश्यकता नहीं है जब systemd बाइनरी को सीधे शुरू करता है (स्क्रिप्ट नहीं)। सेटिंग AmbientCapabilities=CAP_NET_BIND_SERVICEने मेरे साथ संयोजन के लिए पूरी तरह से ठीक काम किया User=
रुद

11

systemd एक sysvinit प्रतिस्थापन है जिसमें विशिष्ट क्षमताओं के साथ डेमन लॉन्च करने का विकल्प होता है। विकल्प क्षमताएं =, CapabilityBoundingSet = systemd.exec (5) मैनपेज में।


2
मैंने पहले इस जवाब की सिफारिश की थी, लेकिन इसे आजमाने के बाद, अब मैं नहीं करता। एक विकल्प के लिए मेरा जवाब देखें जो अभी भी उपयोग करता है systemd
ग्रेग स्लीपप

10

पोर्ट रिडायरेक्ट हमारे लिए सबसे अधिक समझ में आता है, लेकिन हम एक ऐसे मुद्दे पर भागे हैं, जहां हमारा आवेदन स्थानीय रूप से एक यूआरएल को हल करेगा, जिसे फिर से रूट करने की आवश्यकता है; (इसका मतलब है कि तुम शिंदिग हो )।

यह आपको स्थानीय मशीन पर url का उपयोग करते समय पुनर्निर्देशित करने की अनुमति भी देगा।

iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -A OUTPUT -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080


8

सिस्टमड के साथ, आपको केवल प्रचारित सॉकेट को स्वीकार करने के लिए अपनी सेवा को थोड़ा संशोधित करने की आवश्यकता है।

आप बाद में सिस्टमड सॉकेट सक्रिय कर सकते हैं

कोई क्षमताओं, iptables या अन्य चाल की जरूरत है।

यह साधारण python http सर्वर के इस उदाहरण से प्रासंगिक systemd फ़ाइलों की सामग्री है

फ़ाइल httpd-true.service

[Unit]
Description=Httpd true 

[Service]
ExecStart=/usr/local/bin/httpd-true
User=subsonic

PrivateTmp=yes

फ़ाइल httpd-true.socket

[Unit]
Description=HTTPD true

[Socket]
ListenStream=80

[Install]
WantedBy=default.target

7

प्रारंभ होने पर:

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

फिर आप उस पोर्ट को बांध सकते हैं जिसे आप आगे भेजते हैं।


करता --to-portमौजूद हैं? man iptablesकेवल उल्लेख --to-ports(बहुवचन)।
अब्दुल

ive ने कुछ अंतरों पर ध्यान दिया और मैं चारों ओर कूद रहा हूं
जेम्स

इसके साथ कैसे संयोजन करें, इसका उत्तर देखें systemd
ग्रेग स्लीपप


3

'Djb तरीका' भी है। आप इस प्रक्रिया का उपयोग tcpserver के तहत किसी भी पोर्ट पर रूट रनिंग के रूप में अपनी प्रक्रिया शुरू करने के लिए कर सकते हैं, फिर यह प्रक्रिया शुरू होने के तुरंत बाद आपके द्वारा निर्दिष्ट उपयोगकर्ता को प्रक्रिया का नियंत्रण सौंप देगी।

#!/bin/sh

UID=$(id -u username)
GID=$(id -g username)
exec tcpserver -u "${UID}" -g "${GID}" -RHl0 0 port /path/to/binary &

अधिक जानकारी के लिए, देखें: http://thedjbway.b0llix.net/daemontools/uidgid.html


1

चूंकि ओपी सिर्फ विकास / परीक्षण है, चिकना समाधान से कम सहायक हो सकता है:

स्क्रिप्ट के लिए क्षमताओं को प्रदान करने के लिए स्क्रिप्ट का उपयोग दुभाषिया पर सेट किया जा सकता है। यदि वैश्विक दुभाषिया बाइनरी पर सेटकैप स्वीकार्य नहीं है, तो बाइनरी की कोई भी स्थानीय प्रति (कोई भी उपयोगकर्ता) बना सकते हैं और इस प्रति पर सेट करने के लिए रूट प्राप्त कर सकते हैं। Python2 (कम से कम) आपके स्क्रिप्ट विकास के पेड़ में दुभाषिया की एक स्थानीय प्रति के साथ ठीक से काम करता है। कोई suid की जरूरत नहीं है, इसलिए रूट उपयोगकर्ता उन क्षमताओं को नियंत्रित कर सकता है जिनकी उपयोगकर्ताओं तक पहुंच है।

यदि आपको इंटरप्रेटर को सिस्टम-वाइड अपडेट ट्रैक करने की आवश्यकता है, तो अपनी स्क्रिप्ट चलाने के लिए शेल स्क्रिप्ट का उपयोग करें जैसे:

#!/bin/sh
#
#  Watch for updates to the Python2 interpreter

PRG=python_net_raw
PRG_ORIG=/usr/bin/python2.7

cmp $PRG_ORIG $PRG || {
    echo ""
    echo "***** $PRG_ORIG has been updated *****"
    echo "Run the following commands to refresh $PRG:"
    echo ""
    echo "    $ cp $PRG_ORIG $PRG"
    echo "    # setcap cap_net_raw+ep $PRG"
    echo ""
    exit
}

./$PRG $*

1

मैंने कोशिश की विधि के बारे में iptables की कोशिश की। पुराने कर्नेल में ऐसा लगता है कि इस प्रकार का नियम IPv6 के लिए समर्थित नहीं था । लेकिन जाहिरा तौर पर यह अब ip6tables v1.4.18 और लिनक्स कर्नेल v3.8 में समर्थित है।

मैंने यह भी पाया कि मशीन के भीतर शुरू किए गए कनेक्शन के लिए PREROUTING REDIRECT काम नहीं करता है। स्थानीय मशीन से सम्मेलनों के लिए काम करने के लिए, एक OUTPUT नियम भी जोड़ें - देखें कि iptables पोर्ट लोकलहोस्ट के लिए काम नहीं कर रहा है । जैसे कुछ:

iptables -t nat -I OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080

मैंने यह भी पाया कि PREROUTING REDIRECT फॉरवर्डेड पैकेट्स को भी प्रभावित करता है । यही है, अगर मशीन इंटरफेस के बीच पैकेट को अग्रेषित कर रही है (जैसे कि अगर यह एक ईथरनेट नेटवर्क से जुड़े वाई-फाई एक्सेस प्वाइंट के रूप में काम कर रहा है), तो iptables नियम इंटरनेट से जुड़े गंतव्यों से जुड़े क्लाइंट के कनेक्शन को भी पकड़ लेगा, और उन्हें रीडायरेक्ट कर देगा। यंत्र। यही मैं नहीं चाहता था - मैं केवल उन कनेक्शनों को पुनर्निर्देशित करना चाहता था जो मशीन को निर्देशित किए गए थे। मैंने पाया कि मैं केवल बॉक्स को संबोधित पैकेट को जोड़कर इसे प्रभावित कर सकता हूं -m addrtype --dst-type LOCAL। जैसे कुछ:

iptables -A PREROUTING -t nat -p tcp --dport 80 -m addrtype --dst-type LOCAL -j REDIRECT --to-port 8080

एक अन्य संभावना टीसीपी पोर्ट अग्रेषण का उपयोग करने की है। उदाहरण के लिए socat:

socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080

हालाँकि उस विधि के साथ एक नुकसान यह है कि, जो अनुप्रयोग 8080 पोर्ट पर सुन रहा है, तो आने वाले कनेक्शनों के स्रोत पते (जैसे लॉगिंग या अन्य पहचान उद्देश्यों के लिए) को नहीं जानता है।


0

उत्तर 2015 / सितंबर:

ip6tables अब IPV6 NAT का समर्थन करता है: http://www.netfilter.org/projects/iptables/files/changes-iptables-1.4.17.txt

आपको कर्नेल 3.7+ की आवश्यकता होगी

सबूत:

[09:09:23] root@X:~ ip6tables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REDIRECT   tcp      eth0   *       ::/0                 ::/0                 tcp dpt:80 redir ports 8080
    0     0 REDIRECT   tcp      eth0   *       ::/0                 ::/0                 tcp dpt:443 redir ports 1443

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 6148 packets, 534K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 6148 packets, 534K bytes)
 pkts bytes target     prot opt in     out     source               destination
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.