リクエスト時に複数IP分散や自動IP変更をする方法


TL;DR

  • Route53でIP分散
  • Elastic IP付け替え/サーバー再作成で自動IP変更
  • プロキシ用のサーバーはEC2かConoHaあたりが良さげ

はじめに

HTTPリクエストの際などIPを変えたいときってありますよね。
ですが、プロキシを通すにしても一つだけだと都合が悪く、複数に分散させたり、たまにIPを変えたい、といったケースに直面することもあると思います。

今回はそういった場合に使えそうな実装を紹介します。
原始的な方法ですが、同じようなことをやりたい人の参考になればと思います。
また、より効率的な方法を知っている方がいましたらお教えいただけますと幸いです。

ついでにプロキシ用のサーバー選定についても紹介します。

使用したプロキシサーバー

プロキシサーバーは squid を使用しました。

導入、設定には 5分で作るPROXYサーバー を参考にしました。
5分でプロキシサーバーが立ちます。

ケース別の実装紹介

ここからは段階を踏んで、ケース別に必要な実装を紹介していきます。

とりあえずIPを変えたい

適当なサーバーを借りてsquidを入れれば問題ありません。

RubyでHTTPリクエストをするときは以下のような感じで噛ませます。

プロキシを使わないとき
require 'net/http'
require 'uri'

base = 'http://hogehoge.com/fugafuga'
uri = URI.parse(base)
http = Net::HTTP.new(uri.host, uri.port)
プロキシを使うとき
require 'net/http'
require 'uri'

base = 'http://hogehoge.com/fugafuga'
uri = URI.parse(base)
proxy = Net::HTTP::Proxy('プロキシのIP', プロキシのポート番号)
http = proxy.new(uri.host, uri.port)

複数IPにリクエストを分散させたい

一つのIPからリクエストを送ると都合が悪いとき、複数のプロキシにリクエストを分散して送信させる方法です。

これにはRoute53を使用します。
まず適当なドメインを取得し、ホストゾーンを作成。
そしてそのホストゾーンに proxy.mydomain.com のようなAレコードを作成します。

Aレコードが出来たらプロキシサーバーを必要な数だけ立てます。
そしてプロキシサーバーの設定が終わったらレコードのValueにIPを追加。

あとはコードでプロキシの指定先をこのレコードにするだけです。

プロキシを使うとき
require 'net/http'
require 'uri'

base = 'http://hogehoge.com/fugafuga'
uri = URI.parse(base)
proxy = Net::HTTP::Proxy('proxy.mydomain.com', プロキシのポート番号)
http = proxy.new(uri.host, uri.port)

これでリクエストを送信すればレコードに設定したIPへ分散してくれます。

IPを定期的に自動で変更したい

単一のIPでリクエストを続けるとダメになるので度々IPを変更させたいという場合や、上記の複数IPにリクエストを分散させるとき、IP範囲を度々変更させたい場合に使用する方法です。

プロキシを使用せずサーバーのIPを変更する

ここまではプロキシを使用しましたが、AWS EC2であればサーバーを停止することなくElastic IPの付け替えが可能です。

マネジメントコンソールから操作をする場合はEC2 > Elastic IPから、新しいアドレスの割り当て、既存のIPの関連付けの解除、新規IPの関連付けとすれば完了です。

ここでサーバーのIPが変わってしまってはWEBサイトにアクセスが出来なくなってしまうのではと思われるかもしれませんが、Route53 - ELB - EC2のようにPrivate DNSを使用してEC2へアクセスを送れば問題ありません。

またこれをスクリプト化することで自動実行出来るようにします。
gem aws-sdk のv1を使用すると以下のような実装が出来ます。

ElasticIP変更スクリプト
config = {
  access_key_id: ENV['EC2_ACCESS_KEY_ID'],
  secret_access_key: ENV['EC2_SECRET_ACCESS_KEY'],
  ec2_endpoint: 'ec2.ap-northeast-1.amazonaws.com'
}

ec2 = AWS::EC2.new(config)
i = ec2.instances[ENV['INSTANCE_ID']]

