【CPUの脆弱性対応】古いAmazon Linuxのkernelを最新版にアップデートする

AWSで管理しているAmazon Linuxが古いバージョンのまま放置していることありませんか?

CPUの脆弱性対応におけるAWSの公式ドキュメント

Customers with existing Amazon Linux AMI instances should run the following command to ensure they receive the updated package: sudo yum update kernel.

カーネルをアップデートして最新のカーネルにするように書いてあるのですが、
Amazon Linuxのバージョンが古いインスタンスでは、
単にカーネルのアップデートだけでは、最新のカーネルにアップデートされません。

この記事ではその際の対応手順を説明します。

※ 説明のためにコミュニティAMIにある古いAMIを使って進めます。

対象のマシンにsshし、インフォメーションをチェック

しばらくOSをアップデートされていないインスタンスにsshします。
OSが更新されていない場合は、以下のように

$ ssh hogehost

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2016.03-release-notes/
Amazon Linux version 2017.09 is available.

Amazon Linux version 2017.09 is available.
Amazon Linux version 2017.09が利用できます

と表示されていますね。
あまり意識しないと見逃しがちですが、このような情報もしっかり確認しましょう。

さらにカーネルのバージョンを確認します。

$ uname -srv
Linux 4.4.5-15.26.amzn1.x86_64 #1 SMP Wed Mar 16 17:15:34 UTC 2016

カーネルも2016年に作られたバージョンのままになっていますね。

yum.confをチェックし、AMIを特定のバージョンに固定されていないか確認する

AMIを特定のバージョンに固定するにはどうすればよいですか?

上記の公式ドキュメントに書かれているようにAmazon Linuxのマシーンイメージでは、1つのバージョンから次のバージョンへ連続的な更新を提供するように設定されていますが、過去のバージョンでは/etc/yum.confreleasever変数がなかったり、リリースバージョンが固定されていることがあります。

その場合は単にyum updateだけでは最新のパッケージに更新されません。

今回対象のyum.confを見てみると

$ cat /etc/yum.conf
[main]
cachedir=/var/cache/yum/$basearch/$releasever
keepcache=0
debuglevel=2
logfile=/var/log/yum.log
distroverpkg=system-release
exactarch=1
obsoletes=1
gpgcheck=1
plugins=1
installonly_limit=3
deltarpm=0

# by default the yum configuration will point to the latest release
# of Amazon Linux AMI. If you prefer not to automatically move to
# new releases, comment out this line.
releasever=2016.03

#  This is the default, if you make this bigger yum won't see if the metadata
# is newer on the remote and so you'll "gain" the bandwidth of not having to
# download the new metadata and "pay" for it by yum not having correct
# information.
#  It is esp. important, to have correct metadata, for distributions like
# Fedora which don't keep old packages around. If you don't like this checking
# interupting your command line usage, it's much better to have something
# manually check the metadata once an hour (yum-updatesd will do this).
# metadata_expire=90m

# PUT YOUR REPOS HERE OR IN separate files named file.repo
# in /etc/yum.repos.d

releasever2016.03に固定されています。

この状態では、カーネルをアップデートしても変更されません。

$ sudo yum update kernel
Loaded plugins: priorities, update-motd, upgrade-helper
No packages marked for update

そこで更新させるためには以下のように変更する必要があります。

releasever=latest

releaseverを「latest」に変更して、カーネルをアップデート

先ほどのyum.confのリリースサーバーを最新に更新します。

$ cp -ip /etc/yum.conf  /tmp/
$ sudo vi /etc/yum.conf
$ diff /etc/yum.conf /tmp/yum.conf
17c17
< releasever=latest
---
> releasever=2016.03
#更新しました

# kernelをアップデートする
$ sudo yum update kernel
Loaded plugins: priorities, update-motd, upgrade-helper
amzn-main/latest                                                                                                                                                                                                                 | 2.1 kB     00:00
amzn-updates/latest                                                                                                                                                                                                              | 2.3 kB     00:00
Resolving Dependencies
--> Running transaction check
---> Package kernel.x86_64 0:4.9.51-10.52.amzn1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

========================================================================================================================================================================================================================================================
 Package                                                 Arch                                                    Version                                                               Repository                                                  Size
========================================================================================================================================================================================================================================================
Installing:
 kernel                                                  x86_64                                                  4.9.51-10.52.amzn1                                                    amzn-main                                                   17 M

Transaction Summary
========================================================================================================================================================================================================================================================
Install  1 Package

Total download size: 17 M
Installed size: 71 M
Is this ok [y/d/N]: y
Downloading packages:
kernel-4.9.51-10.52.amzn1.x86_64.rpm                                                                                                                                                                                             |  17 MB     00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : kernel-4.9.51-10.52.amzn1.x86_64                                                                                                                                                                                                     1/1
  Verifying  : kernel-4.9.51-10.52.amzn1.x86_64                                                                                                                                                                                                     1/1

Installed:
  kernel.x86_64 0:4.9.51-10.52.amzn1

Complete!

先ほどは、アップデートするカーネルはありませんでしたが、今回はアップデートされました。

再起動後に再度インスタンスにアクセスして、カーネルがアップデートされたか確認します。

$ ssh hogehost
Last login: Sat Jan 20 02:10:39 2018 

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2016.03-release-notes/
No packages needed for security; 138 packages available
Run "sudo yum update" to apply all updates.
Amazon Linux version 2017.09 is available.

$ uname -srv
Linux 4.9.51-10.52.amzn1.x86_64 #1 SMP Fri Sep 29 01:16:19 UTC 2017

カーネルは4.4.5から4.9.51に上がったようですね。ところがまだ最新ではないです。

またsshを行ったら、早速情報が更新されています。

No packages needed for security; 138 packages available
Run “sudo yum update” to apply all updates.

カーネルのアップデートではなく、パッケージのアップデートを勧められています。

全てのパッケージアップデートする

そこでカーネルだけれはなく全てのパッケージをアップデートさせます。

パッケージを全てアップデートすると既存で動いているサービスに影響を与えることがあるので、バージョンの依存関係があるパッケージについては除外しましょう

今回はカーネルを最新にアップデートさせることが目標なので、上記を考慮せずに全てのパッケージをアップデートします。

$ sudo yum update
Loaded plugins: priorities, update-motd, upgrade-helper
Resolving Dependencies
--> Running transaction check
---> Package acpid.x86_64 0:1.0.10-2.1.6.amzn1 will be updated
---> Package acpid.x86_64 0:2.0.19-6.7.amzn1 will be an update
・・・(省略)

# インストールとアップデートをするパッケージが一覧されるのでチェック
========================================================================================================================================================================================================================================================
 Package                                                                Arch                                            Version                                                                Repository                                          Size
========================================================================================================================================================================================================================================================
Updating:
 acpid                                                                  x86_64                                          2.0.19-6.7.amzn1                                                       amzn-main                                           73 k
 at                                                                     x86_64                                          3.1.10-48.15.amzn1                                                     amzn-main                                           66 k
 audit                                                                  x86_64                                          2.6.5-3.28.amzn1                                                       amzn-main                                          272 k
 audit-libs                                                             x86_64                                          2.6.5-3.28.amzn1                                                       amzn-main                                           96 k
・・・(省略)
Installing for dependencies:
 libXcomposite                                                          x86_64                                          0.4.3-4.6.amzn1                                                        amzn-main                                           21 k
 libidn2                                                                x86_64                                          0.16-1.2.amzn1                                                         amzn-main                                          103 k
 libnghttp2                                                             x86_64                                          1.21.1-1.4.amzn1                                                       amzn-main                                           73 k
 libseccomp                                                             x86_64                                          2.3.1-2.4.amzn1                                                        amzn-main                                           79 k
 libunistring                                                           x86_64                                          0.9.3-6.1.amzn1                                                        amzn-main                                          419 k
 perl-Time-HiRes                                                        x86_64                                          4:1.9725-272.5.amzn1                                                   amzn-main                                           46 k
 python27-futures                                                       noarch                                          3.0.3-1.3.amzn1                                                        amzn-main                                           30 k

