2015年1月30日金曜日

ロードバランサーのNginxにキャッシュさせる設定

ロードバランサーになっているNginxにキャッシュさせてバックエンドにあるサーバーに問い合わせないように設定したときの覚書。

環境: CentOS 6.6, nginx 1.6.2

サーバー構成はこんな感じ。

server_structure.fw

 

参考にしたサイト

 

目次

  1. キャッシュ機能を有効に
  2. 静的サイトはまるっとキャッシュ
  3. 動的サイトは一部分キャッシュ
  4. キャッシュを削除

 


1.キャッシュ機能を有効に

nginx.confを編集して、proxy_cache_pathを追記する。

# cd /etc/nginx/
# vi nginx.conf

http {
    # Proxy Cache
    proxy_cache_path /var/cache/nginx/cache_www levels=1 keys_zone=www:4m inactive=7d max_size=50m;
    proxy_cache_path /var/cache/nginx/cache_web levels=1 keys_zone=web:4m inactive=7d max_size=50m;
}

ゾーン名:www, web
保持期間:7日間
最大サイズ:50M

 


2.静的サイト用にまるっとキャッシュ

静的サイトは全てに対して1日キャッシュする設定にする。

デフォルトでPOSTはキャッシュしない。proxy_cache_methodsを設定すればPOSTもキャッシュすることが可能になる。

# vi conf.d/www.conf

upstream webs {
    ip_hash;
    server web01.hoge.com;
}
server {
    listen       80;
    server_name  www.hoge.com;


    #
    # Header
    #
    add_header X-Cache $upstream_cache_status;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;


    #
    # Proxy Cache
    #
    proxy_cache www;
    proxy_cache_key $host$uri$is_args$args;
    proxy_cache_valid  any 1d;


    #
    # Web
    #
    location / {
        proxy_pass http://webs;
    }
}

「add_header X-Cache $upstream_cache_status;」はキャッシュが利用されたか分かって便利(参考:Module ngx_http_upstream_module)。

Nginx再起動
# /etc/rc.d/init.d/nginx configtest
# /etc/rc.d/init.d/nginx restart

別サーバーからApache Benchで試してみる。
# ab -n 50 -c 5 http://www.hoge.com/
同時接続数:5
リクエスト回数:50

 


3.動的サイトは一部分だけキャッシュ

CSS, JS, 画像はキャッシュを使うようにした。

 

< 2015/04/12 Modified >
なぜかCSSやJSの読み込みに失敗する現象が発生。バックエンドのサーバーは200を返しているけど、キャッシュサーバーが304を返し、ブラウザでは「fails」になる。nginx 1.6.3

spdyとnginxのcache機能の組み合わせで起こるみたい。設定ファイルの書き方がダメなのかも。。。

ひとまずspdyを使わないようにした。

 

# vi conf.d/web.conf

upstream webs {
    ip_hash;
    server web01.hoge.com;
}
server {
    #listen       443 ssl spdy;
    listen       443 ssl;
    server_name  hoge.com;

    root /home/httpd/httpdocs/;


    #
    # SSL
    #
    ssl on;
    ssl_certificate      /etc/nginx/ssl.d/2014_hoge_cert.pem;
    ssl_certificate_key  /etc/nginx/ssl.d/2014_hoge_nopass_key.pem;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
    ssl_prefer_server_ciphers   on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;


    #
    # Header
    #
    add_header X-Cache $upstream_cache_status;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Host $http_host;


    #
    # Proxy Cache
    #
    proxy_cache web;
    proxy_cache_key $host$uri$is_args$args;


    #
    # Static Contents
    #
    location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
        proxy_cache_valid any 1d;
        access_log off;
        proxy_pass http://webs;
    }


    #
    # Web
    #
    location / {
        # Disable Proxy Cache
        proxy_no_cache 1;
        proxy_cache_bypass 1;

        # Proxy Backend Servers
        proxy_pass http://webs;
    }
}


実際はincludeを使ってファイルを分けてる。

 

nginxの設定方法で分かったこと。

locationは一致した一つのみ適用される。breakして他のlocationへ移動したり、mixinみたいなことは出来ない。
→ if文で制御する方法
→ 共通項をincludeで別ファイルにする方法

 

キャッシュについて

