سؤال كيفية تشغيل خادم على المنفذ 80 كمستخدم عادي على Linux؟


لقد بحثت عن هذا الأمر لبعض الوقت ، لكنني لم أجده.

أنا على نظام التشغيل Ubuntu Linux وأريد تشغيل خادم على المنفذ 80 ، ولكن بسبب آلية الأمان في Ubuntu ، أحصل على الخطأ التالي:

java.net.BindException: تم رفض الإذن: 80

أعتقد أنه يجب أن يكون بسيطًا بما فيه الكفاية لتعطيل آلية الأمان هذه بحيث يتوفر المنفذ 80 لكافة المستخدمين أو لتعيين الامتيازات المطلوبة للمستخدم الحالي للوصول إلى المنفذ 80.


282
2017-11-10 14:31


الأصل


ما المشكلة في تشغيل الخادم على منفذ آخر غير محمي؟ أنت تفكر في شيء قاس مثل تعطيل آلية الأمان دون توفير سبب جدي على الأقل لتشغيل خادم على هذا المنفذ. هل الخادم مقنن لربط المنفذ 80؟ إذا كان الأمر كذلك ، رميها بعيدا. - Anonymous
أو رسالة خطأ Python: socket.error: [Errno 13] Permission denied - Kazark
ممكن من الازدواجية مستخدم عادي باستخدام منافذ أقل من 1024 - Roman
لا تستطيع تتميز المنافذ الأقل من 1024 بامتياز ويمكن للجذر فقط فتح مآخذ الاستماع عليها. الشيء المناسب للقيام به هو إسقاط الأذونات بعد فتحه. - Falcon Momot
"مجهول" - تم تدريب المستخدمين في العالم للبحث عن خدمات معينة في منافذ معينة. في بعض الحالات ، تم توحيدها. على سبيل المثال ، HTTP على المنفذ 80 و HTTPS على المنفذ 443. نوعه من الصعب تغيير المستخدمين ومعايير العالم. - jww


الأجوبة:


إجابة مختصرة: لا يمكنك ذلك. يمكن فتح الموانئ أدناه 1024 فقط بواسطة الجذر. حسب تعليق - حسنا ، يمكنك استخدام CAP_NET_BIND_SERVICE، ولكن هذا النهج ، المطبقة على java bin سيجعل أي برنامج جافا ليتم تشغيله مع هذا الإعداد ، وهو أمر غير مرغوب فيه ، إن لم يكن خطرًا أمنيًا.

الإجابة الطويلة: يمكنك إعادة توجيه الاتصالات على المنفذ 80 إلى منفذ آخر يمكنك فتحه كمستخدم عادي.

تشغيل كجذر:

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

نظرًا لأن أجهزة الاسترجاع (مثل المضيف المحلي) لا تستخدم قواعد التحويل ، إذا كنت بحاجة إلى استخدام المضيف المحلي ، وما إلى ذلك ، أضف هذه القاعدة أيضًا (شكراFrancesco):

# iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080

ملاحظة: الحل أعلاه ليس وهي مناسبة تمامًا للأنظمة متعددة المستخدمين ، حيث يمكن لأي مستخدم فتح المنفذ 8080 (أو أي منفذ آخر مرتفع تقرر استخدامه) ، وبالتالي اعتراض حركة المرور. (الشكر ل CesarB).

تعديل: حسب سؤال التعليق - لحذف القاعدة المذكورة أعلاه:

# iptables -t nat --line-numbers -n -L

سيؤدي هذا إلى إنتاج شيء مثل:

Chain PREROUTING (policy ACCEPT)
num  target     prot opt source               destination         
1    REDIRECT   tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:8080 redir ports 8088
2    REDIRECT   tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 redir ports 8080

القاعدة التي تهمك هي nr. 2 ، لذلك لحذفه:

# iptables -t nat -D PREROUTING 2

331
2017-11-10 14:41