Transaction Summary
========================================================================================================================================================================================================================================================
Install               ( 7 Dependent packages)
Upgrade  138 Packages

Total download size: 192 M

yum updateでは、インストールを始める前に、インストールとアップデートをするパッケージが一覧されます。
その後にアップデートするか選べるので、パッケージを確認してから、動いているサービスに影響がないか確認するといいと思います。

このままアップデートを実行します。

Is this ok [y/d/N]: y

Downloading packages:
(1/145): acpid-2.0.19-6.7.amzn1.x86_64.rpm                                                                                                                                                                                       |  73 kB     00:00
(2/145): at-3.1.10-48.15.amzn1.x86_64.rpm                                                                                                                                                                                        |  66 kB     00:00
・・・(省略)
  xfsprogs.x86_64 0:4.5.0-9.21.amzn1                              yum.noarch 0:3.4.3-150.70.amzn1                            yum-metadata-parser.x86_64 0:1.1.4-10.20.amzn1                  yum-plugin-priorities.noarch 0:1.1.31-40.29.amzn1
  yum-plugin-upgrade-helper.noarch 0:1.1.31-40.29.amzn1           yum-utils.noarch 0:1.1.31-40.29.amzn1

Complete!

全てのパッケージをアップデートしました。再起動を行い、再度sshします。

$ ssh hogehost
Last login: Sat Jan 20 02:17:24 2018 

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/
10 package(s) needed for security, out of 34 available
Run "sudo yum update" to apply all updates.

$ uname -srv
Linux 4.9.51-10.52.amzn1.x86_64 #1 SMP Fri Sep 29 01:16:19 UTC 2017

カーネルのバージョンはかわっていませんが、

10 package(s) needed for security, out of 34 available
Run “sudo yum update” to apply all updates.

バージョンアップ後、さらにセキュリティ問題のためアップデートするように警告されていますね。

すべでのパッケージをアップデートしたことで、最新のカーネルにアップデートできるようになりました。

パッケージ全てをアップデートする(2回目)

最新のカーネルにアップデートするべく、再度アップデートします。

$ sudo yum update
Loaded plugins: priorities, update-motd, upgrade-helper
Resolving Dependencies
・・・(省略)

Installed:
  kernel.x86_64 0:4.9.77-31.58.amzn1

Dependency Installed:
  libtool-ltdl.x86_64 0:2.4.2-20.4.8.5.32.amzn1                                                                                     nss-pem.x86_64 0:1.0.3-4.3.amzn1

Updated:
  aws-cfn-bootstrap.noarch 0:1.4-27.19.amzn1      aws-cli.noarch 0:1.14.9-1.48.amzn1         curl.x86_64 0:7.53.1-13.80.amzn1               docker.x86_64 0:17.09.1ce-1.111.amzn1            docker-storage-setup.noarch 0:0.6.0-1.18.giteb688d4.amzn1
  ec2-net-utils.noarch 0:0.5-1.34.amzn1           ec2-utils.noarch 0:0.5-1.34.amzn1          ecs-init.x86_64 0:1.16.2-1.amzn1               irqbalance.x86_64 2:1.3.0-1.26.amzn1             java-1.7.0-openjdk.x86_64 1:1.7.0.161-2.6.12.0.75.amzn1
  kernel-tools.x86_64 0:4.9.77-31.58.amzn1        krb5-libs.x86_64 0:1.15.1-8.43.amzn1       libcurl.x86_64 0:7.53.1-13.80.amzn1            nss.x86_64 0:3.28.4-12.80.amzn1                  nss-softokn.x86_64 0:3.28.3-8.41.amzn1
  nss-softokn-freebl.x86_64 0:3.28.3-8.41.amzn1   nss-sysinit.x86_64 0:3.28.4-12.80.amzn1    nss-tools.x86_64 0:3.28.4-12.80.amzn1          nss-util.x86_64 0:3.28.4-3.53.amzn1              openssl.x86_64 1:1.0.2k-8.106.amzn1
  python27.x86_64 0:2.7.12-2.121.amzn1            python27-boto.noarch 0:2.48.0-1.2.amzn1    python27-botocore.noarch 0:1.8.13-1.66.amzn1   python27-devel.x86_64 0:2.7.12-2.121.amzn1       python27-libs.x86_64 0:2.7.12-2.121.amzn1
  ruby20.x86_64 0:2.0.0.648-1.30.amzn1            ruby20-irb.noarch 0:2.0.0.648-1.30.amzn1   ruby20-libs.x86_64 0:2.0.0.648-1.30.amzn1      rubygem20-bigdecimal.x86_64 0:1.2.0-1.30.amzn1   rubygem20-psych.x86_64 0:2.0.0-1.30.amzn1
  rubygems20.noarch 0:2.0.14.1-1.30.amzn1         system-release.noarch 0:2017.09-0.1        wget.x86_64 0:1.18-3.28.amzn1

Complete!

再起動してアップデートを反映させます。


$ ssh hogehost
Last login: Sat Jan 20 02:21:06 2018

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/

$ uname -srv
Linux 4.9.77-31.58.amzn1.x86_64 #1 SMP Thu Jan 18 22:15:23 UTC 2018

カーネルもCPU脆弱性の対応がされた最新のバージョンになりました。

まとめ

今回2016年のAmazon LinuxのKernelを最新版にアップデートにするには以下のような流れです。

  • yum.conf更新(リリースバージョンを最新にする)
  • yum update(1回目。2016 → 2017にコミットされたバージョンをあげる)
  • yum update(2回目。2017 → 最新の2018にコミットされたバージョンをあげる。)

何回 yum updateが必要なのかは、管理しているインスタンスのバージョンによりますが、
OSのバージョンアップは早いうちからやっていた方が明らかに楽ですし、
パッケージを全てアップデートする場合は既存のサービスに影響を与える可能性もあります。

改めてセキュリティ対策は、コツコツアップデートしていかなければという学びを得ました。

また、sshの情報にしっかり目を通すことで、どうアップデートすべきかわかるので最新のOSに保ちつつ管理していきましょう。

続きを読む

環境構築201801 slackbot

はじめに

環境構築時のメモです。
* Amazon Linux AMI release 2017.09
* nvm 0.33.8 (201712)
* node v9.3.0 (201712) 
* redis v2.4.10(201712)
* hubot-slack v4.4 (201712)
* nginx v1.10.3 (201708)
* pyton v3.6.0 (201712)

初期設定

command
$ cat /etc/system-release1
$ sudo yum update -y
$ sudo yum install -y git

タイムゾーンをJSTに変更する。

command
$ sudo ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
$ sudo vi /etc/sysconfig/clock
---
ZONE="Asiz/Tokyo"
UTC=false
---

OSユーザ(例:hoge)作成

command
$ useradd hoge
$ sudo su - hoge
$ cd /home/hoge
$ mkdir .ssh
$ cd .ssh
$ ssh-keygen -t rsa
$ mv id_rsa.pub authorized_keys
$ chmod 600 authorized_keys
$ cat id_rsa ※内容を接続元PCに保存 hoge.pem
※puttyの場合
・Run PuTTYgenを起動
・Load an existing private file を読み込む(load)
・Save public key hoge.ppk
・上記ファイルを"Private key file for authentication"に設定する。
・wheelユーザに追加およびパスワードなしでsudoを利用できるようにする。
$ vi /etc/group
----
wheel:x:10:ec2-user,hoge
----
$ sudo visudo
---
# %wheel        ALL=(ALL)       NOPASSWD: ALL
%hoge      ALL=(ALL)       NOPASSWD: ALL
---

