Amazon Linux上にインストールしたGitLab CEにLet’s Encryptを適用する方法

対象環境

GitLab Community Edition 9.0.4
certbot 0.13.0(Let’s EncryptのCLIクライアント)

原理

Let’s Encryptの「webroot」モードを利用する。
webrootモードはサーバに .well-known ディレクトリが置かれていることを認証基準としてSSL証明書を発行する。
GitLabのログインを回避して .well-known をLet’s Encryptに発見させ、SSL証明書を発行するのが本記事の目的である。

手順

※ GitLabはインストールが完了しており、既に稼働しているものとする。

1. GitLabが利用しているNginxの設定を変更する

GitLabのログインを回避して .well-known の存在を確認させるためにNginxのリダイレクト設定を変更する。
まずは設定ファイルを新規作成。

$ sudo vim /etc/gitlab/custom_gitlab_server_config.conf
/etc/gitlab/custom_gitlab_server_config.conf
location ^~ /.well-known {
    alias /var/letsencrypt/.well-known;
}

その後、設定ファイルを適用。

$ sudo vim /etc/gitlab/gitlab.rb
/etc/gitlab/gitlab.rb
nginx['custom_gitlab_server_config'] = "include /etc/gitlab/custom_gitlab_server_config.conf;"

最後に、Let’s Encryptに発見させる用のディレクトリを作成しておく。
.well-known は作成しなくてよい。

$ sudo mkdir /var/letsencrypt

2. GitLabに設定を適用して再起動

$ sudo mkdir /var/letsencrypt

3. Let’s Encryptをインストール

絶対に最後の --debug を忘れないように。
Amazon Linux限定の手法なので他のOSの場合は不要。

$ sudo mkdir /usr/local/letsencrypt
$ sudo chown `whoami` /usr/local/letsencrypt
$ cd /usr/local/letsencrypt
$ git clone https://github.com/letsencrypt/letsencrypt .
$ sudo ./letsencrypt-auto --debug

4. SSL証明書を取得

[gitlab.example.com] の部分はGitLabに適用しているドメインを指定する。

$ sudo ./letsencrypt-auto certonly --webroot --webroot-path /var/letsencrypt -d [gitlab.example.com]

エラーが出た場合

エラーの場合はこんな表示が出る。

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: gitlab.example.com
   Type:   unauthorized
   Detail: Invalid response from

Typeが unauthorized の場合

  • ログインが回避できていないので、1の手順が正しく完了しているか確認する

Typeが unconnected の場合

  • AWSのセキュリティグループを確認し、80番と443番のポートを開ける
  • 勢い余って /etc/gitlab/gitlab.rbexternal_url をhttpsにしていないか確認する(証明書取得まで禁止!)

5. SSL証明書が自動更新されるよう設定

$ sudo crontab -u root -e
00 05 01 * * /path/to/letsencrypt/letsencrypt-auto renew --force-renew && gitlab-ctl restart

5. SSL証明書をGitLabに適用

external_url をHTTPSに変更する。
[gitlab.example.com] の部分はGitLabに適用しているドメインを指定する。

redirect_http_to_https をtrueにしておくと、HTTPでアクセスされてもHTTPSにリダイレクトされる。
証明書の再発行の際はHTTPによる .well-known の確認が走らないので、HTTP接続を潰してしまってよい。
同じくAWSのセキュリティグループレベルでも80番ポートを潰してしまってよい。

$ sudo vim /etc/gitlab/gitlab.rb
/etc/gitlab/gitlab.rb
nginx['external_url']                = "https://[gitlab.example.com]"
nginx['redirect_http_to_https']      = true
nginx['ssl_certificate']             = "/etc/letsencrypt/live/[gitlab.example.com]/fullchain.pem"
nginx['ssl_certificate_key']         = "/etc/letsencrypt/live/[gitlab.example.com]/privkey.pem"

6. GitLabを再起動

$ sudo gitlab-ctl reconfigure

参考文献

