macOS SierraでAWS CLIインストール時にエラー(Found existing installation: six 1.4.1)

結論、以下のコマンドでインストールできる

sudo pip install awscli --upgrade --ignore-installed six

以下、経緯

AWS CLIをインストールしたい

  • ここを見てインストールをすすめた
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
sudo python get-pip.py
sudo pip install awscli

謎のエラー

Found existing installation: six 1.4.1
    DEPRECATION: Uninstalling a distutils installed project (six) has been deprecated and will be removed in a future version. This is due to the fact that uninstalling a distutils project will only partially uninstall the project.
    Uninstalling six-1.4.1:
Exception:
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/pip/basecommand.py", line 215, in main
    status = self.run(options, args)
  File "/Library/Python/2.7/site-packages/pip/commands/install.py", line 342, in run
    prefix=options.prefix_path,
  File "/Library/Python/2.7/site-packages/pip/req/req_set.py", line 778, in install
    requirement.uninstall(auto_confirm=True)
  File "/Library/Python/2.7/site-packages/pip/req/req_install.py", line 754, in uninstall
    paths_to_remove.remove(auto_confirm)
  File "/Library/Python/2.7/site-packages/pip/req/req_uninstall.py", line 115, in remove
    renames(path, new_path)
  File "/Library/Python/2.7/site-packages/pip/utils/__init__.py", line 267, in renames
    shutil.move(old, new)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 302, in move
    copy2(src, real_dst)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 131, in copy2
    copystat(src, dst)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py", line 103, in copystat
    os.chflags(dst, st.st_flags)
OSError: [Errno 1] Operation not permitted: '/tmp/pip-Rj2bkf-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/six-1.4.1-py2.7.egg-info'

エラーを見てみた

Found existing installation: six 1.4.1
(既存のインストールが見つかりました)
  • sixとかいうのが入っているらしい
  • six:python2系と3系の差異を埋めてくれるユーティリティライブラリ

すでにいろんな人が書いてた

続きを読む

git-secretsをSourceTree (Macintosh)で使えるようにする手順

背景

目的

