akiyoko blog

akiyoko の IT技術系ブログです

Vagrant と Ansible を連携させて Ubuntu 14.04 に MySQL, PostgreSQL を provision する手順

AnsibleとVagrantで開発環境を構築する | さくらのナレッジ
という記事を読んで、開発環境の Ubuntu サーバに MySQL や PostgreSQL をインストールするなら、Vagrant と Ansible を連携させた方がやりやすいな、と思ったのでメモがてらまとめておきたいと思います。


ベースとしては、以前使った Ansible Galaxy を使います。
具体的には、

インストールします。


Vagrant 以外の仮想サーバや通常のサーバに対して、MySQL や PostgreSQL を簡単にインストールする手順については、以下の過去記事を参照してください。

<過去記事>
akiyoko.hatenablog.jp

akiyoko.hatenablog.jp



ホスト

  • macOS Sierra 10.12.3
  • Vagrant 1.9.1
  • VirtualBox 5.1.14


macOS Sierra に Vagrant および VirtualBox をインストールする手順については、以下を参照してください。

<過去記事>
akiyoko.hatenablog.jp


ゲスト

  • Ubuntu 14.04

ゲストマシンのプライベート IPアドレスは「192.168.33.10」に設定しておきます。


データベース

  • MySQL 5.5.54
  • PostgreSQL 9.3.16


インストールと同時に以下の設定もおこなう想定です。

項目 設定内容
データベース名 myproject
データベースユーザ myprojectuser
データベースユーザパスワード myprojectuserpass


ちなみに、MySQL の root のパスワードは「rootpass」となります。
また、PostgreSQL の場合は「postgres」という Linuxユーザが作成されます。



 

MySQL のインストール

MySQL は ANXS.mysql でインストールします。

$ cd ~/dev/vagrant/ubuntu14
$ mkdir provisioning
$ ansible-galaxy install ANXS.mysql -p provisioning/roles


etc_mysql_my.cnf.j2 ファイル内の「character_set_server」および「collation_server」のキーワードを修正します。 *1

$ sed -i '' 's/^character_set_server/character-set-server/g' provisioning/roles/ANXS.mysql/templates/etc_mysql_my.cnf.j2
$ sed -i '' 's/^collation_server/collation-server/g' provisioning/roles/ANXS.mysql/templates/etc_mysql_my.cnf.j2


provisioning/hosts

[db-servers]
192.168.33.10


provisioning/site.yml

- hosts: db-servers
  become: true
  user: vagrant
  vars_files:
    - vars/mysql.yml
  roles:
    - { role: ANXS.mysql }

 

$ mkdir provisioning/vars

provisioning/vars/mysql.yml

mysql_current_root_password: ''
mysql_root_password: rootpass
mysql_databases:
  - name: myproject
mysql_users:
  - name: myprojectuser
    pass: myprojectuserpass
    priv: "myproject.*:ALL"


最終的なディレクトリ構成はこのような感じになります。

~/dev/vagrant/ubuntu14/
├── Vagrantfile
└── provisioning
    ├── hosts
    ├── roles
    │   └── ANXS.mysql
    │       ・
    │       ・
    ├── site.retry
    ├── site.yml
    └── vars
        └── mysql.yml


Vagrantfile

    ・
    ・
  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  config.vm.network "private_network", ip: "192.168.33.10"
    ・
    ・
  # Enable provisioning with a shell script. Additional provisioners such as
  # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
  # documentation for more information about their specific syntax and use.
  # config.vm.provision "shell", inline: <<-SHELL
  #   apt-get update
  #   apt-get install -y apache2
  # SHELL
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "provisioning/site.yml"
    ansible.inventory_path = "provisioning/hosts"
    ansible.limit = "all"
  end


 

provision

サーバを初回起動する際に provision が実行されます。

$ vagrant up


起動済みのサーバには、以下のコマンドを実行することで provision が実行されます。

$ vagrant provision

  or

$ ansible-playbook -i provisioning/hosts provisioning/site.yml -k -vv

後者のコマンドの場合には、vagrant ユーザのパスワードが要求されます。

パスワードを入力したくない場合は、

$ vagrant ssh-config --host 192.168.33.10 >> ~/.ssh/config

### 念のためパーミッションを変更
$ sudo chmod 600 ~/.ssh/config

を設定しておけば、

$ ansible-playbook -i provisioning/hosts provisioning/site.yml -vv

で、パスワード無しで実行可能です。

 

動作確認

$ vagrant ssh

  or

$ ssh vagrant@192.168.33.10

でサーバにログインして、

$ mysql -u root -p

で動作確認します。




 

PostgreSQL のインストール

PostgreSQL は ANXS.postgresql でインストールします。

$ mkdir provisioning
$ ansible-galaxy install ANXS.postgresql -p provisioning/roles

provisioning/hosts

[db-servers]
192.168.33.110

provisioning/site.yml

- hosts: db-servers
  become: true
  user: vagrant
  vars_files:
    - vars/postgresql.yml
  roles:
    - { role: ANXS.postgresql }

 

$ mkdir provisioning/vars

provisioning/vars/postgresql.yml

postgresql_databases:
  - name: myproject
postgresql_users:
  - name: myprojectuser
    pass: myprojectuserpass
postgresql_user_privileges:
  - name: myprojectuser
    db: myproject
    priv: "ALL"


最終的なディレクトリ構成はこのような感じになります。

~/dev/vagrant/ubuntu14/
├── Vagrantfile
└── provisioning
    ├── hosts
    ├── roles
    │   └── ANXS.postgresql
    │       ・
    │       ・
    ├── site.retry
    ├── site.yml
    └── vars
        └── postgresql.yml


Vagrantfile

    ・
    ・
  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  config.vm.network "private_network", ip: "192.168.33.10"
    ・
    ・
  # Enable provisioning with a shell script. Additional provisioners such as
  # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
  # documentation for more information about their specific syntax and use.
  # config.vm.provision "shell", inline: <<-SHELL
  #   apt-get update
  #   apt-get install -y apache2
  # SHELL
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "provisioning/site.yml"
    ansible.inventory_path = "provisioning/hosts"
    ansible.limit = "all"
  end


 

provision

サーバを初回起動する際に provision が実行されます。

$ vagrant up


起動済みのサーバには、以下のコマンドを実行することで provision が実行されます。

$ vagrant provision

  or

$ ansible-playbook -i provisioning/hosts provisioning/site.yml -k -vv

後者のコマンドの場合には、vagrant ユーザのパスワードが要求されます。

パスワードを入力したくない場合は、

$ vagrant ssh-config --host 192.168.33.10 >> ~/.ssh/config

### 念のためパーミッションを変更
$ sudo chmod 600 ~/.ssh/config

を設定しておけば、

$ ansible-playbook -i provisioning/hosts provisioning/site.yml -vv

で、パスワード無しで実行可能です。

 

動作確認

$ vagrant ssh

  or

$ ssh vagrant@192.168.33.10

でサーバにログインして、

$ psql -U postgres
  or
$ sudo su postgres
$ psql

で動作確認します。

おまけ

### ユーザ一覧
postgres=# \du

### データベース一覧
postgres=# \l

### データベース接続
postgres=# \c myproject

### テーブル一覧
myproject=# \d
myproject=# \dt

### 終了
myproject=# \q


 

書籍

Mezzanine の本番設定(その1:AWS 環境構築)〜AWS 環境構築から運用設定まで〜

こんにちは、akiyoko です。

Mezzanine は Python製の WordPress風フルスタックCMSフレームワークですが、個人的にブログサイト(将来的には ECサイトを増設予定)を本番運用するために、昨年12月頃から調査をしてきました。

