सवाल कमांडलाइन से बंदरगाह को मैन्युअल रूप से बंद करना


मैं एक खुला बंदरगाह बंद करना चाहता हूं जो मेरे क्लाइंट और सर्वर एप्लिकेशन के बीच सुनने मोड में है।

क्या पोर्ट बंद करने के लिए लिनक्स में कोई मैनुअल कमांड लाइन विकल्प है?

ध्यान दें:  मुझे पता चला कि "कनेक्ट किए गए सॉकेट के स्वामित्व वाले एप्लिकेशन को केवल इसे बंद करना चाहिए, जो तब होगा जब एप्लिकेशन समाप्त हो जाएगा।"

मुझे समझ में नहीं आ रहा है कि यह केवल एप्लिकेशन द्वारा क्यों संभव है जो इसे खोलता है ... लेकिन मैं अभी भी यह जानने के लिए उत्सुक हूं कि ऐसा करने का कोई अन्य तरीका है या नहीं।


95
2018-04-06 03:39


मूल


नहीं, खुले बंदरगाहों संबंधित प्रक्रिया को खोलने के लिए, बाहर से कोई नियंत्रण संभव नहीं है। जो एक अच्छी बात है, या सभी अनुप्रयोगों को अपने खुले बंदरगाहों (और फ़ाइलों) के साथ गड़बड़ होने की उम्मीद करनी होगी। हालांकि, आप फ़ायरवॉलिंग (iptables) द्वारा किसी पोर्ट को यातायात को अवरुद्ध कर सकते हैं, लेकिन यह बंद नहीं होगा और अन्य उपयोग के लिए बंदरगाह को छोड़ देगा। - Jürgen Strobel
बहुत से उत्तरदाताओं ने इस सवाल के बिंदु को याद किया। यह घोषित करने के लिए बकवास है कि बंदरगाह का मालिक केवल उस एप्लिकेशन को डिस्कनेक्ट कर सकता है। मैं इसे बॉक्स तक चलकर और ईथरनेट केबल को सॉकेट से खींचकर या कनेक्शन के दूसरे छोर पर एप्लिकेशन को मार कर डिस्कनेक्ट कर सकता हूं! इसे संभालने के लिए आवेदन लिखा जाना चाहिए। तो --- आप यह सुनिश्चित करने के लिए कैसे परीक्षण करते हैं कि एप्लिकेशन को शारीरिक हस्तक्षेप और / या अन्य कंप्यूटर के नियंत्रण की आवश्यकता के बिना ठीक से लिखा गया है? - Dale Wilson
"... बाहर से कोई नियंत्रण संभव नहीं है।" यह एक महत्वपूर्ण टिप्पणी है, जिसने मुझे अगले प्रश्न के लिए निर्देशित किया है, मैं बाहर से प्रक्रिया का हिस्सा कैसे बन सकता हूं? GDB। - Dankó Dávid


जवाब:


मुझे एक ही समस्या थी, प्रक्रिया को जिंदा रखना चाहिए लेकिन सॉकेट बंद होना चाहिए। एक चल रही प्रक्रिया में एक सॉकेट बंद करना असंभव नहीं है लेकिन मुश्किल है:

  1. प्रक्रिया का पता लगाएं:

    netstat -np
    

    आपको एक मिलता है source/destination ip:port portstate pid/processname नक्शा

  2. प्रक्रिया में सॉकेट की फ़ाइल डिस्क्रिप्टर का पता लगाएं

    lsof -np $pid
    

    आपको एक सूची मिलती है: प्रक्रिया का नाम, पिड, उपयोगकर्ता, फ़ाइल डिस्क्रिप्टर, ... एक कनेक्शन स्ट्रिंग।

    कनेक्शन के लिए मिलान फ़ाइल डिस्क्रिप्टर नंबर का पता लगाएं।

    अब प्रक्रिया को कनेक्ट करें:

    gdb -p $pid
    
  3. अब सॉकेट बंद करें:

    call close($fileDescritor)
    
    //does not need ; at end.
    

    फिर अलग करें:

    quit
    

    और सॉकेट बंद है।


114
2017-11-01 01:43



