Получение имени хоста или IP-адреса в Ruby on Rails

Я поддерживаю приложение Ruby on Rails и ищу удобный способ найти имя хоста или IP-адрес поля, в котором я включен (так как виртуальная машина и новые экземпляры могут иметь разные имена хостов или IP-адреса). Есть ли быстрый и простой способ сделать это в Ruby on Rails?

Изменить: ответ ниже правильный, но пояснение, предоставленное Крейгом, полезно (см. также предоставленную ссылку в ответе):

Код [ниже] НЕ делает подключения или отправки любых пакетов ( 64.233.187.99, который является google). Поскольку UDP является протоколом без состояния connect() просто делает системный вызов, который определяет, как маршрутизировать пакеты на основе адреса и интерфейс (и, следовательно, IP-адрес) он должен привязываться. addr() возвращает массив, содержащий семейство (AF_INET), локальный порт и локальный адрес (который это то, что мы хотим) сокета.

Ответ 1

От 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"

Ответ 2

Hostname

Простой способ получить имя хоста в Ruby:

require 'socket'
hostname = Socket.gethostname

Ловушка заключается в том, что это зависит от хоста, зная его собственное имя, потому что оно использует системный вызов gethostname или uname, поэтому он не будет работать для исходной проблемы.

Функционально это идентично ответу hostname, не вызывая внешнюю программу. Имя хоста может быть или не быть полностью квалифицированным, в зависимости от конфигурации машины.


IP-адрес

Так как ruby ​​1.9, вы также можете использовать библиотеку Socket для получения списка локальных адресов. ip_address_list возвращает массив объектов AddrInfo. Как вы выберете его, это будет зависеть от того, что вы хотите сделать и от того, сколько интерфейсов у вас есть, но вот пример, который просто выбирает первый IP-адрес IP-адреса без петли в виде строки:

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

Ответ 3

Попробуйте следующее:

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

Ответ 4

Обычно сервер имеет несколько интерфейсов, по крайней мере один частный и один публичный.

Поскольку все ответы здесь касаются этого простого сценария, более чистый способ - спросить Socket для текущего 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, используемые для фильтрации требуемого адреса интерфейса.

Ответ 5

Этот IP-адрес, используемый здесь, - это Google, но вы можете использовать любой доступный IP-адрес.

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

Ответ 6

Simplest host_with_port в контроллере .rb

host_port= request.host_with_port

Ответ 7

Поместите выделенную часть в backticks:

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

Или просто request.host, если вам все равно, является ли он IP или нет.

Ответ 8

Принятый ответ работает, но вам нужно создать сокет для каждого запроса, и он не работает, если сервер находится в локальной сети и/или не подключен к Интернету. Ниже, я считаю, всегда будет работать, поскольку он анализирует заголовок запроса.

request.env["SERVER_ADDR"]

Ответ 9

Как и в ответе, используя hostname, используя внешнюю команду uname в UNIX/LINUX:

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

Ответ 10

Вероятно, у вас будет несколько IP-адресов на каждой машине (127.0.0.1, 192.168.0.1 и т.д.). Если вы используете * NIX в качестве ОС, я бы предложил использовать hostname, а затем запустить DNS, чтобы посмотреть на это. Вы должны иметь возможность использовать /etc/hosts для определения локального имени хоста для разрешения на IP-адрес для этой машины. В Windows аналогичная функциональность, но я не использовал ее, так как Windows 95 была краем кровотечения.

Другой вариант - нажать на службу поиска, например WhatIsMyIp.com. Эти ребята откажут вам ваш реальный IP-адрес. Это также можно настроить с помощью Perl script на локальном сервере, если вы предпочитаете. Я считаю, что 3 строки или около того кода для вывода удаленного IP из% ENV должны покрыть вас.

Ответ 11

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 должен быть доступен все время. Единственная проблема с этим script заключается в том, что если ifconfig выводится в другой усадьбе в ваших системах, вы получите разные результаты для IP. Взгляд хоста должен быть твердым, как Сирс.

Ответ 12

попробуйте: Request.remote_ip

remote_ip()

Определите исходный IP-адрес. REMOTE_ADDR является стандартным, но если пользователь находится за прокси-сервером. HTTP_CLIENT_IP и/или HTTP_X_FORWARDED_FOR устанавливаются прокси-серверами, поэтому проверьте их, если REMOTE_ADDR - прокси. HTTP_X_FORWARDED_FOR может быть разделенным запятыми список в случае нескольких целых прокси; последний адрес, который не является надежным источником IP.

Обновление: К сожалению, я неправильно прочитал документацию.