akiyoko.hatenablog.jp


それ以来いろいろと企画やら調整を地道に進めてきましたが、この 7月にようやく本番運用に漕ぎ着けることができました。

それを記念して(?)AWS の初期設定から Mezzanine の本番デプロイ、ちょっとした運用設定までの記録を一旦ここでまとめておきたいと思います。

かなり長くなるので、

の 4本に記事を分けました。

今回はその 1本目、「その1:AWS 環境構築」について説明します。


AWS 環境構築として実施した内容としては、

  • IAM 設定(ルートアカウント・admin ユーザの設定)
  • VPC 設定(1ネットワーク+ 1サブネット)
  • EC2 設定(Ubuntu 14.04 LTS インスタンスの起動)
  • Amazon SES 設定(ドメイン認証、送信制限の解除申請)

となります。



 

1. IAM の初期設定

基本方針として、AWS ルートアカウントは原則使用せず、AdministratorAccess 権限を持たせた管理者ユーザー「admin」を新たに作成して利用することとします。

なお、ルートアカウントは、MFA(二段階認証)でセキュリティを強化しておきます。


(参考)


 

1. 1. ルートアカウントに MFA 導入

1.1.1. スマホに仮想MFAアプリケーションをインストール

まず、Android に

というアプリをインストールします。


なお、仮想MFA アプリケーションの一覧はこちらです。
私は Android ユーザなので Android を使っていますが、その他のスマホを使っている場合は適宜別のアプリを検討してください。

f:id:akiyoko:20160829014611p:plain

Android Google AuthenticatorAuthy 2 段階認証
iPhone Google Authenticator
Windows Phone Authenticator
Blackberry Google Authenticator

IAM - Multi-factor Authentication より)



(参考)AWS MFAの設定 - Qiita


 

1.1.2. AWS Management Console での設定

[IAM] > [Dashboard] から、[Security Status] > [Activate MFA on your root account] > [Manage MFA] を選択します。

f:id:akiyoko:20160829014934p:plain

[A virtual MFA device](仮想 MFA デバイス)を選択。

f:id:akiyoko:20160829015326p:plain