sudo lsof -np $pid मुझे लगभग 200 लाइनें देता है और मैं चाहता हूं कि वांछित एफडी कैसे ढूंढें। मेरी केस प्रक्रिया में क्रोम टैब है और मैं खुले websockets बंद करने की कोशिश कर रहा हूँ ... - SET
एक पंक्ति आमतौर पर इस तरह दिखती है: फ़ायरफ़ॉक्स 14812 szupervigyor 97u आईपीवी 4 32814564 0t0 टीसीपी 192.168.2.4:40385->173.194.39.65:https (स्थापित): process_name pid उपयोगकर्ता fd [open_for] प्रोटोकॉल डिवाइस inode प्रोटोकॉल_डाटा_toString - Dankó Dávid
* एक पंक्ति आमतौर पर इस तरह दिखती है: फ़ायरफ़ॉक्स 14812 szupervigyor 97u आईपीवी 4 32814564 0t0 टीसीपी 192.168.2.4:40385->173.194.39.65:https (स्थापित) के रूप में: process_name pid उपयोगकर्ता fd [open_for] प्रोटोकॉल डिवाइस inode प्रोटोकॉल_डेटा_toString आपको दूरस्थ आईपी पता होना चाहिए पता लगाएँ और अंतिम कॉल पर खोजें। मेरे उदाहरण में 97 फाइल डिस्क्रिप्टर है। यदि आप लक्ष्य होस्ट के लिए एकाधिक कनेक्शन खोलते हैं तो खोज करना मुश्किल है। - Dankó Dávid
यह एक शानदार समाधान है - marcorossi
यदि आप रिमोट एंड द्वारा बंद सॉकेट को अनुकरण करना चाहते हैं (उदा। पीयर से बाहर निकलना) तो इसका उपयोग करना बेहतर है shutdown: call shutdown($fileDescriptor, 0)। - ecatmur


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

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

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

वैसे भी, यहां एक प्रक्रिया को मारने का तरीका है जो किसी विशेष पोर्ट का मालिक है:

sudo netstat -ap | grep :<port_number>

यह प्रक्रिया होल्डिंग पोर्ट से संबंधित लाइन आउटपुट करेगा, उदाहरण के लिए:

tcp  0  0 *:8000   *:* LISTEN  4683/procHoldingPort

इस मामले में, procHoldingPort बंदरगाह खोला गया प्रक्रिया का नाम है, 4683 इसकी पिड है, और 8000 (ध्यान दें कि यह टीसीपी है) यह पोर्ट नंबर है।

फिर, अंतिम कॉलम देखें, आप देखेंगे /। फिर इसे निष्पादित करें:

kill  <pid>

अगर यह काम नहीं करता है (आप netstat कमांड को फिर से चलाकर जांच सकते हैं)। यह करो:

kill -9 <pid>

आम तौर पर, यदि आप कर सकते हैं तो सिगकिल भेजने से बचना बेहतर है। यही कारण है कि मैं आपको कोशिश करने के लिए कहता हूं kill से पहले kill -9। बस उपयोग कर रहा हूँ kill gentler SIGTERM भेजता है।

जैसे मैंने कहा, अगर आप ऐसा करते हैं तो पोर्ट को फिर से खोलने में कुछ मिनट लगेंगे। मुझे इसे तेज करने का कोई तरीका नहीं पता। अगर कोई और करता है, तो मुझे यह सुनना अच्छा लगेगा।


74
2018-04-06 04:05



@smehmood - विस्तृत स्पष्टीकरण के लिए धन्यवाद .. एक छोटा सा संदेह .. कर्नेल अचानक अचानक मारे गए प्रक्रिया द्वारा एक खुले बंदरगाह को कैसे पुनः प्राप्त करता है ?? .. आपके द्वारा प्रदान किया गया समाधान पोर्ट को पकड़ने की प्रक्रिया को मार रहा है ...
@codingfreak कर्नेल जानता है कि प्रक्रिया समाप्त हो गई है। यह जानता है कि यह बंदरगाह पुनः प्राप्त कर सकते हैं। वास्तव में बंदरगाह बंद करने के समय पर नियम हैं, यह सुनिश्चित करने के लिए कि नेट पर तैरने वाले किसी भी भटकने वाले पैकेट नहीं हैं। यह कैसे पता चलता है कि इन संसाधनों में है? कर्नेल करता है, चीजों का ट्रैक रखता है। - Rich Homolka
जब तक कोई व्यक्ति कुछ समझदार पोस्ट नहीं करता है unix.tools.port.close(<my port number>) मै इस्तेमाल करूंगा init 6। - Snowcrash


