タイトル

Need for Answer

2014年12月4日木曜日

ELB配下にあるDjangoにリクエストプロトコルを判断させたい

ELB配下にあるEC2にプロトコルを渡したい、そんなこと有りますよね!
何が困ってそんなことをって話なのですが、下記2点に該当する人だと思います。

  1. ELBにSSLアクセラレーションさせてる(HTTPS→HTTP変換)
  2. EC2にApache→Djangoを使ってる
で詳細な問題って何?な話なのですが、「ELBが渡してくるリクエストヘッダと、Djangoが解釈するリクエストヘッダが微妙に違う」ってことです。ちなみにこんなかんじです。

  • ELBが送るリクエストヘッダ → X-Forwarded-Proto:https
  • Djangoが解釈したいリクエストヘッダ → X-Forwarded-Protocol:https

なので、「リクエストヘッダの内容を判断して、Djangoに送るヘッダを書き換えよう」ってのが具体的なアクションになります。

という事で、Apacheのconfigを作ってみました。


#
# for Django
#
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
SetEnvIf X-Forwarded-Proto https PROTO_HTTPS
RequestHeader set X-Forwarded-Protocol "https" env=PROTO_HTTPS

2014年11月28日金曜日

AWS-VPCでNATインスタンスを切り替えるのまき

AWS-VPCでNATインスタンス…作ってますか!

NATインスタンスが単一障害点だから…って無言のプレッシャーかけられてるエンジニア、多いと思います!

ということでNATサーバーを切り替えるスクリプト作りました。
NATインスタンスにIAM_Roleを適用してから使うといいと思います!

#!/bin/sh
#======================================================
# NATインスタンスを自分に切り替えるスクリプト
#======================================================
#======================================================
# 概要
#------------------------------------------------------
# 特定のルーティングテーブルのアウトバウンド(0.0.0.0/0)
# を、「シェルを実行しているインスタンス」へ切り替える
# スクリプトです
#======================================================
# つかいかた
#------------------------------------------------------
# 1 - 待機側のインスタンスが、稼働側のインスタンスを死活
#     監視する(実装して下さい)
# 2 - 死亡が確認されたらこのシェルを実行してください
#======================================================
# 前準備
#------------------------------------------------------
# VPC => RouteTable で、「NATサーバーを通過するRouteTableID」
# を調べる。NATインスタンスのいるRouteTableIDではないので
# 注意。下のCHANGE_RTBに記載する
#------------------------------------------------------
CHANGE_RTB="[ここを書き換える]"
#======================================================

# リージョンを宣言 ------------------------------------
export AWS_DEFAULT_REGION=`curl --connect-timeout 3 -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/.$//g'`
MY_ID=`curl -s http://169.254.169.254/latest/meta-data/instance-id`

echo "================================="
echo " CHANGE RouteTable..."
echo "================================="
echo " Current Setting => " `ec2-describe-route-tables ${CHANGE_RTB} --region ${AWS_DEFAULT_REGION} | grep 0.0.0.0`
echo "---------------------------------"
echo " CHANGE RouteTable => ${CHANGE_RTB} / MyInstance-ID => ${MY_ID}"
echo "---------------------------------"

ec2-replace-route ${CHANGE_RTB} --region ${AWS_DEFAULT_REGION} -i ${MY_ID} -r 0.0.0.0/0

echo " Done!!"
echo " Current Setting => " `ec2-describe-route-tables ${CHANGE_RTB} --region ${AWS_DEFAULT_REGION} | grep 0.0.0.0`
echo "================================="

2014年11月25日火曜日

複数台のサーバーでconfigを同期するだけのスクリプト

複数台のサーバーでconfigを同期する必要…有りますよね!
copyしてからサービスの再起動とかよくやると思うんですよ!

いっつも適当に書くので、メモすることにしました。
とりあえずnginxでやってますが、td-agentとかでもやり方は一緒です。

#!/bin/sh
#==========================================
# Enviroment
#==========================================
# 設定ファイルを送信する先
DEPLOY_SERVER="10.10.xxx.xxx"

# 設定ファイルの入っているディレクトリ
SYNC_DIR="/etc/nginx"

