ZFSパッケージ登録記念:Ubuntu 15.10にZFS on Linux

  • ZFS on LinuxのパッケージがUbuntu 15.10のuniverseに登録された。
  • Ubunut 15.10にZFS on Linuxをインストールしてみた。

この春、DebianでZFS on Linux(ZoL)1が近々サポートされるというニュースが流れました2。しかし結局サポートされるようになったのかどうか、全く話を聞かなくになってしまいました。

そして秋にはUbuntuでZFSが使えるようになるというニュースが流れました3。この時は2016年春にリリース予定のUbuntu 16.04での話でした。そのためUbuntuで使えるようになったとしてもまだ先の話かと思っていました。

ところが先日ZFS on Linuxメーリングリストに「UbuntuのパッケジレポジトリにZoLがある」4があるという話が投稿されました。それを読んでUbuntuのパッケージを検索するとこの秋にリリースされたUbuntu 15.10用のZoLパッケージが見つかりました5。これまでもZoLをPPAからUbuntuにインストール出来ました6が、公式のパッケージとしてZoLが登録されたことは大進歩です。これでOSをアップグレードするときにZFSのカーネルモジュールがインストールされているか心配しなくて良くなります。

これまでPPAのパッケージを使ってZoLをインストールしていましたが、せっかくなので新しく登録されたZFS on LinuxのパッケージをUbuntu 15.10にインストールしてみました。

ZFS on Linuxを使えるマシンの条件

ZFS on Linuxを使用するには、次のような必要条件が有ります。

64-bit Ubuntuシステムであること。
32-bit用のパッケージは提供されていません。
最近Ubuntuをインストールしたマシンは、サーバ用とデスクトップ用共に標準で64-bitになっているのでこの条件は問題ありません。ただしアップグレードを繰り返してきたマシンは32-bitのシステムかもしれません。

64-bitか32-bitかは、uname -iコマンドで確認できます。コマンドの出力がx86_64となっていれば64-bitシステムです。

# 64-bit
$ uname -i
x86_64

# 32-bit
$ uname -i
i686
メモリが8GB以上あること。
もっと少ないメモリ容量でも重複排除を使用しなければ動くことは動くらしいです。逆に重複排除を使用するならば、8GBでは少なすぎます。またメモリは読み出しキャッシュともなるので、実用上はさらにほしい所です。
また普通のメモリでもZFSを使用できますが、データを絶対失いたくない用途ではECC付きのメモリが強く推奨されています7

ZFSでECC付きメモリがどの程度必須かは、ヒートアップ間違い無しの話題です。ECCが付いていない普通のメモリを使っていると、 知らないうちにファイルが壊れる、最悪ファイルシステム全体が壊れることがある という恐ろしい意見を良く見かけます。ただ一方で ECC付きメモリでなくて安全性に違いはない という意見も有ります8

ECC付きのメモリを使っておけば、ファイルが壊れた時に本当は別に原因があったとしてもECC付きのメモリにしておかなかったからかもと後悔をしなくてすみます。ちなみに私は、ホーム・ファイル・サーバにECCの付いていない普通のメモリを使用しています。

ZFS on Linuxをインストール

今回はKVM上で動いているUbuntu 15.10マシンにZFS on Linuxをインストールしてみました。

OS
Ubuntu 15.10 64-bit
メモリ
8GB(8192MB)
ドライブ
5GB + ZFS用に5GBx2
ZFSに使用するドライブには、Virttual DiskのAdvanced optionsでSerial numberを書いておきます。今回は、virtio-drive1virtio-drive2としました。こうすることで、後でドライブが識別しやすくなります。
KVMのVirtual DiskにSerial numberを設定する。
KVMのVirtual DiskにSerial numberを設定する。
$ ls /dev/disk/by-id/
ata-QEMU_DVD-ROM_QM00001  virtio-ubuntu-drive0-part1  virtio-virtio-drive3
virtio-ubuntu-drive0      virtio-virtio-drive2

ドライバ名が頭に付くことを忘れていた。

仮想環境でない本物のドライブでは、次のようにモデル名とシリアル番号から自動的に設定されています。また同じドライブに対して、WWN9からも名前が付けられます。

モデル名とS/N、WWNからデバイス名が作成される。
モデル名とS/N、WWNからデバイス名が作成される。
$ ls /dev/disk/by-id/
usb-ST310005_9VPC_246802468024-0:0
usb-ST310005_9VPC_246802468024-0:0-part1
usb-ST310005_9VPC_246802468024-0:0-part2
# 省略

USB接続だからかWWNでの名前がこの時は作られませんでした。SATAで接続するとwwn-0x5000c50017ffe14fのようなwnnで始まるWWNに由来する名前も作成されます。

ZoLは複数ののパッケージに分割されていますが、zfsutils-linuxをインストールすると必要なパッケージが全てインストールされます。ただし現時点ではパッケージの依存関係にバグがあるのかZFS on Linuxのカーネルモジュールをインストールする時に必要なbuild-essentialパッケージがインストールされません10。そこでこれも同時にインストールします。

$ sudo apt-get update
$ sudo apt-get install build-essential zfsutils-linux