फ्यूसर भी इस्तेमाल किया जा सकता है

fuser -k -n *protocol portno*

यहां प्रोटोकॉल टीसीपी / udp है और पोर्टनो वह नंबर है जिसे आप बंद करना चाहते हैं। जैसे

fuser -k -n tcp 37

अधिक जानकारी पर फ्यूसर मैन पेज


18
2018-02-13 08:44



सिर्फ मालिक की प्रक्रिया को मारना मेरे लिए काम नहीं करता था, लेकिन फ्यूसर ने किया था। धन्यवाद! - webwurst
फ्यूसर का उपयोग करने के बाद भी मुझे इसके साथ मिश्रित परिणाम मिल गए, मुझे रूट के रूप में ऐसा करने के लिए मारे गए ऐप से बंदरगाह का पुन: उपयोग करने का प्रयास करते समय "सॉकेट पहले से ही उपयोग में आया"। दूसरी तरफ, सॉकेट को मुक्त करने का समय पहले इतना छोटा लग रहा था, इसलिए वैसे भी धन्यवाद। - Jan Vlcinsky
@JanVlcinsky शायद एक "अभिभावक" प्रक्रिया है जो बाद में मारे गए प्रक्रिया क्षणों को पुनरारंभ करती है fuser दौड़ हैं? - RedBaron
@RedBaron: टिप्पणी के अनुसार superuser.com/a/415236/153413 मेरी समस्या खराब लिखित आवेदन में उत्पन्न होती है, जो समाप्ति के तहत सॉकेट को साफ / बंद नहीं करती है। इसलिए fuser बंदरगाह का उपयोग कर प्रक्रिया पाता है और इसे मारता है, लेकिन इस तथ्य को हल नहीं करता है कि सॉकेट बंद नहीं है। 60 सेकंड और कर्नेल मेरे लिए यह करता है। - Jan Vlcinsky


आप वैकल्पिक रूप से iptables का उपयोग कर सकते हैं:

iptables -I INPUT -p tcp --dport 80 -j DROP

यह मूल रूप से आप जो चाहते हैं उसे पूरा करता है। यह पोर्ट 80 पर सभी टीसीपी यातायात को छोड़ देगा।


5
2018-04-06 09:38



नहीं, यह सॉकेट तब तक खुल जाएगा जब तक कि सभी टाइमआउट उन्हें बंद न करें। (यह मालिकाना प्रक्रिया से सभी ट्रैफिक छुपाएगा, जिसके बाद इसका मतलब यह नहीं है कि इसे बंद करना चाहिए।) आप इसका उपयोग कर सकते हैं -j REJECT टीसीपी रीसेट फ्लैग वापस करने के लिए, जिसे मेरी अपनी प्रक्रिया को देखा जाएगा (लेकिन केवल जब दूसरी तरफ कुछ भेजने की कोशिश करता है)। - Marki555


netstat -anp | grep 80

यह आपको बताना चाहिए, अगर आप अपाचे चला रहे हैं, तो "httpd" (यह केवल एक उदाहरण है, पोर्ट का उपयोग करें जो आपका आवेदन 80 के बजाय उपयोग कर रहा है)

pkill -9 httpd 

या

killall -9 httpd

3
2018-04-06 03:45



-9 का सहारा लेने से पहले एक सामान्य हत्या का प्रयास करें - Thilo
@omfgroflmao - लेकिन यह उस प्रक्रिया को मार देगा जिसने बंदरगाह खोला है ??
@codingfreak बंदरगाह धारण करने वाली प्रक्रिया, हाँ यह इसे मार डालेगी।


आप शायद यह पता लगा सकते हैं कि पोर्ट किस सॉकेट को खोला गया है उस प्रक्रिया से जुड़ा हुआ है, और मार डालो।