eip = ec2.elastic_ips.create(vpc: ENV['VPC_ID'])
old_ip = i.elastic_ip

i.disassociate_elastic_ip
i.associate_elastic_ip(eip)
old_ip.delete

あとはこれをcronに仕掛けるだけです。

なお、EC2では月に100回以上Elastic IPの付け替えをすると、それ以降は1回あたり$0.1ずつ料金が発生するためご注意下さい。

プロキシサーバーを新規で立てて新しいIPを入手する

IPを自動で変更するには、自動でプロキシサーバーを削除して新規に立てれば良い、という考えです。

こちらの方法を実行するには以下のことが前提となります。

  • サーバーの削除や作成がAPIから可能であること
  • サーバーを再作成するとIPが変わること

例えばConoHaなどがこの条件に当てはまります。

こちらも自動化するためにはスクリプトを作成する必要がありますが、具体的な工程は以下のようになります。

  1. レコードから削除するサーバーのIPを削除
  2. サーバーを削除
  3. サーバーを作成(イメージから作成をすれば作成後の手間が少なくなります)
  4. 作成したサーバーでプロキシサーバーの設定と起動
  5. レコードにサーバーのIPを追加

これらのやり方を使い分けたり、また併用することにより使用可能なIPの幅が広がります。

複数IP分散や自動IP変更の実装については以上となります。

プロキシ用のサーバー比較

最後に、プロキシ用のサーバーについて紹介していきます。

前提として、単純にプロキシを立てるだけであればどこでもあまり問題がありませんが、自動でサーバーの再作成をしたいのであればAPIからの操作を出来ることが必要になります。

AWS EC2

  • サーバーの稼働時間毎の課金なので試用や短時間使用にも使いやすい
  • メモリ0.5GBのサーバーが初期費用なし、月額600円ほど(為替により変化)
  • APIからの操作が可能

  • ElasticIPの付け替えでサーバーを停止することなくIPの変更が可能

  • EC2以外でVPC等の知識が必要になる

ConoHa

  • サーバーの稼働時間毎の課金なので試用や短時間使用にも使いやすい
  • メモリ0.5GBのサーバーが初期費用なし、月額630円ほど
  • APIからの操作が可能

  • ページの表示に少々時間がかかる

  • 20個以上サーバーを契約したいときは一度問い合わせが必要

カゴヤクラウド VPS

  • サーバーの稼働日毎の課金なので試用や短時間使用にも使いやすい
  • メモリ1GBのサーバーが初期費用なし、月額864円ほど
  • APIからの操作は不可

  • 管理画面がレガシー

ServerMan@VPS

  • メモリ1GBのサーバーが初期費用なし、月額505円ほど
  • 契約時に、契約日からその月の月末までの日割り料金を支払う必要がある
  • APIからの操作は不可

  • 20台ほど契約すると設備売り切れとなることがある

  • 管理画面がレガシー

さくらインターネット系

概要を調べた程度で会員登録はしていないが参考までに

さくらのVPS

  • メモリ1GBのサーバーが初期費用1620円、月額972円ほど
  • 契約時には初期費用+月額料金2ヶ月分を支払う必要がある
  • APIからの操作は不可

さくらのレンタルサーバー

  • sshが可能な最安のもので初期費用1029円、月額515円ほど
  • 契約時には初期費用+月額料金2ヶ月分を支払う必要がある
  • APIからの操作は不可

さくらのクラウド

  • 石狩リージョンならメモリ1GBのサーバーが1日76円、月額なら1954円ほど
  • API提供がある

  • EC2のようにネットワーク部分についても知識が必要そう

まとめ

IP変更を自動化させたいならConoHa or EC2。

そうでなくても上記の2つは時間当りの料金発生であること、低料金であること、管理画面がモダンなこと、記事が多いこと等から優秀である。

上記2つが使えないという場合にはカゴヤ or ServerManを使用する、という感じで良いと思う。

最後に

こういったことに困っている人が見てくれたら幸いです。

また、かなり説明を端折っている部分もあるので、不明瞭な点があればコメントなどで聞いて下さい。