aws周りのメモ2

postgresqlを使う

RDSへpostgresqlをいれて立ち上げ

認証と接続

import-key-pair — AWS CLI 1.11.87 Command Reference
http://docs.aws.amazon.com/cli/latest/reference/ec2/import-key-pair.html

cd $HOGE
openssl genrsa -out my-key.pem 2048
openssl rsa -in my-key.pem -pubout > my-key.pub
# IAMのコンパネで*.pubを入力
# 多分、権限があれば以下でもいける
# aws iam upload-ssh-public-key

【AWS 再入門】EC2 + RDS によるミニマム構成なサーバー環境を構築してみよう – NET BIZ DIV. TECH BLOG
https://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/

便利

無料枠

無料のクラウドサービス | AWS 無料利用枠
https://aws.amazon.com/jp/free/

AMI

AWS Marketplace: Search Results
https://aws.amazon.com/marketplace/search/results?x=14&y=18&searchTerms=&page=1&ref_=nav_search_box

CFテンプレート

サンプルコード & テンプレート – AWS CloudFormation | AWS
https://aws.amazon.com/jp/cloudformation/aws-cloudformation-templates/

ec2 ami tool & ec2 api tool

Mac で Amazon EC2 API Toolsを設定する – サーバーワークスエンジニアブログ
http://blog.serverworks.co.jp/tech/2013/01/31/mac-amazon-ec2-api-tools-setup/

ec2 api toolは若干心配。

VPCを使う

接続の際に、sshを経由したい。sslでもいいけどなんかsshがいいなと。
パスワードよりkeyのほうがセキュアだからかな。

0から始めるAWS入門①:VPC編 – Qiita
http://qiita.com/hiroshik1985/items/9de2dd02c9c2f6911f3b

導入

Amazon VPC とは? – Amazon Virtual Private Cloud
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Introduction.html

公式のいろいろ

料金 – Amazon VPC | AWS
https://aws.amazon.com/jp/vpc/pricing/

基本は無料だけどNATとVPNは別課金。

【AWS 再入門】VPC 環境に踏み台サーバーを構築して SSH 接続してみよう – NET BIZ DIV. TECH BLOG
https://tech.recruit-mp.co.jp/infrastructure/retry-aws-bastion-host-vpc/#i-3

ec2(Bastion)を配置する必要がありそう。

【AWS 再入門】EC2 + RDS によるミニマム構成なサーバー環境を構築してみよう – NET BIZ DIV. TECH BLOG
https://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/

VPC に推奨されるネットワーク ACL ルール – Amazon Virtual Private Cloud
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/VPC_Appendix_NACLs.html

vpcでのネットワークのポリシーの例

Default VPC

AWSのDefault VPCを削除して困った話 – MikeTOKYO Developers
http://blog.miketokyo.com/post/49939300091/aws-default-vpc

デフォルトvpcは削除したらダメか。使い分けがわからん。

Amazon EC2 と Amazon Virtual Private Cloud – Amazon Elastic Compute Cloud
http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-vpc.html

基本の機能はデフォルトとそうじゃないvpcは同じだけど、
デフォルトvpcがないとちゃんと機能しない。
デフォルトの属性によって、指定がないとipを紐付けたりする。

VPCネットワーク設計

これだけ押さえておけば大丈夫!Webサービス向けVPCネットワークの設計指針 | eureka tech blog
https://developers.eure.jp/tech/vpc_networking/

ネットワークは一度稼働させると移行が大変なので、初期設計が非常に重要になります。

わかりやすい。図が特に。

  • Bastion
  • NAT
  • Security Group

ENI

インフラエンジニアに贈るAmazon VPC入門 | シリーズ | Developers.IO
http://dev.classmethod.jp/series/vpcfor-infra-engineer/

サブネットで指定したIPアドレスのうち、先頭4つと末尾の1つはVPCで予約されるため使用できません。

VPCでは常にDHCP有効とするのがポイントです。

また、DHCPサービスで伝えられる情報(DHCPオプション)は、変更することもできます。

仮想マシンにひもづくENIにより、DHCPサーバーから毎回同じMACアドレス、IPアドレスが付与されます。これは、仮想マシンの状態に依存しないため、仮想マシンを再起動しようと、一旦シャットダウンしてしばらくしてから起動した場合でも必ず同じアドレスが付与されます。

ENI(Elastic Network Interface)か。。なるほど。でも、使うことはなさそうだな。

NAT

IPマスカレードが使えないVPC
NATは、Static(静的・サーバー用途)とElastic(仮想・クライアント用途)がある。
個人的には、このNATインスタンスの実装は、あまり好きではありません。動きがややこしいですし、ユーザーが自分でNATインスタンスの管理をしなければならないのも煩雑な印象を受けます。VPCのネットワークサービスの一つとして提供される機能であれば、ユーザーからはなるべく抽象化され仮想マシンとして意識されないようにするべきと考えます。
ただ、ユーザーから仮想マシンとして見える分、機能・実装が具体的に把握できる点やカスタマイズ性が高い点は良いとも思っています。

NAT インスタンスと NAT ゲートウェイの比較 – Amazon Virtual Private Cloud
http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/vpc-nat-comparison.html

なるほど。。

Bastion

AWSで最低限セキュアな構成を組む – Qiita
http://qiita.com/ausuited/items/09b626fa5264f0c650fd

パブリックSubnetにEC2インスタンス(踏み台サーバーとして)
NATインスタンスを作成した要領で、パブリックSubnetにEC2インスタンスを作成する。Security groupは新規に作成してSSHをAnywhereに。Key pairは厳重に管理。尚、踏み台サーバーは、使用する時以外はStoppedにしておく事で、さらにセキュアな状態とする。このデザインパターンをOn Demand Bastionパターンと呼ぶらしい。

詳しい。「On Demand Bastionパターン」か。なるほど。

vpcへの踏み台サーバー
ポートフォワーディング、トンネルなどと同じ意味。

Network ACL

インスタンス単位じゃなくサブネット単位でより制限してセキュアにしたい場合に使うのかな。

安全なVPC設計 — Commerce Hack
http://tech.degica.com/ja/2016/01/07/designing-vpc-and-subnets/


結局どうするのか、、ひとまずNATはつかわずに、Bistionをつくってみる感じかな。

アベイラビリティーゾーン

リージョンごとでの、障害などで全部やられないように物理的にセグメントされた範囲の単位かな。
RDSではセグメントグループに2つ以上のゾーンを含める。でも、一つしか使わなくていい。ということか。s

RDSのVPC間の移動

サブネットグループの関連付けを変えればいいらしい。間違って設定したので移動した。

【小ネタ】知っていましたか?RDSを別のVPCに移動できることを | Developers.IO
http://dev.classmethod.jp/cloud/aws/rds_can_move_to_another_vpc/

Bastion作成作業をしてみる

主に下記を参考。

【AWS 再入門】EC2 + RDS によるミニマム構成なサーバー環境を構築してみよう – NET BIZ DIV. TECH BLOG
https://tech.recruit-mp.co.jp/infrastructure/retry-aws-minimum-vpc-server-environment/

  • サブネットってなんだっけとか復習。
  • ストレージはどうするのか。
    • とりあえずssdにしたけどマグネティックでよかったかなあ。

      • ssd:$0.12 : 1 か月にプロビジョニングされたストレージ 1 GB あたり
      • マグネティック: 0.05 USD/GB-月
  • public IPは設定必要だよね
  • market placeからamiを取得した方がいいの?
    • とりあえず公式のウィザードを使ったけど。
  • 認証にIAMが追加されていたので使ってみた
    • これとは別にキーペアは必要ってことかな。
  • CFnテンプレート(CloudFormationテンプレート)というのがあるらしい。。
    • これでつくりなおそうかな。。
  • サブネットとかいろいろネットワーク系の設定
    • なんだかんだいっていろいろあった
  • セキュリティグループ
    • エイリアスみたいなセキュリティグループにできたらいいのに。タグや名前で明示化かな。
    • bastionは22をあけて、rdsは5432をbastionからのみあける
  • ログイン
  • DNS
    • あれ、パブリックDNSがうまく割り振ってないな。。
      AWSでPublic DNS(パブリックDNS)が割り当てられない時の解決法 – Qiita
      http://qiita.com/sunadoridotnet/items/4ea689ce9f206e78a523
    • RDSのDNS
      • nslookupしたら内部ipがかえってくるのね。接続できないけどなんか気持ち悪いな。これかな。。
        外部からdnsを引けることを気にしている人は見かけなくて便利だからって話なのかね。
        【AWS】VPC内でPrivate DNSによる名前解決 – Qiita
        http://qiita.com/y_takeshita/items/2eb5e6abb5eb5516d1de

やってるうちはいいけど、しばらくやらないと設定の方法とか忘れそう。。こういうのは学習コストだけじゃないな。

PlantUMLで図にしておく

Kobito.hQIwJs.png

VPC内のRDSへLambdaから接続。。

しまった!アンチパターンだそうだ。。

Lambda+RDSはアンチパターン – Qiita
http://qiita.com/teradonburi/items/86400ea82a65699672ad