Nginxインストール

$ sudo useradd www
$ sudo groupadd www
$ sudo yum install nginx
$ sudo cp /etc/nginx/nginx.conf.default /etc/nginx/nginx.conf
$ sudo vi /etc/nginx/nginx.conf
---
server{
   listen    80;
   server_name localhost;
   root ***設置場所***;
   charset utf-8;
   index index.html index.htm index.php;
   access_log /var/log/host.access.log main;
}
---
$ sudo service nginx start
$ sudo chkconfig nginx on

redisインストール

$ sudo yum --enablerepo=epel install redis
$ sudo service redis start
$ sudo chkconfig --level 35 redis on
$ sudo chkconfig --list | grep redis

nodeインストール

$ git clone git://github.com/creationix/nvm.git ~/.nvm
$ vi .bashrc
---
if [ -f ~/.nvm/nvm.sh ];then
        source ~/.nvm/nvm.sh > /dev/null 2>&1
fi
---
$ source ~/.bashrc
$ nvm ls-remote nodeバージョン一覧表示
$ nvm install v6.9.0
$ nvm alias default v6.9.0  #恒久的な切り替え
$ nvm ls-remote
$ node -v
nvm自身のバージョンアップ
text
$ cd ~/.nvm
$ git pull origin master
$ source ~/.bashrc

Python3インストール

text
$ yum install gcc gcc-c++ make git openssl-devel bzip2-devel zlib-devel readline-devel sqlite-devel
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
$ vi ~/.bashrc
---
export PYENV_ROOT="${HOME}/.pyenv"
if [ -d "${PYENV_ROOT}" ]; then
export PATH=${PYENV_ROOT}/bin:$PATH
eval "$(pyenv init -)"
fi
---
$ sudo yum install patch
$ pyenv install 3.6.0
$ pyenv global 3.6.0
$ pip install --upgrade pip
$ pip install bigquery-python
$ pip install beautifulsoup4
$ pip install jupyter
$ jupyter notebook --generate-config
$ python -c "from notebook.auth import passwd;print(passwd())" ※設定
$ vi ~/.jupyter/ 内に jupyter_notebook_config.py
---
c.NotebookApp.ip = '*'
c.NotebookApp.open_browser = False
c.NotebookApp.password = 'sha1:*******' ※
---

Slackbot構築

Slackにhubotアプリを追加

Add apps| Slack

hubot01png.png

hubot2.png

Hubotインストール

$ cd ~/.nvm/versions/node/(バージョン)/lib/node_modules
$ npm install hubot yo generator-hubot coffee-script hubot-slack
$ cd ~
$ mkdir hello-hubot
$ cd hello-hubot
$ yo hubot
$ vi external-scripts.json
---
heroku packageを削除
---
動作確認
$ vi ./scripts/examples.coffee
---
module.exports = (robot) ->
#(コメントアウトを外す) robot.hear /badger/i, (res) ->
#(コメントアウトを外す) res.send "Badgers? BADGERS? WE DON'T NEED NO STINKIN BADGERS"
---
$ export HUBOT_SLACK_TOKEN=<API Token>
$ ./bin/hubot -a slack 

Slackでbadgerを入力しリプライを確認
hubot3.png

SlackBot設置

slack からgoogle検索ができるか試す。
下記のアンプルコードを scriptsディレクトリに保存し、hubotを起動する。

./bin/hubot -a slack

サンプルコード|SlackBot

slackから作成したアプリに「search is ***」を送信するとreplyが届く。

hubot5.png

続きを読む

AWSでbazelをインストールする方法

0. 環境

OS: Amazon Linux AMI 2017.09.1
  t2.micro

1. ソースをダウンロード

$ wget https://github.com/bazelbuild/bazel/releases/download/0.9.0/bazel-0.9.0-dist.zip
$ unzip bazel-0.9.0-dist.zip

最新のバージョンは
https://github.com/bazelbuild/bazel/releases
で探してください。
2018/1/18現在は0.9.0

2. コンパイル

2.1 JDK

コンパイルに必要なJDKをインストール。
1.8.0が必要らしい。

$ sudo yum -y install java-1.8.0-openjdk-devel

デフォルトでは1.7.0が設定されているので1.8.0に変えます

$ sudo alternatives --config java
2 プログラムがあり 'java' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /usr/lib/jvm/jre-1.7.0-openjdk.x86_64/bin/java
   2           /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.25-0.b18.4.amzn1.x86_64/jre/bin/java

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:

2と入力してEnter

java -versionで1.8.0になったことを確認します。

$ java -version
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)

2.2 bazel

sudo ./compile.sh

でコンパイル
t2.microの場合は以下の2つのエラーが出るはずなので、先に対策しておくとよいと思います。


トラブルシューティング
①もしjava.lang.OutOfMemoryError: Java heap spaceがでたら、この記事を参照してください。
->ソースからbazelをコンパイルする時に”java.lang.OutOfMemoryError: Java heap space”というエラーが出たときの対処法

②もしg++: error trying to exec 'cc1plus': execvp: No such file or directoryというエラーがでたら、

sudo yum install gcc-c++

でgcc-c++をインストールすればOK


最後に、コンパイルされたbazelをパスが通っている/usr/binに移動します。

$ sudo cp output/bazel /usr/bin/

最後に、bazelにパスが通っていることが確認できたら終わりです。

$ which bazel
/usr/bin/bazel

お疲れ様でした!

続きを読む

webプログラミング初学者がAWS Cloud9を使い始める

この記事を書こうと思ったきっかけ

ローカルに環境を用意しなくても開発が始められるという統合開発環境(IDE)Cloud9を始めてみようと思いましたが、ネットで調べてもAWS版のcloud9がリリースされる前の情報が多く、いろいろと戸惑ったこともありましたので記事を書くことにしました。

AWS Cloud9を始める

AWSからCloud9を登録する

https://c9.io/ から、「cloud9を使い始める」をクリック
私はAWSに登録済みだったのでAWSにログインしてcloud9をサービスに追加しました。
(普通にAWSの管理画面からサービスを追加でも大丈夫だと思います。)
リージョンは「シンガポール」を選択しました。
git-hubアカウントでログインができる、という情報もありますが、新規登録はできないようです。

Cloud9のコンソールから環境を設定する

cloud9のコンソールから「Create environment」をクリック
スクリーンショット 2018-01-18 13.32.48.png

環境の名前を入力する

「Name environment-Environment name and description」の画面で環境の名前を「Name」欄に入力します。
名前は適当で大丈夫です。今回は「sample_env」としてみました。
Descriptionは省略しました。必要に応じて説明を入力します。
スクリーンショット 2018-01-18 14.54.48.png

「next step」をクリック

インスタンスの種類などを選ぶ

「Configure settings-Environment settings」
今回はEnvironment type に「EC2」、Instance type 「t2.micro」、Cost-saving setting 「After 30 min」を選択しました。(全てデフォルト)
ネットで検索するとAmazon買収前の情報なのか、ここでアプリケーション毎のテンプレートが選べる、と言う情報がありますが、テンプレートはありません。

インストール後調べてみると、cat /etc/system-release の結果は「Amazon Linux AMI release 2017.09」でした。
python2.7,python3.6,Rails 5.1.4,PHP 5.6などがデフォルトでインストールされていて、web開発ならそのままの状態である程度のことは始められそうな印象です。

スクリーンショット 2018-01-18 14.54.17.png

設定内容を確認する

「Next step」をクリックでReview(確認)画面になります。
スクリーンショット 2018-01-18 15.07.57.png

ログイン済のコンソールが立ち上がる

内容を確認できたら「Create environment」をクリックしてしばらく待つとコンソール画面になります。

スクリーンショット 2018-01-18 15.09.56.png
~/environment にログインした状態でコマンドが使えるようになります。
(左サイドバーにあるファイルツリーで「Sample_env」と表現されているディレクトリが~/environmentになります。)