[Don't show me this dialog again] を選択して次へ。

f:id:akiyoko:20160829015853p:plain


以下の QRコードを 1.1.1. でインストールした「Google 認証システム」アプリでスキャンして、アプリをルートアカウントと紐付けます。

f:id:akiyoko:20160829020107p:plain


これで、AWS ルートアカウントでのログイン時にアプリで払い出されるワンタイムトークンが必要になるため、不正ログインに対するセキュリティが向上します。

 

1.2. パスワードポリシーの変更

[Dashboard] から、[Security Status] > [Manage Password Policy] をクリックします。

f:id:akiyoko:20160829020329p:plain


ここで、パスワードポリシーを

  • パスワードの最小長:8
  • 英大文字、英小文字、数字の組み合わせ
  • ユーザーにパスワードの変更を許可

とします。

有効期間、再利用禁止などのポリシーは今回設定していませんが、ニーズがあり次第、適宜設定することとします。

f:id:akiyoko:20160829020557p:plain


 

1.3. IAMユーザ、IAMグループの管理

 

1.3.1. IAMユーザ作成

管理者ユーザ「admin」を作成します。

f:id:akiyoko:20160829022915p:plain
f:id:akiyoko:20160829022936p:plain

アクセスキーを CSV(credentials.csv)でダウンロードしておきます。
f:id:akiyoko:20160829023157p:plain

User Name,Access Key Id,Secret Access Key
"admin",AKIxxxxxxxxxxxxxxxxx,xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


次に、作成したユーザの [Security Credentials](認証情報)タブから、自動作成パスワードを払い出して設定します。

[Manage Password]をクリック。
f:id:akiyoko:20160829023522p:plain

「Assign an auto-generated password」をチェックして、[Apply]をクリック。
f:id:akiyoko:20160829023547p:plain

念のため、パスワードを CSV(admin_pass_credentials.csv)でダウンロードしておきます。
f:id:akiyoko:20160829023702p:plain

User Name,Password,Direct Signin Link
"admin",xxxxxxxxxxxx,https://53xxxxxxxxxx.signin.aws.amazon.com/console


なお、adminユーザには二段階認証は設定しません。 *1


 

1.3.2. IAMグループ作成

adminユーザのための管理者グループ「admin」を作成します。

f:id:akiyoko:20160829023957p:plain

完全な管理者アクセス権限(AdministratorAccess)ポリシーをアタッチします。

f:id:akiyoko:20160829024245p:plain
f:id:akiyoko:20160829024306p:plain

次に、admin グループに admin ユーザを追加します。

作成したグループを選択して、「Add Users to Group」をクリック。
f:id:akiyoko:20160829024412p:plain

追加したいユーザ(ここでは「admin」)を選択して、「Add Users」をクリック。
f:id:akiyoko:20160829024528p:plain
f:id:akiyoko:20160829024556p:plain


 

1.3.3. admin で再ログイン

以下、adminユーザで操作します。

一旦ログアウトし、

https://{AWS Account ID}.signin.aws.amazon.com/console

から、admin ユーザでログインします。なお、「AWS Account ID」は、AWSアカウントに紐づく 12桁の数字で、My Account ページの[Accout Settings]からも確認できます。


ログインしたら、リージョンを「Tokyo」にしておきます。
f:id:akiyoko:20160829024729p:plain


 

2. VPC の初期設定

以前に書いた 「AWS体験ハンズオン ~セキュア&スケーラブルウェブサービス構築~」に参加してきました - akiyoko blog で実現したような、

  • 別アベイラビリティゾーンに Webサーバを冗長構成して、ELB を使ってロードバランシング
  • プライベートなサブネットに RDS を配置(且つ、別アベイラビリティゾーンにレプリケーション)

は行わず、最小限の構成にしています。


今回構築する構成の最終形は、このようになります。
f:id:akiyoko:20160911110053p:plain


(参考)0から始めるAWS入門①:VPC編 - Qiita

 

2.1. VPC の作成

CIDR が「10.0.0.0/16」の VPC を作成します。

[VPC] > [Your VPCs] から、「Create VPC」ボタンをクリック。

f:id:akiyoko:20160830001821p:plain

以下を設定します。

Name tag P1
CIDR block 10.0.0.0/16
Tenancy Default

f:id:akiyoko:20160830001850p:plain


【注意】
このままの設定では、あとでインスタンスを起動して sudo を実行した際に、下記のエラーが出るので(コマンド自体は実行されているっぽい)、DNS Hostnames の設定を「Yes」に変更します。(すでに EC2インスタンスを起動していた場合には、再起動が必要です。)

$ sudo ls
sudo: unable to resolve host ip-10-0-0-80

f:id:akiyoko:20160830001913p:plain
f:id:akiyoko:20160830001930p:plain

(参考)amazon web services - AWS error - sudo: unable to resolve host ip-10-0-xx-xx - Stack Overflow


 

2.2. Subnet の作成

CIDR が「10.0.0.0/24」のサブネットを作成します。

[Subnets] から、「Create Subnet」ボタンをクリック。

f:id:akiyoko:20160830001951p:plain

以下を設定します。

Name tag P1 Public #1
VPC P1
Availability Zone ap-notrtheast-1a
CIDR block 10.0.0.0/24

f:id:akiyoko:20160830002016p:plain


 

2.3. Internet Gateway の作成

インターネットゲートウェイを作成します。

[Internet Gateways] から、「Create Internet Gateway」ボタンをクリック。

f:id:akiyoko:20160830002038p:plain

名前を「P1 Public #1」に設定。
f:id:akiyoko:20160830002101p:plain

作成した Internet Gateway を選択して「Attach to VPC」ボタンをクリックし、作成した VPC を選択して、Internet Gateway を VPC に紐付けます。

f:id:akiyoko:20160830002124p:plain
f:id:akiyoko:20160830002146p:plain

[Route Tables] から、作成した VPC の Route Table を選択して、Routes を編集します。

f:id:akiyoko:20160830002204p:plain

以下を設定します。

Destination 0.0.0.0./0
Target 作成した Internet Gateway を選択

f:id:akiyoko:20160830002223p:plain
f:id:akiyoko:20160830002254p:plain


これで VPC の設定は完了です。


3. EC2 インスタンスの起動

3.1. SSH鍵の作成

まず、SSH鍵を作成します。

[EC2] > [Key Pairs] から、「Create Key Pair」をクリック。

f:id:akiyoko:20160910223728p:plain

キーペア名は、「aws_p1」としました。
f:id:akiyoko:20160910223833p:plain

作成すると、自動的に鍵がダウンロードされます。
f:id:akiyoko:20160910223853p:plain


ダウンロードした SSH鍵を .ssh 以下に配置します。
(以下の操作は Mac を想定しています。)

$ mv ~/Downloads/aws_p1.pem ~/.ssh/
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/aws_p1.pem
$ ls -l@ ~/.ssh/aws_p1.pem
-rw-------@ 1 akiyoko  staff  1696  6  5 17:35 /Users/akiyoko/.ssh/aws_p1.pem
    com.apple.metadata:kMDItemWhereFroms     199
    com.apple.quarantine      68
$ xattr -d com.apple.metadata:kMDItemWhereFroms ~/.ssh/aws_p1.pem
$ xattr -d com.apple.quarantine ~/.ssh/aws_p1.pem
$ ls -l@ ~/.ssh/aws_p1.pem
-rw-------  1 akiyoko  staff  1696  6  5 17:35 /Users/akiyoko/.ssh/aws_p1.pem

ここで、ダウンロードした際によく分かんない attribute(Extended Attributes と言うものらしい)が付いてしまっているので、削除しています。

(参考)EA (Extended Attributes) の消し方


 

3.2. EC2インスタンス用の Security Group 作成

EC2インスタンスに付与する Security Group を作成します。

f:id:akiyoko:20160910223918p:plain

以下を設定します。

Security group name P1 Webserver #1
Description P1 Webserver #1
VPC P1
Type Protocol Port Range Source
SSH TCP 22 My IP
HTTP TCP 80 My IP
HTTPS TCP 443 My IP

f:id:akiyoko:20160910223941p:plain


 

3.3. EC2 インスタンス用の IAM Role の作成

EC2インスタンス作成時に IAM Role を設定して起動するため、先に作成しておきます。

f:id:akiyoko:20160910224102p:plain

IAM Role の名前は「ec2-prod」(本番 EC2インスタンス用の Role という意味)としておきます。
f:id:akiyoko:20160910224124p:plain

「Role Type」は「Amazon EC2」を選択。
f:id:akiyoko:20160910224151p:plain

完全な管理者アクセス権限(AdministratorAccess)ポリシーを選択します。
f:id:akiyoko:20160910224226p:plain

「Create Policy」をクリックして、IAM Role の作成は完了です。
f:id:akiyoko:20160910224252p:plain


 

3.4. EC2インスタンスの起動

EC2インスタンスを起動します。

f:id:akiyoko:20160910224329p:plain

「Ubuntu Server 14.04 LTS」を選択。
f:id:akiyoko:20160910224351p:plain

インスタンスタイプは(必要に応じていつでもスケールアップできるので、最初は)「t2.micro」でよいでしょう。
f:id:akiyoko:20160910224416p:plain

以下を設定します。

Network P1
Subnet P1 Public #1
IAM role ec2-prod
Enable termination protection 「Protect against accidental termination」にチェック

f:id:akiyoko:20160910224442p:plain

f:id:akiyoko:20160910224508p:plain

インスタンス名を「P1 Webserver #1」とします。
f:id:akiyoko:20160910224525p:plain

3.2. で作成した Security Group を設定します。
f:id:akiyoko:20160910224552p:plain

f:id:akiyoko:20160910224616p:plain

3.1. で作成した SSH鍵を設定して、インスタンスを起動します。
f:id:akiyoko:20160910224643p:plain


 

3.5. Elastic IP の紐付け

最後に、起動した EC2インスタンスに Elastic IP を紐付けます。

[Elastic IPs]>[Allocate New Address]をクリック。
f:id:akiyoko:20160910224724p:plain

「Yes, Allocate」をクリックして、Elastic IP を払い出します。
f:id:akiyoko:20160910224751p:plain

払い出した Elastic IP を選択し、[Actions]>[Associate Address]をクリック。
f:id:akiyoko:20160910224815p:plain

3.4. で起動したインスタンスを選択して「Associate」をクリックし、Elastic IP を紐付けます。
f:id:akiyoko:20160910224835p:plain


f:id:akiyoko:20160910224945p:plain


ここで念のため、疎通確認しておきます。

$ ssh -i ~/.ssh/aws_p1.pem ubuntu@52.xx.xx.xx



 

4. SES の設定

最後に、メールの設定です。
なおここで、AWS 外のレジストラ(ここでは お名前.com)で独自ドメイン「akixxxx.com」を管理していることを前提しています。


まず最初に、Amazon SES は Tokyo リージョンでは対応していないため *2、「Oregon」リージョンに移動します。

f:id:akiyoko:20160910225033p:plain


 

4.1. ドメイン認証

[Domain] > [Verify a New Domain]でドメインを認証します。
f:id:akiyoko:20160910225132p:plain

Domain に「akixxxx.com」を指定します。
f:id:akiyoko:20160910225203p:plain

送信用の TXTレコードと受信用の MXレコードが表示されます。
f:id:akiyoko:20160910225231p:plain


 

4.2. 送信用 TXTレコードと受信用 MXレコード設定

レジストラ(お名前.com)上でドメインNavi にログインし、上記の送信用の TXTレコードと受信用の MXレコードを設定します。


[ドメイン設定] > [ネームサーバーの設定]>[DNS関連機能の設定]から、該当ドメインをチェックして「次へ進む」をクリック。
f:id:akiyoko:20160910225320p:plain

[DNSレコード設定を利用する]>[設定する]をクリック。
f:id:akiyoko:20160910225355p:plain

以下を設定します。

ホスト名 TYPE TTL VALUE 優先 状態
_amazonses.akixxxx.com TXT 3600 (AWS Management Console の Domain Verification Record の値を貼り付け) 有効
akixxxx.com MX 3600 (AWS Management Console の Email Receiving Record の値を貼り付け) 10 有効

なお、MXレコードの優先度は「10」にします(そのまま貼り付けるとダメ。「10」と「inbound-smtp.us-west-2.amazonaws.com」に分割する)。

f:id:akiyoko:20160910225430p:plain

f:id:akiyoko:20160910225513p:plain

f:id:akiyoko:20160910225552p:plain



2時間ほどすると、「Amazon SES Domain Verification SUCCESS」というメールが来ます。
f:id:akiyoko:20160910225630p:plain

ドメインのステータスが「verified」になっていることが確認できます。
f:id:akiyoko:20160910225710p:plain


 

4.3. SES 送信制限の解除申請

ステータスが「verified」になったら、「Request a Sending Limit Increase」の申請をします。

f:id:akiyoko:20160910225743p:plain


申請内容は以下の通り。

Regarding(内容) Service Limit Increase(サービス制限の増加)
Limit Type(制限タイプ) SES Sending Limits(SES送信制限)
Region US West (Oregon)
Limit Desired Daily Sending Quota(希望する一日あたりの送信クォータ)
New limit value 10000
Mail Type(メールの種類) System Notifications(システム通知)
Website URL (メール送信を使用するシステムのURLを指定)
My email-sending complies with the AWS Service Terms and AUP(私は AWS サービス利用規約と AUP に準拠してメールを送信します) Yes
I only send to recipients who have specifically requested my mail(私は明確にリクエストされた受信者にのみメールを送信します) Yes
I have a process to handle bounces and complaints(バウンスや苦情を処理するプロセスがあります) Yes
Use Case Description(申請理由の説明) アカウント登録やパスワード変更など、システムを利用するユーザへの通知に利用します。メール送信は基本的にシステムからの自動送信となり、ユーザ自身が登録したメールアドレス宛に送信するため、バウンスはほとんど発生しません。予想されるユーザ数は当面のところ、○○程度と見込んでいます。(あくまでサンプルですので、状況に合わせて適宜書き直してください。)
Support Language 日本語
Contact method Web(しか選択できません)

f:id:akiyoko:20160910225819p:plain

f:id:akiyoko:20160910225857p:plain


6時間くらい後に承認メールが届きました。
f:id:akiyoko:20160910230541p:plain

Congratulations! After reviewing your case, we have increased your sending quota to 50,000 messages per day and your maximum send rate to 14 messages per second in AWS Region US West (Oregon). Your account has also been moved out of the sandbox, so you no longer need to verify recipient addresses.

AWS Management Console 上はこのようになっています。
f:id:akiyoko:20160910230618p:plain


(参考)Amazon SESによるメール送信環境の構築と実践 | Developers.IO


まとめ

今回、AWS 環境構築として、

  • IAM 設定(ルートアカウント・admin ユーザの設定)
  • VPC 設定(1ネットワーク+ 1サブネット)
  • EC2 設定(Ubuntu 14.04 LTS インスタンスの起動)
  • Amazon SES 設定(ドメイン認証、送信制限の解除申請)

を実施した内容を記載しました。

次回は、Mezzanine 本番設定の第二弾として、「その2:Mezzanine テーマのカスタマイズ」について記載します。


 

参考本

AWS 関連で比較的新しくて良さげな本を紹介します。

*1:というか、1台のスマホにつき紐付けられるユーザは 1つだけなのかな??

*2:「米国西部(オレゴン)」のほか、「米国東部(バージニア北部)」「欧州(アイルランド)」でも SES を利用できますが、今回は日本から物理的に一番近そうな米国西部を選択しました。(参考)https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/regions.html 東京リージョンに対応しました。(参考)Amazon SES 東京リージョン対応のお知らせ | Amazon Web Services ブログ

見よ!これが Python製の WordPress風フルスタックCMSフレームワーク「Mezzanine(メザニン)」だ!

この投稿は 「Python Advent Calendar 2015 - Qiita」 の 23日目の記事です。


煽っておきながら先に言い訳しておきますが、「Mezzanine(メザニン)」は WordPress公式 が作ったものでもサポートしているものではありません。

しかしながら、Mezzanine の 概要ページ の説明を見ると、

In some ways, Mezzanine resembles tools such as Wordpress that provide an intuitive interface for managing pages, blog posts, form data, store products, and other types of content.


Mezzanine は、いくつかの点において、ページ、ブログ記事、フォームデータ、ショップ商品、および他のタイプのコンテンツのための直感的なインターフェースを提供しする Wordpress のようなツールに似ています。

と書かれているので、Mezzanine が WordPress を意識して作られている ことが分かります。



その証拠に、Mezzanine の管理画面を少しお見せすると、

f:id:akiyoko:20151220153711p:plain
(ブログ投稿画面。WordPress のものとそっくりですよね)

f:id:akiyoko:20151220153727p:plain
(画像をアップロードするためのメディアライブラリ画面。こちらも WordPress とほぼ同じですよね)


という感じになっており、ルック&フィールが WordPress と非常に似通っていることがお分かりになるかと思います。WordPress の管理画面を触ったことのある人なら、ほとんどの機能を直感的に理解できるでしょう。


ちなみに、Djangoベースの三大 CMSフレームワーク「django CMS」「Wagtail」「Mezzanine」*1 のうち、他の二つは操作がユニークで、WordPress に慣れた私の脳みそでは直感的に理解ができず、一日ほど触ってそっとインスタンスを閉じました。


Mezzanine の特徴

Mezzanine には、

  • ルック&フィールが WordPress とそっくりな管理画面
  • デフォルトで必要な機能が全部入り(フルスタック)

といった、他の CMSフレームワークには無い大きな特徴があります。


前者については先に説明しましたが、後者のデフォルトで全部入りになっている機能としては、 概要ページ で以下のものが紹介されています。

機能・特徴 説明
Hierarchical page navigation 階層ナビゲーション
Save as draft and preview on site 下書き保存、プレビュー機能
Scheduled publishing 予約投稿
Drag-and-drop page ordering ドラッグ&ドロップでページの順序入れ替え
WYSIWYG editing WYSIWYGエディタ
In-line page editing インラインページ編集
Drag-and-drop HTML5 forms builder with CSV export ??
SEO friendly URLs and meta data SEOフレンドリーなURLとメタデータの設定
Shopping cart module (Cartridge) ショッピングカート(Cartridge プラグイン使用)
Configurable dashboard widgets ダッシュボードのウィジェットが設定ファイルで変更可能
Blog engine ブログ
Tagging タグ付け
Free Themes, and a Premium Themes Marketplace 無料テーマ、プレミアムテーママーケット(まだちょっと少ない。。)
User accounts and profiles with email verification メールアドレスでのユーザ認証、プロフィール機能
Translated to over 35 languages 翻訳(35言語以上)
Sharing via Facebook or Twitter Facebook、Twitter での SNS共有
Multi-lingual sites 多言語サイト
Custom templates per page or blog post ページ、ブログ記事ごとにカスタムテンプレートが適用可能
Twitter Bootstrap integration Twitter Bootstrap連携
API for custom content types カスタムコンテンツタイプのAPI
Search engine and API 検索機能と検索API
Seamless integration with third-party Django apps サードパーティ製のDjangoのアプリとのシームレスな統合
Multi-device detection and template handling マルチデバイス検出とテンプレートハンドリング
One step migration from other blogging engines 他のブログエンジンからワンステップでのデータマイグレーション
Automated production provisioning and deployments 自動プロビジョニングおよびデプロイ
Disqus integration, or built-in threaded comments スレッドコメント機能(Disqus連携 or ビルトイン)
Gravatar integration Gravatar連携
Google Analytics integration Google Analytics連携
Twitter feed integration Twitterフィード連携
bit.ly integration bit.ly連携
Akismet spam filtering Akismet によるスパムフィルタリング
Built-in test suite ビルトインのテストスイート
JVM compatible (via Jython) JVM との互換性(Jythonを使う)

Overview — Mezzanine 4.0.1 documentation を元に akiyoko が意訳)


