‘Server’ カテゴリーのアーカイブ

murave

Firestoreのセキュリティルールのこと

バックエンドをFirebaseでSPAのシステムを作る場合、データを守る砦はデータベース(今回はFirestore)のセキュリティルールです。
Authenticationのログイン情報とFirestore上のユーザー情報を紐付けし権限によりドキュメントへのアクセスを制限するなど、適切な設定しなければなりません。

service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
これは「ログインしているユーザーはフルアクセス」という最低限設定しておくべきルールです。開発中はお世話になりました。
しかし最終的にはもっとこまかく制限をかける必要がありますから、それを前提にデータ構造を設計しておいたほうが良いです。

例として今回作ったシステムのデータ構造とセキュリティルールの一部について解説します。

今回のシステムでは権限による制限が必要だったのでFirestoreにemailをキーとするコレクション、usersを作成し権限情報roleをもたせました。セキュリティルール中でAuthenticationのログイン情報からemailを取得できますので紐づけが可能です。

usersのドキュメント例(権限に関するroleのみ)

murave@hoge.var: {
role: "admin"
}
これを利用してアクセス制限を行います。一部ルールを例示します。

firestore.rules

service cloud.firestore {
match /databases/{database}/documents {
function getUser() {
return get(/databases/$(database)/documents/users/$(request.auth.token.email));
}

match /users/{email} {
allow get: if request.auth != null;
allow read, write: if getUser().data.role == 'admin';
}

match /journals/{journal} {
allow read: if getUser().data.role in ['viewer', 'admin'];
allow create: if request.auth != null;
}

match /summaries/{summary} {
allow read: if request.auth != null;
allow write: if getUser().data.role == 'admin';
}
}
}
この設定は以下の制限・意図となっています。

  • usersはログインしていればドキュメントの(個別)取得は可能。一覧取得、書き込みは管理者(admin)のみ可能。
    ログインしたユーザーが自身の権限情報を取得できる必要がある。
  • ユーザー情報は管理者が管理する。

jornalsへの新規登録はログインしていれば可能。読み出しは閲覧者(viewer)と管理者(admin)が可能。

  • これは集計前の生データなので、ログインしたユーザーすべてが入力する可能性がある。
  • 閲覧者と管理者は登録された生データの分析を行うことができる。

summariesはログインしていれば読み出しは可能。書き込みは管理者(admin)のみが可能。

  • jornalsを集計したデータでユーザーは基本的にはこの集計されたデータを見る。
  • 集計処理はjornalsへのドキュメント新規登録をトリガーとして実行されるFirebase側のFunctionで行われる。
  • 管理者は集計を修正できる。

集計処理はFirebaseのFunctionsを利用しサーバー側に委譲しており、一般・閲覧ユーザーの権限を絞ることが可能となっているのもミソです。

getUser()はAuthenticationのログイン情報のemail(request.auth.token.email)からusersのドキュメントを取得する関数です。内部で使用しているget()等、組み込みの関数には使用回数制限があることに注意してください。同じドキュメントの取得では使用回数は増えないなど独特のルールがあるので意識して、制限を超えないような構造にしなければなりません。

適切なセキュリティルールで安全なFirestoreライフを!

murave

Scalewayに30分でGitHubクローンを建てるよ