Lambda + RDS benchmark – Qiita
http://qiita.com/taruhachi/items/3f95ae3e84f56edb3787

新し目の記事でIAM認証でクリアできそうな。。

【全世界待望】Public AccessのRDSへIAM認証(+ SSL)で安全にLambda Pythonから接続する – サーバーワークスエンジニアブログ
https://blog.serverworks.co.jp/tech/2017/04/27/rds-iam-auth-lambda-python/


セキュアに接続するのと速度のトレードオフになっていたのが
IAM認証のおかげで両方可能になったということっぽい。
でも、ネットのスループット、コネクション数(料金・負荷)、など、、ほかにも気にすることが出て来そうで若干不安。
非同期でよければキューイングして一回投げっぱなしすればどうだろう。
もしくは、似てるけど、Lambdaから一回値を返してもらってからRDSへ投げ直す。
これでいっかなあ。。Lambdaの意味がなくなる?うーん。

今後

  • 疑問としてrdsなど内部向けのdnsを外から見れなくできないものか。
  • というか、rdsのエンドポイントって再起動したら変わったりしないかね。ipは固定されるのか。
    • たぶん、サブネット内でdhcpになるのでipは変動するけどエンドポイントは固定。。じゃないかしら。

posgresqlをつかうための情報

Amazon RDS 上の PostgreSQL – Amazon Relational Database Service
http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.SSL

続きを読む

AWS CLIからAthenaのクエリを実行してみた

AWS CLIがAthena対応したので、試してみました。
(いや〜JDBC接続とかめんどかった・・・)

利用環境はMacです

AWS CLIをバージョンアップ

利用していたAWS CLIのバージョンは1.11.88でした

$ aws --version
aws-cli/1.11.88 Python/2.7.10 Darwin/15.6.0 botocore/1.5.51
$ aws help | grep athena

もちろんAthenaが入っていないのでバージョンアップします
–ignore-installed sixをつけないとバージョンアップできないのはなんとかならないかな・・・

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

バージョンアップ完了

$ aws --version
aws-cli/1.11.89 Python/2.7.10 Darwin/15.6.0 botocore/1.5.52
$ aws help | grep athena
       o athena

ドキュメントを眺める

コマンド一覧

  • batch-get-named-query
  • batch-get-query-execution
  • create-named-query
  • delete-named-query
  • get-named-query
  • get-query-execution
  • get-query-results
  • list-named-queries
  • list-query-executions
  • start-query-execution
  • stop-query-execution

コマンド実行してみる

本日時点ではAthenaが東京リージョンに来てないので、コマンドに–region us-east-1(バージニアリージョン)を指定。(諸事情でprofileは使わない)
すでに、CloudFrontとCloudTrailのログをAthena上に配置
Athenaを使ってAWSのログを集計する

start-query-execution

クエリを実行するコマンド。
必須パラメータ
–query-string:Stringでクエリを記述。FROM句にDB名は必須。
–result-configuration:結果を出力するS3バケットを指定

$ aws --region us-east-1 athena start-query-execution 
    --query-string "SELECT * FROM aws_logs.cloudfront_log limit 10;" 
    --result-configuration OutputLocation=s3://athena-output
{
    "QueryExecutionId": "9d5f2f3a-e80f-4807-ab6c-35139924d374"
}

get-query-results

クエリの実行結果を見る