GitLab Omnibus package の SSL 証明書を Let’s Encrypt で取得する
http://qiita.com/yuuAn/items/09a434d3f6cffa31101e

アクセス制限のかかったGitLabをLet’s Encryptをつかってhttps化する
https://gist.github.com/mamemomonga/a36a194f8a80ce5fa49bf950e092c604

続きを読む

AWS Redshift に SQL Server から DBLink 接続検証

目的

 現状 SQL Server を使用しているシステムが AWS Redshift 上のデータソースを参照するため、SQL Server から Redshift への DBLink 接続を行い、データ参照ができることを確認する。

検証結果

  • OpenQuery を使用すれば Select 可能

    • View ← OpenQuery ← DBLink ← Redshift という構成が現実的
  • DBLink 先のテーブルを直接、または SYNONYM 経由で Select することはできない
    • View 上に Redhisft から取得するカラムを定義する必要がある

検証手順

Redshift 構築

  • 手順の通り構築してみる。

  • 構築時のポイント

    • 予め Amazon Redshift に AmazonS3ReadOnlyAccess ロールを作成する
    • クラスタ作成の際に上記ロールを付与する
    • データロード(copy)時にも上記ロールの arn が必要
  • pgAdmin

    • デフォルトのDB名(dev)は接続した際にDB一覧に表示されない
    • データベースがないとクエリエディタが開けない
      • 新しいデータベースを作成 → クエリエディタ開く → 接続先を dev に切り替えた

SQL Server 構築

 RDS/SQL Server は Link Server 作成の権限がないので、EC2 上に構築する必要がある。

ODBC データソースを作成

image

 ポスグレの場合ですが、参考資料 SQL Server and PostgreSQL Linked Server Configuration – Part 2

SqlServer にリンクサーバ作成

image

EXEC master.dbo.sp_addlinkedserver 
    @server = N'REDSHIFT', --リンクサーバ 名
    @srvproduct=N'AWS Redshift', 
    @provider=N'MSDASQL', 
    @datasrc=N'MyRedshift' -- データソース
EXEC master.dbo.sp_addlinkedsrvlogin 
    @rmtsrvname=N'REDSHIFT',
    @useself=N'False',
    @locallogin=NULL,
    @rmtuser=NULL,
    @rmtpassword=NULL

SQL Server 上に OpenSql 経由のView を作成して Select できること確認

 上記 Redshift の Getting Started で Create, Copy するテーブルを例にする。

Create view [dbo].[viw_users]
(
    userid ,
    username ,
    firstname,
    lastname,
    city,
    state,
    email,
    phone ,
    likesports,
    liketheatre,
    likeconcerts,
    likejazz,
    likeclassical,
    likeopera,
    likerock,
    likevegas,
    likebroadway,
    likemusicals
) as select * from openquery ([REDSHIFT],'select * from [dev].[public].[users]')

select top 10 * from viw_users

問題: リンクサーバは直接 Select できない – (40470) Conversion error

select * from [REDSHIFT].[dev].[public].[users]
select * from [REDSHIFT].[dev].[public].[venue]
select * from [REDSHIFT].[dev].[public].[category]
select * from [REDSHIFT].[dev].[public].[date]
select * from [REDSHIFT].[dev].[public].[listing]
select * from [REDSHIFT].[dev].[public].[sales]
リンク サーバー "REDSHIFT" の OLE DB プロバイダー "MSDASQL" から、メッセージ "エラーを特定できません" が返されました。
リンク サーバー "REDSHIFT" の OLE DB プロバイダー "MSDASQL" から、メッセージ "[Amazon][Support] (40470) Conversion error at column 16 and row 1: Numeric value out of range." が返されました。
メッセージ 7311、レベル 16、状態 2、行 1
リンク サーバー "REDSHIFT" の OLE DB プロバイダー "MSDASQL" のスキーマ行セット "DBSCHEMA_COLUMNS" を取得できません。プロバイダーはインターフェイスをサポートしていますが、インターフェイス使用時にエラー コードが返されました。