バックエンドがWordPressで、ログインしているとレスポンスヘッダーに「pragma:no-cache」が出力されるので、自動でキャッシュが無効になると思いきや、すでにバックエンドに処理が移っているので意味がない。

キャッシュが効いているかはバックエンドのアクセスログを監視しながら確認すると間違いない。

 

Apache Benchについて

ベンチマークをしてみるとhttpに比べて異様に遅い。
# ab -n 50 -c 5 https://hoge.com/demo/wp-content/themes/test/_inc/css/common.css?ver=4.1

トップはある程度速くなった。
# ab -n 50 -c 5 https://hoge.com/demo/

ブラウザで表示すると速い。レスポンスヘッダーに「x-cache:HIT」が表示されているので問題ないと思う。

SSLの復号化に時間が掛かっているのかな?

 


4.キャッシュを削除

コンテンツをアップデートした際に手動でキャッシュをクリアにする。
# rm -rf /var/cache/nginx/cache_www/*

 

 

< Related Posts >

2015年1月29日木曜日

PostfixにDKIMを設定して送信メールサーバーの信頼度を上げる

email_lockサーバーから送信されたメールが迷惑メールと判定されないようにDKIM(DomainKeys Identified Mail)をPostfixに設定したときの覚書。

環境: CentOS 6.6, postfix 2.6.6, opendkim 2.9.0

 

参考サイト

 

目次

  1. OPENDKIMのインストール
  2. OPENDKIMの設定
  3. 公開鍵と秘密鍵を作成
  4. DNSに公開鍵情報を登録する
  5. postfixの設定
  6. メール送信して確認

 


1.OPENDKIMのインストール

YUMでさくっと完了。epelからインストールされた。
# yum install opendkim

 


2.OPENDKIMの設定

設定ファイルを編集
# vi /etc/opendkim.conf

Mode    sv
Umask   022
Selector        hoge
#KeyFile        /etc/opendkim/keys/default.private
KeyTable        /etc/opendkim/KeyTable
SigningTable    refile:/etc/opendkim/SigningTable
ExternalIgnoreList      refile:/etc/opendkim/TrustedHosts
InternalHosts   refile:/etc/opendkim/TrustedHosts

 

 


3.公開鍵と秘密鍵を作成

鍵を保存するディレクトリを作成
# cd /etc/opendkim
# mkdir keys/hoge.com

鍵生成
# opendkim-genkey -D keys/hoge.com/ -d hoge.com -s hoge
-D:出力ディレクトリ
-d:ドメイン名
-s:DNSで登録する時に使うセレクタ名

ファイルのオーナーを変更
# chown opendkim. keys/hoge.com/hoge.*

 


4.DNSに公開鍵情報を登録する

公開鍵を確認
# more keys/hoge.com/hoge.txt

Value Domainの管理画面からDNSを編集する

txt hoge._domainkey v=DKIM1; k=rsa; p=AABBCC

 

署名に使う秘密鍵を指定
# vi KeyTable

hoge._domainkey.hoge.com hoge.com:hoge:/etc/opendkim/keys/hoge.com/hoge.private

 

署名を行うドメインを指定
# vi SigningTable

*@hoge.com   hoge._domainkey.hoge.com

 

署名を許可するホストを確認。デフォルトで127.0.0.1が記載済み。
# less TrustedHosts

 

OPENDKIMの起動。自動起動登録。
# /etc/rc.d/init.d/opendkim start
# chkconfig opendkim on

起動時に下記エラーを出ないようにする。

Generating default DKIM keys:                              [WARNING]
Cannot determine host's domain name, so skipping default key generation.

# vi /etc/sysconfig/opendkim

AUTOCREATE_DKIM_KEYS=NO

確認
# /etc/rc.d/init.d/opendkim restart

 


5.postfixの設定

設定ファイルを編集
# vi /etc/postfix/main.cf

#
# OPENDKIM
#
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept

再起動
# /etc/rc.d/init.d/postfix restart

 


6.メール送信して確認

ログを監視しながらメール送信してみる。
# tail -f /var/log/maillog

# mail hoge@gmail.com

成功するとメールログに出力される。

Jan 28 18:21:13 web01 opendkim[12369]: 4E5CDA0239: DKIM-Signature field added (s=hoge, d=hoge.com)