$ aws --region us-east-1 athena get-query-results 
    --query-execution-id 9d5f2f3a-e80f-4807-ab6c-35139924d374
{
    "ResultSet": {
        "Rows": [
            {
                "Data": [
                    {
                        "VarCharValue": "date"
                    }, 
                    {
                        "VarCharValue": "time"
                    }, 
                    {
                        "VarCharValue": "xedgelocation"
                    }, 
                    {
                        "VarCharValue": "scbytes"
                    }, 
                    {
                        "VarCharValue": "cip"
                    }, 
                    {
                        "VarCharValue": "csmethod"
                    }, 
                    {
                        "VarCharValue": "cshost"
                    }, 
                    {
                        "VarCharValue": "csuristem"
                    }, 
                    {
                        "VarCharValue": "scstatus"
                    }, 
                    {
                        "VarCharValue": "csreferer"
                    }, 
                    {
                        "VarCharValue": "csuseragent"
                    }, 
                    {
                        "VarCharValue": "csuriquery"
                    }, 
                    {
                        "VarCharValue": "cscookie"
                    }, 
                    {
                        "VarCharValue": "xedgeresulttype"
                    }, 
                    {
                        "VarCharValue": "xedgerequestid"
                    }, 
                    {
                        "VarCharValue": "xhostheader"
                    }, 
                    {
                        "VarCharValue": "csprotocol"
                    }, 
                    {
                        "VarCharValue": "csbytes"
                    }, 
                    {
                        "VarCharValue": "timetaken"
                    }, 
                    {
                        "VarCharValue": "xforwardedfor"
                    }, 
                    {
                        "VarCharValue": "sslprotocol"
                    }, 
                    {
                        "VarCharValue": "sslcipher"
                    }, 
                    {
                        "VarCharValue": "xedgeresponseresulttype"
                    }, 
                    {
                        "VarCharValue": "csprotocolversion"
                    }
                ]
            }, 
            {
                "Data": [
                    {
                        "VarCharValue": "2017-03-11"
                    }, 
                    {
                        "VarCharValue": "07:09:39"
                    }, 
                    {
                        "VarCharValue": "NRT20"
                    }, 
                    {
                        "VarCharValue": "485"
                    }, 
                    {
                        "VarCharValue": "182.251.62.172"
                    }, 
                    {
                        "VarCharValue": "GET"
                    }, 
                    {
                        "VarCharValue": "d296z2px268if9.cloudfront.net"
                    }, 
                    {
                        "VarCharValue": "/sample"
                    }, 
                    {
                        "VarCharValue": "200"
                    }, 
                    {
                        "VarCharValue": "-"
                    }, 
                    {
                        "VarCharValue": "curl/7.43.0"
                    }, 
                    {
                        "VarCharValue": "-"
                    }, 
                    {
                        "VarCharValue": "-"
                    }, 
                    {
                        "VarCharValue": "Miss"
                    }, 
                    {
                        "VarCharValue": "7_kRmqTCtndlAsdecditmwIL3kPgVKjsqBggBEFSu68_tsTGWAVK-g=="
                    }, 
                    {
                        "VarCharValue": "d296z2px268if9.cloudfront.net"
                    }, 
                    {
                        "VarCharValue": "https"
                    }, 
                    {
                        "VarCharValue": "99"
                    }, 
                    {}, 
                    {
                        "VarCharValue": "-"
                    }, 
                    {
                        "VarCharValue": "TLSv1.2"
                    }, 
                    {
                        "VarCharValue": "ECDHE-RSA-AES128-GCM-SHA256"
                    }, 
                    {
                        "VarCharValue": "Miss"
                    }, 
                    {
                        "VarCharValue": "HTTP/1.1"
                    }
                ]
            }, 
・・・

これ使いにくい・・・

get-query-execution

クエリ実行結果(成功/失敗)等の情報を取得する
start-query-executionで実行した結果を取得
必須パラメータ
–query-execution-id:実行時に表示されるQueryExecutionIdを指定

$ aws --region us-east-1 athena get-query-execution 
    --query-execution-id 9d5f2f3a-e80f-4807-ab6c-35139924d374
{
    "QueryExecution": {
        "Status": {
            "SubmissionDateTime": 1495269759.131, 
            "State": "SUCCEEDED", 
            "CompletionDateTime": 1495269762.711
        }, 
        "Query": "SELECT * FROM aws_logs.cloudfront_log limit 10", 
        "Statistics": {
            "DataScannedInBytes": 1454, 
            "EngineExecutionTimeInMillis": 3475
        }, 
        "ResultConfiguration": {
            "OutputLocation": "s3://athena-output/3fbf61dd-866e-4de6-9ba4-56cfdb671964.csv"
        }, 
        "QueryExecutionId": "3fbf61dd-866e-4de6-9ba4-56cfdb671964"
    }
}

StatusにSUCCEEDEDと表示されるので成功している
結果は実行時に指定したS3バケット内にCSVで保存される→OutputLocation

スクリプトを組むならこんな感じ?

athena-query.sh
#!/bin/bash

OutputBucket=athena-output # 出力バケット
# クエリ実行
queryId=$(aws --region us-east-1 athena start-query-execution 
    --query-string "SELECT * FROM aws_logs.cloudfront_log limit 10;" 
    --result-configuration OutputLocation=s3://$OutputBucket 
    | jq -r '.QueryExecutionId')
# 結果の確認
status=$(aws --region us-east-1 athena get-query-execution 
    --query-execution-id $queryId 
    | jq -r '.QueryExecution.Status.State')

if [ "$status" == "SUCCEEDED" ]; then
    aws s3 cp s3://${OutputBucket}/${queryId}.csv .
else
    echo "Query Error!"
fi

cat ${queryId}.csv

まとめ

  • 待望のAthenaがAWS CLIに対応しました。
  • BigQueryはbqコマンドで実行できたので、足並み揃い始めた感じでしょうか
  • もうすぐ東京リージョンに来そうな感じなので、期待大です(Comming Soonってなってるので、AWS Summit Tokyoで発表!?)
  • 出力結果がもっといい感じに見れるといいですね

続きを読む

AWSアカウントを作成して、はじめにすること

一番最初にしておきたいことをまとめていきます。

1.MFA(Multi-Factor Authentication)の設定

AWSアカウントを作成するとrootでログインされます。
rootが乗っ取られれないようにMFAの設定は必ずやっておきたいと思います。
以下は、その手順です。

MFAデバイスの用意

公式のMFAページ https://aws.amazon.com/jp/iam/details/mfa/

仮想MFAデバイス

専用のMFAデバイスを購入するほどでもないので、手元のスマートフォンを仮想MFAデバイスとして使用したいと思います。
以下から、MFAアプリケーションをインストールします。

Kobito.PBL4mn.png

IAM(Identity & Access Management)コンソールを表示

  • 次にIAMコンソールからMFAの設定をしていきたいと思います。

Kobito.xZW6Wa.png

「ルートアカウントのMFAを有効化」を選択する

Kobito.EGJ2EL.png

Kobito.qF3Fsw.png

用意した仮想MFAデバイスでQRコードを読み込むと数字が表示されます。
時間が経つと数字が変わるので気をつけてください。

「認証コード1」に数字を入力したら、次に表示される数字を「認証コード2」に入力して「仮想MFAの有効化」をクリックしてください。

再ログインする

次回移行ログインするときは、MFAの確認を要求されるので仮想MFAデバイスに表示されている数字を入力してください。
※ MFAの仮想デバイスの管理には気をつけてください。

2.ユーザーアカウント(IAMユーザー)を作成する

通常使用するようにアカウントを作成したいと思います。

Kobito.JtGo41.png

IAMコンソールの←メニューから「ユーザー」を選択して、「ユーザーを追加」をクリックする

Kobito.x1CcjW.png

ユーザ名を入力して、完了画面を表示する。
Kobito.Kn6G2n.png
アクセスキー、シークレットアクセスキー、パスワードを保持して、別ブラウザでログインをする。

Kobito.SEtuFi.png

最後に権限を付与する

3.CloudTrailの設定

操作ログを記録するようにしたいと思います。

Kobito.A9Mtrw.png

Kobito.x9PIKJ.png

4.開発環境の設定

CLIをローカルの環境にインストールします。

sudo pip install awscli

インストール時に以下のエラーが発生

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:

以下のコマンドで無事にインストール完了
こちらを参考:https://saku.io/failed-to-install-awscli-on-mac/

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

続きを読む

AWS S3 に手軽にファイルをアップロードする方法 (Cyberduck, Transmit or Coda 2.5)

concrete5 のサイトで、S3 にファイルマネージャー内のファイルを保存しています。

その際、concrete5 (ブラウザ + PHP) ではアップロードしきれない大容量ファイルをアップする必要があったので、メモとして残します。

Cyberduck や Transmit、 Coda 2.5 が良い

AWS CLI は、1端末につき1アクセスIDしか付与できませんので、複数アカウント管理している場合、切り替えが面倒です。

無料 (寄付型) ソフトで Mac & Windows 版がある Cyberduck や私が使っている、 Coda 2.5 や Transmit でも Amazon S3 を FTP のように扱える機能がついています。

各ソフト

設定のメモ

  • 接続設定を開く
  • Access ID を登録
  • シークレットキーを入力
  • アクセスできるバケットやフォルダを制限していたら、パスに
    • /[バケット名]/[フォルダ] などアクセスできる先のフォルダを入力する(そうじゃないと権限エラーで接続できない)
  • あとは FTP のようにファイルをやり取りする

参考記事

IAM アカウントを作成

AWS コンソールから IAM アカウントを作成します。

  • IAM ユーザーを作成
  • S3 の権限を付与
    • S3FullAccess ではなく、特定バケットや特定ディレクトリ内のみの権限をあげるようにしましょう。(後述)
  • アクセスキーと、シークレットキーを生成してダウンロード

AWS CLI も良い

AWS CLI を使ってコマンドラインから送る方法もありますが、それは、いろいろ先人の方が記事をかかれているので、検索されると良いかもです。

参考記事

以上

続きを読む

AWS Windows Server 2016でのJMeter環境構築(分散環境編)

この記事では、AWS ec2のWindows Server 2016に、JMeter3.2の環境構築をしました。また、CentOS7と組み合わせた分散環境を構築します。Windows側をマスターに、CentOS側をスレーブにします。リモートデストクップクライアントは、Microsoft Remote Desktop for Mac Beta version 8.2.31を利用しています。

1. Windows単独環境でのJMeter構築

単独環境での構築については、「AWS Windows Server 2016でのJMeter環境構築」を参考にしてください。

2. CentOSでのJMeter構築

ec2でのCentOS7の初期セットアップについては省略します。

必要なコンポーネントを追加します。

$ sudo yum update -y
$ sudo yum install wget -y
$ sudo yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel -y
$ sudo wget http://archive.apache.org/dist/jmeter/binaries/apache-jmeter-3.2.tgz -P /opt/

ダウンロードしたJMeter3.2をインストールします。

$ sudo tar zxvf /opt/apache-jmeter-3.2.tgz -C /opt/

自動起動を設定します。IPアドレスは環境に合わせて指定してください。

$ sudo vi /etc/rc.local
ファイル末尾に
/opt/apache-jmeter-3.2/bin/jmeter-server -Djava.rmi.server.hostname=172.31.27.62 &
を追加します。
$ sudo chmod +x /etc/rc.local

同時接続数を大きくしてもよいように、ファイルディスクリプタの最大数を拡張します。

$ sudo vi /usr/lib/systemd/system/rc-local.service
ファイル内の [Service] の配下に
LimitNOFILE=64000
を追加します。

再起動して動作確認します。

$ ps -ax | grep jmeter
  760 ?        S      0:00 /bin/sh /opt/apache-jmeter-3.2/bin/jmeter-server -Djava.rmi.server.hostname=172.31.27.62
  767 ?        S      0:00 /bin/sh /opt/apache-jmeter-3.2/bin/jmeter -Dserver_port=1099 -s -j jmeter-server.log -Djava.rmi.server.hostname=172.31.27.62
  905 ?        Sl     0:01 java -server -XX:+HeapDumpOnOutOfMemoryError -Xms512m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=250 -XX:G1ReservePercent=20 -Djava.security.egd=file:/dev/urandom -jar /opt/apache-jmeter-3.2/bin/ApacheJMeter.jar -Dserver_port=1099 -s -j jmeter-server.log -Djava.rmi.server.hostname=172.31.27.62
 9107 pts/0    R+     0:00 grep --color=auto jmeter
$ cat /proc/`pgrep java | head -1`/limits | grep 'open files'
Max open files            64000                64000                files     

同様の環境を計4セット構築します。

3. マスター設定

Windwosファイアウォールをオフにします。これをしないと、スレーブとうまく通信できません。

Windows側のJMeterのインストールフォルダ配下binにある、jmeter.propertiesを設定します。IPアドレスは環境に合わせてください。

jmeter.properties
remote_hosts=172.31.27.62,172.31.26.37,172.31.20.153,172.31.28.111

4. Jmeterの実行

JMeterを起動して、「AWS Windows Server 2016でのJMeter環境構築」で作成したテストシナリオを呼び出します。

スクリーンショット 2017-05-05 16.54.00.png

今度は、右上の緑矢印が2つ書かれているボタンをクリックします。
すると、4台分に相当する、約4000リクエスト/秒の性能が測定されていることがわかります。

スクリーンショット 2017-05-05 16.57.22.png

続きを読む

AWS Windows Server 2016でのJMeter環境構築

この記事では、AWS ec2のWindows Server 2016に、JMeter3.2の環境構築をしました。リモートデストクップクライアントは、Microsoft Remote Desktop for Mac Beta version 8.2.31を利用しています。

この記事の発展として、CentOSでのスレーブと組み合わせた分散環境の構築について「AWS Windows Server 2016でのJMeter環境構築(分散環境編)」で解説しています。

1. Windows Serverの環境構築

1.1. Windows Serverのインスタンス作成

AMIのクイックスタートから、Microsoft Windows Server 2016 Base、インスタンスタイプt2.mediumを選択します。

セキュリティグループを以下に設定します。

タイプ プロトコル ポート範囲 送信元
すべてのトラフィック すべて すべて 172.31.0.0/16
RDP TCP 3389 マイIP

タグとして、Name: ec2-JMmasterを追加します。

キーペアを作成するか既存のものがあれば選択して、インスンスを作成します。

1.2. リモートデスクトップ接続

ec2マネジメントコンソールから、先ほど作成したec2-JMmasterを選択して、上にある「接続」ボタンを押下します。ダイアログボックスにおいて「パスワードの取得」を選択して、キーペアの中身をコピーして、バスワードを表示させます。

リモートテスクトップクライアントに表示された内容を設定します。

サーバーをシャットダウンするとパブリックIPアドレスが変わるため、リモートデスクトップクライアントのPC nameを再設定する必要がありますので、注意してください。

これで、リモートデスクトップからWindows Serverにログインできます。

自動的に初期設定された後、他のPCから検索されてよいか?と出ますので、とりあえずNOとしておきます。

1.3. Windowsの日本語化

コントロールパネルからAdd a languageを選択します。日本語を追加して、Optionsをクリックして、Download and install language packをクリックし、インストールします。

インストール完了後、再度Optionsをクリックして、Make this the primary languageをクリックし、ログオフします。

再度リモートデスクトップからログオンすると、日本語環境になっています。

コントロールパネルから、時計、言語、および地域を選択して、タイムゾーンを日本に変更します。また、地域をクリックして、ダイアログボックスの場所タブで日本を、管理タブでシステムロケールを日本に変更します。(再起動が必要です)

次に、キーボードを日本語配列にしたいのですが、macのリモートデスクトップで日本語配列キーボードを使うのは難関のようです。いろいろググって試すものの、私の環境ではうまくいきませんでした。

1.4. IEのセキュリティ設定の解除

デフォルトでは、IEセキュリティ強化の構成がオンになっており、あちこちブラウズして必要なソフトをダウンロードするにあたって、頻繁にアラートが表示されますので、これをオフにしておきます。

「サーバー マネージャ」で、「ローカル サーバー」「プロパティ」セクションで、オプション「IE セキュリティ強化の構成」の設定を「オフ」に切り替えます。

2. JMeterのインストール

2.1 Javaランタイムのインストール

Javaのランタイムをインストールします。この記事では、Version 8 Update 131(リリース日 2017年4月18日)でした。

2.2 JMeter本体のインストール

Download Apache JMeterのページから最新版v3.2をダウンロードして、展開します。出来上がったapache-jMeter-3.2フォルダを、Program Filesに移動して、bin配下のjmeter(Windowsバッチファイル)のショートカットを、デスクトップに配置してくと便利です。

バッチファイルにより、JMeterが無事に起動することを確認します。

スクリーンショット 2017-05-05 13.57.57.png

2.3 JMeter pluginsのインストール

Download JMeter-Plugins.org から、plugins-managerをダウンロードして、JMeterのlib/extに配置します。再度JMeterを起動すると、オプションメニューでPlugins Managerを選択できるようになります。

ここでは、Plugins Managerから、3 Basic Graphsを選択して、イントスールしておきましょう。

3. JMeterの実行

3.1 テスト計画の作成

ツリーメニューの中から、テスト計画を右クリックして、スレッドグループを選択します。

スクリーンショット 2017-05-05 14.11.06.png

スレッド数1000、Ramp-Up期間10、ループ回数10を設定します。
なお、スレッド数をかなり大きくすると、テストが正常に終了しないようです。

スクリーンショット 2017-05-05 15.11.40.png

テスト計画を再度右クリックして、リスナーからjp@gc – Transactions per Secondを選択します。

スクリーンショット 2017-05-05 14.15.17.png

スレッドグループを右クリックして、サンプラーからHTTPリクエストを追加します。

スクリーンショット 2017-05-05 14.17.47.png

別に用意してあるWebサーバー名(IPアドレス)と、パスを指定します。

スクリーンショット 2017-05-05 14.20.08.png

以上で準備は終わりです。作成したテスト計画をセーブしておきます。

3.2 テスト実行と結果の確認

ツールバーから、緑の右三角をクリックしてテストを実行します。
実行結果はグラフで見ることができます。

スクリーンショット 2017-05-05 15.12.43.png

続きを読む

AWS x OpenVPNでP2P接続できる環境を作る

目的

遠隔地の端末XにNATを挟まずに接続したい!

端末Xの既存環境はいじりたくない!

(ついでに、クラウドと連携できると夢が広がるね!)


上記実現のために、

  1. VPN接続、かつルーティングのみで構成する
  2. 端末Xが接続するルーター(ex.ラズパイ等)に、VPNクライアント環境を構築する
  3. AWSパブリックサブネット上にVPNサーバーを構築する

想定するネットワークは以下の通り

image

赤、青、黒色のIPアドレスはそれぞれのサブネット内で割り振られたもので、紫色のIPアドレスはVPNネットワーク上で割り振られるアドレスとする

ここで、赤のVPNクライアント(10.8.0.6)から、青のVPNクライアントサブネット上の端末X(192.168.20.5)に、プライベートアドレス指定でアクセス可能な環境を構築する

具体的にやること

上記環境を構築するために、以下の手順で作業を行う

  1. AWSパブリックインスタンスにOpenVPNを導入する
  2. OpenVPN接続用の証明書を発行する
  3. サーバーの準備をする
  4. クライアントの準備をする
    1. mac編
    2. ubuntu編
  5. 各サブネットに接続確認を行う

なお、VPNクライアントすべてに対して、OpenVPN環境は未導入、VPNクライアント兼ルーターにはRaspberryPiを使用し、すでにルーターとして利用可能な状態であるとする

また、赤のVPNクライアントのOSはmacとする

1. AWSにOpenVPNを導入する

前提条件

AWS上のVPC、及びその内部のパブリックサブネットとプライベートサブネットは作成済みであるものとし、作成方法などの解説は行わない

以下に最低限必要な設定を示す

AWSパブリックサブネット上でVPNサーバーとして利用するインスタンスのOSには、Amazon Linux AMI 2016.09.1(HVM)を使用する

ボリュームサイズや処理性能は特に指定しないが、セキュリティグループ設定の際に、ssh及びVPN接続用に以下のポートを空けておく

  • ssh接続用ポート

    • タイプ:SSH
    • プロトコル:TCP
    • ポート範囲:22
    • 送信元:任意
  • VPN接続用ポート
    • タイプ:カスタムUDPルール
    • プロトコル:UDP
    • ポート範囲:1194
    • 送信元:任意

VPN接続用のポート設定は以降で利用する

他、必要に応じてソフトウェアの更新などを行っておく

合わせて、接続確認用にプライベートサブネット上にインスタンス(10.0.1.228)を立ち上げておく

パブリックサブネット上のインスタンスをOpenVPNサーバーとして動かすに当たり、導入が必要なものは以下の二つである

1. OpenVPN(v2.3.12)
2. easy-rsa(証明書方式の場合)(v3.0.0)

まずはsshでインスタンスに接続し、これらを導入する

OpenVPNのインストール

OpenVPNはyumでインストールできる

$ sudo yum install -y openvpn
...
完了しました!

基本的に、自動で自動起動に登録される

easy-rsaのインストール

拡張性、安全性、そして複数のクライアントを管理するVPNを構成するために、easy-rsaを利用する

easy-rsaはバイナリを取得、解凍して導入する

また、以降の作業は/usr/local/EasyRSA/ディレクトリ下で行うので移動しておく

$ wget https://github.com/OpenVPN/easy-rsa/releases/download/v3.0.0-rc2/EasyRSA-3.0.0-rc2.tgz
...
2017-03-28 02:22:13 (107 KB/s) - `EasyRSA-3.0.0-rc2.tgz' へ保存完了 [34886/34886]
$ tar -xvzf EasyRSA-3.0.0-rc2.tgz
...
EasyRSA-3.0.0-rc2/easyrsa
$ sudo mv EasyRSA-3.0.0-rc2 /usr/local/EasyRSA
$ cd /usr/local/EasyRSA/

2. OpenVPN接続用の証明書を発行する

easy-rsaの初期設定

easy-rsaを導入した際には、以下のコマンドで認証情報を生成するための初期設定を行う必要がある

  1. init-pki
  2. build-ca
  3. gen-dh

init-pki

init-pkiを実行し、初期化を行う

$ ./easyrsa init-pki
init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /usr/local/EasyRSA/pki

ここで生成された/usr/local/EasyRSA/pki/ディレクトリに、以降の手順で生成する認証用ファイルが配置される

build-ca

build-caで認証局を作成する

$ ./easyrsa build-ca
Generating a 2048 bit RSA private key
.+++
..+++
writing new private key to '/usr/local/EasyRSA/pki/private/ca.key'
Enter PEM pass phrase:<パスフレーズ>
Verifying - Enter PEM pass phrase:<パスフレーズ(確認)>
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:<ホスト名等>
CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/usr/local/EasyRSA/pki/ca.crt
  • <パスフレーズ>:任意のパスワード

    • 証明書の発行の際に必要、覚えておくこと
  • <ホスト名等>:認証局を識別するための名称
    • 本気で運用するならばつけるべき
    • 今回はVPN接続目的のみのため適当な名称 or デフォルトで可

gen-dh

gen-dhでDHパラメータを生成する

  • DH:Diffie-Hellman

    • 公開鍵暗号方式の具体的な方法の一つ
    • DHは公開鍵暗号方式の概念を初めて公開した人たちの名前
$  ./easyrsa gen-dh
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
...

DH parameters of size 2048 created at /usr/local/EasyRSA/pki/dh.pem

以上で、証明書の発行準備は完了である

次の手順から、実際に使用するサーバー/クライアント向けの認証ファイルの生成を行っていく

サーバー用秘密鍵・証明書の生成

build-server-fullでサーバー用秘密鍵と証明書の作成、及び署名を行う

$ ./easyrsa build-server-full server nopass
Generating a 2048 bit RSA private key
..........................+++
..................................+++
writing new private key to '/usr/local/EasyRSA/pki/private/server.key'
-----
Using configuration from /usr/local/EasyRSA/openssl-1.0.cnf
Enter pass phrase for /usr/local/EasyRSA/pki/private/ca.key:<登録したパスフレーズ>
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until Mar 26 02:26:31 2027 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated
  • 証明書読み込み時にパスフレーズ不要とする場合はnopassオプションを使用する

    • オプションを使用しない場合、VPN接続時に毎回、パスフレーズの入力が求められる
  • 途中でCA証明書生成時に設定したパスフレーズの入力を求められるので入力する

クライアント用秘密鍵・証明書の生成

build-client-fullでクライアント用秘密鍵と証明書の作成、及び署名を行う

以下に、ファイルを生成するコマンドの例を示す

$  ./easyrsa build-client-full client1 nopass

Generating a 2048 bit RSA private key
.....................................................................+++
.........+++
writing new private key to '/usr/local/EasyRSA/pki/private/client1.key'
-----
Using configuration from /usr/local/EasyRSA/openssl-1.0.cnf
Enter pass phrase for /usr/local/EasyRSA/pki/private/ca.key:<登録したパスフレーズ>
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'client1'
Certificate is to be certified until Mar  8 07:31:37 2025 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated
  • client1には任意のクライアント名を指定する

    • ex, client1,client2,client3,and more…
    • ex, alpha,beta,and more…
  • パスフレーズ不要とする場合はnopassオプションを使用する

同様に、必要なだけクライアント用の秘密鍵、証明書の生成を行う

今回はclient1に加え、ルーター兼用クライアント向けにclient2も作成しておく

その際のコマンドは以下のようになる

$  ./easyrsa build-client-full client2 nopass

以上で、認証に必要なファイルの生成は終了である

次に、これらのファイルを配置し、VPN接続を行うための設定を行っていく

3. サーバーの準備をする

これまでに生成したファイルのうち、以下のファイルを/etc/openvpn/に移動する

  • ca証明書:ca.crt
  • サーバー用証明書:server.crt
  • サーバー用秘密鍵:server.key
  • DHパラメータ:dh2048.pem
$ sudo cp pki/ca.crt /etc/openvpn/
$ sudo cp pki/issued/server.crt /etc/openvpn/
$ sudo cp pki/private/server.key /etc/openvpn/
$ sudo cp pki/dh.pem /etc/openvpn/dh2048.pem

VPNサーバー設定ファイルのサンプルをコピーし、それをもとに実際にサーバーとして動かす際の設定を行う

サンプルの置かれているディレクトリは以下の通りである

/usr/share/doc/openvpn-2.3.12/sample/sample-config-files/server.conf

このサーバー設定ファイルも/etc/openvpn/に配置する

$ sudo cp /usr/share/doc/openvpn-2.3.12/sample/sample-config-files/server.conf /etc/openvpn/server.conf

サーバー設定ファイルを環境に合わせて修正する

好みのエディタで開き、編集する

$ sudo vi /etc/openvpn/server.conf

以下に編集例(抜粋)を示す

port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh2048.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
push "route 10.0.0.0 255.255.0.0"
push "route 192.168.20.0 255.255.255.0"
client-config-dir ccd
route 192.168.20.0 255.255.255.0
client-to-client
keepalive 10 120
comp-lzo
persist-key
persist-tun
status openvpn-status.log
log-append  openvpn.log
verb 3
  • portprototunはそれぞれ接続ポート番号、接続方式(udp/tcp)、インターフェイス形式(tap/tun)を指定する

    • 本環境では、UDP1194ポートをVPN接続用として開放しているので、これを指定する
    • この設定は、後述のクライアント設定ファイルでも使用する
  • cacertkeydhは、各々のサーバー用ファイルの場所を、/etc/openvpn/ディレクトリを基準とした相対パスで入力する
  • serverには、サーバーサブネットアドレス範囲を指定する
  • push "route ..."には、クライアントへ通知する、クライアントからアクセス可能なサブネットを指定する

    • 実際の動作としては、クライアントのルーティングテーブルに、指定したサブネットへアクセスする場合に、VPNサーバーへとルーティングするような設定が追加される
  • client-config-dir ccdオプションは、クライアントサブネットへアクセスする必要がある場合など、クライアントに関する設定が必要な際に有効化する

    • 有効化した際には/etc/openvpn/ccd/ディレクトリを作成しないと、openvpnそのものが正常に起動しなくなるので注意する(次の手順で作成)
    • ディレクトリ名称ccdは任意のディレクトリを指定可能
    • 合わせて、route ...により、クライアントサブネットとして192.168.20.0/24サブネットを、サーバーのルーティングテーブルに追加している
  • client-to-clientオプションは、クライアント間の通信、及びクライアントサブネット間の通信を許可する場合に有効化する
  • 設定項目については以下も参照

上記設定では、サーバー側からVPNクライアントに通知するルーティング設定として、以下の二つのサブネットにアクセスする際に、サーバーへとルーティングするような設定を加えている

  • 192.168.20.0/24
  • 10.0.0.0/16

前者のサブネットは、青のVPNクライアント兼ルーターの属するクライアントサブネットを示す

後者のサブネットは、AWSのVPC上のサブネット10.0.0.0/24(サーバーの立っているパブリックサブネット)と10.0.1.0/24(プライベートサブネット)を内包する

クライアントサブネットへの接続設定

VPNサーバーに、アクセス可能なVPNクライアントサブネットへのルートを登録する

サーバー設定ファイル上で追加したVPNクライアントサブネット192.168.20.0/24への通信をclient2へルーティングするよう設定を加える

まず、/etc/openvpn/ccd/ディレクトリを作成する

$ sudo mkdir /etc/openvpn/ccd

ディレクトリは、サーバー設定ファイル上で行った指定に従う

次に、ccdディレクトリ中にclient2という名称のファイルを生成し、iroute ...にサブネットを指定する

$sudo vi /etc/openvpn/ccd/client2

iroute 192.168.20.0 255.255.255.0

このiroute ...の設定は、OpenVPNサーバーに対し、192.168.20.0/24サブネット(上記設定の場合)への通信を、client2にルートさせるためのものである

サーバーをルーターとして使用可能にする

VPNサーバーにルーターとしての機能を持たせるためには、IPフォワーディングを許可する必要がある

以下のファイルを編集し、net.ipv4.ip_forwardを1に変更する

$ sudo vi /etc/sysctl.conf

net.ipv4.ip_forward = 1

以上で、インスタンス内で実施する必要のある設定は終了である

次に、AWS上で、ルーティング設定の修正を行う

AWS上の設定

AWS上のサブネットとデータの送受信を行うために、以下の設定を行う必要がある

  1. サブネットのルートテーブルへ、VPNネットワークのアドレスを登録
  2. VPNサーバーのインスタンスの送信元/送信先の変更チェックの無効化

ルートテーブルの修正

VPNクライアントからサーバー側サブネットにアクセスするため、サーバー側サブネットのルートテーブルにVPNサブネット(10.8.0.0/24)を登録する

VPNクライアントからサーバー側サブネットに接続するための設定はサーバー側設定ファイル上のpush "route ..."で実施済みであるが、サーバー側サブネットからVPNクライアントに接続するための情報は与えられていない

よって、AWSサブネットに紐づけられたルートテーブルの設定を修正する

  • AWS>[VPC]>[ルートテーブル]>サブネットに関連付けているルートテーブルを選択
    * [ルート]タブ>[編集]>[別ルートの追加]

    • 送信先:10.8.0.0/24(VPNサブネットを指定)
    • ターゲット:OpenVPNインスタンス(のネットワークインターフェイス)を指定

サーバー側サブネットからVPNクライアントサブネットにアクセスする場合には、同様の手順(送信先のみ変更)でルートテーブルに追加する

今回は、サーバー側サブネット-クライアントサブネット間のアクセスはないものと想定し、設定しない

送信元/送信先の変更チェックの無効化

AWSのEC2インスタンスは通常、自身のIPアドレス以外を指定した通信を無視する設定となっている

この状態では、クライアントサブネット間の通信のように、自インスタンス以外に向かう通信をルーティングすることができない

よって、この設定を無効化し、通信を受け取ることができるようにする必要がある

以下の設定を行う

  • AWS>[EC2]>VPNサーバーのインスタンスを選択

    • [アクション]>[ネットワーキング]>[送信元/送信先の変更チェック]
    • ダイアログにて、有効である場合には無効化を行う

02.png

ここまでの設定が終了したならば、念のためインスタンスを再起動させておく

4.1. クライアントの準備をする:mac編

以下の環境を想定し、クライアント側の準備を行う
(先述の想定環境中の赤のVPNクライアントを想定する)

  • OS:mac(macbook pro)
  • VPNクライアント:TunnelBlick(GUI)

クライアントへ必要なファイルを移動

SCPコマンド等を使用し、以下のファイルをクライアントへ移動する

  • ca証明書:ca.crt
  • クライアント用秘密鍵:client1.key等
  • クライアント証明書:client1.crt等

SCPコマンドを使用して、ファイルをダウンロードする際の例を以下に示す

  • 以下はssh接続用のキーが存在する場合の例

    • pemファイル名:xxx.pem
    • ダウンロード元アカウント名:ec2-user(AWSデフォルトの場合)
    • ダウンロード元グローバルIP:xxx.xxx.xxx.xxx(VPNサーバーグローバルIP)
    • ダウンロード元ファイル:/usr/local/EasyRSA/pki/private/ca.key等
    • ダウンロード先ディレクトリ:/etc/openvpn/
  • 接続先のポート番号を指定する場合は、scp -P xxxx -i ...
  • 接続先のパスは絶対パスで指定する
$ sudo scp -i ~/.ssh/xxx.pem ec2-user@xxx.xxx.xxx.xxx:/usr/local/EasyRSA/pki/private/ca.key /etc/openvpn
$ sudo scp -i ~/.ssh/xxx.pem ec2-user@xxx.xxx.xxx.xxx:/usr/local/EasyRSA/pki/issued/client1.crt /etc/openvpn
$ sudo scp -i ~/.ssh/xxx.pem ec2-user@xxx.xxx.xxx.xxx:/usr/local/EasyRSA/pki/private/client1.key /etc/openvpn

取得したファイルは/etc/openvpn/に配置する

クライアント設定ファイルの修正

必要があれば、クライアント設定ファイルのサンプルも、クライアントにコピーし使用する

あるいは、OpenVPNのサイトより、コピーして使用することもできる

ファイル名は任意であるが、ここではclient.confとする

以下にクライアント設定ファイルの設定例(抜粋)を示す

client
dev tun
proto udp
remote <サーバーグローバルIP> 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client1.crt
key client1.key
comp-lzo
verb 3
  • clientは、この設定ファイルを読んだ端末がクライアント側であることを示す
  • devprotoの指定はサーバー設定ファイル(前述)に従う
  • remoteには、<サーバーグローバルIP>とサーバーポート番号をスペース区切りで記述する

    • <サーバーグローバルIP>にはグローバルIPでなくとも、クライアントからサーバーにアクセスできるIPアドレス、あるいはホスト名を指定する
    • サーバーポート番号の指定はサーバー設定ファイルに従う
  • cacertkeyには、max x tunnelblick環境では、/etc/openvpn/ディレクトリを基準としたパスを指定する

    • 今回は/etc/openvpn/直下のためディレクトリ指定は行う必要はない

Tunnelblickへの登録

作成したclient.confを、Tunnelblickで開く

  • エラーが出た場合は修正する

    • どこが間違っているかは教えてくれる
    • tls設定がサンプル時点で有効になっている場合があるので確認が必要
  • 特に、ca証明書のディレクトリ指定などに注意する

問題なく登録が終わったならば、”接続”できるはずである

4.2. クライアントの準備をする:ubuntu編

インストール手法などは異なるものの、linux系統でOpenVPNをクライアントとして導入する手順は同一である
(今回は、具体的にRaspberryPiにOpenVPNを導入する場合を想定する)

ここで、クライアントが所属するサブネットワークへのアクセスを許可する場合、VPNクライアント側で直接設定をする必要は基本的には存在しない

サブネットへのルーティング設定は、VPNサーバー側の設定のみで良い

ただし、ルーター上でサブネットの設定を行う必要はあるが、すでにルーターとして使用可能な状態であり、設定済みであるとして、今回は説明しない

ここでは以下の環境を想定し、クライアント側の準備を行う

  • OS:ubuntu(macbook pro上でrefind使用)
  • VPNクライアント:OpenVPN(CUI)

OpenVPNのインストール

以下のコマンドでOpenVPNをインストールする

$ sudo apt-get install openvpn

クライアントへ必要なファイルを移動

SCPコマンド等を使用し、以下のファイルをクライアントへ移動する

  • ca証明書:ca.crt
  • クライアント用秘密鍵:client1.key等
  • クライアント証明書:client1.crt等

取得したファイルは/etc/openvpn/に配置する

クライアント設定ファイルの修正

VPNクライアント設定ファイルのサンプルをコピーし、それをもとに実際の設定を行う

サンプルの置かれているディレクトリは以下の通りである

/usr/share/doc/openvpn-2.3.12/sample/sample-config-files/client.conf

サーバー設定ファイルが置かれていたディレクトリと同一である

このクライアント設定ファイルも/etc/openvpn/に配置する

$ sudo cp /usr/share/doc/openvpn-2.3.12/sample/sample-config-files/client.conf /etc/openvpn/client.conf

サーバー設定ファイルを環境に合わせて修正する

好みのエディタで開き、編集する

$ sudo vi /etc/openvpn/client.conf

以下に編集例(抜粋)を示す

client
dev tun
proto udp
remote <サーバーグローバルIP> 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca /etc/openvpn/ca.crt
cert /etc/openvpn/client1.crt
key /etc/openvpn/client1.key
comp-lzo
verb 3
  • 一番上のclientは、このファイルを読んだ端末がクライアント側であることを示す
  • cacertkeyには絶対パスを指定する

なお、上記編集例はサーバー設定ファイルの内容に対応する

VPNサーバーへの接続

VPNのクライアントとして起動させるには、起動の際にクライアント設定ファイルを指定する必要がある

以下のコマンドで、クライアントようコンフィグファイルを指定し、クライアントとしてVPNサーバーへ接続する

$ sudo /usr/sbin/openvpn /etc/openvpn/client.conf
...
... Initialization Sequence Completed

※コンソールを一つ占有することに注意する

5. 各サブネットに接続確認を行う

ここでは、以下のような環境で、クライアントからVPNサーバーを経由し、サーバー側サブネットへtracerouteを行う

ここまでの手順通りに行っていれば、問題なく接続できるはずである

netstatコマンドなどで、対応するルーティングが行われているか確認する

VPNクライアントからping、あるいは以下のようなtracerouteコマンドが通れば、正常に設定できている

$ traceroute 10.0.1.228
traceroute to 10.0.1.228 (10.0.1.228), 64 hops max, 52 byte packets
1 10.8.0.1 (10.8.0.1) xxx ms xxx ms xxx ms
2 10.0.1.228 (10.0.1.228) xxx ms xxx ms xxx ms
$ traceroute 10.8.0.10
traceroute to 10.8.0.10 (10.8.0.10), 64 hops max, 52 byte packets
1 10.8.0.10 (10.8.0.10) xxx ms xxx ms xxx ms
$ traceroute 192.168.20.5
traceroute to 192.168.20.5 (192.168.20.5), 64 hops max, 52 byte packets
1 10.8.0.10 (10.8.0.10) xxx ms xxx ms xxx ms
2 192.168.20.5 (192.168.20.5) xxx ms xxx ms xxx ms

以上

続きを読む

MacのAWS DynamoDB GUI ツールを試してみた

Macのdynamodbのツールを試してみた。

機能

AWS or ローカルで接続ができる。
scan, queryを選択して実行するのができる。
フィルター条件を動的に追加、削除できる。
自動ソートができる。
スループットをsleep時間設定して回避ができる。

shot6 (1).png

参考リンク https://github.com/touchduck/dynamon

続きを読む

AmazonAlexaのサンプルを動かしながら、じっくりと基本を学んでみよう

はじめに

Amazon Alexaってご存知でしょうか。
残念ながら現在は日本語には対応していませんが、EchoやTapなどのデバイスに喋りかけると、あらかじめ紐付けておいたスキルに応じて色々な処理を動かすことができます。

  • 「今日の東京の天気はどんな感じ?」
  • 「明日の東京は晴れですよ!」

というステートレスでオープンな簡単な応答もできますし、Alexaとの会話を通じて難しい応答を返すことも作りこみ次第では可能です。

  • 私「旅行に行きたいなぁ」
  • Alexa「どこに行きたいですか?」
  • 私「アジアがいいなぁ」
  • Alexa「アジアのどの辺ですか?」

みたいなやり取りから旅行プランをおすすめしてくれて、チケットを予約してくれる日も近そうです。

この「スキル」は自分で作って公開することもできますし、公開しないでクローズドに動かすこともできます。
今回は入門編ということでAlexaのサンプルを動かしながら、Alexaで出てくる用語や、少しソースの解説をしてみます。

私は少し遠回りしましたが1時間もあれば試すことができます。
サンプルをひとつ動かすだけで、「あれ。ちょっとしたことなら簡単にできるかも。」と思えてしまいますので是非お試しください。


Alexaを構成する登場人物たちを抑えよう

ドキュメントを読むにも登場人物を抑えないとはじまりません。

  • デバイス

    • Echo / Tap / dot / KindleFireTV / Amazonアプリなど色々ありますが、Echoなどは日本では技適が通ってませんのでAmazon.comで購入しても動かしてはいけません。
    • 今のところはiPhoneアプリや公式のシミュレータであるEchosimを使いましょう。
  • Alexa App

    • Alexaのスキルの検索、登録 / カードの表示 / 追加したスキルの設定ができます。
    • PCからでもスキルの追加・変更が可能。http://alexa.amazon.com/spa/index.html
    • アプリを入手するにはアメリカのAppleIDが必要で、ログインにはAmazon.comのアカウントが必要です。
  • Alexa Service

    • デバイスからのデータを受け取り、Lambdaイベントを発火するサービス
  • AWS Lambda

    • Alexa Serviceからデータを受け取り、解析して処理を行いレスポンスを返却します。
  • Amazon Developer Console

    • カスタムスキルを作る場合はDeveloper Consoleで追加しテストなどを行います。ログインにはAmazon.comのアカウントが必要です。
    • スキルの登録には審査が必要で、7日くらいかかるらしいです。
  • AVS(Alexa Voice Service)

    • 自分で作ったデバイスに組み込むことができるSDK。今回は直接関係ありません。

サンプルを動かしてみよう

  • HelloWorldのようなステートレスなものではつまらないので、SessionというAmazonが提供しているサンプルを動かしてみます。
  • このサンプルは自分の好きな色をAlexaに教えるとAlexaが記憶してくれて、「私の好きな色は何?」と聞くと先ほど記憶してくれた色を答えてくれるサンプルです。

環境を用意する

  • Java8とMavenをインストールしましょう(mvnwくらいサンプルに置いといてくれたらいいのに。。)

LambdaFunctionを作る

  • Githubからサンプルをダウンロードする
git clone https://github.com/amzn/alexa-skills-kit-java.git
  • パッケージングする
cd alexa-skills-kit-java/samples
mvn assembly:assembly -DdescriptorId=jar-with-dependencies package
  • target/alexa-skills-kit-1.3.0-jar-with-dependencies.jarができていることを確認する

  • ManagementConsole – Lambdaを開く。この時リージョンは必ず「バージニア北部」であることを確認する

  • LambdaFunctionをデプロイする(難しくないので割愛)

    • トリガーには「Alexa Skills Kit」を選択
    • Java8
    • Handler:session.SessionSpeechletRequestStreamHandler
    • Roleは初回の場合は「テンプレートから新しいRolwを作成」を選択し、適当な名前付けておきます。
  • デプロイが成功したら後で必要となるARNをコピーしておきましょう。

image

  • LambdaFunctionのテストをしたいところですが、DeveloperConsoleから行うのがおススメですのでここからは行いません。

Developer Console

  • [Alexa Skills Kit] – [Get Started]を選択
  • [Add New Skill]を選択し、SkillInformationにこんな感じで登録する

image

  • Interaction Modelに「IntentSchema」「CustomSlotType」「Sample Utterances」を登録する

    • Githubのサンプル内に入っているのでコピペしよう
  • Configuration
    • Endpointsは「AWS Lambda ARN (Amazon Resource Name)」を選択
    • North Americaを選択し、先ほどコピーしたARNを入力します。
  • Test
    • ここではLambdaFunctionのテストができます。
    • ためしに「alexa, open session」と入力してみましょう。
    • うまくレスポンスが返ってくればLambdaResponseにjsonが返却されるはずです。
    • 右下のListenというボタンを押すと実際にechoなどのデバイスから聞こえてくる音声が聞こえてくるはずです。

image

さぁここまでできればデバイスから呼べる準備が完了です。
なお、更改するには審査にパスする必要があり、DeveloperConsoleの内容を全部埋める必要があります。

スキルを追加する

  • スキルを追加するにはAlexaのポータルか、AlexaAppを利用して登録します。
  • 画面左の「Skills」をクリックし、画面右上の「YourSkill」を選択すると先ほどDeveloperConsoleで作成したSkillが表示されるはずです。

image

デバイスを用意する

  • 開発中はechosim.ioを利用すると良いでしょう。
  • Amazonアカウントでログインすることで使用できます。
  • 本物のデバイスでは「Alexa」と呼びかけるのですが、Echosimはボタンを押すことで「Alexa」と呼んだことと同じ意味になります。

image

  • ちなみに私だけかもしれませんがEchosimはMacだと快調に動くのですが、Windows10だとなぜか認識しないことがありました。また、スマホアプリでAVSで作られた無料のものがありますが、これもうまくいったりいかなかったりしました。
  • 色々試した結果、良い感じだったのはAmazonモバイルアプリでした。これのロケールをアメリカにすると音声検索でAlexaが利用できますよ。

しゃべってみましょう

こんな感じのやりとりができますのでやってみましょう。

  • 私「Alexa,open session」(Echo使っていない場合はAlexaは不要です)
  • Alexa「Hello. Welcome to the Alexa Skills Kit sample. Please tell me your favorite color by saying, my favorite color is blue」
  • 私「my color is red」
  • Alexa「I now know that your favorite color is red. You can ask me your favorite color by saying, what’s my favorite color?」
  • 私「whats my color」
  • Alexa「Your favorite color is red」

Alexa用語を覚えておこう

  • そんなに多くないので覚えるのはそんなに大変じゃありません。

Invocation Name

  • Developer Consoleで設定するSkillを特定する一意な名前。
  • Invocation Nameをsessionという名前にしておくと、「Alexa, tell session」でSkillを呼び出すことができます。
  • tell / ask / openなどのあとにInvocationNameを話すとLambdaFunction#onLaunchが呼ばれます
  • 今回のサンプルでは#getWelcomeResponseが呼ばれ、「Hello. Welcome to the Alexa Skills Kit sample. Please tell me your favorite color by saying, my favorite color is blue」を喋らせています。

Intent Schema

  • 説明が難しいですが、Alexaとのやりとりの枠組みを定義します。(そのままじゃん・・・)
  • やり取りの中でSlotを使う場合は合わせてそれを定義します。
  • 今回の場合はMyColorIsIntentとWhatsMyColorIntentというIntentが使われ、MyColorIsIntentではLIST_OF_COLORSというカスタムSlotが利用されることを示しています。このIntentで会話される内容はUtteranceに定義します。
{
  "intents": [
    {
      "slots": [
        {
          "name": "Color",
          "type": "LIST_OF_COLORS"
        }
      ],
      "intent": "MyColorIsIntent"
    },
    {
      "intent": "WhatsMyColorIntent"
    }
  ]
}

Utterance

  • 日本語では「発声」です。IntentとAlexaが認識できる文章を紐付ける役目を持ちます。
MyColorIsIntent  my color is {Color}
MyColorIsIntent  my favorite color is {Color}
WhatsMyColorIntent whats my color
WhatsMyColorIntent what is my color
WhatsMyColorIntent say my color
WhatsMyColorIntent tell me my color
WhatsMyColorIntent whats my favorite color
WhatsMyColorIntent what is my favorite color
WhatsMyColorIntent say my favorite color
WhatsMyColorIntent tell me my favorite color
WhatsMyColorIntent tell me what my favorite color is
  • 「whats my color」と発音するとIntentRequestのintentNameにWhatsMyColorIntentが入りますので、以下のコードのように分岐することでintentに対応する応答を実現することができます。
  • ここでは対応するintentが無い場合は例外を発声させていますが、「再度言ってください」みたいな流れにしてもよさそうですね
        if ("MyColorIsIntent".equals(intentName)) {
            return setColorInSession(intent, session);
        } else if ("WhatsMyColorIntent".equals(intentName)) {
            return getColorFromSession(intent, session);
        } else {
            throw new SpeechletException("Invalid Intent");
        }
  • {Color}というのはSlotを表します。Intent SchemaのNameに対応しており、slotの型はDeveloperConsoleで設定が必要です。

Slot

  • LIST_OF_COLORSに以下のように定義するとUtteranceで{Color}となっている部分が取り得る値を定義することができます。
green
blue
purple
red
orange
yellow

Buildin Intent/Slots

SSML(Speech Synthesis Markup Language)

  • 読み方とかしゃべる間隔などをマークアップで記載することができます。(TwilioのTwiMLとは違うマークアップのようです)
  • 強く読んだり、アルファベットを読み上げたりS3に挙げたmp3を再生することも可能です。
  • マークアップの書き方はSpeech Synthesis Markup Language (SSML) Referenceをどうぞ。
  • 例えば、リストを読み上げるときに一定の間隔をあける場合は以下のように書くことができます。
        String repromptText = "Please choose a category by saying, " +
                "books <break time="0.2s" /> " +
                "fashion <break time="0.2s" /> " +
                "movie <break time="0.2s" /> " +
                "kitchen";
  • どんな感じでしゃべるのかな~というのはDeveloperConsoleのVoiceSimulatorで試すことができます。結構遊べます。

image

Cards

  • 「Alexa, open session」なんて話した後に、スマホのAlexaAppを開いてみます。
  • そうするとやりとりした内容が表示されていると思います。これをCardと言います。

alexaapp.jpg

  • Cardに表示させるにはこんな感じで書くことで表示されます。
        SimpleCard card = new SimpleCard();
        card.setTitle("Session");
        card.setContent("表示したいコンテンツ");
  • Cardは3種類あって、テキストのみ表示する場合はSimple、画像などのイメージを使って表示したい場合はStandard、既存サイトのアカウントとリンクするときのみ使えるのがLinkAccountとなっています。
  • さらに詳しく理解したい場合はIncluding a Card in Your Skill’s Responseを読みましょう。

その他

他は一旦紹介だけしておきます。

Link Account

  • OAuth2.0(RFC6749RFC6750)を使ってアカウントをリンクすることができます。
  • 簡単に流れを説明するとこんな感じです。
    • AlexaAppなどでスキルをEnableにする
    • LinkAccountをクリックすることで認証させたいサイトのログイン画面が開く
    • ユーザがアプリの画面などでID/PWを入力する。
    • 認証をクリアしscopeを承諾すると、AccessTokenが保管される。
    • ここまでがリンクの仕組みで以降のやりとりは音声と一緒にAccessTokenが流れてくるのでこれをLambdaで取得後、認可&リソースにアクセスすることで実現します。
  • 「Authorization code grant」と「Implicit grant」に対応しています。どちらの方式にするか検討が必要ですが、通常はよりセキュアな「Authorization code grant」を選択します。
  • 「Authorization code grant」はcodeを取得し、client_id,secretを使ってAccessTokenを取得する仕組みとなります。client_id,secretの値はあらかじめDeveloperConsoleで登録しておく必要があります。
  • また、tokenの有効期限切れの場合の為にrefresh_tokenの仕組みがOAuthには定義されていますが、こちらはAlexaのドキュメントによればOptionalとなっているので利用するか、tokenの有効期限が切れたら再認証させるかについては決めておく必要があります。
  • Linking an Alexa User with a User in Your System

Alexa BestPractice


おわりに

どうでしたか?結構簡単に作れることがわかると思います。
英語でもかなり色々遊べますので触ってみてはどうでしょうか。

次回はいつになるかわかりませんが、LinkAccountについて書こうかと思います。

続きを読む

Amazon lexで音声チャットボットを作成してみた

天気の良い週末にやることがなく、昼の12時ごろ、趣味の長時間歯磨きをしながらtechCrunchを見ていたら、amazonのlexの記事が乗っていた。

http://jp.techcrunch.com/2017/04/21/20170420amazon-lex-the-technology-behind-alexa-opens-up-to-developers/

Amazonの仮想アシスタントAlexaを支えているテクノロジーであるAmazon Lexが、今朝(米国時間20日)のロイターの記事によれば、プレビュー段階を終了したということだ。

↓↓↓
https://aws.amazon.com/jp/lex/

Amazon Lex は、音声やテキストを使用した会話型インターフェイスをさまざまなアプリケーションに構築するためのサービスです。
Lex では、自動音声認識 (ASR) という音声をテキストに変換するための高度な深層学習機能と、
テキストの意図を理解するための自然言語理解 (NLU) を利用できます。
これにより、非常に魅力的なサービスと生き生きとした音声対話を実現するアプリケーションを構築できます。
Amazon Lex を使うと、すべての開発者が Amazon Alexa に採用されている深層学習技術と同じ技術を利用し、
自然言語での高度な対話ボット (チャットボット) を短時間で簡単に構築できるようになります。

このページにある動画は去年の11月末のものだ。
その頃、某ゲームの開発と並行して走る運営の現場の両方が修羅場で、毎日トラブルと戦っていた。さらにトラブルは現場だけとは限らず、外野がキナ臭くなり、モヒカンと肩パッドの荒くれ供から平和を守るために北斗百烈拳を繰り出していた。明日を見失って、CV千葉繁になっていた記憶がうっすらとある。
当然re:InventのKeynoteなど見る暇はなかった。

Try a sample

まずはこちらのページでサンプルを作ってみる。
https://console.aws.amazon.com/lex/home?region=us-east-1#bot-create:

cb-1.png
BookTripをクリック。

cb-2.png

IAM:自動的に作ってくれるんはありがたい。念のため後でデタッチされた権限を見ることにするけどな。
Child-Directed?:子供専用ではないからNo。

Createを押しやす。


マイクを許可しますかのプロンプトが出るので、許可にする。
このmacには内臓マイクがないので、iPhoneのヘッドホンを繋いでおく。

cb-3.png

しかしこの後、何をどうしたらいいのか、説明がないからさっぱりわからない。。。。。。
困った。

tutorialの動画をみながらもう一度sample chat botをつくる

AWS Lex Demo Tutorial (Jan 2017)
https://www.youtube.com/watch?v=7uG9cuxNo5k
「花の注文をするチャットボット」を10分くらいで作る様子。

4ヶ月ほど前に親切な人が投稿してくれたチュートリアル動画で、
やさしい英語をえらんで説明してくれているが、
英語のききとりがやっとの自分はYoutobeの字幕機能で補いながらみた。
この通りやってみると、なんとなくわかる。

なおこの動画の中では、まだ「Channels」がFacebookしかないが、
3ヶ月後の現在は、3つに増えている。

  • Facebook
  • Twilio SMS ←増えた
  • Slack ←増えた

花屋のサンプルをそのまま真似して、以下のように作ってみた。

name:OrderFlowersSitopp
Description:Bot to order flowers on the behalf of a user
Output voice:Joey

cb-8.png

Buildをするとtest Botでtext入力できるようになる。
Sample Utterancesの1個めをコピペして、
I would like to pick up flowers
と記入してエンターしてみるとすぐ答えが返ってきた。ほうほう。
cb-7.png
あっ、これもうできちゃったのか。早いなぁ。(΄◉◞౪◟◉`)

音声入力してみる

AWSのLexのコンソールに行く
https://console.aws.amazon.com/lex/home?region=us-east-1#bots:

さっき作った「name:OrderFlowersSitopp」を選ぶcb-15.png

右側にチャットボットのタブが現れるので、
入力欄のマイク部分をクリックする。そうすると音声入力モードになった。

cb-13.png


Macに繋いだiPhone用のヘッドフォンのマイクのあたりに話しかけると、テキスト化して、チャットにしてくれます。

上の例だと、私の発音が悪いので、rosesがlosesとかclosesになっている。ひどい(笑)
しかもボットはそのまま「Ok your closes will be ready 」と予約終了してしまった。
いったいなんの花が届くのか。。笑

もちろん、これはサンプルだから何も届かないけど、
ちゃんとカスタムスロットに無いものはエラーにしないと、そのまま注文を受け取ったことになってしまうから、
注意が必要ということで。

sampleを作ってわかったこと

  • サンプルの3種類は以下の通り。主たる目的はこういうものなのかな。

    • 旅行の予約
    • 花屋のオーダー
    • 歯医者の予約

考えられる用途

  • 保険の見積もり
  • 通販サイトのパスワード忘れた
  • 美容院の予約
  • ゲームの進行不具合の通報
  • ゲームのチート疑惑の通報
  • ゲーム掲示板の炎上の通報
  • ゲームの..いかん、つい仕事が

これがFacebookのお店のページに備わってたら、確かに気楽に呼び出しやすい。
でも受け取る側はどうなんだろう? botが応答して解決しない場合もあるだろうし、ちゃんと過去の履歴を呼び出せるのかな?

大変そうな点

Sample UtterancesとSlot typesの用意が大変そう。

Sample Utterancesとは、ユーザーがこういったらこの部分をパラメタとして受け取るという設定。花屋の予約sampleでは2個しかなかったけど、こんなんで済むはずがない。

  • I would like to pick up flowers
  • I would like to order some flowers

様々な言い方を網羅しておかないと、「おっしゃることがわかりません」を連発するポンコツbotになってしまう。
(参考動画 Virgin Flight – Saturday Night Live

Slot typesは、ユーザーの返答の中から受け付けるキーワードの種類で、花屋の予約sampleでは花の種類3つが該当する。だがこんな少なくて済むはずがない。3種類しか売ってない花屋っていうのだったら別だけど。
– roses
– lilies
– tulips

Sample utterancesもSlot TypesもAlexa Skillsにも同様の設定項目があり、これらをいかにきめ細かに定義できるかでbotの優秀さが決まると思う。

まとめ

  • AWSのlexを使ってchatbotが作れる。
  • 連携先は、Facebook、Twilio SMS、slackが選べる。ただし音声入力は、声の入力装置があるプラットフォームじゃないとダメ。(Twilioは電話と連携してるから、これが候補か。)
  • Utterancesとslot typesをちゃんと定義しないと、ポンコツbotになってしまう。人工知能というより人工無能。これはAlexa skillsも同じ。
  • しゃべった言葉を分解してテキストにするところが人工知能。ここはブラックボックス。
  • サンプルでは必要なかったが、ちゃんとbotを作るときにはLambda関数も書く必要がある。(http://docs.aws.amazon.com/ja_jp/lex/latest/dg/getting-started-ex2.html)
  • botの会話ログを見るのってどうするんだろ?

以上!

続きを読む