※ シノニム経由でも変わらず

create synonym [dbo].[s_users] FOR [REDSHIFT].[dev].[public].[users]
select * from [s_users]

対応:OpenQuery 経由ならいける

select * from OPENQUERY([REDSHIFT],'select * from [dev].[public].[users]')
select * from OPENQUERY([REDSHIFT],'select * from [dev].[public].[venue]')
select * from OPENQUERY([REDSHIFT],'select * from [dev].[public].[category]')
select * from OPENQUERY([REDSHIFT],'select * from [dev].[public].[date]')
select * from OPENQUERY([REDSHIFT],'select * from [dev].[public].[listing]')
select * from OPENQUERY([REDSHIFT],'select * from [dev].[public].[sales]')

参考リンク

Amazon Redshiftで使えるPostgreSQL管理ツールを幾つか試してみた | Developers.IO
【AWS】Amazon Redshift のクラスター作成と起動から接続までの方法(入門編) – TASK NOTES

続きを読む

AWS EC2にMongoDBインストールとレプリケーション設定

MongoDBインストールとレプリケーション設定について、簡易的な抜粋メモとして書いています。
詳細に関しては、記事の最後の参考サイトを確認するようにしてください。

◆ 今日やること

  • MongoDBをEC2にインストール
  • レプリケーションの設定と確認
    • 今回せっていするレプリケーションの形式は、以下の図の通り、「Primary with Secondary Members」です。

mongorepl.png
引用元:Replication — MongoDB Manual 3.4

◆ バージョン

  • MongoDB 3.2
  • Linux 4.4.30-32.54.amzn1.x86_64 #1 SMP Thu Nov 10 15:52:05 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

◆ 実装編

> EC2へのインストール

sudo yum update -y
sudo vim /etc/yum.repos.d/mongodb-org-3.2.repo

