Den Hostnamen oder die IP in Ruby on Rails abrufen
-
09-06-2019 - |
Frage
Ich pflege gerade eine Ruby on Rails-App und suche nach einer einfachen Möglichkeit, den Hostnamen oder die IP-Adresse der Box zu finden, auf der ich mich befinde (da es sich um eine VM handelt und neue Instanzen möglicherweise andere Hostnamen oder IP-Adressen haben). .Gibt es eine schnelle und einfache Möglichkeit, dies in Ruby on Rails zu tun?
Bearbeiten:Die Antwort unten ist richtig, aber die Klarstellung, die Craig gegeben hat, ist nützlich (siehe auch den bereitgestellten Link in der Antwort):
Der [unten] Code stellt keine Verbindung her und sendet keine Pakete (auf 64.233.187.99, was Google ist).Da UDP ein staatenloser Protokoll ist Connect () macht lediglich einen Systemaufruf, der herausstellt, wie die Pakete basierend auf der Adresse und an welcher Schnittstelle (und damit IP -Adresse) sie gebunden werden sollen.ADDR () gibt ein Array zurück, das die Familie (AF_Inet), den lokalen Port und die lokale Adresse (die wir wollen) des Sockets enthält.
Lösung
Aus coderr.wordpress.com:
require 'socket'
def local_ip
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true # turn off reverse DNS resolution temporarily
UDPSocket.open do |s|
s.connect '64.233.187.99', 1
s.addr.last
end
ensure
Socket.do_not_reverse_lookup = orig
end
# irb:0> local_ip
# => "192.168.0.127"
Andere Tipps
Hostname
Eine einfache Möglichkeit, den Hostnamen in Ruby abzurufen, ist:
require 'socket'
hostname = Socket.gethostname
Der Haken daran ist, dass dies davon abhängt, dass der Host seinen eigenen Namen kennt, da er entweder den verwendet gethostname
oder uname
Systemaufruf, daher wird es bei dem ursprünglichen Problem nicht funktionieren.
Funktionell ist dies identisch mit der hostname
antworten, ohne ein externes Programm aufzurufen.Abhängig von der Konfiguration der Maschine kann der Hostname vollständig qualifiziert sein oder auch nicht.
IP Adresse
Seit Ruby 1.9 können Sie auch die Socket-Bibliothek verwenden, um eine Liste lokaler Adressen abzurufen. ip_address_list
gibt ein Array von zurück AddrInfo Objekte.Wie Sie daraus auswählen, hängt davon ab, was Sie tun möchten und wie viele Schnittstellen Sie haben. Hier ist jedoch ein Beispiel, bei dem einfach die erste Nicht-Loopback-IPV4-IP-Adresse als Zeichenfolge ausgewählt wird:
require 'socket'
ip_address = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address
Versuche dies:
host = `hostname`.strip # Get the hostname from the shell and removing trailing \n
puts host # Output the hostname
Ein Server verfügt normalerweise über mehr als eine Schnittstelle, mindestens eine private und eine öffentliche.
Da sich alle Antworten hier auf dieses einfache Szenario beziehen, ist es sinnvoller, Socket nach dem Strom zu fragen ip_address_list()
wie in:
require 'socket'
def my_first_private_ipv4
Socket.ip_address_list.detect{|intf| intf.ipv4_private?}
end
def my_first_public_ipv4
Socket.ip_address_list.detect{|intf| intf.ipv4? and !intf.ipv4_loopback? and !intf.ipv4_multicast? and !intf.ipv4_private?}
end
Beide geben ein Addrinfo-Objekt zurück. Wenn Sie also eine Zeichenfolge benötigen, können Sie das verwenden ip_address()
Methode, wie in:
ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?
Sie können ganz einfach die passendere Lösung für Ihren Fall finden, indem Sie die Addrinfo-Methoden ändern, die zum Filtern der erforderlichen Schnittstellenadresse verwendet werden.
Die hier verwendete IP-Adresse ist die von Google, Sie können jedoch jede erreichbare IP-Adresse verwenden.
require "socket"
local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}
Am einfachsten ist host_with_port
in controller.rb
host_port= request.host_with_port
Die akzeptierte Antwort funktioniert, aber Sie müssen für jede Anfrage einen Socket erstellen und es funktioniert nicht, wenn sich der Server in einem lokalen Netzwerk befindet und/oder nicht mit dem Internet verbunden ist.Ich glaube, dass das Folgende immer funktionieren wird, da es den Anforderungsheader analysiert.
request.env["SERVER_ADDR"]
Setzen Sie den hervorgehobenen Teil in Backticks:
`dig #{request.host} +short`.strip # dig gives a newline at the end
Oder nur request.host
wenn es dir egal ist, ob es eine IP ist oder nicht.
Ähnlich wie die Antwort mit hostname
, mit der externen uname
Befehl unter UNIX/LINUX:
hostname = `uname -n`.chomp.sub(/\..*/,'') # stripping off "\n" and the network name if present
Für die verwendeten IP -Adressen (Ihr Computer kann über mehrere Netzwerkschnittstellen verfügen) können Sie so etwas verwenden:
# on a Mac:
ip_addresses = `ifconfig | grep 'inet ' | grep -v 127.0.0.1 | cut -d' ' -f 2`.split
=> ['10.2.21.122','10.8.122.12']
# on Linux:
ip_addresses = `ifconfig -a | grep 'inet ' | grep -v 127.0.0.1 | cut -d':' -f 2 | cut -d' ' -f 1`.split
=> ['10.2.21.122','10.8.122.12']
Sie werden wahrscheinlich feststellen, dass auf jedem Computer mehrere IP-Adressen vorhanden sind (127.0.0.1, 192.168.0.1 usw.).Wenn Sie *NIX als Betriebssystem verwenden, würde ich die Verwendung empfehlen hostname
, und anschließend eine DNS-Suche ausführen.Sie sollten in der Lage sein, /etc/hosts zu verwenden, um den lokalen Hostnamen zu definieren, der in die IP-Adresse für diesen Computer aufgelöst werden soll.Unter Windows gibt es ähnliche Funktionen, aber ich habe sie nicht verwendet, da Windows 95 auf dem neuesten Stand war.
Die andere Möglichkeit wäre, einen Suchdienst wie z. B. aufzurufen WhatIsMyIp.com.Diese Leute geben Ihnen Ihre echte IP-Adresse zurück.Wenn Sie möchten, können Sie dies auch ganz einfach mit einem Perl-Skript auf einem lokalen Server einrichten.Ich glaube, dass etwa drei Codezeilen zur Ausgabe der Remote-IP von %ENV ausreichen sollten.
io = IO.popen('hostname')
hostname = io.readlines
io = IO.popen('ifconfig')
ifconfig = io.readlines
ip = ifconfig[11].scan(/\ \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\ /)
Das Paar antwortet mit require 'socket'
gut aussehen.Diejenigen mit Request.blah_blah_blah gehen davon aus, dass Sie Rails verwenden.
IO sollte jederzeit verfügbar sein.Das einzige Problem mit diesem Skript wäre, dass wenn ifconfig
auf Ihren Systemen anders ausgegeben wird, dann würden Sie unterschiedliche Ergebnisse für die IP erhalten.Die Suche nach dem Hostnamen sollte „Sears“ lauten.
versuchen: Request.remote_ip
remote_ip()
Bestimmen Sie die ursprüngliche IP-Adresse.Remote_ADDR ist der Standard, fällt aber fehl, wenn der Benutzer hinter einem Proxy steht.Http_client_ip und/oder http_x_forwarded_for werden von proxies gesetzt.Http_x_forwarded_for kann bei mehreren angeketteten Proxies eine Kommando-Liste sein;Die letzte Adresse, die nicht vertrauenswürdig ist, ist die Ursprungs -IP.
Aktualisieren:Hoppla, tut mir leid, dass ich die Dokumentation falsch gelesen habe.