あとはお好きに

あとは好きなようにいじり倒してみて下さい。
よくわからなくなったらすぐに同じ手順で環境を作り直すことができます。

ネットにあった情報と違っていて戸惑った点まとめ

  • git-hubアカウントで新規登録することはできないようです。
  • インスタンス作成時にアプリケーション毎のテンプレートは選べません。
  • パッケージ管理はapt-getではなくyumを使います。

続きを読む

【AWS】 SSH を使用した Linux インスタンスへの接続

AWSでEC2インスタンスを作成して、SSHで接続できるようにするまでの手順とその過程でハマったことを書き記します。
間違っている、こうした方がわかりやすいなどありましたらコメントお願いします。

インスタンスに新規ユーザーを追加する

1.インスタンス時に得たキーペアファイルを使って接続する

[user@local ~]$ ssh -i kagi.pem ec2-user@[instance name]

2.rootユーザーにパスワードを設定する

[ec2-user@instance ~]$ sudo su -
[ec2-user@instance ~]$ passwd 

3.ユーザーの追加

[ec2-user@instance ~]$ useradd hoge
[ec2-user@instance ~]$ passwd hoge

4.sudoの許可

[ec2-user@instance ~]$ vi /etc/sudoers

5.EC2のサーバへログイン

// ユーザー名
hoge ALL=(ALL) ALL

6.鍵を生成する

// ~/.ssh/に公開鍵と秘密鍵が生成される
[user@local ~]$ ssh-keygen -t rsa

7.公開鍵をインスタンスへ転送し配置する

// 生成した鍵を、一時的にec2-userのディレクトリへ転送する
[user@local ~]$ scp -i kagi.pem ec2-user@[instance name]:/home/ec2-user

8.EC2のサーバへログイン

[ec2-user@instance ~]$ ls
// あるかチェックする
id_rsa.pub

9.追加したユーザーのホームディレクトリにid_rsa.pubを配置する

[ec2-user@instance ~]$ su hoge

10.ホームディレクトリに.sshというディレクトリを作り、id_rsa.pubをauthorized_keysという名前で移動する

[hoge@instance ec2-user]$ mkdir /home/hoge/.ssh
[hoge@instance ec2-user]$ sudo mv id_rsa.pub /home/hoge/.ssh/authorized_keys

11.転送したファイルとディレクトリのパーミッションを変更する

[hoge@instance ec2-user]$ sudo chmod 600 /home/hoge/.ssh/authorized_keys
[hoge@instance ec2-user]$ sudo chmod 700 /home/hoge/.ssh

12.接続

[user@local ~]$ ssh hoge@[instance name]

13..sshにconfigファイルを書く
ログインのたびに面倒な設定を入力する手間を省く為に入力する

[user@local ~]$ vi ~/.ssh/config
Host hoge
user hoge
HostName [public DNSを記述]
Port 22
IdentityFile id_rsa
// ログインできたら成功
ssh hoge

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|___|___|

注意点・ハマったこと

まずはec2-userにログインしないといけない
そのあとにLinuxコマンドでユーザーを作成
作成したユーザーにパスワードとrootの権限と付与する

※参考
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/managing-users.html

ユーザーアカウントを追加するには