[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/3.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.2.asc
sudo yum install -y mongodb-org
sudo service mongod start

sudo chkconfig mongod on

> 設定周り

  • WoredTigerストレージエンジンの主な設定

    • cacheSizeGB: システムメモリの6、7割
    • blockCompressor:デフォルトはsnappy(中間です)
/etc/mongod.conf
# Where and how to store data.
storage:
  dbPath: /data
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
       cacheSizeGB: 1
       journalCompressor: snappy
    collectionConfig:
       blockCompressor: snappy

> EBSボリュームをAttach

  • EBSボリュームにmongoのデータを溜めるようにする。

Amazon EBS ボリュームを使用できるようにする – Amazon Elastic Compute Cloudに従って、EBSボリュームをアタッチする

  • パーミッションを変更するのを忘れないように。
sudo chown -R mongod:mongod /data
  • /etc/mongod.conf
/etc/mongod.conf
# Where and how to store data.
storage:
  dbPath: /data

> レプリケーションの設定

MongoDBではマスターのことをプライマリ,スレーブのことをセカンダリと呼びます。
MongoDBのレプリケーションの最小構成は,3つのノードが必要です。

  • ネットワークインターフェイスの設定で、レプリケーションを組むサーバのIPを記述しておくこと

レプリケーション設定前には、お互いに通信できることを確認しないといけません
Troubleshoot Replica Sets — MongoDB Manual 3.4

mongodb が listen するIPアドレスはデフォルトでは 127.0.0.1 に設定されており、ローカルからのみアクセスを許可するようになっています
mongod.conf の bind_ip に設定されたIPアドレスで listen するのでこれを変更することで外部からの接続を許可します
ここに 0.0.0.0 を設定すると全てのIPアドレスからの接続を許可します

/etc/mongod.conf
# network interfaces
net:
  port: 27017
  bindIp: [127.0.0.1,10.1.52.111,10.1.51.227,10.1.51.68]


  • レプリケーション名を決める
  • Oplogのサイジングと設定サイズを決める
/etc/mongod.conf
replication:
   oplogSizeMB: 500
   replSetName: testRepl

第4回 MongoDBのレプリケーションを構築してみよう:MongoDBでゆるふわDB体験|gihyo.jp … 技術評論社

OplogはCapped Collectionなので,作成時以外にサイズ変更することができません。 デフォルトのOplogのサイズは「1GBまたは,ディスクの空き領域の5%」
Staleを避けるために,Oplogのサイジングは非常に重要となります。
Oplogのサイズは,mongodの初回起動時にoplogSizeオプションで変更可能です。
Oplogの適切なサイズを見積もる方法のひとつに,本番を想定した書き込みテストを実施し,作成されたOplogのサイズを取得する方法があります。
1時間程度,本番想定と同程度の書き込みテストを行った後,以下のコマンドでレプリケーションの最新情報を取得します。

> db.getReplicationInfo()

1時間で作成されたOplogのサイズがわかれば,Oplogのサイジングの目安となります。
少なくとも8時間のセカンダリのダウンタイムに耐えられるようにしておくことが推奨されています。

  • レプリケーションの設定

どれかのサーバに入って、以下のコマンドを実行

config = {
  _id : "testRepl",
  members : [
    { _id : 0, host : "10.1.51.227:27017" },
    { _id : 1, host : "10.1.51.68:27017" },
    { _id : 2, host : "10.1.52.111:27017"} ] }

rs.initiate(config)
  • スレーブの読み取り専用動作設定

そのままだと、スレーブが読み取り専用としてアクセスできないので以下の設定を行っておく。

スレーブノードで、以下のコマンドを実行

 db.getMongo().setSlaveOk()
  • レプリケーションステータスの確認
testRepl:PRIMARY> rs.status();
{
    "set" : "connobaRepl",
    "date" : ISODate("2017-01-12T07:03:05.556Z"),
    "myState" : 1,
    "term" : NumberLong(6),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "members" : [
        {
            "_id" : 0,
            "name" : "10.1.51.227:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 100310,
            "optime" : {
                "ts" : Timestamp(1484182286, 1),
                "t" : NumberLong(6)
            },
            "optimeDate" : ISODate("2017-01-12T00:51:26Z"),
            "electionTime" : Timestamp(1484104344, 1),
            "electionDate" : ISODate("2017-01-11T03:12:24Z"),
            "configVersion" : 3,
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "10.1.51.68:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 100245,
            "optime" : {
                "ts" : Timestamp(1484182286, 1),
                "t" : NumberLong(6)
            },
            "optimeDate" : ISODate("2017-01-12T00:51:26Z"),
            "lastHeartbeat" : ISODate("2017-01-12T07:03:04.017Z"),
            "lastHeartbeatRecv" : ISODate("2017-01-12T07:03:04.020Z"),
            "pingMs" : NumberLong(0),
            "syncingTo" : "10.1.51.227:27017",
            "configVersion" : 3
        },
        {
            "_id" : 2,
            "name" : "10.1.52.47:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 99751,
            "optime" : {
                "ts" : Timestamp(1484182286, 1),
                "t" : NumberLong(6)
            },
            "optimeDate" : ISODate("2017-01-12T00:51:26Z"),
            "lastHeartbeat" : ISODate("2017-01-12T07:03:05.025Z"),
            "lastHeartbeatRecv" : ISODate("2017-01-12T07:03:05.022Z"),
            "pingMs" : NumberLong(2),
            "syncingTo" : "10.1.51.227:27017",
            "configVersion" : 3
        }
    ],
    "ok" : 1
}

> mongoログインの時の警告メッセージを消す方法

[ec2-user@ip-10-1-52-47 ~]$ mongo
MongoDB shell version: 3.2.11
connecting to: test
Server has startup warnings:
2017-01-11T03:10:18.308+0000 I CONTROL  [initandlisten]
2017-01-11T03:10:18.308+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2017-01-11T03:10:18.308+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2017-01-11T03:10:18.308+0000 I CONTROL  [initandlisten]
testRepl:SECONDARY>

◆ 参考サイト

続きを読む