普通のパッケージはファイルをコピーするだけですが、ZoLはカーネルモジュールをコンパイルしてインストールする必要があります。そのためインストールが完了するまで多少時間がかかります。

インストールが完了したら、ZFSが使えるようになっているか確認します。

$ cat /proc/filesystems |grep zfs
nodev	zfs

$ dmesg | grep -E 'SPL:|ZFS:'
[  848.530602] SPL: Loaded module v0.6.4.2-0ubuntu1
[  848.566350] ZFS: Loaded module v0.6.4.2-0ubuntu1.2, ZFS pool version 5000, ZFS filesystem version 5

ZFSを使ってみた

ZFSが使えることが確認できたら、ミラーリング(mirror, RAID1)で冗長化したZFSを作って/homeに使用してみます11

ZFSを使うには、まず複数のドライブをまとめて冗長性を持った一つの記憶システムpoolを作成し、次にpoolを分割してユーザが使用できるファイルシステムを作ります。

poolの作成

まずドライブと対応するデバイス名を確認します。

$ ls -l /dev/disk/by-id
lrwxrwxrwx 1 root root  9 12月 29 08:12 ata-QEMU_DVD-ROM_QM00001 -> ../../sr0
lrwxrwxrwx 1 root root  9 12月 29 08:12 virtio-ubuntu-drive0 -> ../../vda
lrwxrwxrwx 1 root root 10 12月 29 08:12 virtio-ubuntu-drive0-part1 -> ../../vda1
lrwxrwxrwx 1 root root  9 12月 29 08:12 virtio-virtio-drive2 -> ../../vdb
lrwxrwxrwx 1 root root  9 12月 29 08:12 virtio-virtio-drive3 -> ../../vdc

今回ZFSに使用するドライブがvdbとvdcに接続していることがわかりました。このデバイス名は初期化するときにだけ必要で、以後は分かりやすいby-idで示された名前が使用できるようになります。(本当は最初からby-idの名前を使えるはずですが…。)

poolの作成には、zpoolコマンドを使用します。

$ sudo zpool create -o ashift=12 tank mirror vdb vdc
$ sudo zpool status
  pool: tank
 state: ONLINE
  scan: none requested
config:

	NAME        STATE     READ WRITE CKSUM
	tank        ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    vdb1    ONLINE       0     0     0
	    vdc1    ONLINE       0     0     0

errors: No known data errors

$ sudo zpool list
NAME   SIZE  ALLOC   FREE  EXPANDSZ   FRAG    CAP  DEDUP  HEALTH  ALTROOT
tank  4.97G   360K  4.97G         -     0%     0%  1.00x  ONLINE  -

ドライブがまっさらでパーティションテーブル自体がないときにはエラーになるので、poolを作成するときに-fオプションを追加します。

-o ashift=12オプションは、4KBセクタのドライブに対応するためで、2^12(4096)バイトを単位としてデータを配置させます。

poolの名前をtankとしましたが、この名前は/(root)ディレクトリに無い名前であれば自由に決めることができます。

poolを構成するストレージには、ドライブ丸ごとではなく特定のパーティションを指定することも可能です。ただしドライブ丸ごとのほうが効率が良いということです。

これでpoolの準備は完了です。しかしこれでは障害が発生した時にどのドライブを交換したらよいか分かりにくく、間違ったドライブを交換してしまいそうです。

そこでdisk/by-idで示された分かりやすい名前を使えるようにします。

$ sudo zpool export tank
$ sudo zpool import -d /dev/disk/by-id tank
$ sudo zpool status
  pool: tank
 state: ONLINE
  scan: none requested
config:

	NAME                      STATE     READ WRITE CKSUM
	tank                      ONLINE       0     0     0
	  mirror-0                ONLINE       0     0     0
	    virtio-virtio-drive2  ONLINE       0     0     0
	    virtio-virtio-drive3  ONLINE       0     0     0

errors: No known data errors

これで将来障害が発生したとしても、交換が必要なドライブを間違える心配が減ります。

異なるサイズのドライブの組み合わせ

サイズが異なるドライブ(またはパーティション)を組み合わせた場合は、もっとも容量の小さいドライブに合わせてpoolが作成されます12

また将来ドライブが壊れた時には、壊れたドライブと同じかより大容量のものと交換する必要が有ります。ドライブを交換して最も容量の小さかったドライブが置き換わると、自動的にpoolのサイズが拡張されます。

例えば、500GB + 500GB(500GB)のミラーリングされたpoolのドライブ一台を1TBのドライブと交換したとします。すると500GB + 1TBという構成になりますが、この時のpool容量は500GBのままです。さらに500GBのドライブを1TBのと交換すると1TB + 1TBとなり、poolの容量は自動的に1TBとなります。

ただし容量に空きがあっても小さいサイズのドライブに交換することはできません13

ファイルシステムの作成

poolを作成したらファイルシステムを作成して使用できるようにします。

と言っても実はpoolを作成しただけでファイルシステムが作られて/(root)にマウントされています。そのためpoolの名前に「/(root)ディレクトリに無い名前」という制限があったのです。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
# 省略
tank            4.9G  128K  4.9G   1% /tank