この辺にあるように秘密情報のGitプッシュ・公開を防ぐために、git-secrets (https://github.com/awslabs/git-secrets) を導入したときのことです。

課題

git-secrets をインストール後に、SourceTreeでプッシュしようとすると、エラーを吐くようになりました。

git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree commit -q -F /var/folders/xn/1hl03gp55_3df0y1xl37tg900000gp/T/SourceTreeTemp.xNvMuf 
git: 'secrets' is not a git command. See 'git --help'.
Completed with errors, see above

どうやら「クラウド破産しないように git-secrets を使う」の「SourceTreeなどを使っているなら」部分の設定ができていない様子。

今回の主題

タイトルのとおりですが、git-secrets導入に際して、SourceTreeでGitを使い続けるための具体的な手順をまとめておきます。

環境条件

  • macOS Sierra version 10.12.3
  • SourceTree version 2.3.1
  • Git version 2.10.1 (Apple Git-78)

手順概要

  1. MacintoshのGitコマンドのファイルディレクトリに git-secrets をリンクする
  2. SourceTreeが利用するGitを「システムのGit」を使用するに変更する

概要と書くとこうなるのですが、意外に付帯する作業があったので、書き出していきます。

設定

[手順1] MacintoshのGitコマンドのファイルディレクトリに git-secrets をリンクする

Gitの場所を確認

git の場所を確認しておく -> /usr/bin/git

$ which git
/usr/bin/git

つまり、/usr/bin/git-secrets をリンクすると良いことになります。

git-secretsの場所を確認

git-secrets の場所を確認しておく -> /usr/local/Cellar/git-secrets/1.2.1/bin/git-secrets

$ which git-secrets
/usr/local/bin/git-secrets
$ readlink git-secrets
/usr/local/Cellar/git-secrets/1.2.1/bin/git-secrets

あとは、

cd /usr/bin
sudo ln -s /usr/local/Cellar/git-secrets/1.2.1/bin/git-secrets

で、終了かと思いきや、/usr/local/usr/bin へのリンクはsudo しても拒否されてしまいます。ですので、準備はまだまだ続きます。

System Integrity Protecton(SIP)を無効にする

El Capitan以降のOSでSystem Integrity Protecton(SIP)という機能が追加されセキュリティが強化されたとのことで、これを一旦無効にしてあげる必要があります。

  1. command + r を押したままでMacを起動させ、リカバリーモードで立ち上げる
  2. ヘッダメニューの「ユーティリティ」から「ターミナル」を立ち上げる
  3. ターミナルでSIPコマンド csrutil disable を打つ

git-secretsを/usr/bin/にリンクする

SIPが無効化されたら、いよいよgit-secrets を/usr/bin/にリンクします。

cd /usr/bin
sudo ln -s /usr/local/Cellar/git-secrets/1.2.1/bin/git-secrets

System Integrity Protecton(SIP)を有効にする

目的のリンクがはれたら、SIPを有効にし直します。

  1. command + r を押したままでMacを起動させ、リカバリーモードで立ち上げる
  2. ヘッダメニューの「ユーティリティ」から「ターミナル」を立ち上げる
  3. ターミナルでSIPコマンド csrutil enable を打つ

[手順2] SourceTreeが利用するGitを「システムのGit」を使用するに変更する

システムのGitを選択する

「SourceTree」の「環境設定」を開きます。更に「Git」タブを選択します。
スクリーンショット_2017-02-07_14_44_59.png

「システムのGitを使用する」をクリックして、git選択画面にいきます。 
スクリーンショット_2017-02-07_14_45_36.png

/usr/bingit を選択し、「開く」をクリックします。ここで、同じ階層に先程リンクしたgit-secrets も確認できます。

環境設定の画面に戻るとシステムのGitが選択されていることがわかります。

スクリーンショット_2017-02-07_14_45_41.png

これで、Gitをプッシュし直すとエラー無しでプッシュすることが出来ました。

まとめ

ただリンクするにも意外とやることがあったので、簡単にまとめてみました。

続きを読む

AWS CLI での備忘録

AWS コマンドラインインターフェイスは基本コンソールでGUI操作するって人も知っておくとかなり便利です。
私がよく使うコマンドを備忘録がわりに投稿します。
ちなみに、今は開発者プレビューですが、オートコンプリートとかをしてくれるaws-shellってのも出てます。

基本設定

AWS-Cliのインストール(Mac)

pip install awscli

AWS-CliにはPython 2.6.5 以降が必要です。
pythonが入っていない場合(Macはプリインストールされてるはずなので、ないとは思いますが、、)
Python.org/downloadsから落とすか、下記を実行

python --version  # これで2.6.5以上であればOK
brew install python # homebrew入ってればこれでインストールできる

pipが入っていない場合は、

python get-pip.py

AWS-Cli設定

下記のAccess KeyとSecret Access KeyはIAMの[認証情報] > [アクセスキー]から作成する

$ aws configure
Access Key ID: XXXX
Secret Access Key: XXXX 
region: ap-northeast-1 # 自分が主に使っているリージョンを設定

S3操作

S3でよく使うのは下記

バケット一覧表示

$ aws s3 ls

ローカルとS3とのファイル操作

aws s3 cp . s3://hoge/ --recursive  # localのhoge_localというdirectoryをhogeというバケットに全部アップロードする場合
aws s3 cp s3://hoge/ ./hoge_local --recursive # localのcurrent directoryにhogeというバケットの中身を全部コピーする場合

ローカルとの同期

$ aws s3 sync hoge_local/ s3://hoge/ --delete # localのhoge_localというdirectoryをhogeというバケットを同期

ファイル削除

$ aws s3 rm s3://hoge/ --recursive  # hogeというバケットを削除

続きを読む

AWS Lambda上でOCRして文字の位置を特定したい人生だった。

やりたいこと

  • OCRを使って文字の位置を検出したい
  • そんなに頻繁に使うものじゃないからLambdaで動かしたい
  • Webから使いたい

というわけで、できましたー

文字位置特定 with OCR on AWS Lambda

リポジトリはこちら

tesseractってなに?

  • OCRを行ってくれるソフトウェア
  • Macにはbrewで入る(v3.04)
  • 文字を取得するだけじゃなくて文字の位置をhOCR(html)やtsv形式で出力できる <- 重要

どうやってLambdaで動かすの?

  • StackOverflowを参考に…
  • Lambdaではスタンドアローンなバイナリファイルや.soをちゃんと耳そろえてアップすれば動く
  • subprocess(Pythonのコマンドライン実行ライブラリ)も動く

つまり…!!
tesseractと一緒にアップすればLambdaでOCRが動く!!

ちなみに、AmazonLinux上でビルドしないとPillow(PIL)がELF headerがないとかいう妖精さんの首がもげる現象に立ち会い無事死ねます。

文字列の位置どうやって検出するの?

  • 一般的なOCRでは文字をテキストで返してくれることがほとんど
  • Docを読むとv3.05ではtsv形式がサポートされてるくさい
  • 普通にインスコするとtesseract(v3.04)が入っちゃう
  • v3.05を使うべくStackOverflowのとおりに手でビルドしないといけない

これはつらかった。

というわけでいい加減、どうやって導入したかかきます。

 インストール

全部ec2-userでいいです。

必要なパッケージのインストール

sudo yum install -y gcc gcc-c++ make
sudo yum install -y autoconf aclocal automake
sudo yum install -y libtool
sudo yum install -y libjpeg-devel libpng-devel libtiff-devel zlib-devel
sudo yum install -y git

nvmのインストール

AmazonLinuxではyumでいれたnodeのバージョンが古すぎて色々(後述)つらいのでnvmいれておきます。
とはいえAmazonLinuxじゃないとビルドしたところでLambdaでエラーはいてしまうので頑張りましょう。

$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash
$ source ~/.bashrc 

$ nvm install v6.9.4  
$ nvm alias default v6.9.4  

# バージョンを確認
$ npm -v
$ node -v

Leptonicaのインストール

Leptonica is 画像解析とかやってくれるOSSでtesseract動かすのに必要
ここのバージョンをあげないとtesseractのv3.05も使えない

$ cd ~
$ mkdir leptonica
$ cd leptonica

$ wget http://www.leptonica.com/source/leptonica-1.74.tar.gz

# unzip
$ tar -zxvf leptonica-1.73.tar.gz
$ cd leptonica-1.73

# build
$ ./configure
$ make
$ sudo make install

Tesseractのインストール

まだv3.05はdevなのでリリースに乗ってない == zipが落ちてないのでcloneして頑張ります。

$ cd ~
$ git clone https://github.com/tesseract-ocr/tesseract.git
$ cd tesseract/
$ git checkout -b 3.05 origin/3.05

# initialize
$ ./autogen.sh

# build
$ ./configure
$ make
$ sudo make install

Lambda用にパッケージング

$ cd ~
$ mkdir package
$ cd package

# Copy libraries
$ cp /usr/local/bin/tesseract .
$ mkdir lib
$ cd lib
$ cp /usr/local/lib/libtesseract.so.3 .
$ cp /usr/local/lib/liblept.so.5 .
$ cp /lib64/librt.so.1 .
$ cp /lib64/libz.so.1 .
$ cp /usr/lib64/libpng12.so.0 .
$ cp /usr/lib64/libjpeg.so.62 .
$ cp /usr/lib64/libtiff.so.5 .
$ cp /lib64/libpthread.so.0 .
$ cp /usr/lib64/libstdc++.so.6 .
$ cp /lib64/libm.so.6 .
$ cp /lib64/libgcc_s.so.1 .
$ cp /lib64/libc.so.6 .
$ cp /lib64/ld-linux-x86-64.so.2 .
$ cp /usr/lib64/libjbig.so.2.0 .

# Get trained data
$ cd ..
$ mkdir tessdata
$ cd tessdata
$ wget https://github.com/tesseract-ocr/tessdata/raw/master/eng.traineddata
$ wget https://github.com/tesseract-ocr/tessdata/raw/master/osd.traineddata

# Make config file
$ mkdir configs
$ echo 'tessedit_create_tsv 1' > tsv

$ cd ../..
$ zip -r package.zip package

これでLambdaのパッケージに package を閉じ込めてあげると使えるようになります!

やってみた結果wwwwww

草すみませんでした。

image.png

こんな画像をあげた結果がこれ

level   page_num    block_num   par_num line_num    word_num    left    top width   height  conf    text
1   1   0   0   0   0   0   0   1080    1920    -1  
2   1   1   0   0   0   29  11  1025    50  -1  
3   1   1   1   0   0   29  11  1025    50  -1  
4   1   1   1   1   0   29  11  1025    50  -1  
5   1   1   1   1   1   29  11  548 50  60  GnAflQflAA
5   1   1   1   1   2   640 15  167 43  58  X-IIZII"
5   1   1   1   1   3   899 14  155 44  89  l11:57
2   1   2   0   0   0   0   0   1080    76  -1  
3   1   2   1   0   0   0   0   1080    76  -1  
4   1   2   1   1   0   0   0   1080    76  -1  
5   1   2   1   1   1   0   0   1080    76  95   
2   1   3   0   0   0   192 829 197 66  -1  
3   1   3   1   0   0   192 829 197 66  -1  
4   1   3   1   1   0   192 829 197 66  -1  
5   1   3   1   1   1   192 851 93  44  87  00
5   1   3   1   1   2   336 829 53  66  71  la
2   1   4   0   0   0   122 992 718 109 -1  
3   1   4   1   0   0   122 992 718 109 -1  
4   1   4   1   1   0   122 992 718 47  -1  
5   1   4   1   1   1   122 995 88  44  89  Sign
5   1   4   1   1   2   229 995 31  34  94  in
5   1   4   1   1   3   276 997 40  32  86  to
5   1   4   1   1   4   332 997 64  42  89  get
5   1   4   1   1   5   410 993 66  36  86  the
5   1   4   1   1   6   493 997 104 32  84  most
5   1   4   1   1   7   613 997 66  32  86  out
5   1   4   1   1   8   695 992 41  37  91  of
5   1   4   1   1   9   749 1003    91  36  93  your
4   1   4   1   2   0   122 1065    144 36  -1  
5   1   4   1   2   1   122 1065    144 36  87  device.
2   1   5   0   0   0   124 1269    312 46  -1  
3   1   5   1   0   0   124 1269    312 46  -1  
4   1   5   1   1   0   124 1269    312 46  -1  
5   1   5   1   1   1   124 1269    111 36  87  Email
5   1   5   1   1   2   253 1279    40  26  92  or
5   1   5   1   1   3   310 1269    126 46  89  phone

ソースはこんなん

import requirements

from PIL import Image
import sys
import pyocr
import pyocr.builders

import urllib
import os
import subprocess
import base64
import json
import boto3

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
LIB_DIR = os.path.join(SCRIPT_DIR, 'lib')
LANG_DIR = os.path.join(SCRIPT_DIR, 'tessdata')

def response(code, body):
    return {
        'statusCode': code,
        'headers': {
            'Access-Control-Allow-Origin': '*',
        },
        'body': json.dumps(body),
    }

def handler(event, context):
    # Get the bucket and object from the event
    try:
        tools = pyocr.get_available_tools()
        if len(tools) == 0:
            print("No OCR tool found")
            sys.exit(1)
        tool = tools[0]
        print("Will use tool '%s'" % (tool.get_name()))

        request = event['body']

        result_filepath = '/tmp/result'
        img_filepath = '/tmp/image.png'
        with open(img_filepath, 'wb') as fh:
            fh.write(base64.decodestring(request['template']))

        command = 'LD_LIBRARY={} TESSDATA_PREFIX={} {}/tesseract {} {} -l eng --oem 0  tsv'.format(
            LIB_DIR,
            SCRIPT_DIR,
            SCRIPT_DIR,
            img_filepath,
            result_filepath
        )
        print command

        try:
            output = subprocess.check_output(
                command,
                shell=True,
                stderr=subprocess.STDOUT
            )
            print(output)

            with open(result_filepath + '.tsv', 'rb') as fh:
                print(fh.read())
        except subprocess.CalledProcessError as e:
            return "except:: " + e.output

    except Exception as e:
        print(e)
        raise e

あとはGitHub上のserverless.ymlなり何なりを書き換えてご自由にお使いくださいませー。

続きを読む

Docker+Grafanaでアカウントを横断してCloudWatchを可視化する

ちょっとしたモニタリングだったらCloudWatchでも十分。
ただ、普段コマンドラインツールで操作していることもあるし、複数アカウントを持っていたりするのでマネージメントコンソールだと使い勝手が悪い。
そんな悩みをGrafanaが解決してくれたので自分用にメモメモ。

必要なもの

  • AWSのIAM User
  • aws-cli
  • Docker for Mac(Docker Machineでも可)

credentialsの登録

自分が普段使っているMacでは、aws-cliを使ってprofileをいくつも登録してある。
登録するときはこんな感じ。
profile名は適宜変更すること。
すでに作成済みの場合は実施不要。

$ aws configure --profile hogehoge
AWS Access Key ID [None]: aaaaa
AWS Secret Access Key [None]: bbbbb
Default region name [None]:
Default output format [None]:

すると、以下の感じで必要な情報が登録されているはず。

$ cat ~/.aws/credentials
[hogehoge]
aws_access_key_id = aaaaa
aws_secret_access_key = bbbbb

credentialの取り扱いには気をつけること!

DockerでGrafanaを起動

上記で作成したcredentialsを-vオプションでGrafanaコンテナに渡す。
公式イメージあるので捗る。
Grafanaは3000ポートでListenしているのでそれもあわせてマッピング。

$ docker run -d -p 3000:3000 -v ~/.aws/credentials:/usr/share/grafana/.aws/credentials --name grafana grafana/grafana
3d7de10094f1d84dbedd8a77fb55ef5c997ccdde31722a114bcd25388b1a8b3d

起動した。

Grafanaにデータを追加

接続してみる。

$ open http://localhost:3000

screencapture-localhost-3000-login-1484041461957.png

デフォルトのログインID/PWはadmin/admin
ログインするとこんな感じ。
Kobito.cKv8Tt.png
なんか前見たときよりUIがよくなってるかも。
ちょっと目立つ感じになってるAdd data sourceボタンを押す。

Kobito.b6Dvv3.png
こんな画面になる。
Nameには任意のData Sourceの名前をつけてる。
TypeのプルダウンからCloudWatchを選択。
Auth ProviderはCredentials file以外にもAccess & secret keyやARNが選択できるが、変更せずにCredentials fileを指定する。
Default Regionは適宜選択すること。
Custom Metrics namespaceはなにかあれば入力するが、とりあえず空のままでOK。
左下のAddボタンを押して、Successと表示されれば登録できてるっぽい。

Kobito.KIPEF2.png
こんな感じで登録できた。

あとはdashboardでポチポチグラフを追加していい感じの画面を作ればOK。
Kobito.TV43uj.png


Dockerで起動しているのでこのままだとデータの永続化とかはできてないけど、とりあえず簡単に起動できて便利。

続きを読む

macOSにPowerShellをインストール、ついでに外部パッケージ(AWSPowershell.NetCore)もインストール

普段、職場やプライベートでAWSを利用する場合、Windowsマシンでaws-cliではなくAWSPowerShell(aws-cliのPowerShell版)を利用しています。 自宅のブレーカーが落ちてWindowsマシンが逝ってしまったため、やむを得ず サブ機のMacBookでも同じ環境でAWSを使えたらいいな、と思い、OSS/クロスプラットフォーム化したPowerShellおよびその上で稼働するAWSPowerShell.NetCoreをmacOSに入れてみました。以下、環境構築時の作業メモです。

前提環境

  • macOS Sierra
  • homebrewインストール済
  • homebrew-caskインストール済

環境構築手順

openssl & curl (by homebrew) インストール

macOSに同梱されているopensslはApple社独自開発のもので、一般的なLinuxディストリビューション等で利用されているopensslとは別物のようです。PowerShellは後者の方が相性がいいようなので、homebrewで後者に相当するものをインストールします。

wukann@mac ~$ brew install openssl
wukann@mac ~$ brew install curl --with-openssl

.NET Core requires Homebrew’s OpenSSL because the “OpenSSL” system libraries on macOS are not OpenSSL, as Apple deprecated OpenSSL in favor of their own libraries. This requirement is not a hard requirement for all of PowerShell; however, most networking functions (such as Invoke-WebRequest) do require OpenSSL to work properly.

蛇足:AppleとOpenSSL

AppleがOpenSSLを利用しなくなった経緯についてはこちら↓を参照。

PowerShellインストール

macOS向けのインストーラもあるようですが、今回はhomebrew-caskを利用します。

PowerShellインストール
wukann@mac ~$ brew cask install powershell
==> Caveats
A OpenSSL-backed libcurl is required for custom handling of certificates.
This is rarely needed, but you can install it with
  brew install curl --with-openssl
See https://github.com/PowerShell/PowerShell/issues/2211

==> Satisfying dependencies
==> Installing Formula dependencies from Homebrew
openssl ... already installed
complete
==> Downloading https://github.com/PowerShell/PowerShell/releases/download/v6.0.0-alpha.14/powershell-6.0.0-alpha.14.pkg
######################################################################## 100.0%
==> Verifying checksum for Cask powershell
==> Running installer for powershell; your password may be necessary.
==> Package installers may write to any location; options such as --appdir are ignored.
Password:
==> installer: Package name is powershell-6.0.0-alpha.14
==> installer: Installing at base path /
==> installer: The install was successful.
🍺  powershell was successfully installed!

一応、インストールされていることを確認。

PowerShellインストール確認
wukann@mac ~$ which powershell
/usr/local/bin/powershell

AWSPowershell.NetCoreインストール

PowerShellにもパッケージ(モジュール)管理機能「PowerShellGet」があります。今回インストールしたPowerShell v6には最初から入っているようです。これを利用してAWSPowerShell.NetCoreをインストールします。

PowerShellセッション起動

ここからはmacOSのshellセッションからPowerShellセッションを起動し、その上でPowerShellコマンド操作をします。

PowerShellセッション起動
wukann@mac ~$ powershell
PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.

PS /Users/wukann>

PowerShellリポジトリ設定(PSGallery)

PowerShellGetでモジュールをインストールする場合、事前にモジュールを公開しているリポジトリを登録する必要があります。今回インストールするAWSPowerShell.NetCoreは、Microsoft公式のPowerShell Gallery(PSGallery)で公開されています。
登録済みリポジトリの情報はGet-PSRepositoryコマンドで取得できます。

登録済みPowerShellリポジトリ確認
PS /Users/wukann> Get-PSRepository

Name                      InstallationPolicy   SourceLocation
----                      ------------------   --------------
PSGallery                 Untrusted            https://www.powershellgallery.com/api/v2/

PowerShell Gallery(PSGallery)は最初から登録されていますが、InstallationPolicyUntrustedに設定されています。このままでもPSGalleryからモジュールをインストールできますが、インストールの度に「信頼できなリポジトリからモジュールをインストールしますか?」という確認メッセージにY/N対応する必要があります。
今回はPSGalleryを「信頼済みのリポジトリ」として設定します。

PSGalleryを信頼済みリポジトリに設定
PS /Users/wukann> Set-PSRepository -Name PSGallery -InstallationPolicy Trusted

設定が反映されていることを確認。

PSGallery設定確認
PS /Users/wukann> Get-PSRepository

Name                      InstallationPolicy   SourceLocation
----                      ------------------   --------------
PSGallery                 Trusted              https://www.powershellgallery.com/api/v2/

AWSPowershell.NetCoreインストール

リポジトリの設定が済んだところで、Install-ModuleコマンドでAWSPowerShell.NetCoreをインストールします。

AWSPowerShell.NetCoreインストール
PS /Users/wukann> Install-Module -Name AWSPowerShell.NetCore -Scope CurrentUser

念のため、Get-InstalledModuleコマンドでインストール済みモジュールを確認。

インストール済みモジュールの確認
PS /Users/wukann> Get-InstalledModule

Version    Name                                Repository           Description
-------    ----                                ----------           -----------
1.1.2.0    PackageManagement                   https://powershel... PackageManagement (a.k.a. OneGet) is a new way to discover and in...
1.1.2.0    PowerShellGet                       https://powershel... PowerShell module with commands for discovering, installing, upda...
3.3.38.0   AWSPowerShell.NetCore               PSGallery            The AWS Tools for PowerShell Core lets developers and administrat...


補足・-Scopeオプションなし or -Scope AllUsersを指定した場合

今回、Install-Moduleコマンドに-Scope CurrentUserオプションを付けてモジュールをインストールしました。このオプションがない場合、-Scope AllUsersがデフォルトで指定されます。んで、そうするとこの↓ようにエラーとなります。

-ScopeをCurrentUserにしないで実行した場合
PS /Users/wukann> Install-Module -Name AWSPowerShell.NetCore -Scope AllUsers
PackageManagement\Install-Package : Administrator rights are required to install modules in '/usr/local/microsoft/powershell/6.0.0-alpha
.14/Modules'. Log on to the computer with an account that has Administrator rights, and then try again, or install '/Users/wukann/.local
/share/powershell/Modules' by adding "-Scope CurrentUser" to your command. You can also try running the Windows PowerShell session with
elevated rights (Run as Administrator).
At /usr/local/microsoft/powershell/6.0.0-alpha.14/Modules/PowerShellGet/1.1.2.0/PSModule.psm1:1809 char:21
+ ...          $null = PackageManagement\Install-Package @PSBoundParameters
+                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (Microsoft.Power....InstallPackage:InstallPackage) [Install-Package], Exception

エラーメッセージを見る限りではPowerShellをsudoで起動すれば解決する気がしますが、「ここまでsudo無しで進めてこられたのにここだけsudoするのもなぁ…」ということで試していません。

AWSPowershell.NetCoreインポート

Notice:ここで取り上げているモジュールのインポート(Import-Module)は、そのセッション内でのみ有効です。powershellセッションを立ち上げ直した場合、再度インポートし直す必要があります。
(この件に関する対処方法もいつか書ければ…)

ここまでの手順でAWSPowershell.NetCoreをインストールできましたが、この状態ではコマンドを利用できません。PowerShellセッションにモジュールが読み込まれていないためです。セッションに読み込まれ、利用可能なモジュールを確認するには、Get-Moduleコマンドを実行します。

利用可能モジュール確認
PS /Users/wukann> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty...}
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     1.1.2.0    PackageManagement                   {Find-Package, Find-PackageProvider, Get-Package, Get-PackageProvider...}
Script     1.1.2.0    PowerShellGet                       {Find-Command, Find-DscResource, Find-Module, Find-RoleCapability...}
Script     1.2        PSReadLine                          {Get-PSReadlineKeyHandler, Get-PSReadlineOption, Remove-PSReadlineKeyHandle...

AWSPowershell.NetCoreが一覧になく、セッションに読み込まれていないことが確認できます。
モジュールをセッションに読み込むには、Import-Moduleを実行します。

AWSPowerShell.NetCoreをPowerShellセッションに読み込む
PS /Users/wukann> Import-Module AWSPowerShell.NetCore

再度Get-Moduleコマンドを実行すると、AWSPowerShell.NetCoreがセッションに読み込まれたことが確認できます。

Get-Module
PS /Users/wukann> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Binary     3.3.38.0   AWSPowerShell.NetCore               {Add-AASScalableTarget, Add-ACMCertificateTag, Add-ADSConfigurationItemsToA...
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty...}
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Script     1.1.2.0    PackageManagement                   {Find-Package, Find-PackageProvider, Get-Package, Get-PackageProvider...}
Script     1.1.2.0    PowerShellGet                       {Find-Command, Find-DscResource, Find-Module, Find-RoleCapability...}
Script     1.2        PSReadLine                          {Get-PSReadlineKeyHandler, Get-PSReadlineOption, Remove-PSReadlineKeyHandle...

実際にAWSPowerShell.NetCoreのコマンド(Get-AWSPowerShellVersion)を実行してみます。

AWSPowerShell.NetCoreのコマンド実行
PS /Users/wukann> Get-AWSPowerShellVersion

AWS Tools for PowerShell Core
Version 3.3.38.0
Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Amazon Web Services SDK for .NET
Core Runtime Version 3.3.7.1
Copyright 2009-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Release notes: https://aws.amazon.com/releasenotes/PowerShell

This software includes third party software subject to the following copyrights:
- Logging from log4net, Apache License
[http://logging.apache.org/log4net/license.html]

ヨッシャ(*´ω`*)

続きを読む

OpsWorks管理下のAmazon LinuxをCLIでアップグレードする

はじめに

何かにつけ、GUIが苦手です。WEBブラウザを開くと、トンデモなバナーをクリックしてしまうし、そもそもトンデモなバナーが出来てきてしまうネットワーク広告が怖い。
OpsWorks(AWSマネジメントコンソール)では、広告は表示されないのですが、いつか広告モデルになるかもしれない…
そんな不安から日々のオペレーションは、awscliを用いたCLIで完結したいというのがモチベーションです。
今回は、OpsWorksで唯一GUIなオペレーション(awscliにサブコマンドが用意されていない)となるUpgrade Operating SystemをCLIで実施するコネタを紹介します。

バージョン

動作を確認している環境とそのバージョンは、以下の通りです。

  • OpsWorks(リモート環境)

    • Cehf 11.10
    • Berkshelf 3.2.0
    • Amazon Linux 2016.03 → 2016.09
  • Mac(ローカル環境)
    • aws-cli 1.11.28 Python/2.7.10 Darwin/15.6.0 botocore/1.4.85

Custom JSONの準備

下ごしらえとして、OpsWorksに渡すattributeをCustom JSONとしてJSONフォーマットのファイルにまとめておきます。
OpsWorksのビルドインcookbookであるdependenciesのattributeを上書きします。詳細は、後述します。

$ mkdir ./aws/opsworks && vi $_/upgrade-amazonlinux.json

{
  "dependencies": {
    "os_release_version": "2016.09",
    "allow_reboot": false,
    "upgrade_debs": true
  }
}

コマンド

CLIでAmazon Linuxをアップグレードしていきます。

幸せなchefになるために、独自の味付けをしない、つまり可能な限りビルドインのcookbookを利用するべきです。
Upgrade Operating Systemで実施しているのは、update_dependenciesというdeployになり、dependencies::updateレシピを実行しています。該当のレシピを一読すると、yum -y updateコマンドを実行していました。前述のCustom JSONは、yum -y updateするために必要なattributeとなります。

  • os_release_versionは、アップグレードしたいAmazon Linuxのバージョンを指定します。
  • allow_reboot は、パッケージのアップデートの後に再起動するか指定します。今回は、インスタンスの停止を明示的に実施しますので、falseとしておきます。
  • upgrade_debsは、一見Debianぽいですがパッケージをアップデートするか否かのフラグとして実装されてます。今回は、アップデートするのでtrueとしておきます。

Upgrade Operating Systemの正体を把握できたので、awscliで以下のような一連コマンドを実行していきます。

# 1. Stackのリビジョンを指定
$ aws opsworks --region us-east-1 update-stack --stack-id STACK_ID --custom-cookbooks-source "{"Revision":"UgradeAmazonLinux"}"

# 2. Stackで管理している全EC2インスタンスに対して、update_custom_cookbooksの実行(最新版cookbookを配置)
$ aws opsworks --region us-east-1 create-deployment --stack-id STACK_ID --command "{"Name":"update_custom_cookbooks"}"

# 3. opsworks agentのバージョンアップ(最新版を利用する)
$ aws opsworks --region us-east-1 update-stack --stack-id STACK_ID --agent-version LATEST

# 4. Custom JSONとレシピを指定して、全パッケージをアップデート
$ aws opsworks --region us-east-1 create-deployment --stack-id STACK_ID --instance-ids INSTANCE_ID01 INSTANCE_ID02 --command "{"Name":"execute_recipes","Args":{"recipes":["dependencies::update"]}}" --custom-json file://./aws/opsworks/upgrade-amazonlinux.json

# 5. EC2インスタンスの停止
$ aws opsworks --region us-east-1 stop-instance --instance-id INSTANCE_ID01
$ aws opsworks --region us-east-1 stop-instance --instance-id INSTANCE_ID02

# 6. OpsWorksで保持しているOSのバージョン情報を更新
$ aws opsworks --region us-east-1 update-instance --instance-id INSTANCE_ID01 --os "Amazon Linux 2016.09"

# 7. EC2インスタンスの起動
$ aws opsworks --region us-east-1 start-instance --instance-id INSTANCE_ID01
$ aws opsworks --region us-east-1 start-instance --instance-id INSTANCE_ID02

4でビルドインのcookbookにCustom JSONでattributeを渡し、全パッケージのアップデートを実施します。
5でEC2インスタンスを停止するのは、以下の2つの理由があります。

  • OpsWorksが保持しているEC2インスタンスの情報を更新するためには、該当のEC2インスタンスを停止する必要がある
  • OSアップグレード後は、setupライフサイクルイベントを実施することを推奨されている

setup ライフサイクルイベントは、7の起動時に実行されます。

おわりに

AWSが広告モデルになったら嫌ですね。
Enjoy CLI!

参考

続きを読む

起動中のEC2インスタンスの名前一覧を取得するワンライナー

よく忘れる:frowning2:のでメモ。手元のmacで実行してます。

$ aws ec2 describe-instances --profile dev --filter Name=instance-state-code,Values=16 | jq -r ".Reservations[].Instances[].Tags | map(select(.Key == "Name")) | .[].Value | sort"
db1
db2
web1
web2
:

instance-state-codeやtagの取得名を変えれば、停止中のインスタンス一覧特定のタグ名一覧を取得することもできます。ユニークな値が欲しい場合は、uniqコマンドにパイプするだけです。

留意点として

  • --profileの値は適宜読み替えてください
  • 指定するprofileには、予めEC2の読み取り権限を付けておいてください
  • awsclijqコマンドを使うので、無かったらインスールしてください。
    (sortも使いますが、たいていのディストリビューションであればインストールされていると思われます)

各コマンドのバージョンは以下になります。

$ aws --version
aws-cli/1.11.34 Python/2.7.13 Darwin/15.6.0 botocore/1.4.91
$ jq --version
jq-1.5

参考

AWS CLI のインストールと設定
http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html

続きを読む

Amazon EC2 VPCのIPv6対応 インスタンスからのIPv6アドレス通信

やったこととサマリ

構築した環境と疎通を試したIPv6通信

オハイオリージョンの同一サブネット内に ubuntu 16.04 LTS のインスタンスを2つ立てて、下記のIPv6通信をしてみた。

  1. 同一サブネット内のインスタンス間の直接IPv6通信

    • グローバルユニキャストアドレス経由
    • リンクローカルユニキャストアドレス経由
  2. All Node Address (ff02::1) リンクローカルマルチキャストアドレスあての通信
  3. stateful DHCPv6に頼らず勝手IPv6アドレスをインスタンスに付与しての通信

サマリ

  • インスタンス間の直接IPv6通信はグローバルアドレス, リンクローカルアドレスともに制限なくできた。
  • All Node Address (ff02::1) へのping6 (ICMP echo request送信) で近隣ノード(デフォルトルータを含む)を見つけられない。
  • 勝手にIPv6アドレスを割り当てても使えずAWSのインフラが割り当てたIPv6アドレスだけしか使えない。現時点(2017.1.15)ではVPN用途でユーザが自前のグローバルIPv6アドレスを持ち込んだり、プライベートIPv4アドレスの感覚で、ユニークローカルIPv6アドレス(ULA)を付けられない様子。

構成図

VPCの同一サブネット内にインスタンスを2つ立てた。

                                             +---------+
                                             |    GW   |
                                             +----+----+
                                                  |RA fe80::4fd:d1ff:fec8:f9cf
                                                  |↓
   2001:1f16:XXXX:YYYY::/64([P1]と表記)            |
   --+------------------------------------+-------+--------
     |                               |
     |     [P1]:f557:112e:f9bd:c7f3  |     [P1]:d326:143a:2015:79fa
     |eth0 fe80::4df:a5ff:fe6c:5d57  |eth0 fe80::4f0:13ff:feeb:c61d
+----+----+                     +----+----+
| ubuntu1 |                     | ubuntu2 |
+---------+                     +---------+

インスタンス間の直接IPv6通信

ubuntu1 to ubuntu2 (グローバルユニキャストアドレス)

OK

ubuntu1# ping6 2600:1f16:XXXX:YYYY:d326:143a:2015:79fa
PING 2600:1f16:8df:XXXX:YYYY:112e:f9bd:c7f3(2600:1f16:XXXX:YYYY:f557:112e:f9bd:c7f3) 56 data bytes
64 bytes from 2600:1f16:XXXX:YYYY:f557:112e:f9bd:c7f3: icmp_seq=1 ttl=64 time=0.523 ms
64 bytes from 2600:1f16:XXXX:YYYY:f557:112e:f9bd:c7f3: icmp_seq=2 ttl=64 time=0.603 ms
^C

ubuntu1 to ubutu2 (リンクローカルユニキャストアドレス)

OK

ubuntu1# ping6 fe80::4f0:13ff:feeb:c61d%eth0
PING fe80::4f0:13ff:feeb:c61d%eth0(fe80::4f0:13ff:feeb:c61d) 56 data bytes
64 bytes from fe80::4f0:13ff:feeb:c61d: icmp_seq=1 ttl=64 time=0.466 ms
64 bytes from fe80::4f0:13ff:feeb:c61d: icmp_seq=2 ttl=64 time=0.553 ms
^C

ubuntu1 to All Nodes Address (リンクローカルマルチキャスト)

ubuntu1# ping6 ff02::1%eth0
64 bytes from fe80::4df:a5ff:fe6c:5d57: icmp_seq=1 ttl=64 time=0.024 ms
64 bytes from fe80::4df:a5ff:fe6c:5d57: icmp_seq=2 ttl=64 time=0.032 ms

同一リンク内にいるはずの、ubuntu2からもデフォルトルータからECHO replyは来ず、自分自身からのみ返事がくる。ubuntu2側のeth0を見ていてもECHO requestが来ないので、インスタンス間にある仮想スイッチで止められている動きだった。

ubunut1の近隣キャッシュを見ると

ubuntu1# ip -6 nei
fe80::4f0:13ff:feeb:c61d dev eth0 lladdr 06:f0:13:eb:c6:1d STALE
fe80::4fd:d1ff:fec8:f9cf dev eth0 lladdr 06:fd:d1:c8:f9:cf router STALE

ICMP ECHO requst/reply は疎通しないもののの、ubuntu2,デフォルトルータいずれも近隣探索は成功しておりMACアドレスの解決はできている。仮想スイッチは近隣探索は通している。

RAで通知されたデフォルトルータへのアクセス

ubuntu1# ip -6 route
fe80::/64 dev eth0  proto kernel  metric 256  pref medium
default via fe80::4fd:d1ff:fec8:f9cf dev eth0  proto ra  metric 1024  expires 1799sec hoplimit 64 pref medium

ubuntu1# ping6 fe80::4fd:d1ff:fec8:f9cf%eth0
^C

リンクローカルユニキャストアドレスでデフォルトルータへICMP ECHO requstを飛ばしても返事なし。

インスタンスに勝手IPv6アドレスをつける

prefix::1 (グローバルユニキャストアドレス)をつける

stateful DHCPv6で割り当てられるIPv6アドレス(マネージメントコンソールで確認できるIPv6アドレス)ではないアドレスを手動でつけて通信を試みる。

ubuntu1 to Internet (インスタンス to Internet)

ubuntu1# ip -6 addr add 2001:1f16:XXXX:YYYY::1/64 dev eth0

DADの重複検知がないことを確認して

# ping6 ipv6.google.com
PING ipv6.google.com(2607:f8b0:4001:c09::71) 56 data bytes
^C

結果: IPv6インターネットへの通信不可

ubuntu1 to ubuntu2 (インスタンス同士)

ubuntu1# ping6 2600:1f16:XXXX:YYYY:d326:143a:2015:79fa
PING 2600:1f16:XXXX:YYYY:d326:143a:2015:79fa(2600:1f16:XXXX:YYYY:d326:143a:2015:79fa) 56 data bytes
^C

近隣要請に対して近隣通知が返ってこず近隣探索に失敗している。

ubuntu1# ip -6 nei
2600:1f16:XXXX:YYYY:d326:143a:2015:79fa dev eth0  INCOMPLETE

結果: 通信不可

管理されているアドレスに近いグローバルユニキャストアドレスをつける

DHCPv6で取れるアドレス (2600:1f16:XXXX:YYYY:f557:112e:f9bd:c7f3) + 1 をつける

ubuntu1# ip -6 addr add 2600:1f16:XXXX:YYYY:f557:112e:f9bd:c7f4/64 dev eth0

ubuntu1 to Internet

ubuntu1# ping6 ipv6.google.com
PING ipv6.google.com(in-in-x8a.1e100.net) 56 data bytes
^C

結果: 通信不可

ubuntu1 to ubuntu2

ubuntu1# ping6 2600:1f16:XXXX:YYYY:d326:143a:2015:79fa
PING 2600:1f16:XXXX:YYYY:d326:143a:2015:79fa(2600:1f16:XXXX:YYYY:d326:143a:2015:79fa) 56 data bytes
From 2600:1f16:XXXX:YYYY:f557:112e:f9bd:c7f4 icmp_seq=1 Destination unreachable: Address unreachable
From 2600:1f16:XXXX:YYYY:f557:112e:f9bd:c7f4 icmp_seq=2 Destination unreachable: Address unreachable
^C

結果: 通信不可

グローバルユニキャストアドレス(ULAを含む)はユーザが勝手持込IPv6アドレスを付けられない様子。

リンクローカルユニキャストアドレス

ubuntu1 のリンクローカルアドレスとして手動で fe80::1234 を付ける

ubuntu1# ip addr del fe80::4df:a5ff:fe6c:5d57/64 dev eth0
ubuntu1# ip addr add fe80::1234/64 dev eth0

ubuntu2のリンクローカルアドレスへICMP ECHO requestを飛ばすが返事はない。ubuntu2の近隣探索にも失敗している。

ubuntu1# ping6 fe80::4f0:13ff:feeb:c61d%eth0
PING fe80::4f0:13ff:feeb:c61d%eth0(fe80::4f0:13ff:feeb:c61d) 56 data bytes
From fe80::1234 icmp_seq=1 Destination unreachable: Address unreachable
From fe80::1234 icmp_seq=2 Destination unreachable: Address unreachable
^C

ubuntu1# ip -6 nei
fe80::4f0:13ff:feeb:c61d dev eth0  INCOMPLETE

リンクローカルアドレスも勝手アドレスを付けらず、インフラ(仮想スイッチ)がアドレス(/128)単位でアクセス制限をしているようである。個々のインスタンスを管理するためにstateful DHCPv6を使うのが合理的であるし、ネットワークも割り当てたIPv6アドレスでない勝手IPv6アドレスによる通信を抑止しているようだ。

関連記事

■ Amazon EC2 VPCのIPv6対応 インスタンスへのIPv6アドレス付与は m-flagつきRA + stateful DHCPv6
http://qiita.com/ip6/items/5c307af204ea83097755

続きを読む

無料で使えるSSL – 「Let’s Encrypt」をh2oに設定してhttp2.0に対応してみた

2014年11月にElectronic Frontier Foundation、Mozilla、Cisco Systems、ミシガン大学などが共同で立ち上げた「Let’s Encrypt」。最近では、GoogleがSSLを推奨しており、サイトをSSL対応しておかないと検索順位に影響すると言われています。そんな中、Let’s Encryptは無料で使えるということもあり、導入しているサイトも増えてきています。個人でSSLを導入してhttp2.0対応するにはちょうど良いですね。

ここでは、「Let’s Encrypt」をインストール&h2oに設定してhttp2.0に対応させる方法を説明します。

インストールに使用した環境

Amazon Linux AMI release 2016.09
h2o 2.1.0

h2oがインストールされており、80番ポート、443番ポートともに通信可能になっていることが前提となります。ファイアウォールで80、443が遮断されているとインストールできませんのでご注意下さい。

インストール手順

ソースコード取得

Let’s Encryptのソースコードをgithubのリポジトリから取得してきます。
以下の例では、ホームディレクトリにcloneしていますが、場所はどこでもかまいません。

cd ~
git clone https://github.com/letsencrypt/letsencrypt

インストール

letsencrypt-autoというコマンドが用意されているのでこれを使用します。
必要なパッケージ類を一通りインストールしてくれます。
rootユーザーで実行する必要がありますので、sudoをつけましょう。

cd ./letsencrypt
sudo ./letsencrypt-auto --debug --help

実行中に
「Installing Python packages…」でしばらく止まります。少し待ちましょう。。
以下のようなメッセージが表示されたらインストール完了です。

Installation succeeded.

  letsencrypt-auto [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ...

Certbot can obtain and install HTTPS/TLS/SSL certificates.  By default,
it will attempt to use a webserver both for obtaining and installing the
cert. The most common SUBCOMMANDS and flags are:

obtain, install, and renew certificates:
    (default) run   Obtain & install a cert in your current webserver
    certonly        Obtain or renew a cert, but do not install it
    renew           Renew all previously obtained certs that are near expiry
   -d DOMAINS       Comma-separated list of domains to obtain a cert for

  --apache          Use the Apache plugin for authentication & installation
  --standalone      Run a standalone webserver for authentication
  --nginx           Use the Nginx plugin for authentication & installation
  --webroot         Place files in a server's webroot folder for authentication
  --manual          Obtain certs interactively, or using shell script hooks

   -n               Run non-interactively
  --test-cert       Obtain a test cert from a staging server
  --dry-run         Test "renew" or "certonly" without saving any certs to disk

manage certificates:
    certificates    Display information about certs you have from Certbot
    revoke          Revoke a certificate (supply --cert-path)
    delete          Delete a certificate

manage your account with Let's Encrypt:
    register        Create a Let's Encrypt ACME account
  --agree-tos       Agree to the ACME server's Subscriber Agreement
   -m EMAIL         Email address for important account notifications

More detailed help:

  -h, --help [TOPIC]    print this message, or detailed help on a topic;
                        the available TOPICS are:

   all, automation, commands, paths, security, testing, or any of the
   subcommands or plugins (certonly, renew, install, register, nginx,
   apache, standalone, webroot, etc.)

証明書発行

次に、letsencrypt-autoコマンドを使って証明書の発行を行います。
パラメータに、h2o.confで設定されているホームディレクトリ、ドメイン名(FQDN)、管理者のメールアドレスを指定します。

sudo ./letsencrypt-auto certonly _
  --webroot -w [h2oホームディレクトリのパス] _
  -d [ドメイン名(FQDN)] _
  -m [管理者のメールアドレス] _
  --agree-tos

コマンドを実行すると、以下のディレクトリに証明書とキーファイルが作成されます。

/etc/letsencrypt/live/[ドメイン名]/fullchain.pem
/etc/letsencrypt/live/[ドメイン名]/privkey.pem

h2o.confの設定

作成された証明書をh2o.confに設定します。
併せてhttpでアクセスがあった場合に自動的にhttpsに301リダイレクトする設定にします。

pid-file: /etc/h2o/pid-file
user: root
access-log: /var/log/h2o/access-log
error-log: /var/log/h2o/error-log
file.index: [ 'index.php', 'index.html' ]

listen: 80
listen:
  port: 443
  ssl:
        # 作成した証明書ファイルを設定
    certificate-file: /etc/letsencrypt/live/[ドメイン名]/fullchain.pem
    key-file:  /etc/letsencrypt/live/[ドメイン名]/privkey.pem

hosts:
    # httpでアクセスがあった場合、httpsに301リダイレクトする
  "[ドメイン名]:80":
    paths:
      "/":
        redirect:
          url: https://[ドメイン名]/
          status: 301

    # httpsでアクセスがあった場合はホームディレクトリへ
  "[ドメイン名]:443":
    paths:
      "/":
        file.dir: [ホームディレクトリ]

h2o.confのテスト

設定ファイルに問題が無いかチェックします。

sudo service h2o configtest

証明書を設定してconfigtestを行うと、証明書ファイルのチェックもしてくれます。
結果の中に以下が表示されていれば、正しく証明書が発行されています。

... 略

/etc/letsencrypt/live/[ドメイン名]/fullchain.pem: good

... 略

/etc/letsencrypt/live/[ドメイン名]/fullchain.pem: good

... 略

configuration OK
                                                           [  OK  ]

h2o再起動

configtestに成功したらh2oを再起動しましょう。

sudo service h2o restart

動作確認

ブラウザからhttpsでアクセスして動作を確認します。
以下のように「保護された通信」と緑色で表示されればOKです。

スクリーンショット 2017-01-15 23.13.59.png

また、httpでアクセスすると、自動的にhttpsにリダイレクトされるかもチェックしておきましょう。

併せてアクセスログを見て、http2.0通信になっているか確認します。

XXX.XXX.XXX.XXX - - [15/Jan/2017:23:19:48 +0900] "GET / HTTP/2" 200 43306 "" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36"

http2.0で通信されていれば、アクセスログに「HTTP/2」と表示されます。

まとめ

Let’s Encryptを使うことで、コストをかけること無くSSL通信に対応することが出来ます。また、h2o等のサーバに設定することによってhttp2.0にも対応することが出来るのでとても便利です。是非一度お試し下さい。

最後に注意点

Let’s Encryptは他の証明書とは異なり、3ヶ月に1回更新が必要となります。
無料で使える代わりに管理者の所在確認をまめに行う必要があると言ったところでしょうか。。

しかし3ヶ月に1回更新する手間を考えても、無料で使えるというのは大きなメリットだと思います。

続きを読む