लेकिन, आपको तब तक महसूस करना होगा जब तक कि उस प्रक्रिया में एक हैंडलर है जो सभी चीजों को शुरू करता है जो इसे उपयोग कर रहा था (खुला फाइलें, सॉकेट, कांटे, सामान जो तब तक रुक सकते हैं जब तक कि इसे समाप्त होने पर ठीक से बंद न किया जाए) तो आप सिस्टम प्रदर्शन पर उस ड्रैग को बनाया होगा। इसके अलावा, सॉकेट रहेगी तब तक खुलें जब तक कि कर्नेल को यह न हो कि प्रक्रिया को मार दिया गया है। वह आमतौर पर बस लगभग एक मिनट लगते हैं।

मुझे लगता है कि बेहतर सवाल होगा: क्या पोर्ट (से संबंधित है क्या प्रक्रिया) क्या आप रुकना चाहते हैं?

यदि आप एक पिछवाड़े को खत्म करने की कोशिश कर रहे हैं या वायरस जो आपको मिला, तो आपको कम से कम यह जानना चाहिए कि डेटा आगे और आगे क्या चल रहा है इसे समाप्त करने से पहले। (wireshark इसके लिए अच्छा है) (और प्रक्रिया 'निष्पादन योग्य नाम ताकि आप इसे हटा सकें और इसे रीबूट पर वापस आने से रोक सकें) या, यदि यह कुछ स्थापित है (जैसे HTTPD या FTPD या कुछ) तो आपके पास पहले से ही पहुंच होनी चाहिए प्रक्रिया ही

आमतौर पर इसमें एक नियंत्रण कार्यक्रम होगा (HTTPD रोकें | प्रारंभ या कुछ)। या, यदि यह एक सिस्टम चीज है, तो आपको शायद इसके साथ गड़बड़ नहीं करनी चाहिए। वैसे भी, मैंने सोचा कि चूंकि हर कोई आपको "कैसे-टू" कोण दे रहा है, मुझे आपको चेतावनी देना चाहिए।


2
2018-04-22 05:02



बहुत अच्छी टिप्पणी। मेरे पास एक प्रोग्राम है, जो समाप्ति के तहत सॉकेट को बंद करता है जो वर्णित व्यवहार में परिणाम देता है - सॉकेट लगभग 60 सेकंड के लिए उपयोग करने योग्य नहीं है। जब मैं रुक जाता हूं और उस प्रक्रिया को शुरू करता हूं, तो यह लगभग एक मिनट तक शिकायत कर रहा है कि पता और बंदरगाह पहले ही उपयोग में है। सबसे अच्छा समाधान बुरी तरह से व्यवहार प्रक्रिया को ठीक से बंद करने के लिए सही है, लेकिन कभी-कभी यह एक विकल्प नहीं है। कर्नेल से पूछने का कोई तरीका है कि अवरुद्ध सॉकेट 60 सेकेंड की तुलना में जल्द से जल्द? - Jan Vlcinsky


मैंने पहली बार मोंगो और नोड प्रक्रियाओं की तलाश की, फिर निम्नलिखित किया:

ps -A | grep node

10418 pts/23   00:00:05 node

10551 pts/23   00:00:00 node

ps -A | grep mongo

10490 pts/23   00:00:00 mongod

एक बार पहचानने के बाद, हत्या आदेश के साथ प्रक्रियाओं को मार डालो।

kill -9 10418
kill -9 10490

अंत में, टाइप करें meteor और यह फिर से काम करना चाहिए।


2
2018-05-27 03:46





आप एक स्क्रिप्ट लिख सकते हैं जो iptables को संशोधित करता है और उन्हें पुनरारंभ करता है। बंदरगाह पर सभी पैकेट छोड़ने के नियम को जोड़ने के लिए एक स्क्रिप्ट, कहा नियम हटाने के लिए एक और स्क्रिप्ट।

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


1
2018-04-06 04:10



@ माइकल शिममिन्स ... हम्म घुसपैठ कर रहा है क्योंकि हम सर्वर के किनारे बंदरगाह को अवरुद्ध कर सकते हैं ताकि ग्राहक कोई संदेश न भेजे।
वैसे ग्राहक क्लाइंट को वो भेज सकते हैं जो वे चाहते हैं कि हमने अभी दरवाजा बंद कर दिया है ताकि वे अंदर नहीं जा सकें।


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


1
2017-11-01 02:08