Sunny: التصويتات ليست لأسرع بندقية في الغرب ، ولكن للحصول على أفضل الردود. تفضلوا بقبول فائق الاحترام هو الأفضل حتى الآن (لقد ذكرت فقط iptables ؛ أنك قدمت بالفعل سطر الأوامر الكامل). الشيء الوحيد الذي لا تملكه لك هو التحذير الخاص بالمستخدمين الآخرين الذين يمكنهم أيضًا ربط المنفذ 8080. - CesarB
لاحظ أن هذا لا يعمل مع IPv6. - Emmanuel Bourg
هل يمكن لأي شخص أن يشرح كيف يمكنني إزالة هذه القاعدة لاحقًا عندما أريد ذلك؟ بعد تشغيله ، يعمل ، لكنه على ما يبدو ليس "قاعدة" لأنه لا يظهر عندما أفعل sudo iptables --list. أنا أعرف ما هو iptables ويفعل ، ولكن لم أكن استخدمها حقا قبل ذلك. - Encoderer
شكرا لإجابتك ... كلما أعدت تشغيل Ubuntu ، تختفي هذه القاعدة ويجب أن أقوم بتشغيلها مرة أخرى. هل هناك طريقة لحفظه إلى الأبد؟ - Coderji
Coderji: تحقق من قسم "حفظ" في وثائق المنتدى: help.ubuntu.com/community/IptablesHowTo - Sunny


استعمال authbind.

حتى أنه يعمل مع Java إذا قمت بتمكين مكدس IPv4 لـ Java فقط. أنا أستعمل:

authbind --deep $JAVA_HOME/bin/java -Djava.net.preferIPv4Stack=true …

77
2017-11-14 13:12



إذا كان الخادم هو Tomcat ، فيمكنك استخدام authbind تلقائيًا عن طريق الإعداد AUTHBIND=yes في / etc / default / tomcat6 - Emmanuel Bourg
لم أستطع الحصول على هذا للعمل على خادم Ubuntu مع حزمة Java الافتراضية ... - Ashley Steel
أنا لا ، أي حل معروف؟ - mark
لاحظ أنه يجب عليك تكوين authbind للسماح بذلك بالفعل. من صفحة الرجل: "/ etc / authbind / byport / port يتم اختباره. إذا كان يمكن الوصول إلى هذا الملف للتنفيذ إلى المستخدم المتصل ، وفقًا للوصول (2) ، فإن الإذن بالملقم مسموح به."على سبيل المثال للمنفذ 80 ، sudo touch /etc/authbind/byport/80 ; sudo chmod 777 /etc/authbind/byport/80. التثبيت الأولي من authbind ليس لديه أي تفويضات سابقة التهيئة. - Jason C
أوه لا nonononononono ، لا أبدا أي وقت مضى chmod 777 أي شيء! - Johannes


إذا كان نظامك يدعمها ، فيمكنك استخدام الإمكانيات. اطلع على إمكانات الرجل ، التي ستحتاجها هي CAP_NET_BIND_SERVICE.

على برنامج Debian / Ubuntu الأحدث ، يمكنك تشغيل:

sudo apt-get install libcap2-bin 
sudo setcap 'cap_net_bind_service=+ep' /path/to/program

46
2018-05-30 20:32



هذا يعمل لـ nodejs: setcap 'cap_net_bind_service = + ep' / usr / bin / nodejs - JasonS
هذه. أتساءل لماذا هذا الجواب لم يكن أكثر توترًا. أسهل بكثير من خيار iptables imho. - Dominik R
هذه هي الإجابة الصحيحة والأكثر فاعلية ، جميع الإجابات الأخرى تتسبب في الوصول إلى أداء أو مجرد iffy / غير آمن. - OneOfOne


حل آخر هو جعل التطبيق الخاص بك setuid بحيث يمكن ربط مع المنفذ 80. كجذر ، قم بما يلي

chown root ./myapp
chmod +S ./myapp

