独自ドメインのはてなブログを HTTPS 化しました

概要

本日より、当ブログを HTTPS 化しました。はてなブログで独自ドメインを利用している場合でも HTTPS を用いた配信が可能となったためです。

公式アナウンスについては下記の記事を参照ください。

staff.hatenablog.com


HTTPS 対応によるメリット

各所で何度も語られているため詳細は省略しますが、以下のようなメリットがあります。

セキュリティ強化

正しいサーバと通信できていることや改竄されていないことが確認でき、通信内容の盗聴防止にも繋がります。

新技術への対応

https 化による直接のメリットではないですが、HTTP/2 や Service Worker を始めとした新しい技術では https の利用が前提となっている場合があります。

ブラウザ表示の改善

アドレスバーに錠前アイコンや「保護された通信」などが表示されるため、訪問者から見ても(通信は)安全であることが確認できます。

f:id:yuu2634:20180613202740p:plain

ブラウザによっては http 通信の場合に警告メッセージが表示されることもあり、今後ますます対応が広がっていくと思われます。


独自ドメイン対応の課題

証明書はドメインごとに用意する必要があるため、独自ドメインで HTTPS に対応することは困難でした。証明書1枚ずつに費用も発生してしまいます。

しかし、後述する Let's Encrypt を活用することで証明書の動的取得が可能となり、今回の独自ドメイン HTTPS 対応が実現したようです。

機能リリースに先立ち、はてなブログでは Let's Encrypt への寄付を行っています。 developer.hatenastaff.com


Let’s Encrypt とは

Web 接続全体の暗号化を目指しているプロジェクトです。Mozilla や EFF、Akamai などがスポンサードしていることもあり、無料で証明書を取得できます。

コマンドのみで証明書を発行できることや費用が掛からない点から利用数が伸びており、これまでに1億通を超える証明書が発行されています。最近ではワイルドカード証明書の発行にも対応しました。

私が公開済みの Web サービス「Spla2 API」 などでも活用しています。


はてなブログの対応

Let’s Encrypt を活用し、裏側で 独自ドメイン用の証明書を自動発行・自動適用しているようです。これまでにも Github Pages や BASE などが似た方式を採用しています。

blog.github.com devblog.thebase.in

HTTPS 機能を有効化したところ、(恐らく証明書が発行されるまでの)数秒間のみ証明書エラーが表示されましたが、すぐに正常な HTTPS 通信が行えるようになりました。


HTTPS 有効化後の変化

http でアクセスした場合は、301 リダイレクトによって https へ飛ばされます。現時点で HSTS は有効となっていません。

$ curl -I http://blog.yuu26.com/
HTTP/1.1 301 Moved Permanently
Location: https://blog.yuu26.com/


canonical の値も https に変更されました。

<link rel="canonical" href="https://blog.yuu26.com/"/>


また、Mixed Content を検出するために CSP レポートの設定が行われているようです。報告されたレポートを利用者側が見ることはできないと思われます。

$ curl -I https://blog.yuu26.com/
Content-Security-Policy-Report-Only: block-all-mixed-content; report-uri https://blog.hatena.ne.jp/api/csp_report


まとめ

  • 独自ドメインのはてなブログを HTTPS 化しました
  • 裏側では Let’s Encrypt が活用されています
  • リダイレクトや SEO 関連タグは自動で変換されます

昨年にアナウンスがあってから少し時間が掛かりましたが、無事にリリースされて問題なく動作しているため安心しました。はてなの中の方、お疲れさまでした。

YAMAHA RTX1210 で用途に応じてインターネット回線を使い分ける

概要

YAMAHA RTX1210 の「フィルタ型ルーティング」を利用し、通信用途に応じて複数のインターネット回線を切り替えることができました。

自宅からのインターネット接続には高速な DS-Lite を活用しつつ、外部からの VPN リモートアクセスを受け付けるために PPPoE を併用しています。


接続方式の比較

我が家で利用可能な IPv4 のインターネット接続方式は下記の2つです。

接続方式インターネット通信外部からの接続
DS-Lite速い(空いている)不可
PPPoE遅い(混雑している)可能

IIJmio FiberAccess/NF を利用しているため、どちらも IIJ グループの回線です。

DS-Lite

transix が提供する DS-Lite 方式です。こちらは安定して高速な通信が行える反面、ネットワーク構成の都合で外部からのアクセスを受けられません。