# 設定ファイル編集後に実行するコマンド
RELOAD_CMD="/etc/init.d/nginx reload"

#==========================================
# Config Deploy
#==========================================
# 実行時間計測用
START=`date +%s`

echo "-------------------------------------"
echo " Erase Remote Config Files..."
echo "-------------------------------------"
ssh ${DEPLOY_SERVER} rm -fr ${SYNC_DIR}
ssh ${DEPLOY_SERVER} mkdir ${SYNC_DIR}

echo "-------------------------------------"
echo " Deploy Config Files..."
echo "-------------------------------------"
scp -p -r ${SYNC_DIR}/* root@${DEPLOY_SERVER}:${SYNC_DIR}

echo "-------------------------------------"
echo " Service Reload (Remote)..."
echo "-------------------------------------"
ssh ${DEPLOY_SERVER} ${RELOAD_CMD}

echo "-------------------------------------"
echo " Service Reload (Local)..."
echo "-------------------------------------"
${RELOAD_CMD}

# 実行時間計測用
END=`date +%s`
SS=`expr ${END} - ${START}`
HH=`expr ${SS} / 3600`
SS=`expr ${SS} % 3600`
MM=`expr ${SS} / 60`
SS=`expr ${SS} % 60`

echo "-------------------------------------"
echo " F I N I S H ! !"
echo "-------------------------------------"
echo " Exec Time => ${HH}:${MM}:${SS}"
echo "-------------------------------------"

2014年11月24日月曜日

ELBからのヘルスチェックは適当に200を返そう

Elastic Load Balancing(ELB)便利ですね!ELBの後ろにnginxを置いてる人、多いと思います!

…なのですが、ELBのHTTPヘルスチェックのためにファイルを置くのめんどくさい!ELBにはHTTPで応答できるかだけ監視して欲しいってこと…あると思います!

ということでこんな設定でどうでしょうか!

map $http_user_agent $bot {
  default                  0;
  ~*(ELB-HealthChecker)    1;
}

server {
    if ($bot = 1) {
      return 200;
    }
}

2014年10月1日水曜日

AWSのELBのエフェメラルポートは1024-65535

タイトルに書いてあることが全てなのですが、Amazon Web ServicesのElastic Load Balancingのエフェメラルポートは1024-65535です。ここに書いてあります。
Network ACLs - Amazon Virtual Private Cloud

これが何か?という話なのですが、「Amazon Virtual Private CloudのNetworkACLを使うと、エフェメラルポートを指定する必要がある」ということなんですね。ここでポイントになるのが、「クライアント→ELB→EC2」という通信路の「ELB→EC2」部分のエフェメラルポートになります。

ちなみにLinuxの使うエフェメラルポートは32768-61000です。念のため確認するにはこんな感じのコマンドです。

cat /proc/sys/net/ipv4/ip_local_port_range

どーでもいいんだけど、NetworkACLってTCPフラグで書けるようにならないのかな…

2014年9月16日火曜日

lsyncdでユーザーを指定してsyncしたい

lsyncd便利ですよね!rsyncサービス使わなくてもファイル同期できるので、不要なサービスを起動させなくていいのが利点だと思います!

とはいえrootで実行すると、配布先のファイルパーミッションがrootになってしまう
…そんな悩みを持ってる人もいるかもしれません!

…ということでサクッと解決。

sync {
  default.rsyncssh,
  source = "配布するローカルディレクトリ",
  host= "配布先のホスト名",
  targetdir = "配布先のどのディレクトリに配置するか",

  rsync = {
    archive = true,
    compress = false,
    whole_file = false,
    sh = "/usr/bin/ssh -l [ユーザー名] -i [接続ユーザーが使う鍵ファイル]"
  },

  ssh = {
    port = 22
  }
}

Nginxのステータスをjsonで取得する

Nginx使ってますか!

 …で使ってるとステータスをjsonで取得したくなリますよね!作りました!
Githubへのリンク

作りましたは嘘です!先人の素晴らしいソースをちょっと改良しただけです!
 td-agentでステータスを収集したりとかするときに便利だと思います。