SSH में प्रति होस्ट दो अलग-अलग आईपी पते का उपयोग करें


23

मेरे पास एक सर्वर है, जिसका नाम है gamma , लगातार काम पर चलना और चलना। कभी-कभी मैं इसे घर से कनेक्ट करता हूं, जिस स्थिति में मैं सार्वजनिक आईपी पते का उपयोग करता हूं 55.22.33.99। कभी कभी, मैं इसे करने के लिए कनेक्ट, जब मैं काम पर हूँ, और नहीं बल्कि उछाल की तुलना में मेरी पैकेट अनावश्यक रूप से चारों ओर, मैं स्थानीय आईपी पते के माध्यम से कनेक्ट 192.168.1.100

फिलहाल, मैंने उन्हें दो अलग-अलग प्रविष्टियों में विभाजित किया है ~/.ssh/conf

Host gamma-local
        HostName 192.168.1.100
        Port 22
        User andreas

Host gamma-remote
        HostName 55.22.33.99
        Port 12345
        User andreas

इसलिए, अगर मैं काम पर हूं, तो मुझे लिखना होगा ssh gamma-local और मैं अंदर हूं; अगर मैं घर पर हूं (या दुनिया में कहीं भी), मैं दौड़ता हूं ssh gamma-remote

सर्वर से कनेक्ट करते समय, मुझे नहीं लगता कि मैं जहां हूं, उसके आधार पर एक अलग नाम टाइप करना होगा, मैं चाहता हूं कि यह हिस्सा अपने आप हो जाए; उदाहरण के लिए, कुछ मामलों में मेरे पास स्वचालित स्क्रिप्ट हैं जो कनेक्ट करती हैं कि मुझे नहीं पता कि मैं कहां हूं।

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

क्या इसे प्राप्त करने का कोई वैकल्पिक तरीका है जो बैश स्क्रिप्ट के उपयोग पर निर्भर नहीं करता है, न ही "परीक्षण" यह देखने के लिए कि क्या कनेक्शन पहले काम करता है?


क्या मैं यह पता लगाने की कोशिश कर रहा हूं कि क्या कोई इसे /etc/hostsहासिल करने के लिए या एसएसएच कॉन्फिग फाइल के साथ फील कर सकता है ? या शायद "डिटेक्ट" करने का कोई तरीका है कि आप वर्तमान में किस लैन से जुड़े हैं?
IQAndreas

क्या आपके पास अपने कार्यालय नेटवर्क द्वारा उपयोग किए जाने वाले नेमसर्वर का एक अलग सेट है?
श्री

@ श्री आह, मैं देख रहा हूँ कि आप इस के साथ कहाँ जा रहे हैं; चतुर! हम इस समय नेमसेवर नहीं चला रहे हैं, लेकिन मैं मशीनों में से एक को निश्चित रूप से बदल सकता हूं।
IQAndreas

@ श्री स्वतंत्र महसूस करने के लिए विस्तृत और जोड़ना है कि एक जवाब है कि लाइन के साथ शुरू होता है के रूप में "यदि आप अपने कार्यालय नेटवर्क पर एक
नेमवर है

वह किया। बेझिझक अप / डाउन वोट :)
श्री

जवाबों:


28

यदि आपके पास यह पहचानने का कोई तरीका है कि आप किस नेटवर्क पर हैं तो आप Matchकीवर्ड का उपयोग कर सकते ~/.ssh/configहैं कि आप क्या चाहते हैं। इसके लिए ओपनएसएसएच .56.5 की आवश्यकता होती है।

मैं कुछ इसी तरह का उपयोग करता हूं

Match originalhost gamma exec "[ x$(/sbin/iwgetid --scheme) != xMyHomeESSID ]"
  HostName 192.168.1.100
  Port 22

Host gamma
  User andreas
  Port 12345
  HostName 55.22.33.99

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