ضع في اعتبارك أن إجراء ذلك ، ما لم يتم ذلك تمامًا ، سيعرضك لثغرات أمنية محتملة ، لأن تطبيقك سيتحدث إلى الشبكة ، وسيعمل مع امتيازات الجذر الكاملة. إذا كنت تأخذ هذا الحل ، يجب أن تنظر إلى شفرة المصدر لـ Apache أو Lighttpd أو شيء مشابه ، حيث تستخدم امتيازات الجذر لفتح المنفذ ، ولكن بعد ذلك تتخلى على الفور عن تلك الامتيازات و "تصبح" مستخدمًا أقل امتيازًا الخاطف لا يمكنه السيطرة على جهاز الكمبيوتر الخاص بك بأكمله.

تحديث: كما رأينا في هذا السؤال، يبدو أن نواة لينكس منذ 2.6.24 لديها قدرة جديدة تسمح لك بتمييز برنامج قابل للتنفيذ (ولكن ليس نصيًا ، بالطبع) على أنه يحتوي على "CAP_NET_BIND_SERVICE"القدرة. إذا قمت بتثبيت حزمة debian" libcap2-bin "، يمكنك القيام بذلك عن طريق إصدار الأمر

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

39
2017-11-10 14:44



هذا هو نفس تشغيل الجذر ، ما لم يكن التطبيق يعرف كيفية إسقاط الامتيازات. - CesarB
هذا أمر خطير. هذا يعني أن أي طلب سيعمل كجذر. انها لسبب أن اباتشي يبدأ حتى الجذر لربط ، ومن ثم يسقط الامتيازات إلى مستخدم آخر. - Sunny
بول: إن iptables ليس خطيرًا جدًا ، لأنه حتى إذا تم اختراق التطبيق ، فلن يعرض النظام لهجمات ، على الأقل ليس بامتيازات الجذر. تشغيل التطبيق كجذر هو قصة أخرى. - Sunny
الخطر على iptables هو فقط إذا كان هذا هو نظام متعدد المستخدمين ، كما قال سيزارب ، حيث يمكن لأي شخص أن يرتبط 8080 ، واعتراض حركة المرور. - Sunny
لول ، أحب كيف أن الإجابة المقبولة لديها -15 - Evan Teran


النهج المقترح من قبل صني وسيزارب:

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

يعمل بشكل جيد ولكن لديه عيب صغير - لا يمنع المستخدم من الاتصال مباشرة إلى المنفذ 8080 بدلاً من 80.

خذ بعين الاعتبار السيناريو التالي عندما يمكن أن يكون هذا مشكلة.

لنفترض أن لدينا خادمًا يقبل اتصالات HTTP على المنفذ 8080 واتصالات HTTPS على المنفذ 8181.

نحن نستخدم iptables لإنشاء عمليات إعادة التوجيه التالية:

80  ---> 8080
443 ---> 8181

لنفترض الآن أن خادمنا قرر إعادة توجيه المستخدم من صفحة HTTP إلى صفحة HTTPS. ما لم نعيد كتابة الرد بعناية ، فسوف يعيد توجيهه https://host:8181/. في هذه المرحلة ، نحن مشدودون:

  • بعض المستخدمين سوف المرجعية https://host:8181/ عنوان URL ونحتاج إلى الحفاظ على عنوان URL هذا لتجنب كسر الإشارات المرجعية.
  • لن يتمكن المستخدمون الآخرون من الاتصال لأن خوادمهم الوكيلة لا تدعم منافذ SSL غير قياسية.

أنا استخدم النهج التالي:

iptables -t mangle -A PREROUTING -p tcp --dport 80 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -p tcp --dport 443 -j MARK --set-mark 1
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8181
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -m mark --mark 1 -j ACCEPT
iptables -I INPUT -m state --state NEW -m tcp -p tcp --dport 8181 -m mark --mark 1 -j ACCEPT

