Ruby on Rails에서 호스트 이름 또는 IP 가져 오기


80

Ruby on Rails 앱을 유지 관리하는 중이며 현재 사용중인 상자의 호스트 이름 또는 IP 주소를 쉽게 찾을 수있는 방법을 찾고 있습니다 (VM이므로 새 인스턴스에는 다른 호스트 이름 또는 IP 주소가있을 수 있음). . Ruby on Rails에서이 작업을 수행하는 빠르고 쉬운 방법이 있습니까?

편집 : 아래 답변은 정확하지만 Craig가 제공 한 설명이 유용합니다 (답변에 제공된 링크 참조).

[아래] 코드는 연결하거나 패킷을 보내지 않습니다 (google 인 64.233.187.99로). UDP는 상태 비 저장 프로토콜이기 때문에 connect ()는 주소를 기반으로 패킷을 라우팅하는 방법과 바인딩해야하는 인터페이스 (따라서 IP 주소)를 파악하는 시스템 호출을 수행 할뿐입니다. addr ()은 소켓의 패밀리 (AF_INET), 로컬 포트 ​​및 로컬 주소 (원하는 것)를 포함하는 배열을 반환합니다.

답변:


50

에서 coderrr.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"

1
@ user422543 위 질문의 수정에 따라 IP 주소는 Google에 속합니다.
Topher Fangio 2013-06-22

138

호스트 이름

Ruby에서 호스트 이름을 얻는 간단한 방법은 다음과 같습니다.

require 'socket'
hostname = Socket.gethostname

문제는 이것이 gethostname또는 uname시스템 호출을 사용하기 때문에 자신의 이름을 알고있는 호스트에 의존 하므로 원래 문제에 대해서는 작동하지 않는다는 것입니다.

기능적으로 이것은 hostname외부 프로그램을 호출하지 않고 대답 과 동일합니다 . 호스트 이름은 시스템 구성에 따라 정규화되거나 정규화되지 않을 수 있습니다.


IP 주소

루비 1.9부터 소켓 라이브러리를 사용하여 로컬 주소 목록을 가져올 수도 있습니다. AddrInfo 객체 ip_address_list의 배열을 반환 합니다. 선택 방법은 수행하려는 작업과 보유한 인터페이스 수에 따라 다르지만, 다음은 첫 번째 비 루프백 IPV4 IP 주소를 문자열로 선택하는 예입니다.

require 'socket'
ip_address = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address

Socket.gethostname이 항상 FQDN을 반환하지는 않습니다. FQDN이 필요한 경우 'hostname'.strip을 사용하는 것이 더 안정적 일 수 있습니다.
Travis Bear

소켓. gethostname시 주석을 참조 분명히 항상 안정 stackoverflow.com/q/14112955/32453
rogerdpack


24

이 시도:

host = `hostname`.strip # Get the hostname from the shell and removing trailing \n
puts host               # Output the hostname

4
순도에 대한 Socket.gethostname 같은 I, 그러나 당신이 알고있는 체제에 단순 조회에 대한 hostname작업을 것입니다, 당신은 간단하게 그것을 이길 수 없습니다
데이브 Smylie

당신은 또한 할 수 uname -n.SUB (/\..*/, '')
는 Tila

13

일반적으로 서버에는 둘 이상의 인터페이스, 최소한 하나의 개인 및 하나의 공용이 있습니다.

여기에있는 모든 답변은이 간단한 시나리오를 다루기 때문에 다음과 같이 소켓에 전류를 요청하는 것이 더 깨끗한 방법입니다 ip_address_list().

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

둘 다 Addrinfo 객체를 반환하므로 문자열이 필요한 경우 다음 ip_address()과 같이 메서드를 사용할 수 있습니다 .

ip= my_first_public_ipv4.ip_address unless my_first_public_ipv4.nil?

필요한 인터페이스 주소를 필터링하는 데 사용되는 Addrinfo 메소드를 변경하여 케이스에 더 적합한 솔루션을 쉽게 찾을 수 있습니다.


9

여기에 사용 된이 IP 주소는 Google의 것이지만 액세스 가능한 모든 IP를 사용할 수 있습니다.