adduser コマンドを使用して、newuser アカウントがシステムに追加され、 (/etc/passwd ファイルにエントリが追加される

このコマンドでも、グループが作成され、アカウントのホームディレクトリが作成される

[ec2-user ~]$ sudo adduser newuser

ユーザーを Ubuntu システムに追加する場合は、このコマンドを使用して、–disabled-password オプションを追加し、アカウントにパスワードが追加されないようにする

[ec2-user ~]$ sudo adduser newuser --disabled-password

新しいアカウントに切り替えると、新しく作成したファイルに適切な所有権が与えられる

[ec2-user ~]$ sudo su - newuser
[newuser ~]$

newuser ホームディレクトリに .ssh ディレクトリを作成し、
そのファイルのアクセス許可を 700 (所有者のみ、読み取り、書き込み、削除が可能) に変更する

[newuser ~]$ mkdir .ssh
[newuser ~]$ chmod 700 .ssh

authorized_keys という名前のファイルを .ssh ディレクトリに作成し、そのファイルのアクセス許可を 600 (所有者のみ、読み取りおよび書き込みが可能) に変更する

[newuser ~]$ touch .ssh/authorized_keys
[newuser ~]$ chmod 600 .ssh/authorized_keys

authorized_keys ファイルを開きます。キーペアのパブリックキーをファイルに貼り付ける

//例:
ssh-rsa ----
------------
------------
------------
------------
------------
------------
------------
-----EXAMPLE

ユーザーを削除する

[ec2-user ~]$ sudo userdel -r olduser

続きを読む

AWSのEC2で行うAmazon Linuxの初期設定

AWSのEC2で行うAmazon Linuxの最低限の初期設定をまとめてみました。まだすべき設定が残っているとは思いますので、こちらを更新していければと思っています。

開発環境

  • Mac OS X(El Capitan) 10.11.6
  • Amazon Linux AMI 2017.09.1 (HVM), SSD Volume Type – ami-33c25b55

事前に用意しておく必要があるもの

  • 接続先EC2のパブリックDNS
  • デフォルトユーザ(Amazon Linuxの場合デフォルトはec2-user)
  • EC2からダウンロードした秘密鍵(デフォルトは****.pem)

参考

AWSのEC2にSSH接続

秘密鍵の配置設定

以下のコマンドを実行してEC2からダウンロードした秘密鍵を【.ssh】ディレクトリに配置し、管理しやすくします。

$ mv /Users/ユーザ名/Downloads/秘密鍵名.pem ~/.ssh/

秘密鍵の権限設定

SSHを機能させるためには秘密鍵が公開されていないことが必要ですので、以下のコマンドを実行てし権限の設定をします。

$ chmod 400 ~/.ssh/秘密鍵名.pem

SSH接続

以下のコマンドを実行してAWSのEC2にSSH接続します。

$ ssh -i ~/.ssh/秘密鍵名.pem ユーザ名@パブリックDNS

ログイン完了

以下が表示がされたらログイン完了です。

Last login: Mon Jan 15 17:27:41 2018 from ***.***.***.***

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/

Amazon-linuxの初期設定

パッケージの更新

以下のコマンドを実行してAmazon-linuxのパッケージを更新します。

# パッケージの更新
$ sudo yum update -y

パッケージの自動更新設定

以下のコマンドを実行してyum-cronをインストールし、パッケージの自動更新を設定します。

# インストール
$ sudo yum install yum-cron -y

# 有効化確認
$ sudo chkconfig --list yum-cron

# 有効化
$ sudo chkconfig yum-cron on

# 自動更新設定
$ sudo sed -i "s/^apply_updates.*$/apply_updates = yes/g" /etc/yum/yum-cron.conf

# 起動
$ sudo service yum-cron start

# 起動確認
$ sudo service yum-cron status

タイムゾーンの変更

以下のコマンドを実行してインスタンスのローカルタイムとハードウェアクロックを変更します。

# 現在の設定確認
$ date

# ローカルタイムを【Japan】に変更
$ sudo ln -sf /usr/share/zoneinfo/Japan /etc/localtime

# ハードウェアクロックを【Japan】に変更
$ sudo sed -i s/ZONE=\"UTC\"/ZONE=\"Japan\"/g /etc/sysconfig/clock

# システム再起動
$ sudo reboot

# 現在の設定確認
$ date

文字コードを日本語に変更

以下のコマンドを実行して文字コードを日本語対応に変更します。

# 文字コードを日本語に変更
$ sudo sed -i s/LANG=\"en_US.UTF-8\"/LANG=\"ja_JP.UTF-8\"/g /etc/sysconfig/i18n

不要なサービスの停止

以下のコマンドを実行してGUIで不要なサービスの停止することができます。

# 不要サービスの一括設定(GUI)
$ sudo ntsysv

ユーザーアカウント追加

ユーザーアカウント追加

以下のコマンドを実行して新規ユーザーアカウントを追加します。今回は【newuser】として作成します。

# newuserを追加
$ sudo adduser newuser

sudo権限の変更

以下のコマンドを実行してsudoersファイルを安全に編集します。

# sudoersファイルの編集
$ sudo visudo

作成したnewuserグループをsudoコマンドがパスワード無しで実行できるように追記します。

## Same thing without a password
# %wheel        ALL=(ALL)       NOPASSWD: ALL
+ %newuser       ALL=(ALL)       NOPASSWD: ALL

ユーザーアカウント切り替え

以下のコマンドを実行してnewuserへ切り替えます。

# newuserへ切り替え
$ sudo su - newuser

公開鍵認証設定

公開鍵認証用ファイルの作成

以下のコマンドを実行して公開鍵認証用のディレクトリとファイルを作成します。

# newuserのホームディレクトリに.sshディレクトリを作成
$ mkdir .ssh

# ファイルパーミッションを700(所有者のみ、読み取り、書き込み、削除が可能)に変更
$ chmod 700 .ssh

# authorized_keysを作成
$ touch .ssh/authorized_keys

# ファイルパーミッションを600(所有者のみ、読み取りおよび書き込みが可能)に変更
$ chmod 600 .ssh/authorized_keys

キーペアのパブリックキーをコピー

以下のコマンドを実行してパブリックキーをコンピュータから取得します。

# パブリックキーをコンピュータから取得
$ ssh-keygen -y

# キーを持つファイルのパスを指定
Enter file in which the key is (/Users/****/.ssh/id_rsa): /path_to_key_pair/my-key-pair.pem

表示されたインスタンスのパブリックキー(※以下は例)の末尾の【キーペア名】を除いてコピーします。

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQClKsfkNkuSevGj3eYhCe53pcjqP3maAhDFcvBS7O6V
hz2ItxCih+PnDSUaw+WNQn/mZphTk/a/gU8jEzoOWbkM4yxyb/wB96xbiFveSFJuOp/d6RJhJOI0iBXr
lsLnBItntckiJ7FbtxJMXLvvwJryDUilBMTjYtwB+QhYXUMOzce5Pjz5/i8SeJtjnV3iAoG/cQk+0FzZ
qaeJAAHco+CY/5WrUBkrHmFJr6HcXkvJdWPkYQS3xqC0+FmUZofz221CBt5IMucxXPkX4rWi+z7wB3Rb
BQoQzd8v7yeb7OzlPnWOyN0qFU0XA246RA8QFYiCNYwI3f05p6KLxEXAMPLE

取得したキーペアのパブリックキーをペースト

以下のコマンドを実行して、コピーしたキーペアのパブリックキーを【authorized_keys】にペーストします。

#.ssh/authorized_keysを編集
$ vi .ssh/authorized_keys

デフォルトユーザ(ec2-user)を削除する場合

追加したユーザーアカウントでAWSのEC2にSSH再接続

以下のコマンドを実行してAWSのEC2にSSH再接続します。

$ ssh -i ~/.ssh/秘密鍵名.pem 追加したユーザーアカウント@パブリックDNS

ログイン完了

以下が表示がされたらログイン完了です。

Last login: Mon Jan 15 17:27:41 2018 from ***.***.***.***

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/

デフォルトユーザーの削除

以下のコマンドを実行してデフォルトユーザ(ec2-user)とそのホームディレクトリを削除します。

# ec2-userとそのホームディレクトリの削除
$ sudo userdel -r ec2-user

ブログ記事の転載になります。

続きを読む

[AWS,EC2]初期設定(インスタンス作成,SSH接続,料金のモニタリング)

AWSのアカウントを作成

https://qiita.com/Hikery/items/b919ae9e35f0f66e6a95

インスタンス作成

Step1 サービス > EC2 を選択

ec2.jpg

Step2 localの変更

time.jpg

Step3 マシーンイメージの選択

insutance.jpg

Step4 インスタンスタイプの選択

i_type.jpg

Step5 セキュリティグループの設定

・インスタンス設定
・ストレージ追加
はそのままで
・タグの追加 は適当にtagをつける。

セキュリティグループの設定 は HTTP を追加する。
security.jpg

Step6 キーペアを選択する

key2.jpg

鍵をDownloadして、インスタンスの作成をする。

SSH で繋いでみる

Step1 –

接続をおす
i_ssh_1.jpg

スタンドアロン SSH クライアント
i_ssh_1.jpg

Step2 – .pem fileを .ssh配下に配置する

terminal
$ mv /Users/[user name]/Downloads/***.pem /Users/[user name]/.ssh
$ chmod 600 football_chant.pem
$ ssh -i "***.pem" ec2-user@ec2-**-***-**-***.ap-northeast-1.compute.amazonaws.com
The authenticity of host 'ec2-**-***-**-***.ap-northeast-1.compute.amazonaws.com (**.***.**.***)' can't be established.
ECDSA key fingerprint is SHA***:*******************************************.
Are you sure you want to continue connecting (yes/no)?

yesを選択する。

terminal
Warning: Permanently added 'ec2-**-***-**-****.ap-northeast-1.compute.amazonaws.com,**.***.**.***' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/

環境によっては

terminal
$ sudo yum update

料金をモニターする

画面で料金を確認

右上のアカンウトクリック > 請求ダッシュボード
https://console.aws.amazon.com/billing/home#/
こんな感じで見れます。
price2.jpg

使用した料金をメールで受け取る。

https://console.aws.amazon.com/billing/home#/preference
とりあえず、全部受け取るようにする。
setting.jpg

請求アラートを管理する

“請求アラートを管理する”にLinkする。

アラート.jpg

アラームを作成

make.jpg

メトリック設定

メトリック : 請求
チェック : USD
時間 : 6時間
setting2.jpg

アラームの定義

0$を超えた時、0$に戻った時を指定します。
setting6.jpg

また心配であれば5ドルや10ドルを超えた時点でもアラートを出すと良いかと思います。

参考

AWSアカウントの保護

アカウントのセキュリティ保護のために下記の記事を参考に、
MFAデバイス認証をいれました。

https://qiita.com/tmknom/items/303db2d1d928db720888

料金

初心者なので、これは気をつけようと思いました。参考になります。
https://qiita.com/mochizukikotaro/items/a0e98ff0063a77e7b694

RDSでMySQLを起動させ、EC2のインスタンスにつなぐ

下記を参考にした。
https://qiita.com/na0AaooQ/items/7c69a88c80f1efb4cad3
https://qiita.com/hiroshik1985/items/6643b7323183f82297b2

続きを読む

CPUの脆弱性におけるEC2の保守対応(Amazon Linux、Windows)

CPUの脆弱性

年明け早々に問題になっている「CPUの脆弱性」について、AWSでの保守についてのメモです。

今回騒ぎになっているのは1月3日にProject Zeroの記事で紹介されたCPU脆弱性。

CPUの脆弱性の影響や対応方法などは、以下の記事がとてもわかりやすかったです。

上記の記事で、問題点や影響について大変わかりやすく解説されているので、この記事で脆弱性の問題は省いて、AWSのEC2における対応を書いて行きたいと思います。

EC2(Amazon Linux、Windows)の対応

Processor Speculative Execution Research Disclosureを簡単に要約すると、

KPTIのバグに対処と、CVE-2017-5754(不正なデータキャッシュ読み込み)の軽減策を改善するカーネルをリリースしました。最新のAmazon LinuxカーネルかAMIにアップデートすることによって対応されたカーネルが使えるようになります。

アップデートを推奨されているサービスは、
EC2EC2 WindowsECS Optimized AMElastic Beanstalk

また、RDSは現段階でユーザーが対応することは無いようです。

今回EC2について対応の流れを紹介していきます。

Amazon Linux

OSがAmazon Linuxの場合、最新のAMI、又はカーネルをアップデートして再起動。
現在(2018年1月11日)アップデートされるカーネルは以下になります。
Linux version 4.9.75-25.55.amzn1.x86_64
https://alas.aws.amazon.com/ALAS-2018-939.html


#対象のインスタンスにログインする
$ ssh hoge-instance

$ sudo su -

# カーネルを確認
# uname -srv
Linux 4.4.5-15.26.amzn1.x86_64 #1 SMP Wed Mar 16 17:15:34 UTC 2016
# 末尾のタイムスタンプはビルドされた日時を指している。

# カーネルをアップデートする
# yum update kernel -y
Loaded plugins: priorities, update-motd, upgrade-helper
amzn-main/latest                                                                                                                                                               | 2.1 kB     00:00
amzn-updates/latest                                                                                                                                                            | 2.5 kB     00:00
mackerel/latest/x86_64                                                                                                                                                         | 2.5 kB     00:00
mysql-connectors-community/x86_64                                                                                                                                              | 2.5 kB     00:00
mysql-tools-community/x86_64                                                                                                                                                   | 2.5 kB     00:00
mysql56-community/x86_64                                                                                                                                                       | 2.5 kB     00:00
8 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package kernel.x86_64 0:4.9.75-25.55.amzn1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

======================================================================================================================================================================================================
 Package                                    Arch                                       Version                                                 Repository                                        Size
======================================================================================================================================================================================================
Installing:
 kernel                                     x86_64                                     4.9.75-25.55.amzn1                                      amzn-updates                                      18 M

Transaction Summary
======================================================================================================================================================================================================
Install  1 Package

Total download size: 18 M
Installed size: 72 M
Downloading packages:
kernel-4.9.75-25.55.amzn1.x86_64.rpm                                                                                                                                           |  18 MB     00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : kernel-4.9.75-25.55.amzn1.x86_64                                                                                                                                                   1/1

  Verifying  : kernel-4.9.75-25.55.amzn1.x86_64                                                                                                                                                   1/1

Installed:
  kernel.x86_64 0:4.9.75-25.55.amzn1

Complete!

カーネルをアップデート後、awsのコンソール画面より再起動。
(再起動しないとカーネルが更新されない)

# 再起動後
# uname -srv
Linux 4.9.75-25.55.amzn1.x86_64 #1 SMP Fri Jan 5 23:50:27 UTC 2018

脆弱性対応されたカーネル(Linux version 4.9.75-25.55.amzn1.x86_64)になっていることを確認。
このバージョンがビルドされた日も1月5日と最新ですね。

補足:使用しているAMIのバージョンが古い場合は、最新のAMIにアップデートする必要があります。

問題の脆弱性に対応できているか確認する

Linuxが脆弱性「Spectre」「Meltdown」に対応済みか調べる方法の記事を参考に、アップデートされたカーネル(Linux version 4.9.75-25.55.amzn1.x86_64)で検査しまします。

Spectre and Meltdown mitigation detection tool v0.24

Checking for vulnerabilities against live running kernel Linux 4.9.75-25.55.amzn1.x86_64 #1 SMP Fri Jan 5 23:50:27 UTC 2018 x86_64

CVE-2017-5753 [bounds check bypass] aka 'Spectre Variant 1'
* Checking count of LFENCE opcodes in kernel:  NO  (only 35 opcodes found, should be >= 70)
> STATUS:  VULNERABLE  (heuristic to be improved when official patches become available)

CVE-2017-5715 [branch target injection] aka 'Spectre Variant 2'
* Mitigation 1
*   Hardware (CPU microcode) support for mitigation:  YES 
*   Kernel support for IBRS:  NO 
*   IBRS enabled for Kernel space:  NO 
*   IBRS enabled for User space:  NO 
* Mitigation 2
*   Kernel compiled with retpoline option:  NO 
*   Kernel compiled with a retpoline-aware compiler:  NO 
> STATUS:  VULNERABLE  (IBRS hardware + kernel support OR kernel with retpoline are needed to mitigate the vulnerability)

CVE-2017-5754 [rogue data cache load] aka 'Meltdown' aka 'Variant 3'
* Kernel supports Page Table Isolation (PTI):  YES 
* PTI enabled and active:  YES 
> STATUS:  NOT VULNERABLE  (PTI mitigates the vulnerability)

A false sense of security is worse than no security at all, see --disclaimer

AWSのProcessor Speculative Execution Research Disclosureに書いてあるように
確かにKPTIのバグ(Variant 3)は対処されていますが、CVE-2017-5754(不正なデータキャッシュ読み込み)の軽減策を改善するだけで、根本的に解決はできていないようです。

Windows 8.1 又は Windows Server 2012 R2

OSがWindows 8.1 又は Windows Server 2012 R2の場合
KB4056898のセキュリティプログラムをインストールします。

手順は対象のwindowsインスタンスからMicrosoft®Update カタログにアクセスし、対象のセキュリティプルグラムをインストール、再起動すれば完了です。

確認は、「コントロールパネル」 > 「システムとセキュリティ」 > 「Windows Update」 >「更新の履歴」
のタブを開き

Windows 用セキュリティ更新プログラム (KB4056898) インストール状態: 成功しました

となっていれば、対応完了です。

補足:更新プログラムしばらく更新していないマシンは、インストールに失敗する場合があるので、「コントロールパネル」 > 「システムとセキュリティ」 > 「Windows Update」 > 「更新プログラムを確認」 を開いて、プログラムを最新のものに更新して再起動してから、上記のセキュリティプログラムをインストールしましょう。

終わりに

今回の対応をとして完全に脆弱性が解決しているわけではないので、継続的にAmazon Linux AMI Security Centerをチェックして、(RSS feed有り)最新のカーネルにアップデートし続けた方が良さそうです。

今回のCPUの脆弱性で多くのマシンを保守していると脆弱性の対応がとても大変だなと痛感しました。エンジニアとして、できるだけ自分達で保守するものが少なくなるように努めて行きたいなと思います。

続きを読む

ALBのアクセスログに対してElasticStackのMachine Learningを試してみた

はじめに

Advent Calendar25日目ということでクリスマスですね!:santa:
でも、いつもと変わらないですね!

ということで、
今回は、異常検知してくれる?ElasticStackのX-Packの中のMachine Learningについて試してみましたので書きたいと思います( ゚Д゚)ゞビシッ1

こんな流れで話すよ

  1. ログ取込フロー
  2. 環境について
  3. ALBのログを出力して、LogstashからElasticsearchにストア
  4. Machine Learning使うよ!

ログ取込フロー

AWSでWebサービスを提供している環境で、WebAPサーバの前段にはALBを配置してます。
以下の流れでログを取り込みます。

image.png

  1. ALBログを指定バケットに出力
  2. LogstashがS3からALBのログを収集
  3. LogstashがElasticsearchにストア

環境について

  • ALB
  • Amazon Linux AMI 2017.09.1 (HVM)
  • Logstash 6.0
  • logstash-input-s3
  • Elasticsearch 6.0
  • Kibana 6.0
  • X-Pack 6.0

ElasticStackは、事前にインストールしていることを前提にしてます。
インストールされていない環境は、以下を参考にして頂ければと思います。

ALBのログを出力して、LogstashからElasticsearchにストア

ALBのロギングを有効化については以下を参考にしてください。

ここからは、S3に格納されているALBログをLogstashで取得するための方法について書きます。

S3 input pluginをインストール

S3からログを取得するには、Logstashのプラグインである”S3 input plugin”をインストールする必要があります。

インストール方法を以下に書きます。

$ cd /usr/share/logstash
$ bin/logstash-plugin install logstash-input-s3

ALBのログを取り込むための準備

ALBのログは、以下の形式で出力されます。

### Log Format
type timestamp elb client:port target:port request_processing_time target_processing_time response_processing_time elb_status_code target_status_code received_bytes sent_bytes "request" "user_agent" ssl_cipher ssl_protocol target_group_arn trace_id

### Sample Log
http 2016-08-10T22:08:42.945958Z app/my-loadbalancer/50dc6c495c0c9188 
192.168.131.39:2817 10.0.0.1:80 0.000 0.001 0.000 200 200 34 366 
"GET http://www.example.com:80/ HTTP/1.1" "curl/7.46.0" - - 
arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/my-targets/73e2d6bc24d8a067
"Root=1-58337262-36d228ad5d99923122bbe354"

この出力されたログを取り込むために、Grok Patternを作成したり、型変換をLogstashで施す必要があります。

フィールド定義

それでは、ログフォーマットからフィールド名と型の定義を行います。
ALBが受け付けてからクライアントに返すまでの処理時間を表すフィールドをfloatにします。
対象は、”request_processing_time”、”target_processing_time”、”response_processing_time”です。

Log Field Type
type type string
timestamp date date
elb elb string
client:port client_port string
target:port target_port string
request_processing_time request_processing_time float
target_processing_time target_processing_time float
response_processing_time response_processing_time float
elb_status_code elb_status_code string
target_status_code target_status_code string
received_bytes received_bytes long
sent_bytes sent_bytes long
request ELB_REQUEST_LINE string
user_agent user_agent string
ssl_cipher ssl_cipher string
ssl_protocol ssl_protocol string
target_group_arn target_group_arn string
trace_id trace_id string

Grok Pattern

ALBのログに正規表現をかけて、構造化するため、Grokする必要があります。
Grokを直接Logstashのconfファイルに書くことも可能ですが、可読性を重視するため、パターンファイルとして外出しします。

以下が、ALBのログをよしなに取り込むためのGrok Patternファイルです。

alb_patterns
### Application Load Balancing
ALB_ACCESS_LOG %{NOTSPACE:type} %{TIMESTAMP_ISO8601:date} %{NOTSPACE:elb} (?:%{IP:client_ip}:%{INT:client_port}|-) (?:%{IP:backend_ip}:%{INT:backend_port}|-) (:?%{NUMBER:request_processing_time}|-1) (?:%{NUMBER:target_processing_time}|-1) (?:%{NUMBER:response_processing_time}|-1) (?:%{INT:elb_status_code}|-) (?:%{INT:backend_status_code}|-) %{INT:received_bytes} %{INT:sent_bytes} \"%{ELB_REQUEST_LINE}\" \"(?:%{DATA:user_agent}|-)\" (?:%{NOTSPACE:ssl_cipher}|-) (?:%{NOTSPACE:ssl_protocol}|-) %{NOTSPACE:target_group_arn} \"%{NOTSPACE:trace_id}\"

Multiple Pipelines

Logstashのconfファイルを呼び出すためにMultiple Pipelinesを使用します。
Pipeline.ymlの定義は、以下です。

pipelines.yml
- pipeline.id: alb
  pipeline.batch.size: 125
  path.config: "/etc/logstash/conf.d/alb.cfg"
  pipeline.workers: 1

Pipelineの設定については、以下を参考にして頂ければと思います。

Logstashのディレクトリ構成

ここまで準備しましたが、以下の様に各ファイルを配置します。

/etc/logstash
  ├ logstash.yml
  ├ conf.d
  │ └ alb.cfg
  ├ jvm.options
  ├ log4j2.properties
  ├ alb_patterns
  └ pipelines.yml
  • ALBのalb.cfgをconf.d配下に配置
  • ALBのGrok PatternファイルをLogstash配下に配置
  • alb.cfgを呼び出すpipeline.ymlをLogstash配下に配置

ALBのconfファイルを作成するよ

  • Input: S3からALBのログを取得する2

  • Filter: 取得したログに対してフィルタをかける

  • Output: Elasticsearchにストア

alb.cfg
input {
  s3 {
    region => "ap-northeast-1"
    bucket => "hoge"
    prefix => "hoge"
    ### S3へのポーリング間隔を指定
    interval => "60"
    sincedb_path => "/var/lib/logstash/sincedb_alb"
  }
}
filter {
  ### 読み込むGrok Patternファイルを"patterns_dir"で指定
  grok {
    patterns_dir => ["/etc/logstash/alb_patterns"]
    match => { "message" => "%{ALB_ACCESS_LOG}" }
  }
  date {
    match => [ "date", "ISO8601" ]
    timezone => "Asia/Tokyo"
    target => "@timestamp"
  }
  ### グローバルIPから国などをマッピングするために指定
  geoip {
    source => "client_ip"
  }
  ### デフォルトの型がstringのため、フィールド定義で定義した型に変換
  mutate {
    convert => [ "request_processing_time", "float" ]
    convert => [ "response_processing_time", "float" ]
    convert => [ "target_processing_time", "float" ]
    convert => [ "received_bytes", "int" ]
    convert => [ "sent_bytes", "int" ]
    ### 不要なフィールドを削除
    remove_field => [ "date", 'message' ]
  }
}
output {
  elasticsearch {
    hosts => [ "localhost:9200" ]
  }
}

ここまで整ったらLogstashを起動

$ initctl start logstash
logstash start/running, process 3121

Machine Learning使うよ!

KibanaでアクセスしてMachine Learingをクリックします。
新しくジョブを作成するので、”Create new job”をクリックします。

以下の画面で”Single metric”をクリックします。

image.png

“Aggregation”と”Filed”を指定します。
Filedは、”target_processing_time”にすることで、バックエンドのサーバへリクエストしてから返ってくるまでの時間をみます。
そうすることで、サーバ内の処理遅延が発生しているかを確認できます。
画面の右上から期間を指定します。

image.png

“Name”と”Description”を入力し、”Create job”をクリックします。

image.png

ジョブが実行され、結果を表示するため”View Results”をクリックします。

image.png

指定期間の中で普段より乖離している部分を赤やオレンジでマークされます。

image.png

今回は、Single metricでやりましたが、Multi metricを使うことで、
グローバルIPアドレスやUserAgentと合わせて検出することも可能です。

さいごに

いかがでしたか?ログを取り込んでジョブを作成するだけで簡単に実行できました。
今までは、人の目で判断していたところをMachine Learningを用いることで、普段の傾向から乖離している部分を自動で検出してくれるのは便利ですね。

Advent Calendar最終日ですが、これにておしまいです。
ありがとうございました!


  1. Machine Learningは、X-Packという有償プラグインですが、期間限定で試すことが可能です 

  2. S3バケットへのアクセスするためのIAM Roleが適用されていることを前提とする 

続きを読む

シェルシェルのAWS運用術

この記事は「OpsJAWS Advent Calendar 2017」と「Shell Script Advent Calendar 2017」の 18日目の記事です。

あらすじ

時はまさに大AWS時代、この荒波をレガシー技術を駆使して乗りこなす、この世の全てはそこから持ってきた!

AWS-Makefile

AWS-Makefileは GNU Makeを使ってAWS Cloudformationのスタックと AWS EC2のAMIをビルドする為の共通定義インクルードファイルとユーティリティスクリプト群を一式にまとめたものです。複数の CloudformationスタックとカスタムAMIを組み合わせたビルドを下記の様な Makefileを記述するだけで定義できます。

Makefile
include AWS-Makefile.mk

KEY_NAME=your-key-name
CW_NAME_TAG=customweb:latest

all: MyCustomWeb

MyCustomWeb: MyNetwork MyCustomWebAmi MyCustomWebStack

MyCustomWebStack: CW_AMI_ID = $(shell ./amibake id $(CW_NAME_TAG))
MyCustomWebStack: CC_OPTS = --parameters ParameterKey=NetworkStackName,ParameterValue=MyNetwork ParameterKey=MyCustomWebAmiId,ParameterValue=$(CW_AMI_ID) ParameterKey=KeyName,ParameterValue=$(KEY_NAME)
MyCustomWebStack: $(DAM)/MyCustomWeb.stack

MyCustomWebAmi: AB_NAME_TAG = $(CW_NAME_TAG)
MyCustomWebAmi: $(DAM)/MyCustomWeb.ami

MyNetwork: $(DAM)/MyNetwork.stack

clean:
    @./cfn_delete.sh --wait MyCustomWeb
    ./amibake rmi $(CW_NAME_TAG)
    @./cfn_delete.sh --wait MyNetwork
    @rm -f $(DAM)/*.stack $(DAM)/*.ami

この Makefileが makeコマンドを実行すると MyNetwork MyCustomWebAmi MyCustomWebStackターゲットが順にビルドされ、構築されたWebサーバにアクセスしてみると。。。はい、拍手!

MA!.png

最初にインクルードしている AWS-Makefile.mkは現状こんな感じです。まだ幾つか不便な箇所は有るので、適宜修正&追加していく予定です。内容を簡単に説明しておくと .amwmakeディレクトリに指定の *.stackファイルが無い場合は CFnTemplate/*.yamlを create-stackして作成、*.amiファイルが無い場合は AMIBakefile/*.amibを amibake buildして作成、既にビルド済みの場合は前回ビルドしたものを削除してからビルドする等の定義を行っています。

AWS-Makefile.mk
DAM=.awsmake
CFNT=CFnTemplate
AMIB=AMIBakefile
TOOL_PATH=./
CFN_CREATE=cfn_create.sh
CFN_DELETE=cfn_delete.sh
AMIBAKE=amibake

$(DAM)/%.stack: $(CFNT)/%.yaml
    @if [[ -f $@ ]]; then \
        echo $* stack clean; \
        $(TOOL_PATH)$(CFN_DELETE) --wait $* $(CD_OPTS); \
    fi
    @echo $* stack build
    @$(TOOL_PATH)$(CFN_CREATE) --wait $* $< $(CC_OPTS)
    @if [[ ! -d $(DAM) ]]; then \
        mkdir -p $(DAM); \
    fi
    @touch $@

$(DAM)/%.ami: $(AMIB)/%.amib
    @if [[ -f $@ ]]; then \
        echo $* ami clean; \
        $(TOOL_PATH)$(AMIBAKE) rmi $(AB_NAME_TAG) $(AB_OPTS); \
    fi
    @echo $* ami build
    @$(TOOL_PATH)$(AMIBAKE) build -f $< $(AB_OPTS)
    @$(TOOL_PATH)$(AMIBAKE) push $(AB_NAME_TAG) $(AB_OPTS)
    @if [[ ! -d $(DAM) ]]; then \
        mkdir -p $(DAM); \
    fi
    @touch $@

cfn_create & cfn_delete

AWS-Makefile.mkで使用している cfn_create.shと cfn_delete.shは AWS CLIの cloudformationコマンドをラップして、作成するスタック名とテンプレートファイル名、削除するスタック名だけ指定すればよい様にしたスクリプト、–waitオプションで作成、削除の完了待ちをする機能を追加してます。現状 –parametersオプションの指定が冗長なので、近いうちに何とかしたいなと

$ ./cfn_create.sh [--profile <prof>] [--wait] <stack_name> <template_file> [more parameters]

$ ./cfn_delete.sh [--profile <prof>] [--wait] <stack_name> [more parameters]

cfn_create.shに渡している Cloudformationテンプレートは特に解説するつもりは無かったのですが、テンプレート間で作成リソースIDを受け渡しを行っているクロススタック参照部分はわりと調べたので記述例として上げておきます。

CFnTemplate/MyNetwork.yaml(一部抜粋)

Outputs:
  MyVPCId:
    Value: !Ref MyVPC
    Export:
      Name: !Sub ${AWS::StackName}-MyVPCId

CFnTemplate/MyCustomWeb.yaml(一部抜粋)

Resources:
  MyCustomWebSg:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: MyCustomWebSg
      VpcId:
        Fn::ImportValue:
          !Sub ${NetworkStackName}-MyVPCId

Parameters:
  NetworkStackName:
    Type: String
    Default: MyNetwork

amibake

AWS-Makefile.mkで使用している amibakeは AWS CLIと packerコマンドをラップして、Dockerfile風の定義ファイルでカスタムAMIを作成したり、Dockerイメージ風の name:tag で AMIを管理出来る様にしたツールコマンドです。何でこんなものを作ったかというと Docker確かに便利で情報系のサービスや検証環境の構築には凄い良いのだけれど、ミッションクリティカルな用途にはインフラが多重化して障害点が増えるし、パフォチュー&トラシューのノウハウも必要やし、Dockerと同じ操作感でネイティブクラウドインフラが構築出来ればいいじゃね?という発想から、docker-compose相当の部分は Terraformと Cloudformationのどちらを採用するか一瞬検討したけど、管理情報を別建てで保持しなくていいのが楽そうだったので後者を採択

$ amibake tag ami-xxxxxxxx amazonlinux:201703
$ amibake id amazonlinux:201703
$ amibake search amazonlinux

$ # After writing AMIBakefile
$ amibake build
$ amibake push my_app:20170819
$ amibake run my_app:20170819
AMIBakefile/MyCustomWeb.amib
# AMIBakefile: MyCustomWeb
MAINTAINER nmrmsys
FROM ami-da9e2cbc # Amazon Linux AMI 2017.09.1 (HVM), SSD Volume Type
USER ec2-user
#BUILDER "vpc_id":"vpc-xxxxxxxx","subnet_id":"subnet-xxxxxxxx","associate_public_ip_address":true

COPY AMIBakefile/MyCustomWeb.sh ~/
COPY AMIBakefile/html/index.html ~/

RUN sudo sh ~/MyCustomWeb.sh
RUN sudo mv ~/index.html /var/www/html/

ami_backups & aws_stops

AWS-Makefileとは全く関係無いですが AWS CLIと jqの組み合わせで作ってみたシリーズのスクリプトで ami_backupsは EC2のタグにバックアップ指定を設定しておくと取ってくれるヤツ、売りはAMIでn世代バックアップとか出来る点と –dry-runオプションで動作確認出来る様にした所でしょうか、aws_stopsは RDSのSingleAZインスタンスが停止が可能になったけど 1週間で勝手に上がってくるぜって時に、なら毎日朝晩に開始停止をすればいいんじゃね? と RDS ついでに EC2も同じくタグ設定に基づいて所定の時刻に開始停止させるようにしたヤツです。

ami_backups [--profile <prof>] [--all | <inst>] [--dry-run] [--reboot] [--oneshot [suffix]] [--no-wait]

# Tag Setting Backup Mode
# Setting Backup Instance Tag 
# Backup:on, Generation:3, Reboot:off (optional) 
ami_backups --profile prof1 --all 

# Single Instance Backup Mode
ami_backups --profile prof1 inst1 

# First time running recommended to add --dry-run option.
aws_stops --profile <prof> [--dry-run <target_time>]

# Setting Stop/Start Instance Tag 
# Stop: 22:00, Start: 08:00 
aws_stops --profile prof1 

# First time running recommended to add --dry-run option.
# In actual operation, use cron

車輪の再発見とか

まーあれですよ『枯れた技術の水平思考』とでも言うと思ったかい、その態度、想定の範囲内だよ!
ルネサンスが古代ギリシャ・ローマの文化の再発見であったかのように歴史は何度でも繰り返される。
であるなら、最新のコジマ技術を獲得するのと同程度には、過去の用兵術にも目を向けるべきであろう

参考文献

続きを読む