جنبا إلى جنب مع قاعدة REJECT الافتراضية على سلسلة INPUT يمنع هذا النهج المستخدمين من الاتصال مباشرة إلى المنافذ 8080 ، 8181


35
2018-02-20 16:19



هذا أمر جيد ، ولكن لماذا لا نربط البرنامج بـ localhost فقط: 8080 بدلاً من 0.0.0.0:8080؟ أريد أن أفعل ذلك ، لكني أحتاج إلى iptables لذلك. - Amala
يعمل ، رائع حقا. - xtian


أنا ببساطة استخدام Nginx في الجبهة. يمكن أن تعمل على مضيف محلي أيضا.

  • apt-get install nginx

.. أو ..

  • pkg_add -r nginx 

.. أو ما يناسب نظام التشغيل الخاص بك.

كل ما تحتاجه في nginx.conf ، إذا كان يعمل على localhost ، هو:

الخادم {
        الاستماع 80 ؛
        server_name some.domain.org؛
        موقعك / {
            proxy_set_header مضيف $ host؛
            proxy_set_header X-Real-IP $ remote_addr؛
            proxy_set_header X-Forwarded-For $ proxy_add_x_forwarded_for؛
            proxy_pass http://127.0.0.1:8081 ؛
        }
}

35
2017-11-20 14:30



أنا حقا أحب هذا الحل. - thomasfedb
هذا هو واحد من الحلول المقترحة من JFrog نفسها: jfrog.com/confluence/display/RTF/nginx - stolsvik


تقليديا على يونكس ، يمكن ربط الجذر الوحيد إلى المنافذ المنخفضة (<1024).

إن أبسط طريقة لحل هذا هو تشغيل الملقم على متوسط منفذ (على سبيل المثال ، 8080) واستخدام قاعدة iptables بسيطة لإعادة توجيه الاتصالات من المنفذ 80 إلى المنفذ 8080. لاحظ أنه مع هذا تفقد الحماية الإضافية من المنافذ المنخفضة ؛ يمكن لأي مستخدم على جهازك ربط المنفذ 8080.


29
2017-11-10 14:36





إذا كان نظامك يدعمها ، فيمكنك استخدام الإمكانيات. نرى man capabilities، الذي ستحتاجه CAP_NET_BIND_SERVICE. لا ، أنا لم أستخدمها بنفسي أبداً ولا أعرف إن كانوا يعملون حقًا :-)


23
2017-11-10 16:27



تعمل ، أستخدم CAP_NET_RAW لتشغيل أدوات مثل tcpdump كمستخدم عادي. - Justin


استخدم proxy عكسي (nginx أو apache + mod_proxy) أو بروكسي معكوس للتخزين المؤقت (Squid، Varnish) أمام خوادم التطبيقات الخاصة بك!

باستخدام proxy معكوس ، يمكنك تحقيق الكثير من الأشياء المثيرة للاهتمام مثل:

  • تحميل موازنة
  • إعادة تشغيل خوادم التطبيقات الخاصة بك مع المستخدمين الذين يتلقون صفحة خطأ مزعجة
  • تسريع الأشياء مع ذاكرة التخزين المؤقت
  • إعدادات دقيقة الحواف تقوم بها عادةً مع proxy عكسي وليس مع خادم تطبيقات

11
2017-10-18 15:36





يمكنك استخدام برنامج redir:

sudo redir --lport=80 --laddr=192.168.0.101 --cport 9990 --caddr=127.0.0.1

6
2017-11-27 12:48





استخدم sudo.

تكوين sudo بحيث يمكن للمستخدم العادي تشغيل الأوامر المناسبة:

/etc/init.d/httpd start

أو

apachectl stop

أو

/usr/local/apache2/apachectl restart

أو

/myapp/myappbin start

(أو أي أمر أو برنامج نصي آخر تستخدمه لبدء / إيقاف تطبيق webserver / app)


4
2017-11-10 19:40



هذا له نفس المشكلة - تشغيل الخدمة كجذر هو ممارسة سيئة. - Kevin Panko