zuntan02のはてなブログ

備忘録的なものです。時々職場の技術者ブログにも転記してますが、メインはこちらで。

【AWS+ELB+SSL+Wordpres】ELB配下のWordpressでサイト全体をSSL化しようとしてハマった

AWS Certificate ManagerでSSL取ってELB配下のEC2でWordpressをサイト全体SSL(所謂”常時SSL”)で動かそうとしてはまったのでメモ。

【結論】
wp-config.phpの上部に

# for https on
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
    $_SERVER['HTTPS'] = 'on';

を追記した上で、Wordpressの管理画面でURLをSSLにしてやる。

□公式ドキュメント
Function Reference/is ssl « WordPress Codex



【原因】
こちらに詳しい。とても分かりやすい解説。
snickerjp.blogspot.jp


曰く
SSLの処理を別サーバーに任せる(SSLオフロード)と『is_ssl関数』が効かない
→function is_ssl() では判定が「Port 443」だったらHTTPS、となっているが、ELB等SSLオフロードのために内部的にPort 80で受けていると、これが動作しない

勉強になりました。。。

追記:/etc/nginx/conf.d/hogefuga.conf

server {
    listen 80;

    server_name hoge.fuga.jp;
    root /var/www/html/hogefugajp/;
    index   index.php index.html index.htm;

    if ($http_x_forwarded_proto != https) {
      return 301 https://$host$request_uri;
    }

    access_log  /var/log/nginx/hoge.fuga.jp.access.log  main;
    error_log   /var/log/nginx/hoge.fuga.jp.error.log   warn;
    charset utf-8;


    # Deny all access to the wp-config.php
    set $deny_f 0;
    if ($request_uri ~* .*\/wp-config\.php$ ){
        set $deny_f 1;
    }
    if ( $deny_f = 1) {
        return 403;
    }


    location / {
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

}

【ATS】ロリポップのSSLがATSに対応できてない模様

★(20170718追記)
internet.watch.impress.co.jp


以下はもう過去の話なのですが枯れ木も山の賑わいで。

ロリポップ(ライトプラン)で独自ドメインSSL証明書(2万円!)を設置した後で
iOSアプリからhttpsリクエストができないという事が判明。

■確認方法
blog.kishikawakatsumi.com

nscurl --ats-diagnostics --verbose https://hoge.fuga.jp

2016-06-30 13:34:49.390 nscurl[11546:612680] CFNetwork SSLHandshake failed (-9824)
2016-06-30 13:34:49.391 nscurl[11546:612680] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
Result : FAIL

問い合わせたら下記の回答があった。

ご連絡いただいた件につきまして、誠に恐れ入りますが
「App Transport Security」について弊社のサーバーは
要件を満たしていない状況でございます。

そのため、本年度中には要件を満たすよう
メンテナンスを予定しております。

現時点で明確な期日をお伝えできませんこと
大変申し訳ございませんが、
何卒ご了承いただけますと幸いでございます。

本年度中かー。

それよりこの証明書どうしたらいいの。

AWS Certificate Manager使ってみた

AWS Certificate Manager、略称ACMならSSLが無料(※)で利用できると聞いたのでやってみた。
よくある質問 - AWS Certificate Manager(簡単に SSL/TLS 証明書を作成、管理、配置) | AWS
※実際はELBの費用を考える必要がある。下記参照されたい。

【2018年追記】

★2017年11月よりメール認証のほかにDNSでの認証も可能となった。
 こっちのほうが楽ちんなので今後はDNS認証で行くことになると思われる。
DNS を使って AWS Certificate Manager の検証を簡単に | Amazon Web Services ブログ
以下はメール認証しかなかった時代の遺物です。。

【メリット】

  • 証明書は一年ごとの自動更新となり、更新は1年ごとのメール承認のみである模様。
  • 証明書自体のの利用は無料。

【デメリット】

  • ACMドメイン認証(DV)のみとなり、組織認証(OV)、実在認証(EV)証明書の発行はされません。
  • 証明書の設置はロードバランサ上となるため、別途ロードバランサの費用が発生する。

→EC2インスタンス1個で賄っている様なサイトの場合、ELBを追加すると最低月額$18くらいの増加を覚悟しないといけない。SSL化”だけ”が目的ならこれまで通りCoreSSLとかで買ってwebサーバで解決、の方が安いかも。
ACMの証明書は「少なくとも 1 つのドメイン」が登録できるので、「*.hogehoge.com」と「*.fugafuga.jp」の両証明書を1台のELBにオフロードさせることができる。複数ドメインを総SSL化するとか言いうときはコストメリットあり。

【感想】

・最初の承認メールさえ受信できればあとはスゲー簡単。
・Route53使ってないとダメかなと思ってたけど外部DNSでも大丈夫だった。
・もう「開発環境のオレオレ証明書」とも、(なんと)年次更新作業ともオサラバな感じ。素晴らしい。

証明書の作成

[AWSマネコン]-[Certificate Manager]-[今すぐ始める]
 ドメインhoge.fuga.jp
 追加の名前 *.hoge.fuga.jp(ワイルドカード証明書も使える)
[確認とリクエスト]-[続行]、で、認証メールが届く

※メールのあて先はFAQにあるように、
WHOISルックアップしてドメインの連絡先情報から登録車・管理者・技術担当者(これはwhois公開代行してるとNG)
・リクエストしたドメイン
 admin@
 administrator@
 hostmaster@
 webmaster@
 postmaster@
 にも送られる。この辺から受信して
”To approve this request, go to Amazon Certificate Approvals at”の次に来るURLでサイトを開き、
[I Approve]で承認したら作成は完了

証明書のELBへの配置

AWS Certificate Manager 証明書はElastic Load Balancing または Amazon CloudFrontで使用できます

ELB新規作成の時

f:id:zuntan02:20160628180332p:plain

ELBで既にSSL証明書を設置していた場合の更新画面

f:id:zuntan02:20160628180339p:plain

証明書の選択、配置は特に迷うことはないはずです。
 
f:id:zuntan02:20160628180535p:plain
証明者発行者がAmazonなのが新鮮。

【MacBookPro+BootCamp6+Windows10】Win7などからWin10にアップグレードしたとき、既にBootCamp4が動作している状態でBootCamp6を上書きインストールしようすると「error」が出てインストールできなかった時の対応ログ

Win7→Win10に上げたついでに、せっかくだからBootCamp6にしよう、と最新版をOSXのBootCampツール経由で取得、Windows10でインストールすると
f:id:zuntan02:20160617133042p:plain
こんな感じでエラー終了してしまった。
ググったところ、以下の方法で解決を見た。

1)トラブルシューティングツールのダウンロードと実行

