質問

Ruby on Rails アプリを保守している最中で、使用しているボックスのホスト名または IP アドレスを簡単に見つける方法を探しています (VM であり、新しいインスタンスは異なるホスト名または IP アドレスを持つ可能性があるため)。 。Ruby on Rails でこれをすばやく簡単に行う方法はありますか?

編集:以下の答えは正しいですが、Craig が提供した説明は役に立ちます (回答にあるリンクも参照してください)。

以下]コードは、接続を作成したり、パケットを送信したりしません(Googleである64.233.187.99まで)。UDPはStateless Protocol connect()であるため、アドレスに基づいてパケットをルーティングする方法と、バインドするインターフェイス(したがってIPアドレス)に基づいてパケットをルーティングする方法を把握するシステムコールを作成するだけです。addr()ソケットのファミリ(AF_INET)、ローカルポート、およびローカルアドレス(これが必要なもの)を含む配列を返します。

役に立ちましたか?

解決

から 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"

他のヒント

ホスト名

Ruby でホスト名を取得する簡単な方法は次のとおりです。

require 'socket'
hostname = Socket.gethostname

問題は、ホストが自分の名前を知っていることに依存していることです。これは、ホストが次のいずれかを使用するためです。 gethostname または uname システムコールなので、元の問題には機能しません。

機能的にはこれと同じです hostname 外部プログラムを呼び出さずに応答します。ホスト名は、マシンの構成に応じて、完全修飾名である場合とそうでない場合があります。


IPアドレス

Ruby 1.9 以降では、Socket ライブラリを使用してローカル アドレスのリストを取得することもできます。 ip_address_list の配列を返します アドレス情報 オブジェクト。どのように選択するかは、何をしたいのか、またインターフェースの数によって異なりますが、最初の非ループバック IPV4 IP アドレスを文字列として単純に選択する例を次に示します。

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

これを試して:

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

通常、サーバーには複数のインターフェイスがあり、少なくとも 1 つはプライベート、もう 1 つはパブリックです。

ここでのすべての回答はこの単純なシナリオを扱っているため、よりクリーンな方法は、ソケットに現在の情報を問い合わせることです。 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 メソッドを変更することで、より適切な解決策を簡単に見つけることができます。

ここで使用される IP アドレスは Google のものですが、アクセス可能な任意の IP を使用できます。

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

最も単純なのは host_with_port コントローラ.rb内

host_port= request.host_with_port

受け入れられた答えは機能しますが、リクエストごとにソケットを作成する必要があり、サーバーがローカルネットワーク上にある場合やインターネットに接続されていない場合は機能しません。以下は、リクエストヘッダーを解析しているため、常に機能すると思います。

request.env["SERVER_ADDR"]

ハイライトされた部分をバッククォートで囲みます。

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

あるいは単に request.host IPかどうかを気にしない場合。

を使用した回答と同様 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']

各マシンに複数の IP アドレス (127.0.0.1、192.168.0.1 など) があることに気づくでしょう。OS として *NIX を使用している場合は、次の使用をお勧めします。 hostname, 、それに対して DNS ルックアップを実行します。/etc/hosts を使用してローカル ホスト名を定義し、そのマシンの IP アドレスに解決できるようにする必要があります。Windows にも同様の機能がありますが、Windows 95 が最先端だったので使用していません。

もう 1 つのオプションは、次のような検索サービスをヒットすることです。 WhatIsMyIp.com. 。奴らはあなたの現実世界の IP アドレスをキックバックします。これは、必要に応じて、ローカル サーバー上の Perl スクリプトを使用して簡単にセットアップできるものでもあります。%ENV からリモート IP を出力するコードは 3 行程度でカバーできると思います。

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を持っている人は、あなたがレールを使用していると仮定します。

IO は常に利用可能である必要があります。このスクリプトの唯一の問題は、次のような場合です。 ifconfig がシステム上の異なる形式で出力されると、IP について異なる結果が得られます。ホスト名検索は Sears のように確実に行われる必要があります。

試す: Request.remote_ip

リモートIP()

発信元 IP アドレスを決定します。remote_addrは標準ですが、ユーザーがプロキシの背後にいる場合は失敗します。http_client_ipおよび/またはhttp_x_forwarded_forはプロキシによって設定されているため、remote_addrがプロキシである場合、これらを確認してください。http_x_forwarded_forは、複数の鎖のプロキシの場合のコンマリミタルリストになる場合があります。信頼されていない最後のアドレスは、発生するIPです。

アップデート:おっと、申し訳ありませんが、ドキュメントを読み間違えていました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top