dfコマンドで使用量がわかるのがZFSの便利なところです。

/homeをZFSにする

このままどんぶり勘定的に使用することも可能ですが、一般的にはこの領域をzfsコマンドで分割して使用します。

ここでは/homeをZFS上に作成して、ドライブが一台壊れてもデータを守れるようにしてみます。

$ sudo zfs create -o atime=on -o relatime=on -o compression=lz4 tank/home
$ sudo zfs list
NAME        USED  AVAIL  REFER  MOUNTPOINT
tank        396K  4.89G    96K  /tank
tank/home    96K  4.89G    96K  /tank/home

これで新しい/homeとなるファイルシステムが出来ました。

zfsコマンドの-o atime=on -o relatime=onオプションは、ファイルアクセス時刻の記録方法をext4のデフォルトと同じにするためです。また-o compression=lz4オプションは、データをlz4で圧縮して記録することを指示しています。

新しいファイルシステムができたので、これまでの/homeを移動させて/homeを切り替えます。

$ sudo rsync -a /home/ /tank/home
# /home/とソースはスラッシュ(/)で終わっている必要がある。
$ ls /tank/home/
# 全てのユーザディレクトリが表示されるはず。

$ cd /
$ /homeを外部メディアにバックアップ
$ sudo rm -r /home/*
$ sudo zfs set mountpoint=/home tank/home
$ sudo zfs list
NAME        USED  AVAIL  REFER  MOUNTPOINT
tank        448K  4.89G    96K  /tank
tank/home   124K  4.89G   124K  /home

$ ls /home/
# 以前と同じく全てのユーザディレクトリが表示されるはず。

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
# 省略
tank            4.9G  128K  4.9G   1% /tank
tank/home       4.9G  128K  4.9G   1% /home

再起動して問題なければ、バックアップを削除します。

$ sudo rm /tank/home.tgz

参照と脚注

  1. ZFS on Linux
    これまでもZFSは、FUSEではサポートされていました。

  2. ZFS & Libdvdcss Should Soon Be In Debian – phoronix
    Debian Is Still Working To Tackle ZFS On Linux Support – phoronix

  3. 2015年10月9日号 ZFSとUbuntu・UWN#436 – Ubuntu Weekly Topics

  4. [zfs-discuss] ZoL available on the Ubuntu repositories

  5. Ubuntuパッケージ検索結果

  6. ZFS Stable Releases for Ubuntu

  7. Do I have to use ECC memory for ZFS? – ZFS ON LINUX FAQ

  8. 第7回 ZFSベストプラクティス-FreeBSD Journal March/April 2015 – BSD界隈四方山話

  9. WWNは、World Wide Nameの略。World Wide Name – ウィキペディア

  10. 本来必要なパッケージは全てインストールされるはずですが、
    zfs-dkms is missing dependency on build-essential – Ubuntu zfs-linux package bugs

  11. ZFSでは、ミラーリングの他にraidz1(RAID5相当)とraidz2(RAID6相当)を冗長化に使用できます。

  12. ドライブ2台のミラーリングでは差が現れませんが、Btrfsは容量が異なるドライブを組み合わせても、できるだけ無駄のないpoolを作成してくれます。btrfs disk usage calculator

  13. Btrfsは、使っている容量が収まれば小さい容量のドライブに置き換えることができるそうです。

ApacheでOCSP Staplingを有効にしてみた

Apacheでは設定を二行加えるだけでOCSP Staplingを有効にできた。

HTTPSによるアクセスでは、通信を暗号化するためにサイトの証明書が必要です。

この証明書には有効期間が有りますが、有効期間内であっても証明書が失効している可能性が有ります。そのため証明書が失効していないか確認する必要が有ります。

証明書が有効か確認するには、CRLとOCSPという二種類が有ります1。この二種類の方法の内、現在はレスポンスのが速いという利点2から主にOCSPが使用されています。

ただしOCSPにも次のような問題点が有ります3

  • OCSP応答が得られない場合にサーバ証明書の失効検証を正しく行わないままSSL通信を許可してしまう可能性がある。
  • OCSPを使った場合には、あるサイトにアクセスがあったことをOCSPレスポンダも知り得てしまう。

そこでこの問題を回避するために、RFC6066ではコンテンツを配信するサーバがOCSPレスポンダを兼ねる(キャッシュする)ことができる方法が提案されています4。これによりOCSPレスポンダに関するどちらの問題点も解消できます。

なおこのRFC6066の証明書状態リクエスト(TLS Certificate Status Request)は、OCSP staplingと一般に呼ばれています5

OCSP staplingを有効にするApacheの設定

OCSP staplingの説明が長くなりましたが、ApacheでOCSP staplingを有効にする設定はいたって簡単です6

UbuntuのapacheパッケージでApacheをインストールしたならば、SSLのグローバル設定である/etc/apache2/mods-enabled/ssl.confに次の二行を追加します。

SSLUseStapling		On
SSLStaplingCache        shmcb:${APACHE_RUN_DIR}/ssl_stapling(32768)

設定はこれだけです。

設定を変更したらapacheを再起動します。

$ sudo apachectl configtest
Syntax OK

$ sudo service apache2 restart

OCSP staplingが有効か確認

OCSP staplingが有効になっているかは、opensslコマンドを使用して確認します。

OCSP staplingが有効になっている場合は、次のようにOCSP Response Dataを含む結果が得られます。

$ openssl s_client -connect www.example.jp:443 -status -servername www.example.jp < /dev/null | head
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
verify error:num=20:unable to get local issuer certificate
verify return:0
CONNECTED(00000003)
OCSP response: 
======================================
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
    Version: 1 (0x0)
    Responder Id: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
    Produced At: Dec 23 14:51:00 2015 GMT
    Responses:
DONE

もし次のようにOCSP response: no response sentとなった場合は、OCSP staplingが有効になっていません。

$ openssl s_client -connect www.example.jp:443 -status -servername www.example.jp < /dev/null | head
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
verify error:num=20:unable to get local issuer certificate
verify return:0
DONE
CONNECTED(00000003)
OCSP response: no response sent
---
Certificate chain
 0 s:/CN=www.nosuz.jp
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate

参照と脚注

Let’s Encryptから証明書を取得して常時HTTPS化

  • Let’ EncryptからHTTPS(暗号化)通信に必要な証明書を無料で発行してもらいました。
  • HTTPSが有効になるようにApacheの設定を変更して、暗号化されていることを示す鍵アイコンが表示されることを確認しました。
  • HTTPでのリクエストをHTTPSに転送して常時HTTPS化しました。
  • HTTPSの証明書には有効期限があるので、自動的に更新できるようにしました。

  • 証明書の取得
  • Apacheの設定
  • 証明書の自動更新

HTTPSはWebの通信を暗号化するために使われていると一般的には思われています。しかし実際には暗号化だけでなく、Webサイトを運営する会社・組織の身元を保証する1ためにも使われています。

そのため身元を保証してもらいたい会社・組織は審査を受ける必要が有り、時間とそれなりのお金をかけて証明書を発行してもらっていました。その結果としてユーザは安心してオンラインで買い物をしたり預金を確認できます。

一方、身元の保証は必要なく単純に安全な通信のためにHTTPSを使いたいという場合には、これまでのやり方は非常に手間がかかりハードルが高いものです。そこで誰でもHTTPSの暗号化機能を手軽に使えるようにするためLet’ Encryptプロジェクトが、Webサイトの身元は保証しないけど暗号化に使用できる証明書を機械的かつ無料で発行する実験が開始されました。

会社・組織の身元保証が無いので商業利用向きではありませんが、個人のWebサーバでも簡単にHTTPSを使って安全な通信を行えるようになりました。

ここではHTTPSに必要な証明書の取得方法からサーバの設定、証明書の更新方法について説明します。

証明書の取得

HTTPSの証明書は、専用のプログラムletsencryptを使用して取得します。

letsencryptをインストール

letsencryptは、Debianなどパッケージとして配布されている場合も有りますが、Ubuntuではまだパッケージになっていなのでgitコマンドを使ってプログラムを取得します2

$ sudo apt-get install git # gitをまずインストールする。
$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt

HTTPSの証明書を取得

letsencrypt-autoコマンドを実行してHTTPSの証明書を取得します。

WebサーバにApacheを使用している場合は、次のコマンドを実行します3

ただしこのコマンドを実行するとサーバが一時的に停止します。ダウンタイムを最小にするには、--apacheの代わりに--webrootオプション(webroot mode)を使用します4

$ ./letsencrypt-auto --apache

実行すると必要なパッケージがインストールされ、証明書を取得するために必要な質問をいくつかされます。質問に答えてしばらく(1分程度)待つとHTTPS証明書が/etc/letsencrupt/live/に保存されます。

もしかすると、証明書を取得するときにHTTPSポートが開いている必要があったかもしれません。その場合は、次の「HTTPSポート(443)を公開」を参照してください。

証明書を取得するときに質問される項目は次の3つです。

  1. 現在のApacheがホストしているドメインの内で証明書に含めるドメイン名。
  2. 連絡先のメールアドレス。
  3. Let’s Encryptを使用するための決まりに同意するか。

1.で選択したドメイン名は、全て同じ証明書を使ってHTTPS通信が行えます(SAN Certificate?)。また-dオプションで事前に対象のドメイン名を指定しておくことができます。

複数のサーバ名を指定すると「複数のサーバ名はサポートしていない」というようなエラーが表示されますが、問題なく使えています。

2.と3.の質問は、それぞれ--email--agree-tosオプションで事前に指定しておけます。

オプションの詳しい説明は、

$ ./letsencrypt-auto --help all

で取得できます。説明が表示されるのが遅いので、次のようにリダイレクトを使って説明を保存しておくと後で参照しやすくなって便利だと思います。

$ ./letsencrypt-auto --help all > help.txt

--apacheオプションは、証明書の取得の他にインストールもするということですが、具体的に何をしているのか私には分かりませんでした5。Apacheの設定を変えてくれるということもありませんでしたし、インストール機能がないwebrootでも証明書は同じ場所に保存されました。

またletsencrypt-autoを実行すると、/var/log/letsencrypt/letsencrypt.logにログが記録されます。

HTTPSポート(443)を公開

HTTPSで通信するには、HTTPS用のポートに外部からアクセスできる必要が有ります。

HTTPSポートを開くためには、次のルールをiptablesの設定に追加します。既にHTTP用のルールが書かれていると思うので、その後ろあたりに追加するのが良いと思います。また二番目のようにmultiportモジュールを使ってHTTPポートとHTTPSポートをまとめてルールにすることもできます。

iptables -A INPUT -p tcp --syn -m state --state NEW --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --syn -m state --state NEW --dport 443 -j ACCEPT

# or

iptables -A INPUT -p tcp --syn -m state --state NEW -m multiport --dports 80,443 -j ACCEPT

iptablesの設定はサイトを守る上で非常に重要ですので、十分注意してください。

Apacheの設定

HTTPSの証明書を取得できたら、その証明書を使ってHTTPS通信ができるようにApacheの設定を変更します。

SSLモジュールを有効化

HTTPS通信をするには、ApacheのSSLモジュールを有効にします。

次のようにしてSSLモジュールを有効にしますが、もしかするとletsencrypt-auto --apacheが既にモジュールを有効にしているかもしれません。もちろん既にsslモジュールが有効になっているときにこのコマンドを実行してしまっても問題はありません。

$ sudo a2enmod ssl
$ sudo a2ensite default-ssl # optional

a2ensite default-ssl/etc/apache2/sites-enabledにSSL用の雛形default-sslが作成されますが、000-default.confに設定を加えても問題ありません。

Apacheの設定変更

実際にHTTPSで通信するにするには、<VirtualHost *:80/>に加えて<VirtualHost *:443/>を加えます。

例えば、私の場合はVirtualHostなので、次のような内容を設定に追加しました。

<VirtualHost *:443>
    # これまでの設定内容をコピーする。

    SSLEngine		on
    SSLProtocol		all -SSLv2 -SSLv3

    # Apache 2.4.7まで
    SSLCertificateFile    /etc/letsencrypt/live/_MY_DOMAIN_NAME_/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/_MY_DOMAIN_NAME_/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/_MY_DOMAIN_NAME_/chain.pem

    # Apache 2.4.8以降
    # SSLCertificateChainFileが廃止になった。
    #SSLCertificateFile    /etc/letsencrypt/live/_MY_DOMAIN_NAME_/fullchain.pem
    #SSLCertificateKeyFile /etc/letsencrypt/live/_MY_DOMAIN_NAME_/privkey.pem

    # 使用したSSLプロトコルと暗号化方式をログに記録することもできます。
    #CustomLog logs/ssl_request_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>

その他の設定オプションは、/etc/apache2/sites-available/default-ssl.confを参照して設定に追加します。

また/etc/letsencrypt/options-ssl-apache.confに書かれているようなグローバル設定は、/etc/apache2/mods-enabled/ssl.confで設定します。

設定を変更したら、次のコマンドで設定の書き方に問題がないか確認しておきます。

$ sudo apachectl configtest

SSLで接続できるか確認

Apacheの設定が終わったら、サーバを再起動してHTTPSで接続できるか確認します。

$ sudo service apache2 restart

まずApacheがHTTPSのポートを見ているか確認します。ApacheがHTTPSポートで待っている場合は、次のように表示されます。何も出力がないときはポート番号に間違いがないか設定を再確認してください。

$ ss -lnt | grep 443
LISTEN     0      128                      :::443                     :::*

次にWebブラウザからWebページを開いてみます。この時URLの頭をhttp:からhttps:に変更してページにアクセスします。

Webページを開けない時は、ファイアウォールでHTTPSのポートが閉じられていないか確認してください。

HTTPを転送して常時HTTPS化

常時HTTPS化するかはサイト毎のポリシーですので必須ではありません。

常時HTTPS化するには、HTTPで接続を求めてきたリクエストを全てHTTPSにリダイレクトします。この例ではリダイレクトステータスをR=301で恒久的な移動を示す301にしています。

<VirtualHost *:80>
    ServerName www.nosuz.jp
    LogLevel warn
    #LogLevel warn rewrite:trace8
    CustomLog ${APACHE_LOG_DIR}/access.log
    ErrorLog ${APACHE_LOG_DIR}/error.log
    RewriteEngine On
    RewriteRule . https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

アドレスバーの鍵表示

HTTPSでアクセスすると多くのWebブラウザでは、通信が暗号化されていることを鍵アイコンが表示されます。

しかしHTTPSでアクセスしているのに鍵アイコンが表示されないことが有ります。この時は、画像やJavaScriptの読み込みなど一部にHTTPでのアクセスが使われています。

鍵アイコンを表示させるには、ページのソースを開いてhttp://となっている部分を探して、その部分をhttps://またはhtpを削除して単に//と変更します6

証明書の自動更新

Let’s Encryptが発行する証明書の有効期間は90日なので、最低三ヶ月に一度証明書を更新する必要が有ります。もちろんここも人が介在すること無く証明書の更新を自動化できます。

更新処理の自動化にはcronサービスを使用するのが簡単です。例えば次のようなエントリーをrootのcrontabに登録すると、奇数月7の15日3時21分に更新処理が行われます。

21 3 15 */2 * /_PATH_/letsencrypt-auto certonly --text --renew-by-default --webroot -w /var/www-root -d www.example.jp > /var/log/letsencrypt/renew-cert.log 2>1 && service apache2 restart