送信されたメールヘッダーを見ても確認できる。

 

 

< Related Posts >

2015年1月28日水曜日

メール送信時にエラー。複数サーバー構成でのSPF設定を見直す

email_wormサイトの問い合わせ画面からメール送信しようとすると下記エラーが表示されたので調べたときの覚書。ちなみにメール自体は届く。

環境: CentOS 6.6, postfix 2.6.6

# tail -f /var/log/maillog

Jan 27 19:51:28 web01 postfix/pickup[4502]: EB2FEA0216: uid=498 from=<nginx>
Jan 27 19:51:28 web01 postfix/cleanup[5109]: EB2FEA0216: message-id=<512ad4f4dd41bc3ad80aa18f9d3cc874@www.hoge.com>
Jan 27 19:51:28 web01 postfix/qmgr[1266]: EB2FEA0216: from=<nginx@hoge.com>, size=930, nrcpt=1 (queue active)
Jan 27 19:51:31 web01 postfix/smtp[5111]: EB2FEA0216: host ASPMX.L.GOOGLE.com[2404:6800:4008:c01::1b] said: 421-4.7.0 [2401:2500:102:2b04:111:222:333:444      15] Our system has detected an 421-4.7.0 unusual rate of unsolicited mail originating from your IP address. To 421-4.7.0 protect our users from spam, mail sent from your IP address has been 421-4.7.0 temporarily rate limited. Please visit 421-4.7.0 http://www.google.com/mail/help/bulk_mail.html to review our Bulk 421 4.7.0 Email Senders Guidelines. mz9si1019871pdb.205 - gsmtp (in reply to end of DATA command)
Jan 27 19:51:33 web01 postfix/smtp[5111]: EB2FEA0216: to=<info@hoge.com>, relay=ASPMX.L.GOOGLE.com[173.194.72.26]:25, delay=4.7, delays=0.03/0.01/2.9/1.8, dsn=2.0.0, status=sent (250 2.0.0 OK 1422355893 nh15si1218912pdb.42 - gsmtp)
Jan 27 19:51:33 web01 postfix/qmgr[1266]: EB2FEA0216: removed

 

日本語訳(参考:SMTP エラー リファレンス - Google Apps ヘルプ

421, "4.7.0", ご使用の IP アドレスから送信された異常な数の未承諾メールが検出されました。ユーザーを迷惑メールから保護するため、ご使用の IP アドレスから送信されたメールを一時的にブロックしました。Google の一括送信ガイド ラインをご覧ください。

 

まずはおとなしくヘルプを読む。

 

設定を見なおして確認したこと。

  • このサーバーのIPアドレスをSPFレコードに記述済み
  • 送信元(From)がそもそも存在しないドメインだった
    → たぶんこれが原因

送信元を修正して再送しても同様のエラーになるので1日待ってみる。。。

。。。12時間くらい待ってみても同じエラー。

 

このサーバーはロードバランサーのバックエンドになっていて、IPアドレスに対応するAレコードを設定してなかったので、Aレコードを追記して試してみた。

するとエラーが消えた。

 

これで完了かと思いきや、SPFの認証に失敗している模様。メールヘッダーを見てみると「softfail」になっている。

Received-SPF: softfail (google.com: domain of transitioning nginx@hoge.com does not designate 2401:2500:102:2b04:111:222:333:444 as permitted sender) client-ip=2401:2500:102:2b04:111:222:333:444;

他のドメインは同じ設定で成功しているので謎。試しにSPFの書き方をIPからドメインに変えてみた。(Value Domainで管理)

txt @ v=spf1 +a:hoge.com +a:web01.hoge.com +a:app01.hoge.com +a:app02.hoge.com include:_spf.google.com ~all

。。。しばらくして試してみると「Received-SPF: pass」になった。タイミングの問題だったかもしれない。
注)↑「a」の設定方法を勘違いしてた。詳しくは下に書いた追記を参照。

 

。。。と思ったらサーバーのmaillogに一番最初のエラーがまた表示されるようになった。

 

DKIMをPostfixに設定することにした。それは別記事で。

それでもダメな場合はGoogleに報告すると何とかなるかもしれない。

 