https://support.microsoft.com/ja-jp/help/17588/fix-problems-that-block-programs-from-being-installed-or-removed
よりトラブルシューティングツール
MicrosoftProgram_Install_and_Uninstall.meta.diagcab
をダウンロードして起動

2)[アンインストール]を選択し、導入済みの「Boot Camp サービス」をアンインストールします

f:id:zuntan02:20160617133101p:plain
削除された模様
f:id:zuntan02:20160617133107p:plain

3)再度BootCamp6のSetup.exeを実行

→途中でインストーラーのエラーが出てくるけど「プログラムを終了します」で進める
→そのままインストーラーの処理は進み、正常に終了、再起動するとバージョンが上がっていることが確認できました。
f:id:zuntan02:20160617133127p:plain

動作はほとんど変わらないので、今普通に動作している人は無理に最新版にする必要はないと思われますが、メモまで。

MySQL5.6.8以前と以後とでquery_cache_typeのデフォルト値が違うので注意

5.6.8以前はquery_cache_size=0のものを適当に大きな値にしてやればOK、だったのが、
以降は明示的にquery_cache_type=1にしてやる必要がある。

> (MySQL 5.6.8 より前では、1 のデフォルトの query_cache_type で、デフォルトのサイズは 0 です。)
MySQL :: MySQL 5.6 リファレンスマニュアル :: 8.9.3.3 クエリーキャッシュの構成


なんか古い手順のままやってたらどうしてもキャッシュされてなくてあれ?みたいなことが。。。

↓こんな感じだった

mysql> SHOW VARIABLES LIKE 'have_query_cache';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| have_query_cache | YES   |
+------------------+-------+

mysql> show variables like 'query_cache_%';
+------------------------------+-----------+
| Variable_name                | Value     |
+------------------------------+-----------+
| query_cache_limit            | 1048576   |
| query_cache_min_res_unit     | 4096      |
| query_cache_size             | 524288000 |
| query_cache_type             | OFF       |★これ★
| query_cache_wlock_invalidate | OFF       |
+------------------------------+-----------+

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+------------+
| Variable_name           | Value      |
+-------------------------+------------+
| Qcache_free_blocks      | 1          |
| Qcache_free_memory      | 524269912  |
| Qcache_hits             | 0          |
| Qcache_inserts          | 0          |
| Qcache_lowmem_prunes    | 0          |
| Qcache_not_cached       | 1339960605 |
| Qcache_queries_in_cache | 0          |
| Qcache_total_blocks     | 1          |
+-------------------------+------------+