ここで、「フルスタック」と聞くと、欲しい機能がある程度揃っていて便利である一方、そのプロダクトへの依存度が高まってしまうことが懸念されるなど、メリットとデメリットが表裏一体になっていることもあると思います。
その点、Mezzanine は「Mezzanine(=中二階)」というだけあって、1階部分には「Django(ジャンゴ)」という人気ナンバーワンの Webアプリケーションフレームワークが土台となっているので、Mezzanine-way *2 ではなく Django-way でのアプリケーション拡張ができるようになっていて、フレームワークを採用する側としては非常に安心感があります *3

f:id:akiyoko:20151220160001p:plain





インストールしてみる

では早速、Mezzanine + Cartridge(Mezzanine 向けのショッピングカートプラグイン)をインストールしてみましょう。

なお、以下の手順は本番用ではありませんのでくれぐれもご注意を。

環境

  • Ubuntu 14.04 LTS(on Vagrant)
    • IPアドレス:192.168.33.10
  • Python 2.7.6
  • Django 1.8.7
  • Mezzanine 4.0.1
  • Cartridge 0.10.0

 

### 最低限のインストール
$ sudo apt-get update
$ sudo apt-get -y install python-dev git tree

### pip をインストール
### sudo apt-get -y install python-pip でインストールすると pip のバージョンが古いので、get-pip.py で最新版を入れる
$ wget https://bootstrap.pypa.io/get-pip.py
$ sudo -H python get-pip.py
$ pip --version
pip 7.1.2 from /usr/local/lib/python2.7/dist-packages (python 2.7)