require "socket"
local_ip = UDPSocket.open {|s| s.connect("64.233.187.99", 1); s.addr.last}

8

가장 간단한 것은 host_with_portcontroller.rb입니다.

host_port= request.host_with_port

2
단점은 요청에 액세스하려면 컨트롤러에 있어야한다는 것입니다.하지만 좋은 생각입니다!
Tilo

다른 답변은 해킹에 불과한 것처럼 보이지만 올바른 방식으로 수행됩니다. 왜 그 아래에 묻혀 있습니까?
tbodt 2014

2

수락 된 답변은 작동하지만 모든 요청에 ​​대해 소켓을 만들어야하며 서버가 로컬 네트워크에 있거나 인터넷에 연결되어 있지 않으면 작동하지 않습니다. 아래는 요청 헤더를 구문 분석하기 때문에 항상 작동한다고 생각합니다.

request.env["SERVER_ADDR"]

3
OP는 실제로 IP 주소가 필요한 지점에서 요청 객체에 액세스했다고 말하지 않았습니다. 소켓 기반의 솔루션은보다 일반적인하다
크리스 맥컬리

2

강조 표시된 부분을 백틱에 넣으십시오.

`dig #{request.host} +short`.strip # dig gives a newline at the end

또는 request.hostIP인지 아닌지 신경 쓰지 않는 경우.


2

UNIX / LINUX hostname에서 외부 uname명령을 사용 하는를 사용한 대답과 유사합니다 .

hostname = `uname -n`.chomp.sub(/\..*/,'')  # stripping off "\n" and the network name if present

사용중인 IP 주소 (컴퓨터에 여러 네트워크 인터페이스가있을 수 있음)에 대해 다음과 같이 사용할 수 있습니다.

 # 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']

1

각 컴퓨터에 여러 IP 주소 (127.0.0.1, 192.168.0.1 등)가있을 수 있습니다. * NIX를 OS로 사용하는 경우을 사용 hostname하고 DNS 조회를 실행하는 것이 좋습니다 . / etc / hosts를 사용하여 로컬 호스트 이름을 정의하여 해당 시스템의 IP 주소로 확인할 수 있어야합니다. Windows에도 비슷한 기능이 있지만 Windows 95가 최첨단 이었기 때문에 사용하지 않았습니다.

다른 옵션은 WhatIsMyIp.com 과 같은 조회 서비스를 사용하는 것 입니다. 이 사람들은 실제 IP 주소를 당신에게 돌려 줄 것입니다. 또한 원하는 경우 로컬 서버에서 Perl 스크립트를 사용하여 쉽게 설정할 수 있습니다. % ENV에서 원격 IP를 출력하는 코드는 3 줄 정도가 될 것입니다.


외부 인터넷 액세스가 없으면 WhatIsMyIP.com이 작동하지 않습니다.
The Tin Man

1
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}\ /)

몇 가지 대답이 require 'socket'좋아 보입니다. request.blah_blah_blah가있는 사람들은 Rails를 사용하고 있다고 가정합니다.

IO는 항상 사용할 수 있어야합니다. 이 스크립트의 유일한 문제 ifconfig는 시스템의 다른 매너로 출력 되는 경우 IP에 대해 다른 결과를 얻을 수 있다는 것입니다. 호스트 이름 조회는 Sears처럼 견고해야합니다.


0

시도 : Request.remote_ip

remote_ip ()

원래 IP 주소를 결정합니다. REMOTE_ADDR은 표준이지만 사용자가 프록시 뒤에 있으면 실패합니다. HTTP_CLIENT_IP 및 / 또는 HTTP_X_FORWARDED_FOR는 프록시에 의해 설정되므로 REMOTE_ADDR이 프록시인지 확인하십시오. HTTP_X_FORWARDED_FOR는 다중 체인 프록시의 경우 쉼표로 구분 된 목록 일 수 있습니다. 신뢰할 수없는 마지막 주소는 원래 IP입니다.

업데이트 : 죄송합니다. 문서를 잘못 읽었습니다.


이것은 Rails 앱을 실행하는 머신의 IP 주소가 아니라 Rails 앱에 요청을 보내는 사용자의 IP 주소를 제공합니다.
jsears
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.