< 2015/01/29 Modified >
DKIMの記事書いた。

これでGoogleのSMTPエラーは表示されなくなった(App01、App02で出力される)。ただSPFは「softfail」のままなので設定を見なおしてみた。参考サイト

今回のサーバー構成は下図で、各バックエンドがそれぞれ同じ送信元(info@hoge.com)でメールを送る。

server_structure.fw

この場合のDNSレコードのSPF設定は下記のようにした(Value Domainで管理)。念のためIPv6も記述。

txt @ v=spf1 include:_spf.google.com a:mail.hoge.com ~all
a @ 1.1.1.1
a web01 1.1.1.2
a app01 1.1.1.3
a app02 1.1.1.4
a mail 1.1.1.1
a mail 1.1.1.2
a mail 1.1.1.3
a mail 1.1.1.4
aaaa mail 2401:2500:100:2200:1:1:1:1
aaaa mail 2401:2500:100:2200:1:1:1:2
aaaa mail 2401:2500:100:2200:1:1:1:3
aaaa mail 2401:2500:100:2200:1:1:1:4

これで無事「Received-SPF: pass」になった。SPFとDKIMを理解してスッキリ感。

 

< Related Posts >

2015年1月22日木曜日

TCPDFにGoogle Noto Sans CJK Fontを追加したい(失敗)

google-noto-fonts_tcpdfTCPDFで帳票を出力するときにNoto Sans CJKを試したときの覚書。

環境: PHP 5.4.36, TCPDF 6.2.4

ちなみに日本語を表示するだけなら「cid0jp」「kozgopromedium」「kozminproregular」を使えばできる。

Noto Sans CJKは公式サイトからダウンロード。90Mくらいある。

解凍した中から「NotoSansCJKjp-Regular.otf」だけインストールしてみる。

「NotoSansCJKjp-Regular.otf」をTCPDFのtoolsディレクトリに置いておく。

# cd /path/to/tcpdf/tools/
# ./tcpdf_addfont.php -i NotoSansCJKjp-Regular.otf

。。。失敗。。。

その後いろいろ試したけど失敗した。試したこと。

ttfに変換出来ても実際日本語を表示すると豆腐になる。そんなに頑張ることでもないので諦めた。

下記サイトも参考になる気がする。

 

< Related Posts >

2015年1月14日水曜日

Value DomainからGoogle Domainsにドメイン移管する

value-googleすでにInvitation Codeが送られていたのに気付いて試したときの覚書。記事書いてたら一般公開されたというニュースが。。。

バリュードメインから他社へ移管する手順は公式ヘルプを参考に。

 

まずはバリュードメインで作業。

  1. 管理画面から「WHOIS」を選択して、「管理担当者情報」のメールアドレスが自分のメールアドレスになっているか確認。
    「登録者情報を↓にコピー」を使うと簡単。
  2. 画面下にある「認証鍵情報」をメモっておく

 

次にGoogle Domainsで作業

  1. 「Transfer a domain name」から移管したいドメインを検索
  2. ドメインが移管できる状態かチェックされるので確認する。メールアドレスはバリュードメイン側を変更してから数分で反映された。
  3. 「Get authorization code」はバリュードメインの「WHOIS」画面の下のほうにある「認証鍵(Authorization Info)」を入力。
  4. 今のDNS設定をインポートできるので確認する。
    Google Apps関連は問題なくインポートされてた。
    Aレコードの設定が反映されてなかったのでここで追加。
  5. 連絡情報を入力する。
    バリュードメインで入力してたのをコピー
    「Make my info private」で非公開になる。
  6. Google Walletを経由で支払い
    どうやら日本の住所のクレジットカードだと「サポートされてないお支払い方法」と出て選択出来ない。
    Google Walletの管理画面で請求先住所を適当なアメリカの住所にしたら選択できた。(MasterCard)
  7. 確認メールが届くので「Confirm Transfer」する
  8. 10分ぐらいしたらバリュードメインから確認のメールが来るので承認する
  9. Googleから移行が完了したとメールが来る

 

