Ruby on Rails でのホスト名または IP の取得
-
09-06-2019 - |
質問
Ruby on Rails アプリを保守している最中で、使用しているボックスのホスト名または IP アドレスを簡単に見つける方法を探しています (VM であり、新しいインスタンスは異なるホスト名または IP アドレスを持つ可能性があるため)。 。Ruby on Rails でこれをすばやく簡単に行う方法はありますか?
編集:以下の答えは正しいですが、Craig が提供した説明は役に立ちます (回答にあるリンクも参照してください)。
以下]コードは、接続を作成したり、パケットを送信したりしません(Googleである64.233.187.99まで)。UDPはStateless Protocol connect()であるため、アドレスに基づいてパケットをルーティングする方法と、バインドするインターフェイス(したがってIPアドレス)に基づいてパケットをルーティングする方法を把握するシステムコールを作成するだけです。addr()ソケットのファミリ(AF_INET)、ローカルポート、およびローカルアドレス(これが必要なもの)を含む配列を返します。
解決
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 のように確実に行われる必要があります。
リモートIP()
発信元 IP アドレスを決定します。remote_addrは標準ですが、ユーザーがプロキシの背後にいる場合は失敗します。http_client_ipおよび/またはhttp_x_forwarded_forはプロキシによって設定されているため、remote_addrがプロキシである場合、これらを確認してください。http_x_forwarded_forは、複数の鎖のプロキシの場合のコンマリミタルリストになる場合があります。信頼されていない最後のアドレスは、発生するIPです。
アップデート:おっと、申し訳ありませんが、ドキュメントを読み間違えていました。