### virtualenv, virtualenvwrapper をインストール
$ sudo -H pip install virtualenv virtualenvwrapper

### virtualenvwrapper の設定
$ cat << EOF >> ~/.bash_profile

if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
EOF
$ cat << EOF >> ~/.bashrc

source /usr/local/bin/virtualenvwrapper.sh
export WORKON_HOME=~/.virtualenvs
EOF
$ source ~/.bashrc

### Djangoプロジェクトの virtualenv 環境を作成してアクティベート
$ mkvirtualenv myproject

### /opt/webapps 配下にプロジェクトの外箱を作成
$ sudo mkdir -p /opt/webapps/myproject
$ sudo chown -R `whoami`. /opt/webapps

### イメージライブラリのインストール
### http://mezzanine.jupo.org/docs/overview.html#dependencies
$ sudo apt-get -y install libjpeg8 libjpeg8-dev
$ sudo apt-get -y build-dep python-imaging


### Mezzanine プロジェクトを作成
$ cd /opt/webapps/myproject/
### Cartridge のインストール
$ pip install -U cartridge

### プロジェクトのディレクトリ構造は
### myproject/ as <repository_root> also as <django_project_root>
### └─ config/ as <configuration_root>
$ mezzanine-project -a cartridge config .

$ tree /opt/webapps/myproject/
/opt/webapps/myproject/
├── config
│   ├── __init__.py
│   ├── local_settings.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── deploy
│   ├── crontab.template
│   ├── gunicorn.conf.py.template
│   ├── local_settings.py.template
│   ├── nginx.conf.template
│   └── supervisor.conf.template
├── fabfile.py
├── __init__.py
├── manage.py
└── requirements.txt


### アプリケーションを起動
$ python manage.py createdb --noinput
$ python manage.py runserver 0.0.0.0:8000


ブラウザで
http://192.168.33.10:8000/
にアクセスすれば、以下のトップ画面が表示されるはずです。

f:id:akiyoko:20151220161820p:plain




WordPress 風の管理画面と比べて、ちょっと画面がショボいなぁあっさりしているなぁと不安に思われるかもしれません。

でも安心してください。そういった場合には、テーマテンプレートの変更ができますから。


WordPress のようにボタンをポチポチすれば完了というわけにはいきませんが、チュートリアル に沿ってコマンドを実行することによって、比較的簡単に、例えば以下のようなテーマテンプレートを利用することができます。


mezzanine-themes/nova を使用)
f:id:akiyoko:20151220170242p:plain

mezzanine-themes/flat を使用)
f:id:akiyoko:20151220170257p:plain

mezzanine-themes/moderna を使用)
f:id:akiyoko:20151220170328p:plain

mezzanine-themes/solid を使用)
f:id:akiyoko:20151220170355p:plain


この 4種類のフリーテーマの他にも、いくつかのフリーテーマ有料テーマ も公開されていますが、WordPress と比べるとまだまだ量が少ないのが実情です。



あと、個人的に無いと困る、「多言語サイト」(WordPress でいうところの「qTranslate X」に当たる機能)もデフォルトで入っています *4 。こちらも チュートリアル に従って進めていけば、ブログ投稿時に次のような言語選択オプションが表示され、多言語対応のブログ投稿ができるようになります。

f:id:akiyoko:20151220172734p:plain




 

まとめ

Python製の WordPress風フルスタックCMSフレームワーク、ということで「Mezzanine」を紹介してみましたが、いかがだったでしょうか?


WordPress を使ったことのある人なら間違いなく違和感なく使えるでしょうし、私も今のところ全然違和感なく使えています。今後は、ショッピングカートと課金まわりを少しディープに調べてみたいと考えています。



明日は、TakesxiSximada さんの 24日目の記事です。よろしくお願いします。

*1:https://www.djangopackages.com/grids/g/cms/ を参照

*2:玉石混交ですが、Apps for Mezzanine は https://www.djangopackages.com/grids/g/mezzanine/ で紹介されています

*3:しかしながら、用意されたものが気に入らなければ自分で作るしかない、というリスクは許容しなければなりませんが。。

*4:厳密には、django-modeltranslation を pip install する必要がありますが、まあよしとしましょう。^^

年額8.85ドル(約1,100円)の SSLサーバ証明書「RapidSSL」を試してみる

1. はじめに

以前、自己署名証明書(いわゆるオレオレ証明書)のことを書きましたが、今回は、認証局の発行した、ちゃんとした SSLサーバ証明書を取得してみることにします。


そもそも SSLサーバ証明書には、信頼性の高い順に、「EV SSL証明書」「企業認証(OV)証明書」「ドメイン認証(DV)証明書」という種類のものがあるのですが、今回は、個人サイト向けにドメイン認証を目的としたSSLサーバ証明書を取得します。

参考



できるだけ安いものを探していたのですが、

で紹介されていた「GoGetSSL」という海外のサイトがよさそうだったので、そこで探すことにしました。
www.gogetssl.com


Domain Validation(ドメイン認証)の SSL証明書のリストを見てみると、

製品 価格(1年契約) 価格(3年契約)
Comodo Positive SSL $ 8.95 /年 $ 3.65 /年
RapidSSL Standard $ 8.85 /年 $ 7.38 /年

の二つが候補に挙がったのですが(価格は2015年7月現時点)、契約期間は1年分だけでよかったので、今回は「RapidSSL Standard」を購入することにしました。


以下、

  • お名前.com でドメイン取得
  • GoGetSSL で「RapidSSL Standard」取得
  • Amazon EC2インスタンス起動
  • お名前.com で Aレコード設定
  • Amazon EC2インスタンスで SSLサーバ証明書の動作確認

をするための手順です。


 

2. お名前.com でドメイン取得

まずは、例えば、お名前.com などのレジストラでドメインを取得します。






2.1. お名前.com でドメインを取得

f:id:akiyoko:20150726100934p:plain

ここでは、Whois情報公開代行サービスを付けておきましたが、CSR申請時に一旦解除することになります。

SSLサーバー証明書など一部サービスにおいて、本人確認の手段としてドメインのWhois情報を利用する場合は、いったん「Whois情報公開代行」を解除し、承認作業が完了したのち、再度「Whois情報公開代行」を設定してください。


Whois情報公開代行|ドメイン取るならお名前.com」より