GitHubクローン、Gogs(https://gogs.io/)をScalewayに5分で建てるというLTネタができるのでは?
と思ってのにやってみたら30分かかることが判明したでござる(完全敗北)

こんにちプレミアム。公開は月曜日だけど書いているのはフライデー。muraveです。

ここのところ続けて書いている Vagrant + Ansible で Scaleway にサーバーを建てるネタの集大成的な内容です。シナリオは

  • CentOS7 インスタンスを起動
  • CentOS7 基本設定
    基本ツール類導入
  • firewalld起動

CEFSプロジェクト提供のエラッタに基づきセキュリティアップデートMySQL 5.7 導入Nginx 導入Gogs 導入Gogs 初期設定・インストール(Web画面)最初のユーザー(管理者)作成テスト用リポジトリ作成リポジトリにpush

Gogsの導入時にNginxのリバースプロキシ設定やSELinuxのポリシーモジュール追加などやってるのでPHP動かしたりするときなどにも色々と参考になると思います(と未来の自分に語りかける)

jmurabe/scaleway-centos7gogs

経過時刻を挿入しつつ vagrant up からの進行状況を貼っていきます。

2017年 9月29日 金曜日 13時20分27秒 JST
開始です。

$ vagrant up
Bringing machine 'default' up with 'scaleway' provider...
==> default: Creating a server with the following settings...
==> default: -- Commercial Type: VC1S
==> default: -- Image: 9103368e-4fab-4243-aa8d-18121796c086
==> default: -- Name: scw-******
==> default: Starting the server...
==> default: Waiting for server to become "ready"...
==> default: Waiting for SSH to become available...
2017年 9月29日 金曜日 13時22分53秒 JST
インスタンスが起動するのに2分半。

==> default: [vagrant-hostsupdater] Checking for host entries
==> default: Rsyncing folder: /Users/murave/scaleway/gogs/ => /vagrant
==> default: Running provisioner: ansible...
2017年 9月29日 金曜日 13時24分31秒 JST
プロビジョニング開始時で4分が経過。

default: Running ansible-playbook...

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [default]

TASK [centos7common : add EPEL] ************************************************
changed: [default]

TASK [centos7common : installs] ************************************************
changed: [default] => (item=[u'bind-utils', u'yum-utils', u'git', u'unzip', u'libselinux-python', u'libsemanage-python', u'policycoreutils-python', u'python-pip', u'firewalld'])

TASK [centos7common : running and enabled firewalld] ***************************
changed: [default]

TASK [centos7common : firewalld] ***********************************************
ok: [default]

TASK [centos7secup : install on yum security update] ***************************
changed: [default] => (item=[u'yum-plugin-security', u'createrepo', u'bzip2'])

TASK [centos7secup : check /security exists] ***********************************
ok: [default]

TASK [centos7secup : make /security] *******************************************
changed: [default]

TASK [centos7secup : create repo for CEFS project] *****************************
changed: [default]

TASK [centos7secup : download vmfarms/generate_updateinfo] *********************
changed: [default]

TASK [centos7secup : download CEFS errata.latest.xml.bz2] **********************
changed: [default]

TASK [centos7secup : update CEFS project repo and yum security update] *********
changed: [default]
2017年 9月29日 金曜日 13時31分54秒 JST
セキュリティアップデートおわったー。11分半経過。

TASK [mysql : install mysql57 repository] **************************************
changed: [default]

TASK [mysql : install on mysql] ************************************************
changed: [default] => (item=[u'mysql-community-server', u'MySQL-python'])

TASK [mysql : run and enable mysqld] *******************************************
changed: [default]

TASK [mysql : check /root/.my.cnf exists] **************************************
ok: [default]

TASK [mysql : get root temporary password] *************************************
changed: [default]

TASK [mysql : change root password] ********************************************
changed: [default]

TASK [mysql : deploy /root/.my.cnf] ********************************************
changed: [default]

TASK [mysql : deploy /etc/.my.cnf] *********************************************
changed: [default]

TASK [mysql : remove anonymous mysql_user] *************************************
ok: [default]

TASK [mysql : restart mysqld] **************************************************
changed: [default]
2017年 9月29日 金曜日 13時37分33秒 JST
MySQL導入(基本状態)、17分経過。

TASK [nginx : install nginx] ***************************************************
changed: [default]

TASK [nginx : running and enabled nginx] ***************************************
changed: [default]

TASK [nginx : firewalld] *******************************************************
changed: [default]

TASK [nginx : firewalld] *******************************************************
changed: [default]

2017年 9月29日 金曜日 13時39分00秒 JST
Nginx導入(基本状態)、18分半経過。

TASK [gogs : add git user] *****************************************************
changed: [default]

TASK [gogs : create mysql database for gogs] ***********************************
changed: [default]

TASK [gogs : create mysql user for gogs] ***************************************
changed: [default]

TASK [gogs : download gogs zip] ************************************************
changed: [default]

TASK [gogs : debug] ************************************************************
ok: [default] => {
"msg": "/home/git/linux_amd64_0.11.29.zip was downloaded"
}

TASK [gogs : unarchive gogs zip] ***********************************************
changed: [default]

TASK [gogs : cp gogs.service to /etc/systemd/system/] **************************
changed: [default]

TASK [gogs : running and enabled gogs] *****************************************
changed: [default]

TASK [gogs : copy nginx.conf(location deleted)] ********************************
changed: [default]

TASK [gogs : check gogs.conf] **************************************************
ok: [default]

TASK [gogs : set selinux's httpd_can_network_connect on] ***********************
ok: [default]

TASK [gogs : copy ssh_keygen_test.pp (custom policy module)] *******************
changed: [default]

TASK [gogs : install ssh_keygen_test.pp] ***************************************
changed: [default]

TASK [gogs : copy gogs.conf and restart nginx] *********************************
changed: [default]

RUNNING HANDLER [gogs : restart nginx] *****************************************
changed: [default]

PLAY RECAP *********************************************************************
default : ok=41 changed=33 unreachable=0 failed=0
2017年 9月29日 金曜日 13時44分08秒 JST
Gogsの導入まで完了しました。23分半。

IP確認のために vagrant ssh-config

$ vagrant ssh-config
Host default
HostName ***.***.***.***
User root
Port 22
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /Users/murave/.ssh/id_rsa
IdentitiesOnly yes
LogLevel FATAL
ブラウザでアクセスすると初期設定・インストール画面が表示されます。

  • MySQLのユーザをgogsに変更し、パスワードには.envのGOGS_MYSQL_PWに設定した文字列を入力
  • ドメイン、アプリケーションのURLをIPベースで入力(とりあえず)。
    NginxでリバースプロキシしているのでURLの3000番ポート指定ははずしてください。

「Gogsをインストール」をクリック

起動しました。

右上の「登録」から最初のユーザーを作成します。このユーザーは管理者になります。

ログインしてテスト用リポジトリを作成します。

画面の通りにコマンドラインで新しいリポジトリを作成してpushします。

2017年 9月29日 金曜日 13時49分32秒 JST
ということで、約29分でのゴールでした。

murave

ScalewayのSecurity groupに期待しすぎるのをやめる

muraveです。

自分の前の記事『Vagrant+AnsibleでCentOS7のセキュリティアップデートまで』の余談で「ScalewayのSecurity groupについて事前に調整しとくと良いよ」みたいなことを書きましたが、

「Scalewayさんのスパムメール送信対策なんやな〜」

ぐらいの気持ちで接してSecurity groupはなるべく素通しで他の手段で対策したほほうが良さそう、という話。

まず、このときにも書いたようにインスタンスを立ち上げ直さないと変更が反映されないので、この時点で実運用ではかなり致命的。

そして私が諦めた直接の理由ですが、inboundをまとめてdropして必要なportだけをacceptする設定にすると外部へのhttp/httpsアクセスができなくなる。つまり外部のAPIへのアクセスが遮断されます。

aws-cli使ってS3へのバックアップするときにコケてて原因調べたら外部へのhttp/httpsアクセスが全滅してたっていうね。

HTTP not working
https://community.online.net/t/http-not-working/1438

によると

With the rule TCP inbound 0.0.0.0/0 drop, outbounds connections can’t work. That’s because the firewall is stateless.

だそうです。

「iptablesつかえや」みたいな話がみえたので、CentOS7ですしfirewalldでがんばることにしました。

ということで、

jmurabe/scaleway-centos7base

更新しました。

ScalewayのCentOS7.3のイメージにはfirewalldの導入もされていなかったので導入して有効化する処理を追加しています。

sshを許可する処理も入れてますが、もともとsshは許可されているので書き方のサンプルみたいなものです。削除しても問題ありません。

ついでに、調査時digやnslookupが使えなくてつらかったのでbind-utils、みんなaws-cli入れるよね? いれるときに入ってたほうが便利よね? ってことでpython-pipなど追加してます。

murave

Vagrant+AnsibleでCentOS7のセキュリティアップデートまで

muraveです。ここ最近の記事、

についてスクリプト化してGitHubで公開しました

jmurabe/scaleway-centos7base

クラウド(Scaleway)上で動かすのでセキュリティ確保のために yum update するべき。しかし全部アップデートすると時間がかかりすぎる。そこでセキュリティアップデート出来るようにセットアップして実行するところまで自動で、という内容です。

冪等性が確保できているとは言い難い所はありますが(/securityが存在するか?だけでsecurityリポジトリが作成されているか判断している等)、ベースとしては使えるとおもいます。


実行するとこんな感じ(一部伏せてます)。

$ git clone git@github.com:jmurabe/scaleway-centos7base.git
Cloning into 'scaleway-centos7base'...
remote: Counting objects: 15, done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 15 (delta 0), reused 15 (delta 0), pack-reused 0
Receiving objects: 100% (15/15), done.

$ cd scaleway-centos7base

$ cp .env.example .env
.env の内容を修正してください。

$ vagrant up
Bringing machine 'default' up with 'scaleway' provider...
==> default: Creating a server with the following settings...
==> default: -- Commercial Type: VC1S
==> default: -- Image: 9103368e-4fab-4243-aa8d-18121796c086
==> default: -- Name: scw-******
==> default: Starting the server...
==> default: Waiting for server to become "ready"...
==> default: Waiting for SSH to become available...
==> default: Machine is booted and ready for use!
==> default: [vagrant-hostsupdater] Checking for host entries
==> default: Rsyncing folder: /Users/murave/scaleway/centos7base/ => /vagrant
==> default: Running provisioner: ansible...
default: Running ansible-playbook...

PLAY [all] *********************************************************************

TASK [Gathering Facts] *********************************************************
ok: [default]

TASK [centos7common : installs] ************************************************
changed: [default] => (item=[u'yum-utils', u'git', u'unzip', u'libselinux-python', u'libsemanage-python', u'policycoreutils-python'])

TASK [centos7secup : install on yum security update] ***************************
changed: [default] => (item=[u'yum-plugin-security', u'createrepo', u'bzip2'])

TASK [centos7secup : check /security exists] ***********************************
ok: [default]

TASK [centos7secup : make /security] *******************************************
changed: [default]

TASK [centos7secup : create repo for CEFS project] *****************************
changed: [default]

TASK [centos7secup : download vmfarms/generate_updateinfo] *********************
changed: [default]

TASK [centos7secup : download CEFS errata.latest.xml.bz2] **********************
changed: [default]

TASK [centos7secup : update CEFS project repo and yum security update] *********
changed: [default]

PLAY RECAP *********************************************************************
default : ok=9 changed=7 unreachable=0 failed=0

HostName(IP)はssh-configで確認するのが便利かと思います。

$ vagrant ssh-config
Host default
HostName ***.***.***.***
User root
Port 22
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /Users/murave/.ssh/id_rsa
IdentitiesOnly yes
LogLevel FATAL
余談centos7commonとSELinuxについてcentos7commonでSELinux制御絡みのパッケージ等を入れてるのは環境構築時に必要になるだろうという理由でなんですが、実は指定しているScalewayのイメージから起動するインスタンスではSELinuxは無効となっていたりします。

$ vagrant ssh
Last login: Tue Sep 19 08:41:21 2017 from 114.160.75.94
[root@scw-****** ~]# getenforce
Disabled
SELinux関係はVirtualBoxで試していて追加したのですが、そもそもcentos7common自体の内容が薄いのでこれをなくして、パッケージが必要なRoleすべてにinstallを書いたほうがRoleの再利用性が高まる気もしています。でも、Roleの依存性を全てなくそうとするのは逆効果ですしねぇ。

ScalewayのSecurity groupについて

このスクリプトで起動したScalewayのインスタンスでは、Default security group が設定されるかとおもいますので(ORGANIZATION DEFAULTを変更していなければ)、このフィルターを事前に調整しておくと良いかと思います。

ScalewayのSecurity groupの変更はインスタンス起動時しか反映されないようなので注意してください(稼働中インスタンスに適用するにはコントロールパネルからインスタンスを起動しなおさないとダメっぽい)

動作の詳細を確認したい時

Vagrantfileの

config.vm.provision "ansible" do |ansible|
ansible.playbook = "provisioning/playbook.yml"
#ansible.verbose = "extra"
ansible.limit = 'all'
end
でコメントアウトしている ansible.verbose = “extra” を生かして下さい。

murave

CentOS7 での yum –security update 事情

夏風邪で減った体重がすっかりもどってしまいました。muraveです。
自身への細菌の侵入は許しましたが、サーバーへの侵入は防がねばなりません(自然な導入)

そんなわけで Ansible では yum update 相当の

yum: name=* state=latest
を毎回やっていたのですが、時間がかかりすぎて辛くなってきました。そんなわけでセキュリティアップデートだけするのがいいかな、と調べ始めました。

yum-plugin-securityというパッケージを利用して

$ yum --security update
が出来ることを知りました(そもそもCentOS7ではyum-plugin-securityがyumに統合されている模様)。 やったぜ!

CentOSのリポジトリではセキュリティアップデート情報が提供されていなくて正常動作しないらしいことも知りました。 やってなかったぜ!

先人の知恵と努力を頼りましょう。

Inject a little security in to your CentOS repositories

  • CEFSのエラッタからupdateinfo.xml作るスクリプト作ったぜー、という話。

CentOS 7でyumからSecurityUpdateを行えるようにする

  • 作業内容は殆どこちらのページそのままです。ありがとうございます。

ということでまとめますと、securiy用のローカルリポジトリを作り、CEFSが提供しているSpacewalk用のエラッタからupdateinfo.xmlを作って設置、yum –security update します。

はじめましょう。CentOS7、rootでの作業とします。

必要なパッケージを導入します。

$ yum install createrepo bzip2
セキュリティアップデート用のローカルリポジトリを作ります。

$ mkdir /security
$ createrepo /security
$ cat << "EOF" >> /etc/yum.repos.d/CentOS-Base.repo
[security]
name=CentOS-$releasever - Security
baseurl=file:///security
EOF
/security に移動(以降ここで作業)、CEFSのエラッタからupdateinfo.xml作るスクリプト generate_updateinfo.py を設置します。

$ cd /security
$ curl https://raw.githubusercontent.com/vmfarms/generate_updateinfo/master/generate_updateinfo.py -O
CEFSのエラッタからupdateinfo.xmlを更新します。Ansibleスクリプト化のことを考慮し一旦 errata.latest.xml.bz2 を保存してからの処理としています。

$ curl http://cefs.steve-meier.de/errata.latest.xml.bz2 -O
$ python generate_updateinfo.py --destination=/security --release=7 <(bzip2 -dc errata.latest.xml.bz2)
$ modifyrepo /security/updateinfo-7/updateinfo.xml /security/repodata/
セキュリティアップデートが正常に動作するか、まずは check-update してみましょう。

$ yum --security check-update
読み込んだプラグイン:fastestmirror
base/7/x86_64 | 3.6 kB 00:00:00
extras/7/x86_64 | 3.4 kB 00:00:00
security | 3.3 kB 00:00:00
security/updateinfo | 48 kB 00:00:00
security/primary_db | 1.1 kB 00:00:00
updates/7/x86_64 | 3.4 kB 00:00:00
Loading mirror speeds from cached hostfile
* base: centos.crazyfrogs.org
* extras: centos.quelquesmots.fr
* updates: mirrors.standaloneinstaller.com

<途中省略>

11 package(s) needed for security, out of 171 available

glibc.x86_64 2.17-196.el7 base
glibc-common.x86_64 2.17-196.el7 base
libtirpc.x86_64 0.2.4-0.10.el7 base
nss.x86_64 3.28.4-11.el7_4 updates
nss-sysinit.x86_64 3.28.4-11.el7_4 updates
nss-tools.x86_64 3.28.4-11.el7_4 updates
nss-util.x86_64 3.28.4-3.el7 base
policycoreutils.x86_64 2.5-17.1.el7 base
policycoreutils-python.x86_64 2.5-17.1.el7 base
python-perf.x86_64 3.10.0-693.2.2.el7 updates
rpcbind.x86_64 0.2.0-42.el7 base

やったぜ!

update で実際のセキュリティアップデートを実行します。

$ yum --security update
リポジトリ作成済なので、以降は以下のコマンドセットでセキュリティアップデートできますね。

$ cd /security
$ curl http://cefs.steve-meier.de/errata.latest.xml.bz2 -O
$ python generate_updateinfo.py --destination=/security --release=7 <(bzip2 -dc errata.latest.xml.bz2)
$ modifyrepo /security/updateinfo-7/updateinfo.xml /security/repodata/
$ yum --security update
murave

VagrantでScaleway使うと開発に便利なのでは?という話

Dockerに傾倒していたので久しぶりにVagrantさわりました。muraveです。

少し前に弊社代表から「ScalewayってクラウドARM使えるし安いし、いいよ!(ネットワーク的に遠くてもいい場合には)」という情報が社内Slackに投げ込まれて気になっておりました。

Scaleaway (https://www.scaleway.com/)

私としてはX86系最安価でも 2Core + 2GB Memory + 50GB SSD + 1public IPv4 という構成で €2.99/month (€1=¥130として¥388.7) の価格性能比に魅力を感じます。

更に調べると詳細には

  • VC1Sサーバー(2Cores 2GB Memory): €1/month (€0.002/hour)
  • 50GB SSD Volume: €1/month (€0.002/hour)
  • 1 public IPv4: €0.99/month (€0.002/hour)

合計 €2.99/month (€0.006/hour)

という価格内訳で(https://www.scaleway.com/faq/billing/)、パッケージ単位での上限が€2.99/monthとのこと。

上限が無くても時間単位で31日間フル稼働で€4.464(¥580.32)ですので、開発でインスタンスの使い捨てを繰り返して上限が無効な場合でもとんでもないことにはならないと思われます。

課金についてあまり気にしなくてもいいというのは精神的に良いです。

そんなわけでVagrantでScalewayをお気軽に使いたいと思います。

Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :

#.envにて各種設定(vagrantのpluginとしてdotenvが必要)
Dotenv.load

Vagrant.configure("2") do |config|
if ENV['TARGET'] == 'scaleway'
config.vm.provider :scaleway do |scaleway, override| #要vagrant-scaleway plugin
scaleway.token = ENV['SCALEWAY_TOKEN']
scaleway.organization = ENV['SCALEWAY_ORG']
scaleway.commercial_type = 'VC1S'
scaleway.image = '9103368e-4fab-4243-aa8d-18121796c086' #CentOS 7.3

override.ssh.private_key_path = ENV['SCALEWAY_PKEY']
override.nfs.functional = false
end
else
# ENV['TARGET']はboxの指定
config.vm.provider :virtualbox do |vb|
vb.customize ["setextradata", :id, "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled", 0]
end
config.vm.box = ENV['TARGET']
config.vbguest.auto_update = false
config.vm.network :private_network, ip: '192.168.66.10'
end
end
弊社ではサーバーにCentOSを使うことが多いのでscaleway.imageにはCentOS7.3のものを指定しています。秘匿したい各種パラメータは.envで与えます。

.env

TARGET = 'scaleway'
#TARGET = 'centos/7'
# for Scaleway
SCALEWAY_TOKEN = 'your Scaleway token'
SCALEWAY_ORG = 'your Scaleway organization id'
SCALEWAY_PKEY = '~/.ssh/id_rsa'
おまけでTARGETにboxを指定するとVirtualBoxで動作するようにしています。

plugin導入

未導入の場合は導入してください。

$ vagrant plugin install vagrant-scaleway
$ vagrant plugin install dotenv
必要情報の収集scaleway.token
トークンScalewayコントロールパネル、ユーザーのCredentialsで作成scaleway.organization
organization idcurl https://account.cloud.online.net/organizations -H “X-Auth-Token: トークン” で確認可能scaleway.commercial_type
サーバータイプCreate a server の画面で確認可能。‘VC1S’: StarterのX86最安価(2Cores, 2GB memory)scaleway.image
OSイメージID。作成されたサーバーについては FROM IMAGE からのリンク先で確認可能。その他設定についてoverride.ssh.private_key_path
ssh接続のための秘密鍵を指定事前にScalewayコントロールパネル、ユーザーのCredentialsから公開鍵の登録が必要override.nfs.functional = false
/vagrantについてnfs連携しようとしてエラーとなるのを防ぎ、rsync連携とする。基本操作vagrant upイメージからサーバーインスタンスを起動。ipはreservedされない(起動中のみ設定される)

$ vagrant up
Bringing machine 'default' up with 'scaleway' provider...
==> default: Creating a server with the following settings...
==> default: -- Commercial Type: VC1S
==> default: -- Image: 9103368e-4fab-4243-aa8d-18121796c086
==> default: -- Name: hugahoge
==> default: Starting the server...
==> default: Waiting for server to become "ready"...
==> default: Waiting for SSH to become available...
==> default: Machine is booted and ready for use!
==> default: [vagrant-hostsupdater] Checking for host entries
==> default: Rsyncing folder: /Users/murave/scaleway/vagrant_only/ => /vagrant
稼働状況

サーバー

vagrant ssh

起動したサーバーインスタンスにsshで接続する。

vagrant ssh-config

ssh接続用情報を表示(IPアドレスの確認等可能)。

$ vagrant ssh-config
Host default
HostName 192.0.2.1
User root
Port 22
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /Users/murave/.ssh/id_rsa
IdentitiesOnly yes
LogLevel FATAL
※ HostNameはサンプル用IPに書き換えてます。

vagrant halt

サーバーインスタンス停止。

$ vagrant halt
==> default: Stopping the server...
==> default: [vagrant-hostsupdater] Removing hosts
稼働状況

停止中でもVolumeについては課金が発生します。一ヶ月止っぱなしで放置した場合でも€1はかかるということですね。

vagrant destroy

サーバーインスタンス破棄。

$ vagrant destroy
default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Destroying the server...
==> default: [vagrant-hostsupdater] Removing hosts
稼働状況

halt後にdestroyすると、このようにVolumeは削除されませんので注意が必要です(コントロールパネル等から削除するまで課金発生)

(haltせず)動作中にdestroyし「default: Are you sure you want to destroy the ‘default’ VM? [y/N]」で yとした場合はVolumeも削除されるので、インスタンスを使い捨てする場合にはhaltしないでdestroyしたほうが良いです。

murave

Mac からのリモートデスクトップ接続で日本語キーボード使う

muraveです。仕事では日本語キーボードな Mac を使ってます。

Windows Server でがんばる系のお仕事がきそうなのでクラウド上に実験環境を作ろうと思いました。

EC2 で Windows Server インスタンスをたてる

とりあえず実験なのでAWSの無料枠からはじめましょうかね。

Amazon EC2 で Windows Server 2016 を実行

AWSで日本語版Windowsサーバーを構築する方法。初心者でもわかる!

ということでこれらのサイトを参考にさせていただき EC2 でインスタンスたてました。

順調。

リモートデスクトップで接続する

Windows インスタンスへの接続

を見ながら Microsoft Remote Desktop での接続を行いました。

このページについては接続に必要な情報の取得についてめんどうなことが長々と書くのやめて「接続ボタンをクリックせよ。そこに全部書いてある」にかえるといいと思いました。

リモートデスクトップ(RDP)接続できたので、おもむろにメモ帳などを立ち上げ、日本語入力はどうかねぇなどと試してみます。

うわ、USキーボードになってる。 「つらい」

Windows 10 / Windows Server 2016 環境でキーボード レイアウトが英語キーボードとして認識してしまった際の対処方法

を参考にさせていただいて、「英語キーボード(101/120キー)」から「日本語キーボード(106/109キー)」変更。

変化なし。Microsoft Remote Desktop 側かな?

そして決定版なページ発見! ありがてぇ

Mac からのRDP 接続で日本語キーボードを設定する

Microsoft Remote Desktop はやめて Parallels Client を使うのが良い模様。

しかし、Parallels Client でつなぎ直してもすぐには解決せず。

ごちゃごちゃと色々な事を試していましが、ふと「どこかで設定がキャッシュされてたり?」と思い Windows Server と Mac の両方をリブート、つなぎ直したら日本語キーボードが認識されました!

Mac 側について「ことえり」じゃなきゃだめといった情報もありましたが、私の環境だと「Google 日本語入力」でも大丈夫な感じです(様子見中)

余談1

Wireshark でパケットをながめてみたりもしましたがRDPのパケット、わからなかったです。

余談2

最近また「Web系でMac多いのなんで?」みたいな話をみたのですが、私の場合は

  • macOSは(ライセンス的に)Macでしか動かせないがWindowsはVMなどでどうにかなる
  • iPhone関係の開発のため
  • WindowsよりはWeb関係の開発環境を整えるのが楽(たぶん)

って感じです。

Windows 関係の開発もするので Windows 側が改善されてきたら戻りたい気持ちもありますが、今のところは仕事は Mac かなぁといった感じ。家では、Windows 使ってることが多いんですけどね。Macbook もありますけどほぼ iTunes 専用。

murave

DockerのJenkinsコンテナでアクセスログについて悩んでいた

muraveです。

今年の4月にリリースされたJenkins 2系をDocker公式イメージ

OFFICIAL REPOSITORY jenkins

で試していたのですが、Webフックからキックしてのビルドを試していて大変ハマリました。Webフックからのアクセス状況とかどうなってんだ?などなどtcpdumpとか使って調べてたんですけど、アクセスログもあったほうがいいよね、と思ったのでした。

公式イメージのJenkinsさんってそのまま立ち上げたらアクセスログ出してくれないんですよね。

調べまして、JENKINS_OPTSに

--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger --simpleAccessLogger.format=combined --simpleAccessLogger.file=ログファイルのパス
てな感じで設定すれば良いことはわかりました。分かりましたが、コンテナ内やボリュームにログファイルを出すのは違う気がします。docker logs で見ることができるログはどういう扱いなんでしょう?

デフォルト設定のロギング・ドライバのログ(JSON形式)はホストの

/var/lib/docker/containers/(コンテナID)/(コンテナID)-json.log
にあって、これが docker logs の表示元になっています。

問題はどうやったらここに出力されるのか?ですが、標準出力、標準エラー出力へ出力すれば良いそうです。例えば、Nginx公式イメージのDockerfileでは

# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
と、/dev/stdout と /dev/stderr へのシンボリックリンクを作成することで対応しているようです。

Jenkinsさんの場合は先ほどのJENKINS_OPTSでログファイルのパス指定が可能でしたので

--accessLoggerClassName=winstone.accesslog.SimpleAccessLogger --simpleAccessLogger.format=combined --simpleAccessLogger.file=/dev/stdout
と設定すると標準出力に出力されるようになり、コンテナのログにJenkinsさんへのアクセスログが記録されるようになりました。

これでDockerのロギング・ドライバでアクセスログも統一的にあつかえますね。
例えばFluentdロギング・ドライバに切り替えてログ集約するようにしたりする場合にも安心です。

murave

ConoHaでDocker Machine、2016年夏

Docker for Mac からベータが取れて久しいですが、インストールしたまま放置状態でしたので勉強中です。

とりいそぎ手元の開発環境構築で使いたいのですが、最近よく開発用に利用している ConoHa で Docker Machine していました。なぜか。

Docker for Mac vs. Docker Toolbox を読みますと、Docker for Mac を手元で使う分には Docker Machine を意識する必要すらなくなっているようですが、docker-machineコマンドも含まれてはいたので調べていたらそういうことになっていたのでした。

docker-machineコマンドでConoHa上にDockerのHostをVMレベルからcreateしたりstopしたりrmしたりできるようになったわけですがいまのところあまり使い道が思いつきません。ConoHaだとVM(サーバー)止めてても課金が止まらないんですよねぇ。

検証用や確認用に一時的にHostを立ち上げて(create)終わったらすぐ消す(rm)、とかでしょうか。

せっかくですし、すぐに忘れてしまいそうなので引っかかった箇所のメモを残しておこうと思います。

基本的に ConoHaでDocker Machineを使う そのままなのですが、一部変更しないとうまくいかなかった箇所があります。

$ docker-machine create \
-d openstack \
--openstack-flavor-name g-1gb \
--openstack-image-name vmi-ubuntu-14.04-amd64 \
--openstack-sec-groups "default,gncs-ipv4-all" \
conoha-docker-host
Running pre-create checks...
Creating machine...
(conoha-docker-host) Creating machine...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with ubuntu(upstart)...
Error creating machine: Error running provisioning: Something went wrong running an SSH command!
command : DEBIAN_FRONTEND=noninteractive sudo -E apt-get install -y -o Dpkg::Options::="--force-confnew" curl
err : exit status 100
output : E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)
E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?

残念、provisioningでエラー発生です。調べた所 Digital Ocean でも似た状況が発生しているようです。

Digital ocean driver create command fails on new ubuntu 16.04 LTS image

「Digital Ocean のせいだから課題はクローズだ!」という状況な模様。

イメージが原因?と試しに vmi-ubuntu-14.04-amd64 から vmi-ubuntu-16.04-amd64 にイメージを変更してみました。

$ docker-machine create \
-d openstack \
--openstack-flavor-name g-1gb \
--openstack-image-name vmi-ubuntu-16.04-amd64 \
--openstack-sec-groups "default,gncs-ipv4-all" \
conoha-docker-host
Running pre-create checks...
Creating machine...
(conoha-docker-host) Creating machine...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with ubuntu(systemd)...
Installing Docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env conoha-docker-host

完走Σ(・∀・;)

以前はうまく動いていたであろうバージョンのイメージでは失敗しますが、現在最新バージョンのイメージではうまくいくようです。原因について深くは追っていませんが、再現性はあり。セキュリティフィックスなどで元イメージに手がはいると状況はまた変わりそうです。

ConoHaでDocker Machine、2016年夏の状況は以上です。


では軽く Docker Machine の動きを。

docker-machine create 後のConoHaコントロールパネル

createした状態。133-130-109-78がcreateされたHostです。

$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
conoha-docker-host - openstack Running tcp://133.130.109.78:2376 v1.12.0

ほらね?(もう削除しているのでIPなどそのまま出していきます)

次に必要な環境変数を確認。

$ docker-machine env conoha-docker-host
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://133.130.109.78:2376"
export DOCKER_CERT_PATH="/Users/murave/.docker/machine/machines/conoha-docker-host"
export DOCKER_MACHINE_NAME="conoha-docker-host"
# Run this command to configure your shell:
# eval $(docker-machine env conoha-docker-host)

Run this command to configure your shell とのことですので教えに従いましょう。

$ eval $(docker-machine env conoha-docker-host)

以降、このShellでdockerコマンドを使うとConoHa上のHostへの操作となります。ローカルがHostの場合と同様の操作で扱えますが、-vオプションでローカルのディレクトリをバインドなどは当然できません(わかっていながら一応試したりした)。

Hostにsshするには

$ docker-machine ssh conoha-docker-host
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-31-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

18 packages can be updated.
10 updates are security updates.

使い捨ての場合はあまりsshする必要もなさそうですが、そのまま運用する際などはHost側の設定調整などで必要になりそうです。

scpも出来ます。

$ docker-machine scp conoha-docker-host:/etc/passwd .
passwd 100% 1551 1.5KB/s 00:00

Doker周りについては以下のようにsshしたりしなくてもアップグレード可能。

$ docker-machine upgrade conoha-docker-host
Waiting for SSH to be available...
Detecting the provisioner...
Upgrading docker...
Restarting docker...

停止(stop)、開始(start)、再起動(restart)はご想像のとおりかと思うので省略。

docker-machine stop conoha-docker-host 後のConoHaコントロールパネル

上記画像は stop したときのConoHaコントーロールパネルです。

最後に(-fをつけて強制)rmしてHost(133-130-109-78)を削除して終了。

docker-machine rm -f conoha-docker-host 後のConoHaコントロールパネル

$ docker-machine rm -f conoha-docker-host
About to remove conoha-docker-host
(conoha-docker-host) Deleting OpenStack instance...
Successfully removed conoha-docker-host

murave

QNAP ファームウェア4.2.1 で起動スクリプトを追加して dhcpd を自由に設定する

「NAS(ナス)とNIC(肉)の相性は最高だネ」 夏野菜ジョークでハートキャッチ! muraveです。

QNAP TurboNAS で既存のファイルサーバー(Samba)を置き換えるための準備をしています。
このサーバーは DHCP Server の役割も担っているので NAS の選定時、機能が載っているという確認はしていました。

ところがいざ仕入れてセットアップと動作確認を進めると

「DHCP Server (dhcpd) の設定画面が NAS の IP より後ろしか range の設定できないという仕様でク◯だ!」

「設定した『既定のゲートウェイ』を再起動時に無視して自分のIPを設定しやがって◯ソとかいうレベルじゃなくバグってんじゃねーか!」

などありまして、大変困ってしまったのでした。 あまり使われてないんですかね。

置き換えするサーバーが居るネットワークはなぜか真ん中あたりにゲートウェイが居るし、range だって複数設定したいんだよ!

ということで、回避方法を調べていたところ dhcpd の設定ファイルを書き換えてから kill -HUP する独自の起動スクリプト(autorun.sh)を追加するという方法にたどり着きました。

参考にさせていただいたサイトです。


さて、はじめましょう。

QNAP TurboNAS のファームウェアは 2016/06/01 に公開された現時点では最新の 4.2.1 です。
adminでssh接続して作業します。autorun.sh 等の設置場所については qpkg.conf での他の起動スクリプトの場所を参考にしました。

qpkg.conf に独自の起動スクリプトについて追加します。
vi /etc/config/qpkg.conf

[autorun]
Name = autorun
Version = 0.1
Author = murave
Date = 2016-06-20
Shell = /share/CACHEDEV1_DATA/.qpkg/autorun/autorun.sh
Install_Path = /share/CACHEDEV1_DATA/.qpkg/autorun
Enable = TRUE

autorun.sh を作ります。
mkdir /share/CACHEDEV1_DATA/.qpkg/autorun
vi /share/CACHEDEV1_DATA/.qpkg/autorun/autorun.sh

#!/bin/sh
cp /share/CACHEDEV1_DATA/.qpkg/autorun/dhcpd_eth0.conf /etc/dhcpd_eth0.conf
kill -HUP `pidof dhcpd_eth0`

2つetherがある機種でeth0側で動作させているので dhcpd_eth0 になっているようです。

実行権限付与
chmod +x /share/CACHEDEV1_DATA/.qpkg/autorun/autorun.sh

元ファイルをコピーして独自 dhcpd_eth0.conf を作成。
cp /etc/dhcpd_eth0.conf /share/CACHEDEV1_DATA/.qpkg/autorun/dhcpd_eth0.conf
vi /share/CACHEDEV1_DATA/.qpkg/autorun/dhcpd_eth0.conf

max-lease-time 86400;
default-lease-time 86400;
ddns-update-style ad-hoc;
allow booting;
allow bootp;
class "pxeclients" {
match if substring(option vendor-class-identifier,0,9)="PXEClient";


}
subnet xxx.xxx.xxx.0 netmask 255.255.255.0{
interface eth0;
#複数range書いたり、自由だ!(xxxは伏せ字的なヤツです)
range xxx.xxx.xxx.100 xxx.xxx.xxx.159;
range xxx.xxx.xxx.161 xxx.xxx.xxx.200;
option routers xxx.xxx.xxx.160;


option domain-name-servers 8.8.8.8, 8.8.4.4;
}

まず、autorun.sh を直接実行してみて動作を確認。次に reboot して動作確認。

ps ax | grep dhcpd

11072 admin 744 S /mnt/ext/opt/netmgr/api/core/dhcpdLink/dhcpd_eth0 -cf /etc/dhcpd_eth0.conf -lf /var/state/dhcp/dhcpd_eth0.leases -pf /mnt/ext/opt/netmgr/api/core/dhcpdLink/eth0.pid

端末を対象ポート側に接続してdhcpでのIP振出確認。

IP振出履歴の確認。
more /var/state/dhcp/dhcpd_eth0.leases

オマケでWeb管理画面からの起動動作を調査して予想した手動でのeh0側 dhcpd 起動方法。

/sbin/daemon_mgr dhcpd_eth0 start "/mnt/ext/opt/netmgr/api/core/dhcpdLink/dhcpd_eth0 -cf /etc/dhcpd_eth0.conf -lf /var/state/dhcp/dhcpd_eth0.leases -pf /mnt/ext/opt/netmgr/api/core/dhcpdLink/eth0.pid"

設定ファイルが正しいかの確認などで便利です(kill -HUP して上がってこないので悩んでいたら設定ファイルが間違ってたのは秘密)