機能一覧

  • www.hoge.com」か「hoge.com」へのアクセスを別ドメイン(IPも可)に転送可能
  • info@hoge.comなどのメールを別メールアドレスに転送可能
  • WHOIS情報は非公開に出来る(whoisproxy.comに置き換えられる)
  • 他のネームサーバーも指定可能
  • Glue Recordも指定可能
  • Google Appsとも簡単に連携できる予感がする(下図参照)
  • カスタムレコードは100まで指定可能

image

 

Google Appsの設定やDKIMのTXTレコードも問題なく移行出来たので他のドメインも移行する予定。

Route53みたいにAPI提供してくれれば最強だと思う。

ちなみに12ドル(今だと約1400円)なのでバリュードメインの方が安い。

 

< Related Posts >

2015年1月5日月曜日

WordPressのCache機能をAPCからRedisに変更

wordpress_redisPHP 5.4をサポートしているAPC(Alternative PHP Cache)はベータ版だし、最近は更新されていないようなので、既にインストール済みのRedisを使ってキャッシュすることにした。

環境: CentOS 6.6, Redis Server 2.8.19, WordPress 4.1

Redisをインストールしてない場合は前の記事を参考に。

PHPからRedisに接続するためのドライバーをインストールする。
# yum install php-pecl-redis

php-fpmを再起動
# /etc/rc.d/init.d/php-fpm restart

 

次にWordPressのキャッシュ機能を設定する。

それ用のプラグインが公開されている。

内部的にはGitHubで公開されているのを使っているので、こちらからobject-cache.phpをダウンロードして/wp-content/に配置。

配置するだけで動作する。

接続するデータベースを変更する場合は「WP_REDIS_BACKEND_DB」をwp-config.phpで定義する。他にもソースコードを見ると設定できる項目がわかる。

 

どんな値が登録されているかはRedis Desktop Managerを使うと簡単に分かって便利。

クライアントから接続するために下記設定を忘れずに。

  • サーバー側の/etc/redis.confのbindを編集
    → 開発環境ならコメントアウトでいい
  • ファイヤーウォールの設定。ポート番号はデフォルトで6379

こんな画面。

image

 

< 2015/01/15 Modified>
キャッシュをクリアする場合は下記コマンド
# redis-cli flushall

 

< 2015/02/12 Modified >
プロジェクトごとに「WP_CACHE_KEY_SALT」をwp-config.phpに設定して、キャッシュが競合しないようにした。

define('WP_CACHE_KEY_SALT', 'hoge_');
 

< Related Posts >

2015年1月2日金曜日

XCode6にあげたらTitanium CLI(SSH経由)からSimulatorが起動しない

xcode_titanium_warning開発環境を最新にしてからSSHでビルドコマンドを打つと下記エラーでシミュレーターが起動してくれない。

[INFO]  Launching iOS Simulator
[ERROR] Project failed to build after 1s 455ms

ちなみに直接Macのターミナルから実行すると問題なく起動する。

環境: OS X 10.10.1, XCode 6.1.1, Titanium SDK 3.4.1.GA

WindowsからMacにSSHで接続している私としてはこれだけで開発効率がかなり落ちる。

下記サイトでXCodeの問題ということと解決するための方法が載ってた。

方法としては別のSSHデーモンを起動してそちらから接続すればいいらしい。

起動スクリプトをダウンロード。~/scripts/customsshdに置く。

スクリプトを読んで必要なディレクトリを作成
$ cd
$ mkdir customkeys

鍵を生成するスクリプトもあるようなので実行。
$ chmod 755 scripts/customsshd
$ ./scripts/customsshd install

customkeysにSSHの鍵が出力される。

生成された公開鍵(ssh_host_rsa_key)をsustomsshdの「CUSTOM_ID_RSA_PUBKEY」へ代入している部分に貼り付ける。

SSHDデーモン起動。
$ ./scripts/customsshd

TeraTermから接続してみる。
ポート番号:50111
ユーザー名:(Macのユーザー名)
パスフレーズ:(なし)
秘密鍵:customkeys/ssh_host_rsa_key

Titanium CLIでビルドしてみる。
$ ti build -p iphone -T simulator --sim-64bit --tall

無事シミュレーターが起動。

Macを再起動してもこのSSHDデーモンも起動してくれる。

そのうちXCodeのバージョンアップで直っていると思う。

 

< Related Posts >

Related Posts Plugin for WordPress, Blogger...

Blog Archives