Matchधन्यवाद में +1 चतुर उपयोग ! शून्य या गैर-शून्य निकास स्थिति के साथ बाहर निकलने वाली स्क्रिप्ट में पहचान को लपेटना एक अच्छा विचार हो सकता है, क्योंकि यह पुन: प्रयोज्य बना देगा।
पीटर डे 22'14

@ वाट्सएप इसे निश्चित रूप से एक बाहरी स्क्रिप्ट में समाहित कर सकता है, लेकिन मुझे अब तक केवल एक जगह की जरूरत थी, इसलिए तीन का नियम अभी तक नहीं बना है।
माइकल पोलित्स्की

यदि आप काम पर थे, तो क्या होगा, लेकिन आप वास्तव में किसी और मशीन से जुड़ना चाहते हैं? चूंकि आप अपने होमेसिड के साथ वाईफाई पर नहीं हैं, और इसलिए होस्टनाम को 192.168.1.100 पर सेट करने के बाद से निष्पादन विवरण मैच नहीं करेगा?
चला गया

@ मुझे सवाल समझ नहीं आ रहा है। मैच टारगेट होस्ट पर भी है।
मिशैल पोलित्स्की

1
@typelogic आसानी से नहीं, जहाँ तक मुझे पता है। आप उपयोग करने की कोशिश कर सकते हैं ProxyCommand nc $address ssh, लेकिन फिर जैसे। क्या सभी उपकरणों में एक ही होस्ट कुंजी है? यदि आपको किसी भी तरह से एक पर्यावरण चर निर्धारित करना है, तो क्या यह आसान नहीं होगा कि आप पते को सीधे तर्क के रूप में जोड़ सकें ssh?
मिशैल पोलितोव्स्की

5

यदि आपके पास काम पर एक निजी नेमसर्वर है और यदि आप कार्यालय और घर से एक ही लैपटॉप का उपयोग करते हैं, तो आप इसका लाभ उठा सकते हैं:

  1. अपने संशोधित nsswitch.confपहले DNS में जाँच करने के लिए अपने मशीन में
  2. gammaकार्यालय में अपने निजी डीएनएस में 192.168.1.100 को हल करने के लिए एक डीएनएस प्रविष्टि बनाएं ।
  3. gamma55.22.33.99 को हल करने के लिए अपनी मशीन के / etc / मेजबान फ़ाइल में एक प्रविष्टि बनाएँ ।

इस तरह, जब आप ssh gammaकार्यालय से आते हैं, तो यह कार्यालय DNS से ​​192.168.1.100 तक और जब आप घर से कनेक्ट करते हैं, तो यह आपकी मेजबानों फ़ाइल से 55.22.33.99 पर हल होगा।

पुनश्च : यह उत्तर मानता है कि आप सार्वजनिक डीएनएस प्रविष्टि के लिए गामा नहीं चाहते हैं। इसके अलावा, अगर आप विंडोज मशीन से अपने सर्वर पर SSHing कर रहे हैं, तो मुझे लगता है कि मेजबान फ़ाइल प्रविष्टियों को ओवरराइड करने के लिए nssswitch.conf फाइल के बराबर कुछ जगह होनी चाहिए।


वहाँ है - यह मेजबान फ़ाइल है। और यह ठीक है कि मैं इसे कैसे करता हूं - जब घर पर मेरा सार्वजनिक डोमेन मेरे स्थानीय आईपी का समाधान करता है। बहुत बढ़िया जवाब - यह पहली चीज थी जो मैंने भी सोची थी। खैर ... आज वह है, जब मैंने कुछ साल पहले इसे स्थापित किया था, मुझे इसका समाधान खोजने के लिए बहुत कुछ करना पड़ा।
मोकेसर

2