f:id:yuu2634:20180527230120p:plain

PPPoE

IIJmio が提供する PPPoE 方式です。NTT 側の設備が常に混雑しており、あまり速度が出ません。しかし、外部からのアクセスを直接受けられます。

f:id:yuu2634:20180527230241p:plain


背景

我が家のルータでは VPN リモートアクセスを有効化しており、外出先から自宅ネットワークに接続したり、公衆 Wi-Fi 利用時のセキュリティを確保するために活用しています。

そのため、外部からの接続を受け入れられる環境が必要となってきます。


2つの接続方式を併用する

外部から接続できるようにしたいけれど、自宅から日々使う回線が遅いのもちょっと。。。と言うことで、2つの接続方式を併用できないか試行錯誤しました。

下記のようなルーティングを行うことで、求めていた構成となります。

優先度通信内容プロトコル利用する回線
(1)VPN 通信L2TP/IPsecPPPoE (IIJmio)
(2)通常のインターネット通信TCP, UDP 等DS-Lite (transix)

f:id:yuu2634:20180528215058p:plain


フィルタ型ルーティングの設定

冒頭にも書きましたが、YAMAHA ルータの「フィルタ型ルーティング」機能を活用することで実現ができました。

UDP: 500, 4500, 1701 の通信のみを PPPoE にルーティング、それ以外は DS-Lite へルーティングする設定です。

ip route default gateway tunnel 2 gateway pp 1 filter 500001 500002 500003
ip filter 500001 pass * * udp 500 *
ip filter 500002 pass * * udp 4500 *
ip filter 500003 pass * * udp 1701 *

// pp 1: IIJmio PPPoE 接続
// tunnel 2: transix DS-Lite 接続

上記で指定した UDP: 500, 4500, 1701 の通信は、NAT 超えで L2TP/IPsec を張る際に利用されるポート番号です。つまり、VPN リモートアクセスの通信で用いられます。


VPN 経由でインターネットに接続

外出先から VPN で自宅ネットワークを経由してインターネットに出る場合は、以下のような経路となっているはずです。よく分からない図になってきましたが。。。

f:id:yuu2634:20180528221201p:plain

iPhone から確認したところ、ちゃんと transix 経由になっています。

f:id:yuu2634:20180528221708p:plain


参考資料


まとめ

  • RTX1210 で VPN リモートアクセスのみを別回線に振り分けました
  • フィルタ型ルーティングで通信経路を切り替えられます
  • L2TP/IPsec の通信のみを PPPoE に流すようにしました

DS-Lite の高速な回線と、外から繋げられる PPPoE のいいとこ取りを実現できました。

Google Home + Nature Remo API で室温を喋らせる

概要

Google Home と Nature Remo の温度センサーを組み合わせることで、現在の室温を Google Home から喋らせることに成功しました。


実現方法

Google Home に任意の固定メッセージを喋らせるだけであれば IFTTT で実現できますが、今回は「室温」という動的な要素が含まれるため IFTTT 単体では不可能です。

通常であれば Google Home 用のアプリ開発が必要ですが、今回は少し変わったアプローチでチャレンジしてみました。以下の流れです。

f:id:yuu2634:20180523233759p:plain

  • (1) Google Home に室温を尋ねる
  • (2) IFTTT の Webhook で ngrok を叩く
  • (3) ngrok がローカルの node.js を呼び出し
  • (4) Nature Remo API から室温を取得
  • (5) google-home-notifier 経由で Google Home を喋らせる


準備するもの

1. google-home-notifier の準備

まずは google-home-notifier が動作する node.js 環境を用意します。詳細な手順については、以前の記事 で解説しています。

簡単な動作確認スクリプトを実行し、Google Home が喋ることを確認。

// Google Home が「テストメッセージです。」と喋る
$ node step01.js


2. Nature Remo API の準備

室温を取得するため、Nature Remo API を準備します。アクセストークンを用意し、curl で実行できることを確認します。

// 情報が取得できることを確認
$ curl https://api.nature.global/1/devices -H "Authorization: Bearer XXXXX"

// 室温のみに絞り込む
$ curl https://api.nature.global/1/devices -H "Authorization: Bearer XXXXX" | jq .[].newest_events.te.val

こちらも、以前の記事 で詳しい手順を紹介しています。