この後、GMO Internet からメールアドレス有効性認証のための確認メールが届くので、メール中のリンクをクリックして認証を完了させます。

f:id:akiyoko:20150726100942p:plain

f:id:akiyoko:20150726100950p:plain


 

2.2. Whois情報公開代行サービスを解除

ドメイン認証の申請のために、Whois情報公開代行サービスを解除しておきます。


ドメインNavi にログインし、「ドメイン設定」->「ドメインWhois情報変更」から、対象のドメイン名をクリックして「登録者情報の変更」にチェックを入れると登録者情報が表示されるので、情報が正しいか確認しておきます。

f:id:akiyoko:20150726100957p:plain



次に、「Navi TOP」のドメイン一覧から、対象のドメインの「Whois情報公開代行」の「解除する」をクリックして、処理を完了させます。

f:id:akiyoko:20150726101008p:plain



Whois情報公開代行サービスを解除したら、Whois検索で、自分で取得したドメインの Whois情報を確認しておきます。Registrant(登録者名)に自分の登録者情報が表示されていれば OKです。

Whois検索 - お名前.com


 

2.3. メール転送設定

最後に、ドメイン認証申請の際に送信される確認メールが受信できるように、特定のメールアドレスの転送設定をしておきます。


ドメインNavi の「オプション設定」->「メール転送設定」から、対象のドメインの「設定する」をクリックします。

f:id:akiyoko:20150726101020p:plain

転送元メールアドレスのローカル部に「admin」、転送先メールアドレスに実際に受け取れるメールアドレスを入力して「新規追加」をクリックし、「確認画面へ進む」をクリック。

f:id:akiyoko:20150726101029p:plain

設定が完了したら、念のため、転送元メールアドレス宛に送信したメールが受信できるかチェックしておきます。



3. GoGetSSL で RapidSSL Standard 取得

3.1. RapidSSL Standard を購入

GoGetSSL のトップページから、「Domain Validation」の「View SSL List」をクリック。

f:id:akiyoko:20150726101044p:plain


「RapidSSL Standard」の「Details」を選択します。

f:id:akiyoko:20150726101053p:plain

「BUY SSL」をクリック。

f:id:akiyoko:20150726101101p:plain

「Business Company or Private/Individual」に「Private customer (Individual)」を選択して、「Next Step」をクリック。

f:id:akiyoko:20150726101115p:plain

「Create new account」をクリックして、新規アカウントを作成します。

f:id:akiyoko:20150726101212p:plain

アカウント情報(CSRに使われる情報ではない)を入力して、次へ。

f:id:akiyoko:20150726101247p:plain

決済方法を選択して、「Complete Order」をクリックし、決済を完了させます。
ちなみに現時点で、8.85ドル=1,136円 でした。

f:id:akiyoko:20150726101259p:plain


支払いが完了したら、サイトに再度ログインします。

f:id:akiyoko:20150726101333p:plain


 

3.2. Online CSR Generator で CSR を作成

Certificate Signing Request(CSR)を作成します。

ここでは OpenSSL を利用せず、GoGetSSL が提供しているオンラインのツール(Online CSR Generator)で作成します。


GoGetSSL のダッシュボードから、「Online Tools」->「Online CSR Generator」と選択。

f:id:akiyoko:20150726101345p:plain


CSR の申請内容は以下の通りです。
ちなみに、個人の場合と法人の場合とで内容が少し異なっています。(なお、このツールでは「OU:部署名」が省略不可のため、適当な値を入れています。)

入力項目 個人の場合の入力例 法人の場合の入力例
Common Name(CN:コモンネーム) www.akiyoko.com(サイトのFQDN) 同じ
Organization(O:組織名) Taro Yamada(英語氏名) ABC Company Co.,Ltd.(正式英語組織名)
Department(OU:部署名) OU1 ( *1 ) System Solution Department
City(L:市区町村名) Xxx-shi / Xxx-ku 同じ
State(S/ST:都道府県名) Tokyo 同じ
Country(C:国名) JP 同じ
Email admin@{ドメイン名} 同じ

f:id:akiyoko:20150726101400p:plain

ちなみに、OpenSSL を使用する場合は以下を参考に。
Apache + OpenSSL CSR生成手順 (新規)ジオトラスト



「Generate CSR」をクリックすると、作成された CSR と秘密鍵が画面に表示されるので、両方ともコピペして保存しておきます。

f:id:akiyoko:20150726101410p:plain



 

3.3. CSR を申請

3.2.で作成した CSR を、GoGetSSL から申請します。


GoGetSSL のダッシュボードから、「Manage SSL certificates」をクリックし、リストから CSRを申請したい証明書の「Generate」をクリックします。

f:id:akiyoko:20150726101434p:plain


STEP 1 - CSR Configuration

Order Type New Order
Web Server Software Nginx
Paste your CSR 2.4.で生成した CSRをまるごとコピペ
Please select signature algorithm SHA2

上記を入力後、「Validate CSR」をクリック。

f:id:akiyoko:20150726101444p:plain


STEP 2 - Select validation method

2.3.で設定したメールアドレスを選択して、「Next Step」をクリックします。

f:id:akiyoko:20150726101457p:plain


管理者情報(Administrative Contact)を入力し、「agree to the Terms and Conditions」をチェックして、「Complete Generation」をクリック。

f:id:akiyoko:20150726101513p:plain


この時点では、証明書のステータスは「Processing」になっています。

f:id:akiyoko:20150726101535p:plain


この後数分で、「RapidSSL Certificate Request Confirmation」というタイトルのメールが、STEP2 で設定したメールアドレス宛に送られてきます。

f:id:akiyoko:20150726101545p:plain

メール中の上記のリンクにアクセスし、「承認します」をクリックします。

f:id:akiyoko:20150726101554p:plain

f:id:akiyoko:20150726101603p:plain

ステータスが「Active」になりました。

f:id:akiyoko:20150726101612p:plain



 

3.4. SSL証明書・中間CA証明書をダウンロード

My SSL Certificates から、対象の証明書の「View」ボタンをクリック。

f:id:akiyoko:20150726101622p:plain


SSL証明書は「Download SSL」、中間CA証明書は「CA Bundle」のリンクからダウンロードすることができます。ファイル名はそれぞれ、

  • www_akiyoko_com.crt
  • www_akiyoko_com.ca-bundle

となります。

f:id:akiyoko:20150726101632p:plain




 

4. Amazon EC2インスタンス起動

以下の設定で、Amazon EC2インスタンスを起動します。

Region Tokyo
VPC default
Subnet No preference
SecurityGroup 22, 80, 443番を許可(MyIPのみ)
AMI Ubuntu Server 14.04 LTS (HVM)
Elastic IP 52.68.xxx.xxx





 

5. お名前.com で Aレコード設定

5.1. ドメインNavi で Aレコードを設定

ドメインNavi にログインし、「ドメイン設定」->「DNS関連機能の設定」から、対象ドメインを選択して、「次へ進む」をクリック。

f:id:akiyoko:20150726101653p:plain

「DNSレコード設定を利用する」の「設定する」ボタンをクリック。

f:id:akiyoko:20150726101708p:plain


サブドメインを「www」に設定したホスト名の Aレコードに、4.で起動したインスタンスの Elastic IP を設定して、「追加」ボタンをクリック。

f:id:akiyoko:20150726101715p:plain

「確認画面へ進む」ボタンをクリックして、設定を完了させます。

f:id:akiyoko:20150726101723p:plain



 

5.2. メール転送設定を解除