मुझे नहीं पता कि ऐसा करना संभव है या नहीं, ~/.ssh/configलेकिन एक अन्य दृष्टिकोण आपके बाहरी आईपी पते के आधार पर एक या दूसरे से जुड़ना होगा। चूंकि, संभवतः, जब आप काम पर हों, तो आपका आईपी होगा 55.22.33.NNN, आप कुछ इस तरह से चला सकते हैं:

[[ $(wget -qO - http://wtfismyip.com/text) =~ ^'55.22.33.' ]] && 
    ssh 192.168.1.100 ||
    ssh -p 12345 55.22.33.99

एक और भी सरल तरीका है अपने आंतरिक आईपी का उपयोग करना। मुझे नहीं पता कि आपके दो नेटवर्क कैसे सेट किए गए हैं, लेकिन अगर यह निर्धारित करना आसान है कि आप अपने आईपी के माध्यम से काम पर हैं या नहीं (उदाहरण के लिए, यदि आपके पास काम पर एक विशिष्ट आईपी है, जैसे 192.168.1.12), तो आप कर सकते हैं ( eth0आपके नेटवर्क कार्ड का नाम जो कुछ भी है उसे बदल दें):

[[ $(ip address show dev eth0 | grep -Po 'inet \K[\d.]+') = '192.168.1.12' ]] && 
    ssh 192.168.1.100 ||
    ssh -p 12345 55.22.33.99

आप जो भी उपयोग करने का निर्णय लेते हैं, आप इसे अपने शेल में एक उपनाम के रूप में जोड़ सकते हैं ( ~/.bashrcयदि आप उपयोग कर रहे हैं , तो अपने शेल की आरंभीकरण फ़ाइल में यह पंक्ति जोड़ें bash):

alias gamma="[[ $(wget -qO - http://wtfismyip.com/text) =~ ^'55.22.33.' ]] && ssh 192.168.1.100 || ssh -p 12345 55.22.33.99

आप इसे एक स्क्रिप्ट में भी बना सकते हैं यदि आप चाहते हैं कि अन्य स्क्रिप्ट तक इसकी पहुंच हो ( .bashrcलिपि चलाते समय एलियास को पढ़ा नहीं जाता है)।


2

~/.ssh/configहोस्ट नामों के रूप में IP पतों का उपयोग करते समय आप इसे प्राप्त नहीं कर सकते । अतिरिक्त जटिलता इस तथ्य से शुरू होती है, कि आप न केवल अलग-अलग आईपी पते बल्कि विभिन्न बंदरगाहों से भी जुड़ रहे हैं, क्योंकि आपके DNS रिज़ॉल्वर के किसी भी ट्विकिंग से बहुत अधिक नियम हैं।

मैं सही हूं - आप Match originalhost ... exec ...कॉम्बो का उपयोग कर सकते हैं ~/.ssh/config- @ MichałPolitowski का जवाब देखें । हालाँकि, यद्यपि यह OpenSSH के लिए पूरी तरह से ठीक काम करेगा, आप अन्य SSH क्लाइंट में समान कार्यक्षमता नहीं पा सकते हैं।

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

यदि आपके पास स्थानीय और दूरस्थ दोनों नेटवर्क के लिए एक ही पोर्ट हो सकता है, तो आप अपने /etc/resolv.confनेटवर्क के आधार पर अपना संपादन कर सकते हैं - जाहिर है यह स्वचालित रूप से किया जाना होगा (सबसे अधिक संभावना आपके डीएचसीपी क्लाइंट की हुक स्क्रिप्ट से)। या - बेहतर - स्थानीय नाम सर्वर (उदाहरण के लिए dnsmasq) चलाएं और इसे उपयुक्त कॉन्फ़िगरेशन के साथ आपूर्ति करें। हालांकि इस सवाल के दायरे से परे है।

एक अन्य विकल्प - यदि आपको केवल अंतःक्रियात्मक रूप से कनेक्ट करने की आवश्यकता है - कमांड पूरा करने का उपयोग करना है जो स्कैन करेगा ~/.ssh/config। यह आपको कुछ टाइपिंग से बचाएगा (विशेषकर यदि आपके पास पर्याप्त Hostप्रविष्टियाँ बदलती हैं)। कुछ इस तरह से ( bashआरंभ के लिए):

# complete session names for ssh
declare -g _ssh_complete_hostlist 2> /dev/null
function _ssh_complete_init () {
    _ssh_complete_hostlist=$( \
        sed -nr '/^\s*Host\s*=/{s/^[^=]+= *//;s/ /\n/g;p}' ~/.ssh/config \
        | sort )
}
_ssh_complete_init

function _ssh_complete () {
    local match=${COMP_WORDS[${COMP_CWORD}]}
    local hosts=
    local default=
    for h in $_ssh_complete_hostlist; do
        if [[ $h =~ ^$match ]]; then
            hosts="$hosts $h"
        fi
    done
    if ! (( ${COMP_CWORD} == ${#COMP_WORDS[@]}-1 )); then
        default=$( compgen -f ${COMP_WORDS[${COMP_CWORD}]} )
    fi
    COMPREPLY=($hosts $default)
}
complete -F _ssh_complete ssh

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

इस सभी ने कहा, इस समस्या से निपटने का सही तरीका एक वीपीएन के माध्यम से कार्य नेटवर्क में जुड़ रहा है और इस तरह से स्थानीय कार्य आईपी पता सुलभ है जैसे कि आप कार्यालय में थे। : फिर आप कड़ी मेहनत से तार जो कुछ भी जो भी परत आप पसंद करते हैं में पता कर सकते हैं ~/.ssh/config, /etc/resolv.confया (imho सबसे अच्छा विकल्प) कार्यालय नाम सर्वर।


पोर्ट पत्थर में सेट नहीं हैं। मैं निश्चित रूप से स्थानीय एसएसएच पोर्ट gammaको रिमोट पोर्ट से मिलान करने के लिए बदल सकता था अगर यह चीजों को आसान बना देगा।
IQAndreas

2

कुछ साल पहले, मैंने इसी तरह के उद्देश्य के लिए एक कार्यक्रम लिखा था । यह आपकी आवश्यकताओं के अनुरूप हो सकता है। उस प्रोग्राम के साथ ssh कॉन्फ़िगरेशन इस तरह दिख सकता है:

Host gamma
    ProxyCommand ssh-multipath-proxy 192.168.1.100:22 55.22.33.99:12345
    User andreas

1

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

आप उस विन्यास फाइल का चयन करें जिसका आप उपयोग करना चाहते हैं -F <configfile>


धन्यवाद। मुझे -Fविकल्प पसंद है ।
टाइपेलॉजिक

0

आंशिक उत्तर:

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

function identifyConnection {
    gatewayIP=$(route -n | grep -e '^0\.0\.0\.0' | tr -s ' ' | cut -d ' ' -f 2)

    if [[ ! -z "$gatewayIP" ]]
    then
        # Identify the gateway by its MAC (uniqueness...)
        log "Gateway IP address=$gatewayIP"
        log "Obtaining corresponding gateway MAC address"
        gatewayData=($(arp -n $gatewayIP | grep -e $gatewayIP | tr -s ' '))
        if [[ "${gatewayData[1]}" == "(incomplete)" ]]
        then
            log "Status of gateway $gatewayIP "incomplete""
            echo ""
        elif [[ "${gatewayData[2]}" == "--" ]]
        then 
            log "No MAC address found for $gatewayIP"
            echo ""
        else
            log "Gateway MAC address=[${gatewayData[2]}]"
            echo "${gatewayData[2]}"
        fi
    fi
}

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

मेरे मामले में, स्क्रिप्ट प्लाज्मा डेस्कटॉप सूचनाओं का उपयोग करके चलाया जाता है, इसलिए सब कुछ उपयोगकर्ताभूमि में है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.