3. 室温取得スクリプト作成

まずは室温を取得する部分のみ、node.js で書いてみました。

12-14行目で Nature Remo API から取得、16行目で jq を使って絞り込んでいます。

$ node step02.js
現在の室温は27度です。


4. Google Home 応答処理追加

取得した室温を Google Home が喋るように書き換えます。

実行すると、Google Home が室温を喋ってくれました。

$ node step03.js
Device notified


5. ngrok 対応

このままではローカルでしか実行できないため、あまり意味がありません。ngrok を利用して外部からのアクセスを待ち受けるようにします。

実行すると、ngrok のエンドポイントが表示されます。

$ node step04.js
Endpoint: https://123abcde.ngrok.io

この URL(https://123abcde.ngrok.io) にアクセスすることでスクリプトが実行され、Google Home が喋りだします。


6. IFTTT 登録

ここまで来たらあと一歩です。Google Home をトリガーに Webhook を実行 するように、IFTTT の設定(アプレット)を作成します。

f:id:yuu2634:20180523225226p:plain

IFTTT の登録手順については、以前の記事 にて画像付きで詳しく解説しています。


7. 完成

もう一度動画を貼っておきます。多少のラグはありますが、Google Home が現在の室温を教えてくれるようになりました。

www.youtube.com


まとめ

  • Google Home + Nature Remo で室温を喋らせました
  • IFTTT, ngrok, nodejs, Nature Remo API, google-home-notifier を組み合わせました

Google Home から動的なメッセージを返したい場合、google-home-notifier を使うと楽に実現できるためオススメです。


関連記事

blog.yuu26.com blog.yuu26.com blog.yuu26.com

google-home-notifier ではなく Google Home アプリとして開発した例↓ blog.yuu26.com

Web サイトの速度測定に便利な3大ツール

概要

Web サイトの表示速度を測定する際に便利なツールを3つ紹介します。

ここ数年はサイト高速化の話題を聞くことも多く、日経電子版dev.to 、昔ながらの 阿部寛のホームページ がバズったりもしました。

私自身も仕事でサイト高速化に関わることがあり、効果測定の手段として下記3ツールを活用しています。概要と使い分けについてまとめてみました。


なぜ表示速度が重要か

そもそもなぜサイトを早く表示する必要があるのか、軽く触れておきます。

  • ユーザ側として
    自分が見る側に立った場合、サッと表示されるとストレスもなく嬉しいです。

  • コンバージョンへの影響
    「1秒の遅延でコンバージョンが7%下がる」など数字は様々ありますが、表示速度が売上にも影響すると言われています。

  • 閲覧環境に依存しない
    ユーザが理想的な環境とは限らないため、低速回線でも快適に見られるとベストです。月末はパケット数制限により回線速度の低いユーザが増える時期でもあります。


PageSpeed Insights

URL: https://developers.google.com/speed/pagespeed/insights/

点数 で結果が表示される、シンプルで非常に分かりやすいツールです。

モバイル版・パソコン版の2種類で測定し、それぞれのスコアと改善策を表示してくれます。

f:id:yuu2634:20180426212837p:plain


アクセス数の非常に多いサイトであれば、Chrome からの情報を基にした 秒数 も表示してくれます。Yahoo! Japan で試したところ1秒台の結果でした。早いです。

f:id:yuu2634:20180426212428p:plain


ひとまず速度を見たい、適用できるベストプラクティスを知りたい、複数のサイトを比較したい、といった場面で利用しています。


Lighthouse

URL: https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk

Chrome の拡張機能として動作するツールです。

モバイルに特化 した作りとなっており、パフォーマンスだけでなく PWA 対応度やアクセシビリティ、低速回線での表示速度も評価されます。

f:id:yuu2634:20180426214219p:plain


改善提案も「どのリソースが、どれだけ削減可能か」まで細かく出力してくれます。英語でしか提供されていませんが、Chrome の翻訳機能を使うと日本語で読むことも可能です。

f:id:yuu2634:20180426214707p:plain


優先度の高い項目から一つずつ対応していくことで、効率的に速度改善を進められます。指摘事項をすべてクリアすると非常に高速なサイトになると思われます。


WebPagetest

URL: https://www.webpagetest.org/

オープンソースプロジェクトとして提供されている測定ツールで、計測結果をURL共有 できます。また、インストールして自前で利用できるバージョンも提供されています。

f:id:yuu2634:20180426220400p:plain


計測地点と使用ブラウザを指定し、実際の挙動に近い計測が可能です。1サイトを複数環境から測定したり、複数のサイトを同一環境から計測することができます。

f:id:yuu2634:20180426220009p:plain


得られる情報量が多いのも特徴です。Details タブでは、ヘッダ情報や取得に要した時間をリソースごとに確認できます。ぜひ、計測結果(Yahoo! Japan の例) を直接ご覧になってみてください。

f:id:yuu2634:20180426220936p:plain


応用編

定期的に計測結果を取得することで、手間を省く&成果が可視化できて便利です。

サイトにアクセスしなくとも、下記のような API やコマンドで自動計測が行なえます。

結果を CSV やスプレッドシートに出力し、グラフ生成まで自動化できるとベストかもしれません。


まとめ

  • Web サイトの速度測定ツールを3つ紹介しました
  • 「PageSpeed Insights」 ……サクッと測りたいときに
  • 「Lighthouse」 ……改善ポイントを知りたいときに
  • 「WebPagetest」 ……実環境に近い計測をしたいときに

自サイトだけではなく、普段利用しているサイトや構成を知りたいサイトを計測してみるのも楽しいです。ぜひ色々お試しください。

Kubernetes on CentOS on ESXi 環境を構築してみた

概要

これまでは GKE 環境を使って Kubernetes で遊んでいましたが、Kubernetes 自体の動きを見てみたいこともあり、手元にクラスタを構築しました。

kubeadm を使って、CentOS 上に Kubernetes クラスタを構築し、ダッシュボードの導入まで行いました。メモを兼ねて手順を紹介します。


システム構成

タイトル通り「Kubernetes on CentOS on ESXi」の構成となっており、ESXi 自体は Intel NUC で動いています。

  • Kubeadm 1.9.6
  • Kubernetes 1.9
  • CentOS 7.4
  • VMware ESXi 6.0
  • Intel NUC6i5SYH

f:id:yuu2634:20180325183441p:plain


0. 事前確認

今回は、Master 1台、Worker Node 2台の構成。(仮想CPU2コア・メモリ4GB × 3台)

ひとまず作って動かすことを優先するため、kubeadm で構築。


参考にした公式ドキュメント: Installing kubeadm | Kubernetes


1. サーバ共通部分の構築

CentOS を用意し、NIC やネットワーク周りが正常に動作していることを確認。yum update なども済ませておく。

ポート開放は後回しとして、Docker をインストール。
Installing kubeadm | Kubernetes - Installing Docker

# yum install -y docker
# systemctl enable docker && systemctl start docker

Kubernetes 用のリポジトリを追加。

# vi /etc/yum.repos.d/kubernetes.repo

[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg

Kubeadm, Kubelet, Kubectl をインストール。

# yum install -y kubelet kubeadm kubectl
# systemctl enable kubelet && systemctl start kubelet

SELinux を無効化。(未対応らしい)

# setenforce 0
# vi /etc/selinux/config

SELINUX=enforcing
      ↓
SELINUX=disabled

iptables のバイパスを避けるパラメータ追加。

# echo "net.bridge.bridge-nf-call-ip6tables = 1" >> /etc/sysctl.d/kubernetes.conf
# echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.d/kubernetes.conf
# sysctl -p

Cgroup Driver が、Docker とKubelet で一致していることを確認。

# docker info | grep -i cgroup
→systemd

# grep -i cgroup /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
→systemd

swap が有効になっている場合は無効化。/etc/fstab の記載も削る。

# swapoff -a
# vi /etc/fstab

/etc/hosts に自サーバのホスト名を追記。

# vi /etc/hosts

192.168.xxx.yyy kube-master


2. サーバクローン

今回は ESXi を利用しているため、VMware 自身の機能でサーバを複製する。

f:id:yuu2634:20171215220801p:plain

2台複製し、ホスト名・IPアドレス・hosts の修正をしておく。

念のため、MACアドレスが重複していない(再生成されている)ことも確認。


3. Master 構築

1台を選定し、Master としてセットアップを進める。

序盤にスキップした firewalld の設定を追加。
Installing kubeadm | Kubernetes - Check required ports

# firewall-cmd --add-port=6443/tcp --zone=public --parmanent
# firewall-cmd --add-port=2379-2380/tcp --zone=public --parmanent
# firewall-cmd --add-port=10250/tcp --zone=public --parmanent
# firewall-cmd --add-port=10251/tcp --zone=public --parmanent
# firewall-cmd --add-port=10255/tcp --zone=public --parmanent


本題の Kubernetes クラスタを作成。

--pod-network-cidr は Kubernetes で利用するネットワーク指定でデフォルトのまま。--apiserver-advertise-address は kube-apiserver 用アドレス指定。ここでは master サーバ自身の IP とする。

# kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.xxx.yyy


無事に構築できたことを確認し、kubeadm join …… のコマンドを控えておく。

Your Kubernetes master has initialized successfully!

(中略)

You can now join any number of machines by running the following on each node
as root:

  kubeadm join --token aaaa.bbbbbb 192.168.xxx.yyy:6443 --discovery-token-ca-cert-hash sha256:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz


普段使うユーザに切り替え、kubectl の接続設定を反映。

$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config

$ kubectl cluster-info
Kubernetes master is running at https://10.0.xxx.yyy:6443


4. Pod ネットワーク構築

Using kubeadm to Create a Cluster | Kubernetes - (3/4) Installing a pod network

今回は Flannel を利用するため、yml ファイルを一旦ダウンロード。

$ curl https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml -o kube-flannel.yml


利用する NIC 名を command: の末尾に追記。

$ vi kube-flannel.yml
      containers:
      - name: kube-flannel
        image: quay.io/coreos/flannel:v0.9.1-amd64
        command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr", "--iface=ens160" ]


編集済みの yml ファイルを適用。kube-dnsRunning になれば完了。

$ kubectl apply -f kube-flannel.yml

$ kubectl get pod -n kube-system | grep kube-dns
kube-dns-6f4fd4bdf-vmtnx                3/3       Running   0          2d

$ kubectl cluster-info
Kubernetes master is running at https://10.0.xxx.yyy:6443
KubeDNS is running at https://10.0.xxx.yyy:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy


5. Worker Node 構築

先ほどクローンしたサーバの状態からスタート。

今度は Worker Node 用の設定を追加。
Installing kubeadm | Kubernetes - Check required ports

# firewall-cmd --add-port=10250/tcp --zone=public --parmanent
# firewall-cmd --add-port=10255/tcp --zone=public --parmanent
# firewall-cmd --add-port=30000-32767/tcp --zone=public --parmanent


Master 構築時に提示されたコマンドだけでノード追加完了。

# kubeadm join --token aaaa.bbbbbb 192.168.xxx.yyy:6443 --discovery-token-ca-cert-hash sha256:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz


kubectl から結果を確認。

$ kubectl get node
NAME            STATUS    ROLES     AGE       VERSION
kube-master     Ready     master    2d        v1.9.6
kube-worker01   Ready     <none>    2d        v1.9.6

同様に2台目の Worker Node も追加。


6. Kubernetes Dashboard 導入

Kubernetes Dashboard - README.md に従ってデプロイするだけ。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml

$ kubectl get service -n kube-system
NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
kubernetes-dashboard   ClusterIP   10.103.221.252   <none>        443/TCP         2d


ClusterIP には外から直接アクセスできないため、ローカルプロキシを作成。

$ kubectl proxy


この状態で http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ にアクセス。

f:id:yuu2634:20180326205840p:plain

クラスタ情報取得のため、ログインを求められる。


7. Dashboard 用ユーザ作成

Creating sample user · kubernetes/dashboard Wiki を参考に yaml ファイルを作成して設定追加。

まずはユーザ作成。

$ cat <<EOF >admin-user.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system
EOF

$ kubectl create -f admin-user.yaml


ロールを割り当て。

$ cat <<EOF >admin-user_role.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system
EOF

$ kubectl create -f admin-user_role.yaml


アクセストークンを取得。最後の token: 部分だけコピーして、Dashboard に貼り付け。

$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

token:      eyJhbhp(略)o700OSpvTT9zlBsu-b35lzXGBRHzv5g_RA


ダッシュボードが見えるようになった。かっこいい。

f:id:yuu2634:20180326211451p:plain


7. Dashboard を NodePort 化

毎度 kubectl proxy するのも手間なので、NodePort からアクセスできるようにする。
Accessing Dashboard 1.7.X and above · kubernetes/dashboard Wiki

Service の設定を編集。

$ kubectl -n kube-system edit service kubernetes-dashboard


エディタが開くので type: 欄を修正して上書き保存。

  type: ClusterIP
   ↓
  type: NodePort


Service を確認すると NodePort が付与された。

$ kubectl get service -n kube-system
NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
kube-dns               ClusterIP   10.96.0.10       <none>        53/UDP,53/TCP   2d
kubernetes-dashboard   NodePort    10.103.221.252   <none>        443:32701/TCP   2d


これにより https://<MasterのIPアドレス>:32701 でアクセス可能となった。
Google Chrome だと証明書エラーで開けない場合があるので、Firefox からアクセス。


まとめ

  • kubeadm を利用して CentOS 上に Kubernetes クラスタを構築しました
  • Dashboard のデプロイ&初期設定&NodePort 対応を行いました

自宅に一つ Kubernetes を用意することで、費用を気にせずコンテナ立て放題・yaml 検証可能な環境が整いました。

CoreOS も試したいと考えているため、近い内にノードとしてクラスタに追加予定です。

Web システム障害時の原因切り分け32パターン

概要

Web システムの障害原因って幅が広いよなと感じる機会があり、頭の整理も兼ねて書き出してみました。

単に原因と言ってもシステム構成や障害の深刻さによって異なってくるため、ひとまず思いついた項目だけをまとめてみます。全体的にインフラ寄りです。


ページすら開けない場合

ドメイン編

  • 名前解決が成功するか
  • CNAMEを利用している場合、IPアドレスまで取得できるか

ネットワーク編

  • 別のインターネット回線から接続できるか
  • ping応答が返ってくるか(塞いでいない場合)
  • 公開ポートへのtelnet接続が可能か

HTTPS編

  • TLSコネクションが確立できるか
  • 利用している証明書は有効か

ロードバランサ編

  • 有効状態の Web サーバがぶら下がっているか

Webサーバ編

  • Web サーバのプロセスが起動しているか
  • 443(80)ポートがLISTENとなっているか
  • (アクセスログ等で)クライアントからの接続が来ているか
  • 同時接続数等の上限に達していないか
  • (リバースプロキシ時)バックエンドのサーバから応答があるか

データベース編

  • DBにログイン→クエリ発行が可能か
  • デッドロックが発生していないか
  • スロークエリが大量に出ていないか
  • 物理的/論理的なディスクが枯渇していないか

メモリキャッシュ編

  • memcached/Redis などプロセスは起動しているか
  • 最大コネクション数に達していないか
  • メモリ領域が不足していないか

サーバOS編

  • サーバの負荷(CPU, RAM, I/O, NW)に問題が無いか
  • 他サーバと通信する場合、ローカルポートが枯渇していないか
  • ファイルディスクリプタが枯渇していないか

API編

  • APIとの通信が確立できているか
  • APIからのレスポンスが遅延していないか
  • APIからのレスポンス内容は正常か

出力内容がおかしい場合

フロントエンド編

  • CSS / JavaScript などのリソースが取得できているか
  • 他のブラウザでも再現するか
  • ブラウザコンソールにエラーが出ていないか

データ編

  • 入力内容やログイン状態を切り替えても再現するか

キャッシュ編

  • ブラウザキャッシュが古い状態でないか
  • CDNキャッシュが古い状態でないか


まとめ

やはり多いですね。。。パブリッククラウドやマネージドサービスでは気にしなくてよい部分も出てきましたが、知識として持っておいて損はないかなと感じます。

物理レイヤやアプリレイヤなども含めるとさらに倍以上になりそうです。「他にこんなものがあるよ!」と言ったコメントやツッコミもお待ちしています。

Fastly API を Postman 経由で簡単に呼び出す方法

概要

REST API のテストツールである Postman を使って、Fastly API を呼び出す手順を紹介します。curl で叩くよりも楽になるのでオススメです。


Postman とは

REST API のクライアントです。似たようなソフトウェアとしては、Chrome 向けの Advanced REST client などがあります。

GET や POST リクエストの組み立てはもちろん、レスポンスヘッダやボディも見やすく整形してくれるため、REST API のテストに最適なツールです。

f:id:yuu2634:20180226204404p:plain


Postman のセットアップ

以下リンクからダウンロードできます。

www.getpostman.com


基本的な使用方法については、以下の記事が参考になるかと思います。


fastly-postman

Fastly のエンジニアが公開している Postman 連動用のリポジトリです。Postman にインポートし、初期設定をするだけで利用可能です。

github.com


git clone もしくは ZIP ダウンロードで取得しましょう。

f:id:yuu2634:20180226203231p:plain


初期設定

右上の設定ボタンから環境設定画面を開きます。

f:id:yuu2634:20180226204610p:plain


Import から、fastly.postman_*.json の3ファイルをインポート。

f:id:yuu2634:20180226204715p:plain


左下の Globals から、Fastly のアカウント情報を登録します。

f:id:yuu2634:20180226204840p:plain

  • username: ログインユーザ名
  • password: ログインパスワード
  • token: アクセストークン(※)
  • customer_id: Company settings の Company ID
  • user_id: User management のユーザ名の右隣

※アクセストークンの発行手順は こちらの記事 を参照


サービス登録

Fastly 上のサービスを登録していきます。作成されている Fastly をクリック。

f:id:yuu2634:20180228000129p:plain


管理画面の service_id, service_name, version_no を書き写します。

f:id:yuu2634:20180227235928p:plain

f:id:yuu2634:20180227235622p:plain

これで使うための準備が一通り完了しました。


CDN設定を取得する

始めに、API 経由で Request Settings を取得してみます。

  1. 先ほど設定した環境を選択
  2. Collections を開く
  3. 実行したい API (Configuration - Request Settings の GET) を選択
  4. リクエスト送信

f:id:yuu2634:20180228001357p:plain

うまく行けば画面下部に取得結果が出力されます。簡単ですね。


Instant Purge を実行する

Fastly の特徴でもある Instant Purge を実行してみます。方法は複数ありますが、今回は該当 URI に PURGE リクエストを送ることでパージします。

  1. Purging - Purging - individual_url を選択
  2. 対象 URI を入力
  3. リクエスト送信

f:id:yuu2634:20180228002810p:plain

正常に処理されたことがレスポンスから読み取れます。

このように、Fastly 提供の API を簡単な操作で呼び出すことが可能です。


まとめ

  • Postman + fastly-postman の組み合わせで利用できます
  • Globals には Fastly のアカウント情報を登録します
  • Environment には Fastly のサービス情報を登録します

Fastly API Documentation からも分かる通り、Fastly には豊富な API が揃っています。Postman と組み合わせることで、リクエストの組み立てや API の検証を効率化できます。

NHK のサブドメイン使い分けについて調べてみた

概要

NHK のウェブサイトでは複数のサブドメインが使われています。

オリンピックが盛り上がっており、Twitter などから NHK のサイトに飛ぶ機会が増えましたが、よく見ると www. www1. www3. など複数のサブドメインがあるようです。

調査してみたところ、コンテンツ別にドメインが設定されていて、複数の CDN が利用されていると判明しました。

f:id:yuu2634:20180219002048p:plain


仮説

NHK ほどの規模になると、間違いなく CDN を利用していると思われます。サブドメインが複数あることから、配信用途に応じて利用サービスを使い分けていると仮定しました。

ドメインごとの調査結果

検証環境

  • 日時: 2018/02/18 23:30 頃
  • DNS: さくらインターネットの DNS サーバ(国内拠点)


www.nhk.or.jp

www.nhk.or.jp.    300   IN  CNAME   www.nhk.or.jp.edgekey.net.
  • CDN: Akamai
  • Google: 426,000 件
  • 利用用途: 各放送局のサイトなどメインコンテンツ
  • 参考URL: https://www.nhk.or.jp/


www1.nhk.or.jp

www1.nhk.or.jp.   300   IN  CNAME   55aa563dc2f0c3c189a7a4b584816c97.cdnext.stream.ne.jp.


www2.nhk.or.jp

www2.nhk.or.jp.   300   IN  CNAME   nhkjp.hs.llnwd.net.


www3.nhk.or.jp

www3.nhk.or.jp.   600   IN  CNAME   nhk.or.jp.edgekey.net.
  • CDN: Akamai
  • Google: 65,300 件
  • 利用用途: 全国ニュース、地域ニュースなど (NHK NEWS WEB)
  • 参考URL: https://www3.nhk.or.jp/news/


www4.nhk.or.jp

www4.nhk.or.jp.   300   IN  CNAME   nhkjp.hs.llnwd.net.


www5.nhk.or.jp

www5.nhk.or.jp.   300   IN  CNAME   nhk.or.jp.edgekey.net.


www6.nhk.or.jp

www6.nhk.or.jp.   300   IN  CNAME   nhkjp.hs.llnwd.net.
  • CDN: Limelight
  • Google: 31,300 件
  • 利用用途: ドラマ・アニメなどジャンル別のサイト
  • 参考URL: http://www6.nhk.or.jp/drama/


まとめ

  • Akamai、CDNext、Limelight を利用していることがわかりました。
  • コンテンツ別にドメインと CDN を使い分けているようです。

ドメインや IP アドレス情報を調べてみることで、どのサービスを利用しているかが分かったりします。Chrome の開発者ツールと同様に、気になるウェブサイトの裏側を覗いてみるのも楽しいですよ。

Google Chrome Canary で Symantec 証明書無効化を検証

概要

Google Chrome で将来的に無効化される Symantec 証明書の検証を行いました。

Canary バージョンの Google Chrome を利用することで、2018年4月以降にエラーとなる証明書を事前に確認することができます。


シマンテック証明書の問題

Symantec 系の認証局において、証明書発行に関する不手際が過去にありました。

それを受けて、Google Chrome では Symantec から発行された証明書の信頼を段階的に無効化すると発表しています。

developers-jp.googleblog.com


第一弾として、Google Chrome 66 から 2016年5月以前に発行された証明書を信頼しない 状態となります。該当する証明書では以下のような表示が出てしまうことに。

f:id:yuu2634:20180206220753p:plain


外部リソースの証明書も要チェック

サイト自体の証明書に問題がなくても、外部から読み込んでいるスクリプトや CSS のサーバ(証明書)が該当する場合は、アドレスバーが警告表示となります。

f:id:yuu2634:20180206222418p:plain


リソース自体も読み込まれなくなるため、ページの表示が崩れてしまう原因にもなりかねません。

f:id:yuu2634:20180206221715p:plain


外部リソースの証明書をすべて確認するのは手間もかかりますので、今回は Chrome Canary を活用しました。


Google Chrome Canary とは

Google Chrome では、開発中のバージョンである Canary 版 が公開されています。

f:id:yuu2634:20180206220219p:plain

安定板(通常版)よりおおよそ2つ先のバージョンが公開されており、現在は Chrome Canary 66 となっています。

すでに 2016年5月以前に発行された証明書を信頼しない 状態となっているため、Chrome Canary 66 からアクセスするだけで事前確認が可能となります。


Canary はデベロッパーや開発段階の機能に興味があるユーザー向けに設計されており、動作が安定しない可能性があります。

なお、注意書きにもある通り、開発版のため動作が不安定になることもあります。 利用する際は安定版との併用をお勧めします。(Canary 版と安定版は同時インストール可能)


動作検証

以下の内容は、2018年2月6日時点 の検証結果です。

日本最大のポータルサイトにアクセスしてみます。 https://www.yahoo.co.jp/

f:id:yuu2634:20180206223751p:plain

保護されていません の表示が出てしまいました。


大手フリマアプリのサイトも見てみます。 https://www.mercari.com/jp/

f:id:yuu2634:20180206224528p:plain

同様に 保護されていません の表示が出てしまいました。


開発者ツールで確認すると、ページ内の外部リソースで証明書エラーが発生しているようです。(両サイトとも同様のエラーでした)

Yahoo! タグマネージャー s.yjtag.jp の証明書がエラーとなっています。

f:id:yuu2634:20180207150441p:plain


現在の安定版である Chrome 64 でアクセスした場合は問題ありません。開発者ツールのコンソールにメッセージは表示されるものの、赤字の警告が出ることはないです。

しかし、外部ドメインの証明書が更新されない限りは、2018年4月17日 までに予定されている Chrome 66 安定版のリリースでこの現象が発生してしまいます。


まとめ

  • 特定の Symantec 証明書が Google Chrome で信頼されなくなります
  • Google Chrome Canary を用いて事前に確認可能です
  • 自サイトだけでなく外部リソースの証明書もチェックが必要です

広告関連やアクセス解析のスクリプトなど、外部リソースを活用しているサイトは多くあると思います。ぜひこの機会に確認してみることをお勧めします。