ここでついでに、ドメイン認証の申請のために、一旦解除していた Whois情報公開代行サービスを復活させます。


「Navi TOP」のドメイン一覧から、対象のドメインの「Whois情報公開代行」の「申し込む」をクリックして、Whois情報公開代行サービスを設定します。

f:id:akiyoko:20150727004850p:plain

再設定は無料で行えるようです。

f:id:akiyoko:20150727005805p:plain

 

5.3. メール転送設定を解除

ついでのついでに、「オプション設定」->「メール転送設定」から、メール転送設定を解除しておきます。

f:id:akiyoko:20150726101732p:plain




 

6. Amazon EC2インスタンスで動作確認

 

6.1. 非SSLバージョンで動作確認


まずは、非SSLバージョンで動作確認をしておきます。

4.で起動したインスタンス上で、Django + Gunicorn + Nginx でアプリケーションを構築し、非SSLでアクセスできるように設定します。


以降、EC2インスタンスに乗り込んで操作します。

$ ssh -i ~/Downloads/T1-key.pem ubuntu@52.68.xxx.xxx


Django をインストール、アプリケーションを作成します。

### pip をインストール
$ sudo apt-get update
$ sudo apt-get install -y python-pip python-dev

### virtualenv をインストール
$ sudo pip install virtualenv

### Django をインストールし、/opt/webapps配下に Djangoプロジェクトを作成
$ sudo mkdir -p /opt/webapps
$ sudo chown `whoami`. /opt/webapps
$ cd /opt/webapps/
$ virtualenv venv
$ source venv/bin/activate
(venv)$ pip install django
(venv)$ pip list | grep Django
Django (1.8.3)

### Djangoプロジェクトを作成
(venv)$ django-admin.py startproject myproject
(venv)$ cd myproject/
(venv)$ python manage.py migrate
(venv)$ python manage.py createsuperuser
(admin/admin@example.com/adminpass)

### settings.py に最後の一行を加える
(venv)$ vi myproject/settings.py
---
  ・
  ・
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
---

(venv)$ python manage.py collectstatic


Gunicorn をインストールして起動します。

(venv)$ pip install gunicorn

### デーモンとして実行
(venv)$ gunicorn --workers 3 --bind unix:/tmp/myproject.sock --daemon myproject.wsgi:application


Nginx をインストールして起動します。

$ sudo apt-get install -y nginx
$ nginx -v
nginx version: nginx/1.4.6 (Ubuntu)
### デフォルトの設定ファイルを書き換え
$ sudo vi /etc/nginx/sites-available/default
---
upstream myproject_backend {
    server unix:/tmp/myproject.sock fail_timeout=0;
}

server {
    listen 80;
    server_name www.akiyoko.com;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /opt/webapps/myproject;
    }

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass http://myproject_backend;
    }
}
---

$ sudo service nginx reload


http://www.akiyoko.com/
http://www.akiyoko.com/admin/
にアクセスして、動作確認します。


f:id:akiyoko:20150727210354p:plain

f:id:akiyoko:20150727210406p:plain



 

6.2. SSL証明書をサーバに設定して動作確認

次に、Nginx で SSL証明書の設定をして、動作確認を行います。


3.4.でダウンロードした SSL証明書をサーバに配置します。

### SSL証明書をサーバに転送(on Mac)
$ scp -i ~/Downloads/T1-key.pem ~/Downloads/www_akiyoko_com.crt ubuntu@52.68.xxx.xxx:/home/ubuntu/
### SSL証明書を配置
$ sudo mkdir /etc/nginx/ssl
$ sudo mv /home/ubuntu/www_akiyoko_com.crt /etc/nginx/ssl/


秘密鍵をサーバに配置します。

sudo vi /etc/nginx/ssl/www_akiyoko_com.key
---
3.2.で保存した秘密鍵をペースト
---


Nginx の設定ファイルを SSL用に書き換えます。

$ sudo vi /etc/nginx/sites-available/default
---
upstream myproject_backend {
    server unix:/tmp/myproject.sock fail_timeout=0;
}

server {
    listen 443 ssl;
    server_name www.akiyoko.com;
    ssl_certificate /etc/nginx/ssl/www_akiyoko_com.crt;
    ssl_certificate_key /etc/nginx/ssl/www_akiyoko_com.key;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /opt/webapps/myproject;
    }

    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_pass http://myproject_backend;
    }
}
---

$ sudo service nginx reload

参考




最後に、
https://www.akiyoko.com/
https://www.akiyoko.com/admin/
にアクセスして、SSL通信が正しく行えるかチェックをします。

f:id:akiyoko:20150727211207p:plain

f:id:akiyoko:20150727211218p:plain



7. まとめ

個人サイト向けの「RapidSSL Standard」であれば(事前準備ができていれば)審査は数分で完了するので、やり方さえ分かれば、ものの一時間ほどでドメインの取得から SSLサーバ証明書の取得まで完了させることができます。


年額3.65ドルでSSL証明書を手に入れる - Qiita」のように年額3.65ドルとまではいきませんでしたが(「Comodo Positive SSL」の3年契約なら年額3.65ドル)、国内のサイト(例えば「SSLストア」 )であれば最安 2,980円くらいする「RapidSSL Standard」が年額8.85ドル(約1,100円)で取得できるというのは、かなりお得な感じがしました。

*1:省略可。同一コモンネームで複数の証明書が必要になる場合の区別のために使う。

Amazon EC2インスタンスのデスクトップ環境を操作する方法(Ubuntu Server から X window を飛ばす)

「Xを飛ばす」というのは、Windowsでいうところの「リモートデスクトップ接続」のように、Linuxのデスクトップ環境を別マシンから操作することを指します。

いくつかやり方があるようですが、今回は、Linuxサーバ側に「vnc4server」を起動させて、WindowsからはVNCビューア経由で X window を取得する方法を試してみます。

やりたいこと

環境(サーバ側)

環境(クライアント側)

 

1. Ubuntu Server 12.04 LTS インスタンスを起動

Amazon Web Service から、EC2インスタンスを立ち上げます。

リージョン Tokyo(任意)
AMI Ubuntu Server 12.04 LTS (PV) - ami-f381f5f2 (64-bit)
Instance type t1.micro(何でもよいですが、テストなので小さめ)
Availability zone ap-northeast-1a
Security groups SSH用に「22」、VNC用に「5901」を開けます(クライアント側のIPを指定)

f:id:akiyoko:20140227232355p:plain



2. PuTTY から EC2インスタンスにログイン(クライアント側)

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
から、「PuTTYgen (puttygen.exe)」をダウンロードします。

f:id:akiyoko:20140227022902p:plain


「PuTTYgen (puttygen.exe)」を起動し、「Load」ボタンをクリックして EC2インスタンスに割り付けた Key pair(pemファイル) を読み込んだ後、

f:id:akiyoko:20140227222546p:plain


「Save private key」をクリックして、PuTTY用の鍵に変換します(拡張子は「.ppk」などとして保存します)。

f:id:akiyoko:20140227022855p:plain



同じく、
http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
から、「For Windows on Intel x86」の「PuTTY (putty.exe)」をダウンロードします。

f:id:akiyoko:20140227022121p:plain

PuTTY (putty.exe)」を起動し、[Connection] -> [SSH] -> [Auth] の「Private key file for authentication」から、変換した「.ppk」ファイルを選択します。

f:id:akiyoko:20140227023652p:plain


あとは、EC2の「Public IP」アドレスを指定して、SSH接続します。

f:id:akiyoko:20140227023622p:plain


3. vncserverを起動(サーバ側)