参照と脚注

  1. Webデザイナーなら知っておくべき サーバ知識相談室

  2. Quick Start Guide – Let’s Encrypt

  3. Ngixサーバの場合は、--ngixオプションが将来使えるようになる予定です。しかし現在は、--webrootオプションを使うなど他の方法で証明書を取得する必要が有ります。

  4. webroot modeを使用すると、起動中のWebサーバを使用して証明書を取得します。そのため多少時間がかかる証明書を取得する過程でもサービスを停止しないですみます。ただしHTTPSを有効にするところでWebサーバの再起動が必要になります。

  5. Plugins – Let’s Encrypt

  6. URLがいきなり//で始まる場合は、現在のプロトコールでそのリソースにアクセスします。そのため<img src='//domain/img.png'>を含むページをHTTPで開いた場合はHTTPでimg.pngを取得し、HTTPSで開いた場合はHTTPSでimg.pngを取得します。

  7. crontabの月は時間や分とスタートが異なり1-12なので、*/2は1-12/*と同じ意味です。よって2で割り切れる順番の月、すなわち0番目1月、2番目3月…と奇数月にcrontabエントリーが実行されます。偶数月ならば、21 3 15 2-12/2 * commandとなります。

KiCadの情報源メモ

この記事はQiitaのKiCad Advent Calendar 2015の17日目です。
←16日目(kinichiroさん)・17日目・18日目(starfort-jpさん)→

すみません、全く画像がない非常に地味な内容です。

KiCadに関する情報源は色々あると思いますが、今回は私がよく参照させてもらっているサイトを紹介します。「これを抜かしたらモグリだ」1というようなサイトがあったらぜひ教えてください。

静的な情報源は、KiCadを使う上で基礎となるサイト(と本)です。頭からお尻まで精読しないまでも、全体を流し読みしておくだけで基礎力がアップします。特にKiCad公式ドキュメントをこの夏に読む機会を得られたことは収穫でした。

動的な情報源は、回転寿司のように目の前をいろんな話題が流れてい行くので、お茶を飲みながらプラプラ見て回るだけでKiCadに詳しくなった気になれます。

マニアックな情報源は、KiCadを使う上で特に役立つということは ありません 。でも、バグらしきものに気がついてしまったり2、この夏から秋にかけての「新しいKiCadはいつ出る?」という時には欠かせません。

静的な情報源

KiCad公式ドキュメント 日本語ほか
説明するまでもありませんがKiCad 4.0のドキュメントです。オリジナルと翻訳ともGitHubで管理されているので、間違いを見つかたらPullRequestで指摘できます。
一人で始めるプリント基板作り(SP No.127) 日本語
この本(+ CERNがサポートというニュース)でKiCadを使い始めました。KiCad 4.0が公開された今となっては一部操作など異なっている部分は有りますが、Webより全体の流れをつかみやすくて今でも役に立つと思います。
KiCad.jp Wiki 日本語
一通り見ておくと、問題にぶつかった時に「そんなことが書かれていたな」となり、無駄に悩まなくてすみます。特に過去に出た質問には助けられます。
KiCad Scripting Reference Manual 英語
Pythonスクリプトのドキュメントってこれだけ?
KiCAD pcbnew scripting 英語
Pythonスクリプトを実際に書くときには、こっちのリファレンスのほうが重要そう。
Kicad/FAQ 英語
そんなのもあるってことで。

動的な情報源

kicad.jp –Twitter 日本語
KiCadに関するツイートを ボットかと思うような早さ でリツイートする(ボット?)ので、フォローしているだけでKiCadに詳しくなれます。誰かが困ってることをツイートすると、解決策を提示しているのをよく見かけます。
KiCad.info Forums 英語
KiCadの使い方・機能に関するフォーラム。他人の困りごとは蜜の味。見ているだけでそんなことができるのかと頭でっかちになれます。Twitter(@ContextualElec)をフォローしていると、新規投稿のタイトルをチェックできます。
kicad-users 英語
KiCadユーザのYahoo!グループ。私はたまに見るている程度です。
Questions for KiCad 英語
KiCadプロジェクトへの質問と問題報告。新しいメッセージは少ない。

この他に日本語でのメーリングリストがあるのですが、現在の所ネット上にアーカイブが公開されていません。

マニアックな情報源

kicad-developers team mailing list archive 英語
タイトルのようにKiCad開発のメーリングリストです。
kicad-lib-committers team mailing list archive 英語
KiCadの部品とフットプリントのコミッターを主としたメーリングリストです。
KiCad bugs 英語
KiCad本体のバグ報告です。
~kicad-product-committers/kicad/product 英語
KiCadのコミット記録です。ほとんど修正のコミットですが、KiCadがどんどん改善されているのが見えて面白いです。
  1. 「モグリ」って21世紀では死語でしょうか。

  2. バグ報告でKiCadをより良く – Qiita KiCad Advent Calendar 2015の11日目

Shift JIS(SJIS)をlessのようにページャー表示

lvコマンドを使用すれば、SJISやJISコードのテキストをlessコマンドのようにページャー表示できる。

長いテキストファイルを眺めるには、lessコマンドを使用します。ただしLESSCHARSETで指定した文字コード意外のテキストファイルを表示すると文字化けしてしまいます。

LESSCHARSETが指定されていない場合は、UTF-8が指定されたとみなされます。

SJISなどで書かれたテキストファイルを表示するには、次の例のようにiconvコマンドで変換して表示させることができます。

# SJISで書かれたファイルを表示する。
iconv -f SJIS sjis.txt | less

lvコマンドを使う

たまにであれば、iconvコマンドを使いますが、頻度が高くなってくるとだんだん面倒になってきます。

そんな時にはlvコマンドを使用します。このページャ表示コマンドであれば、SJIS以外にもJIS(ISO-2022-JP)やEUC-JPで書かれたテキストファイルもページャ表示できます。

使える操作コマンドはlessコマンドのより少ないようですが、ページの先頭や最後への移動など基本的な使い方は同じです。

lvコマンドのインストール

Ubuntuにはlvコマンドは初期状態ではインストールされていません。そこで次のようにlvコマンドをインストールする必要が有ります。

sudo apt-get install lv

秘密にしたいファイルを完全に削除する方法

復元されたくないファイルを完全に削除するには、shredコマンドでドライブごとデータを削除する。

ファイルは、普通の操作で削除しても一般的にディレクトリ情報が削除されるだけでデータ自体はハードディスク上に残っています。そのため簡単とは言えませんがデータを復元できる可能性が有ります。実際消した思っていたメールが復元されて賭博の証拠が見つかってしまった事件1が有りました。

犯罪の証拠になりそうなデータはなくとも、誰かに自分のデータを見られるのは気分の良いものではありません。このような場合には、ファイルのデータを復元できないように削除するshredコマンドが役に立ちます。

shredコマンドでファイルを削除

Linux(Ubuntu)には、データを復元できないように削除するshredコマンドが標準でインストールされています。このコマンドを使用することで、ファイルを復元できないよう完全に削除することができます。

shredコマンドは次のように使用します。

shred -uz -n 3 file

これでfileを安全に削除できます。

主なオプションには次のものが有ります。

-n num
ランダムなデータでnum回上書きする。-zオプションを使う場合に、0を指定することでランダムデータの書き込みをスキップできます。
-u
データを上書き後にファイルを削除する。
-v
進行状況を表示する。
-z
最後に0で上書きする。

shredコマンドでの欠点

shredコマンドは、ファイルに上書きする時に記録メディアで元と同じ場所に書き込まれることを前提としています。そのため一部のファイルシステムでは上書きしたはずのデータが残ってしまう可能性が有ります。

ドライブのデータを完全に削除

そこでパソコンを廃棄する場合などは、ファイルレベルではなくファイルシステムに依存しないディスクレベルでデータを削除することをオススメします。

Linuxではドライブもファイルの1つとして扱うことができるので、ファイルの削除と同じようにshredコマンドを使用して完全にデータを削除できます。

# 三回ランダムデータで上書きして、最後に0で上書きする。進行状況の表示付き。
sudo shred -nzv 3 /dev/sdb

# 時間がかかるので、普通のデータならこれで十分かな。
sudo shred -nzv 0 /dev/sdb

この例ではドライブを/dev/sdbとしていますが、環境によってファイル名が異なります。間違ったファイルを指定するとシステムを破壊してしまうので十分に気をつけてください。

ドライブの指定には、/dev/sdbではなく/dev/disk/by-idを使用するとファイル名とドライブの対応付けが分かりやすくファイル名の間違いを防げます。

Windowsのデータを完全に削除

WindowsのデータもドライブとしてみればWindowsもLinuxも違いはありません。

そこでWindowsで使用していたドライブをUbuntu(Linux)システムに接続するか、そのままUbuntuなどのLiveCDを使って起動して、shredコマンドでデータを削除できます。

参照と脚注

KiCadのBOM出力プラグイン書いてみた

この記事はQiitaのKiCad Advent Calendar 2015の8日目です。

←7日目(kinichiroさん)
・8日目・9日目(starfort-jpさん)→

KiCad 4.0では、プラグインを使用してBOMを出力するようになりました。この変更によりユーザがプラグインを作成してBOMの内容を簡単に変更できるようになりました。

ネットを見回すと、BOM情報を元にDigi-KeyMOUSERなどの情報を参照してコストを計算するプラグインKiCostなどが有ります。

ここまでの高機能は必要ありませんが、部品の発注(買い物)と実装を少しだけ便利にするBOMプラグインを書いて使っています。標準のBOM出力プラグインに毛が生えた程度の簡単なものですが、自分ではとても楽をできている気がします。

ここではプラグインと言ってもただのフィルタープログラムで、「こんなだったらもっと便利なのを作れるぞ」という切っ掛けにしてもらえたらと思います。

プラグインを作成する言語

KiCadのディレクトリを見ると、CSV形式のBOMファイルを出力するためのプラグインなど何種類かのプログラムが標準で添付されています1。これらのプラグインは全てXSLTで書かれていて、私には理解不能です。

そこで基本に戻ってKiCadのドキュメントを参照すると、次のように書かれておりXMLファイルを読めればどの言語で書いても良いことがわかりました。

中間ネットリストファイルに後処理のフィルタリングをすることで、部品表 (BOM) ファイルのような他形式のファイルを生成できます。この変換はテキストからテキストへの変換なので、この後処理フィルタは、Python や XSLT など、入力として XML を扱える処理系で記述できます。

KiCadの標準的なスクリプト言語はPythonですが片言しか話せないので、今回はRubyを使用してプラグインを作成しました。

中間ネットリストファイルの構造

中間ネットリストファイルは、普通のXMLファイルです2。この大まかな構造は、次のように5つの大きなエレメントからなっています。

<?xml version="1.0" encoding="utf-8"?>
<export version="D">
  <design>
    ...
  </design>
  <components>
     <comp ref="P1">
      <value>CONN_4</value>
      <libsource lib="conn" part="CONN_4"/>
      <sheetpath names="/" tstamps="/"/>
      <tstamp>4C6E2141</tstamp>
    </comp>
    ...
  </components>
  <libparts>
    ...
  </libparts>
  <libraries>
    ...
  </libraries>
  <nets>
    ...
  </nets>
</export>

BOMファイルの出力に必要な部分は、主に<components>エレメントです。この中に部品のリファレンスや値が入っています。<libparts>エレメントには部品の説明などが入っているので、詳しい説明入りのBOMファイルを作成するなどに使えそうです。

プラグインを書いてみた

今回は単純に<components>エレメントの情報を使って部品の注文(買い物)と実装を少しだけ便利にするBOMプラグインを書いてみました。

部品の注文には、部品名と個数が必要です。そこで注文用には同じ部品を数え上げて、部品ごとの個数をBOMファイルに出力するようにしました。

注文(買い物)用のBOM。部品と必要数を表にしています。
注文(買い物)用のBOM。部品と必要数を表にしています。

部品を実装する時に多くの方は同じ部品、例えば1kの抵抗を5つとかまとめて実装しているのではないでしょうか。そこでリファレンスの番号に関係なく同じ値の部品でグループを作るようにソートしてBOMファイルに出力するようにしました。

実装用のBOM。リファレンス順でなく、同じ部品がグループを作るように並べています。
実装用のBOM。リファレンス順でなく、同じ部品がグループを作るように並べています。

実装用と注文用のBOMファイルをCSV形式で個別に書き出しても良いのですが、結局表示するときにはExcelを使用するので一つのExcelファイル内で別シートとして書き出すようにしました。Excel形式での書き出しにはaxlsxライブラリを使用しました。

こうして書き上げたプラグインはGistで公開しているbom2excel.rbを参照してください。

プラグインのインストールとBOM出力

今回書いたプラグインは外部ライブラリーを使用しているので次のコマンドで必要な外部ライブラリー(axlsx)をインストールしておきます。

sudo gem install axlsx

プラグインを使用するには、KiCadにプラグインを登録します。

  1. Eeschemaを起動してBOMアイコンをクリックする。
  2. Add Pluginボタンをクリックしてプラグインを選択する。
  3. Command line欄を次のように編集する。
/???/bom2excel.rb "%I" "%O.xlsx"

???の部分はプラグインを置いてある場所に依存して変わります。

EeschemaのBOMアイコンをクリックすると表示されるダイアログ。ここでプラグインの登録とBOMの作成を行います。
EeschemaのBOMアイコンをクリックすると表示されるダイアログ。ここでプラグインの登録とBOMの作成を行います。

これでプラグインがKiCadに登録されたので、GenerateボタンをクリックするとBOMファイルがプロジェクトディレクトリ内に作成されます。

こんな簡単なプラグインですが、このBOMリストで部品の買い物と実装がだいぶ楽になりました。ただ実装するときにも必要な部品の個数が必要なのと、買い物の時にあまり馴染みのないリファレンスのプレフィックスだと「何だったかな?」となるので名前で表示するように今後のPythonの勉強を兼ねて改良したいと考えています。

最後に

このようにKiCad 4.0では、慣れた言語で自由にBOM作成プラグインを作成できるようになりました。私の作成したプラグインは非常に簡単なものですが、今後KiCostのようにより便利なプラグインがたくさん出てくることを期待しています。

脚注と参照

  1. Linux版ではプラグインが/usr/lib/kicad/pluginsに、WindowsではC:\Program Files\KiCad\bin\pluginsに有ります。

  2. 中間ネットリストファイルの構造 – Eeschema