メモまで。

さくらのクラウドでロードバランサ使うときはループバックアドレス設定が必要

さくらのクラウドでロードバランサしつつ逆引きする

逆引き例

ex) nslookup 1xx.2xx.1xx.2xx

name = fugafuga.hogehoge.jp.
とかが返ってくる様にしたい。

設定方法

さくらのクラウドでロードバランサを利用する場合

1)[さくらのクラウド管理画面]ルータ+スイッチで16IP付きのものを契約
2)ロードバランサでバランシングされる対象のサーバに対してloopbackアドレスを設定する

/etc/sysctl.confファイルに以下の2行の設定を追記します。

net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2

# arp_ignore 1 - reply only if the target IP address is local address
# arp_announce 2 -reply only if the target IP address is local address
# arp(アドレス解決プロトコル)に反応させないのはmacアドレスを覚えさせないため
# 負荷分散させたときに、送りたい機器へ通信がいくようにする

lo:0デバイスの作成

vi /etc/sysconfig/network-scripts/ifcfg-lo:0

DEVICE=lo:0
IPADDR=仮想IPアドレス
NETMASK=255.255.255.255

設定後、”ifup lo:0″コマンドで設定を反映

→同一サーバに2個以上付与するときは、lo:1,lo:2など増やしていきます。
【参照】http://knowledge.sakura.ad.jp/beginner/3529/

3)[さくらのクラウド管理画面]ロードバランサの「VIP」に上記逆引きできるIPを登録、該当サーバの80/443などにバランシング設定します
4)DNSで上記VIPへの正引きを設定しておきます。

 →ドメイン名で該当サーバに流入することを確認

5)[さくらのクラウド管理画面][スイッチ]でルータの[IPアドレス]について、逆引きさせたいものを該当IPの「ホスト名」に記載します

以上

【Apache】IPとQueryStringの値によってアクセス制限/BASIC認証

【目的】
Aipoのタイムカード操作についてのみ、許可IP以外からはBASIC認証としたい

【参考】
ApacheでQueryString(URLパラメータ)の値によってBASIC認証をかけたい!
qiita.com

こちらが大変参考になった。ただ、上記にある
> RewriteRule (.*) $1 [E=admin_access:1]
だと、すべてをいったんリライトしてしまっていて、タイムカードのPOSTがGETになる件
hakobe932.hatenablog.com
があって、期待通りに動作しなかった。

【解決】
上記のキモはenvに値を載せて、その値があるときだけBasic認証、なので、リライトしない(-)
> RewriteRule .* - [E=admin_access:1]
でいいのかなと。

Aipoではタイムカードを投稿・修正するとき「template=ExtTimecard」というクエリストリングがPOSTされているので、これを条件にして以下の様にしてみました。

※なお、Aipoは
ameblo.jp
この辺参考に、tomcat直じゃなくてapache経由で接続している前提で、あくまでApacheのallow/denyで解決しています。

Basic認証する場合

RewriteEngine On
# 許可IP群でない、かつクエリストリングがマッチしたらtmcrdに1
RewriteCond %{REMOTE_ADDR} !^xxx.xxx.xxx.xxx
RewriteCond %{REMOTE_ADDR} !^xxx.xxx.xxx.xxx
RewriteCond %{QUERY_STRING} template=ExtTimecard
RewriteRule .* - [E=tmcrd:1]

<Location />
    Order allow,deny
    Allow from All
    Deny from env=tmcrd
    
    AuthType Basic
    AuthName "Restricted Area"
    AuthUserFile "/hoge/fuga/.htpasswd"
    Require valid-user
    
    Satisfy Any
</Location>

Basic認証がいらない場合

RewriteEngine On
# 許可IP群でない、かつクエリストリングがマッチしたらリライトせず403終了
RewriteCond %{REMOTE_ADDR} !^xxx.xxx.xxx.xxx
RewriteCond %{REMOTE_ADDR} !^xxx.xxx.xxx.xxx
RewriteCond %{QUERY_STRING} template=ExtTimecard
RewriteRule .* - [F]