$ sudo apt-get update
$ sudo apt-get -y install ubuntu-desktop
(※完了まで 15分ほどかかります。なお、インストール後は reboot させなくても大丈夫です)

$ sudo apt-get -y install vnc4server

# ディスプレイ番号を「:1」と指定するとポート5901で起動(デフォルトが 5900+ディスプレイ番号)
$ vncserver :1

You will require a password to access your desktops.

Password: (パスワードを入力)
Verify: (同上)
xauth:  file /home/ubuntu/.Xauthority does not exist

New 'ip-xx-xx-xx-xx:1 (ubuntu)' desktop is ip-xx-xx-xx-xx:1

Creating default startup script /home/ubuntu/.vnc/xstartup
Starting applications specified in /home/ubuntu/.vnc/xstartup
Log file is /home/ubuntu/.vnc/ip-xx-xx-xx-xx:1.log

/home/ubuntu/.vnc/xstartup、その他諸々のファイルが作成されます。
ここで、VNC接続時のパスワードを決定して入力するのですが、長すぎる(8文字を超える)場合は「先頭8文字を使う」とのことです。


次に、

# vncserver を一旦停止
$ vncserver -kill :1

vim ~/.vnc/xstartup
-----
exec gnome-session &
vncconfig -nowin &
-----
(※↑を最終行に追加)

# ディスプレイ番号「1」、解像度「1440x800 」、色深度「24」で起動
$ vncserver :1 -geometry 1440x800 -depth 24

参考
http://sdc.sangi.jp/2012/10/amazonec2guiubuntu.html


ちなみに、vncserver の起動ポート番号を固定する方法もあります。

# まずは使用中のポートを確認
$ netstat -untap

$ sudo vim /usr/bin/vncserver
-----
$vncPort = 5900 + $displayNumber;
  ↓
$vncPort = 5999;
-----

参考
評判のさくらのVPSを使ってVNCを使ってリモートデスクトップの環境を設定してみる


4. VNCで接続(クライアント側)


RealVNC をインストールします。

https://www.realvnc.com/
から、「Download」をクリックします。*1

f:id:akiyoko:20140227024735p:plain


https://www.realvnc.com/download/
から、「VNC Viewer」の Windows のアイコンをクリック。

f:id:akiyoko:20140227024928p:plain


VNC Viewer for Windows (exe) 64-bit」を選択します。

f:id:akiyoko:20140227025442p:plain


f:id:akiyoko:20140227025032p:plain


f:id:akiyoko:20140227025541p:plain


f:id:akiyoko:20140227025550p:plain




VNC-Viewer-5.1.0-Windows-64bit.exe」を起動します。

VNC Server <EC2インスタンス の Public IP>:5901
Encryption 任意

f:id:akiyoko:20140227025730p:plain


f:id:akiyoko:20140227025847p:plain


パスワードは、vncserver起動時に設定したものを指定します。

f:id:akiyoko:20140227025852p:plain


デスクトップ環境が操作できるようになりました。

f:id:akiyoko:20140227025919p:plain



なお、

VNCクライアントから直接ログインする設定
このままだと、VNCで画面を表示するまでに一度、ubuntuにターミナルなどでログインしてから、VNCサーバを起動したあとVNCクライアントでubuntuにアクセスしなければなりません。VNCクライアントで直接ログインするためには、xinetdを使用する必要があります。また、使用するポートの設定を行うため、「/etc/services」ファイルの設定も行います。

http://www.uetyi.mydns.jp/wordpress/colinux-setting/entry-279.html

というのがあるそうですが、なるほどUbuntuを再起動すると、一旦sshで接続して、
vncserver :1 -geometry 1440x800 -depth 24
を叩いておかないと、VNCから接続できなくなります。
毎回めんどいけど、まあ今のところはいいかな。


参考
http://ur.edu-connect.net/archives/543


注意

Xmint+PuTTYを使うやり方もあったのですが、表示されたデスクトップ環境が不安定だったので、結局ヤメにしました。

参考
http://d.hatena.ne.jp/horus531/20110227/1298791923



で、何が楽しいのか?

Firefox がプログラムから操作できます。
つまり、Amazon EC2 で、Selenium のテストができるのが最大の利点です。*2

$ sudo apt-get -y install python-pip
$ sudo pip install splinter
Downloading/unpacking splinter
  Downloading splinter-0.6.0.tar.gz
  Running setup.py egg_info for package splinter

    no previously-included directories found matching 'tests'
Downloading/unpacking selenium>=2.39.0 (from splinter)
  Downloading selenium-2.40.0.tar.gz (2.5Mb): 2.5Mb downloaded
  Running setup.py egg_info for package selenium

Installing collected packages: splinter, selenium
  Running setup.py install for splinter

    no previously-included directories found matching 'tests'
  Running setup.py install for selenium

Successfully installed splinter selenium
Cleaning up...

Splinterは内部でSeleniumを使っているので、Seleniumも同時にインストールされるようです。(The remote driver uses Selenium Remote to control a web browser on a remote machine.)


test_splint.py

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from splinter import Browser

with Browser() as browser:
    # Visit URL
    url = "http://www.google.com"
    browser.visit(url)
    browser.fill('q', 'splinter - python acceptance testing for web applications')
    # Find and click the 'search' button
    button = browser.find_by_name('btnG')
    # Interact with elements
    button.click()
    if browser.is_text_present('splinter.cobrateam.info'):
        print "Yes, the official website was found!"
    else:
        print "No, it wasn't found... We need to improve our SEO techniques"



GUI(デスクトップ)環境を使わず、SSHクライアント上で実行すると、

$ chmod +x test_splint.py

$ ./test_splint.py
Traceback (most recent call last):
  File "./test_splint.py", line 6, in <module>
    with Browser() as browser:
  File "/usr/local/lib/python2.7/dist-packages/splinter/browser.py", line 53, in Browser
    return driver(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/splinter/driver/webdriver/firefox.py", line 33, in __init__
    self.driver = Firefox(firefox_profile)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/webdriver.py", line 59, in __init__
    self.binary, timeout),
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/extension_connection.py", line 47, in __init__
    self.binary.launch_browser(self.profile)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/firefox_binary.py", line 61, in launch_browser
    self._wait_until_connectable()
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/firefox_binary.py", line 100, in _wait_until_connectable
    self._get_firefox_output())
selenium.common.exceptions.WebDriverException: Message: 'The browser appears to have exited before we could connect. The output was: Error: no display specified\n'

とエラーになるのですが、VNC上から実行すると Firefoxが立ちあがってテストが始まります。

f:id:akiyoko:20140227031917p:plain



また、素の Selenium だとこうなります。

test_selenium.py

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from selenium import webdriver
driver = webdriver.Firefox()
driver.get(u"http://www.google.co.jp")
$ chmod +x test_selenium.py
$ ./test_selenium.py

参考
http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp


参考
http://webtech-walker.com/archive/2013/04/xvfb-js-unit-test.html
http://d.hatena.ne.jp/tushuhei/20131009/1381302187



おまけ

Macからリモート接続する場合は、Finder メニュー -> [移動] -> [サーバへ接続] で、
vnc://(EC2インスタンスの Public IP):5901」
とすれば接続可能です。

f:id:akiyoko:20140227232854p:plain

参考
http://blog.inouetakuya.info/entry/20111211/1323605040

*1:後で気付いたのですが、「RealVNC日本語インストール版」の方がインストールも楽でいいかもしれません。

*2:なお、UbuntuChrome をインストールして、Chromeを立ち上げることもできます。Chromeのインストールにはひと手間かかりますが。