2016年6月15日水曜日

KVMその1

というわけで、ようやく本命のKVMに入れる。
(初めて触るので、正直どこまでやれるか…)

なので、まずは環境整備から。

KVMを使用するためには、作業用端末でX Window System(以下X)を利用できる状態にする必要があるようだ。(サーバ本体でX Window Systemを動かしてもいいんだけど、それだと常にサーバの前にいないといけないので…)

で、作業用端末がWindowsの場合、X Window Systemが動くようにするには、幾つかの方法がある。
  • 製品を買う。(ASTEC-XとかReflextionXとか)
  • Cygwin-Xで頑張る
  • VcXsrvを使う
  • その他…
細かいことは抜きにして、今回はVcXsrvを使用することにする。(フリーだし、同じくフリーで実績のあったXmingの分離版らしいし。)
VcXsrvはsourceforgeからダウンロード出来る。(https://sourceforge.net/projects/vcxsrv/)
但し、動かすためには、VC++2015 Runtimeが必要だ。併せて入手しておこう。

細かいところは省略するけど、VC++RuntimeとVcXsrvをそれぞれインストールしておくこと。

導入が終わったら、VcXsrvを立ち上げておく。
スタートメニューから、VcXsrv→XLaunchを起動しよう。
起動したら、Display settingsで、画面の形式を指定するダイアログが表示される。
デフォルトの「Multiple windows」のまま「次へ」
Display numberもデフォルトの-1のままで構わない。

次のClient startupも、「Start no Client」でいいだろう。

次のExtra settingsも、デフォルトのままでいい。

最後に、この3画面分の設定を保存することが出来る。保存してもいいし、都度XLaunchから設定しても構わない。

タスクトレイに「X」みたいなアイコンが表示されたら起動完了だ。


続いて、teratermのssh転送で、X転送が可能なようにしておこう。
これは簡単で、ログイン前のteratermのメニューから、「設定」→「ssh転送」

出てくるダイアログの「リモートの(X)アプリケーションをローカルのXサーバに表示する」のチェックを入れて「OK」してから、sshでUbuntu Linuxへログインすればいい。


これで作業用PCの設定は終わりだ。
続いてUbuntu Linux側の環境を整えよう。

幾つか必要なパッケージがあるけど、最低限qemu-kvmは入れておく必要が有る。
$ dpkg-query -l qemu-kvm

OS構築の時に「Virtual Machine」というパッケージグループを入れているので、入っているはずだ。
もし入っていなかったら、以下のコマンドで入れておこう。
$ sudo apt-get install qemu-kvm

それ以外にも、virt-managerというのが入っていると便利らしいのだが、今はまだ入れないでおく。
この先、導入する予定だ。
$ dpkg-query -l virt-manager

で、qemu-kvmを導入した時かどこかのタイミングで、/dev/kvmというデバイスファイルが出来る。
このデバイスファイル、ubuntuの場合はグループがkvmグループになるはずなんだけど、そのためには一度再起動をしておく必要が有るらしい。
$ ls -l /dev/kvm

もし、/dev/kvmの所有グループがkvmではなかった場合は、一旦再起動しておこう。
$ sudo shutdown -r now

で、kvm関連の操作には、/dev/kvmへのアクセス権限も含めて、kvmグループに属しておく必要があるらしい。そのため、以下のコマンドで自分のアカウントをkvmグループに含める。
$ grep kvm /etc/group
$ id
$ sudo adduser (自分のユーザ名) kvm
$ grep kvm /etc/group
(一旦exitで抜けて、再度ログイン)
$ id

あと、カーネルにkvmモジュールが組み込まれているか確認しておこう。
$ lsmod | grep kvm
使っているマシンがIntel NUCなので、kvm_intelとkvmの2モジュール出てくるはずだ。

ここまで来たら、kvmコマンド自体は使用可能になっているはず。簡単な操作で確認してみる。
$ kvm -monitor stdio
これを実行したら、勝手に一つウィンドウが開いたのではないだろうか?
これを表示させるために、先にVcXsrvをインストールした。
(作業用PCをUbuntu Linuxの間のネットワークが、モバイルネットワーク(4G回線等)の場合、表示されるまでに非常に時間がかかると思うが、数分待ってみて欲しい。)

よく見てみると、「Booting from Floppy」だの「Booting from DVD/CD...」だの、PCが起動する時のBIOSのメッセージに似ているというのに気付くはずだ。
最終的に「No bootable device.」で終わっている。
過去に、PCのOS用HDDがクラッシュしたことのある人なら、恐怖とともに見たことがあるメッセージではないだろうか?
QEMU環境で、簡単なBIOSブートをしてみた、というのがこの画面だ。
この画面が出れば、QEMU(KVMのベースとなる環境)が稼働しているということになる。

teratermの方を見てみると、プロンプトが(qemu)となっているはずだ。
これが、qemuを操作するためのプロンプトだが、詳細は不明なので、おいおい書いていくこととする。

qemuのプロンプトから、kvmの状態確認コマンドを打ってみる。
(qemu) info kvm
kvm spport: enabled と表示されるはずだ。
このマシンで kvm が利用できる、ということらしい。

最後に、quitで抜けておこう。
(qemu) quit
先ほど起動したウィンドウも消滅したはずだ。

まずはココまで。
--2016/06/20追記
間違って「X Windows System」と書いてしまってた場所が有ったので、「X Window System」に修正。
同じく「Flopply」と書いていたので、「Floppy」に修正。

2016年6月13日月曜日

iSCSIを利用しようその3

前回、iSCSIで10GBのディスク容量を確保出来た。

今度はそれをLVMでボリューム作成、ファイルシステム作成、及びマウントと読み書きをしてみたい。

その前にLVMって何?って話だけど…。
既にLinuxディストリビューションを使っていたり、HP-UXやAIXを使っている人なら説明は要らないと思うけど、念の為に書いておく。

LVMというのは、Logical Volume Managerの略だ。
物理HDDを、一度論理的に束ねて、それを今度は論理的に分割、ファイルシステムを載せるためのブロックデバイスにする仕組みだ。
これは、HDDの容量不足が起きた時に、システム停止をゼロもしくは出来るだけ短くするための仕組みだ。(実際には、さらに拡張され、ミラーリングやRAID5等の冗長構成も組めるようになっている。)

で、LVMを説明する時に、自分が必ず描く画がある。

これは、HDDからファイルシステム、ファイルまでの各層を示したものだ。
私は必ず、こういった画を描くようにしている。

実際のHDD(今回はiSCSIで見えてきた /dev/sdb を意味する)からファイルシステムまでの間に、複数の層が存在し、これらの層を通ってようやくファイルへのI/Oが出来るようになっている。

この内、LVMとなっている3つの層が、LVMで扱う層だ。
LVMが無かった頃は、mbr/gptパーティションのすぐ上に、File Systemの層が来ていた。

LVMの層をよく見て欲しいのだが、Volume Groupによって、複数のPhysical Volumeを一つにまとめ、それをLogical Volumeとして分割している。
これが、複数のHDDにまたがっている点が重要だ。

10GBのHDDが3本あるが、25GBの大きな一つの領域が必要だという場合、従来ならもっと容量の大きなHDDを買ってくる必要があった。
LVMによって、3つのHDDを束ね、25GBという大きなLogical Volumeを作れば、25GBという容量のファイルシステムを用意することが出来る。

また、使っている容量が不足気味になってきた場合に、新しいHDDを足して、Volume Groupに追加すれば、その上のLogical Volumeを拡張することが出来る。

これらが、LVMを使用する最大のメリットだ。

また、HDDを操作する場合、上記の層を意識しながら操作することで、自分が今何をやっているのか?それがドコに影響を及ぼすのか?が分かる。
より安全に操作することが出来る様になる訳だ。

では、先ほどの図に従って、下から順に作っていこう。(HDDは1本だけだけどね。)

まずは、mbr/gptパーティションの作成だ。
今回は、容量が10GBということもあって、mbrパーティションでも良いわけだが、敢えてgptで作ってみよう。
$ sudo parted /dev/sdb print
「ディスクラベルが認識できません」というようなエラーが出たはずだ。
これは、「このディスクをmbrで使いますか?gptで使いますか?」というフラグが立っていないために出るメッセージだ。
gptで使うよ、という指示をしておこう。
$ sudo parted /dev/sdb mklabel gpt
$ sudo parted /dev/sdb print

成功したら、パーティションの作成だ。今回は全体を使って、一つのパーティションにしよう。
$ sudo parted /dev/sdb mkpart primary 0% 100%
$ sudo parted /dev/sdb set 1 lvm on
$ sudo parted /dev/sdb print
"primary"と指定しているのは、名前に相当する部分らしい。マニュアルを見ると、primary / extended / logical を指定しろ、とのことだが、gptの場合は関係が無いはず。だが、コマンドラインでは何かを指定しないとパーティションが作成できない。
そのため、primaryを指定した。
先頭を0%と指定しているのに、出来上がったパーティションは1029kBから、となっていると思う。(ディスクのタイプによって異なるかも)
これは、gptの場合は先頭部分が少し利用できない(予約領域)からだ。1MB程度の容量減なので、気にしないでおこう。
また、2行目は、「この領域をLVMで使用するよ」というフラグだ。必要かどうかはイマイチ分かっていない。

パーティションが出来上がったら、/dev/sdb1が出来上がっているはずだ。
$ ls -l /dev/sdb*
この/dev/sdb1が、sdbに作った一つ目のパーティションだ。(一つしか作っていないので、sdb1しか無いのは正常だ)

今度は、これ(/dev/sdb1)を、LVMのPhysical Volume(PV)として定義しよう。
$ sudo pvcreate /dev/sdb1
$ sudo pvdisplay /dev/sdb1
$ sudo pvs /dev/sdb1
一つ目のコマンドが、/dev/sdb1をPVとして定義するコマンド。
二つ目、三つ目のコマンドは、PVとして定義されているかどうかの情報を見るコマンドだ。
PVとして定義されてなかった場合はエラーになる。

PVとして定義出来たら、今度はVolume Group(VG)を作成し、このPVをVGの1つとして定義する。
$ sudo vgcreate vg-test /dev/sdb1
$ sudo vgdisplay -v vg-test
$ sudo vgs vg-test
一つ目のコマンドがVGを作るコマンドだ。vg-testというのが今回作成したVGの名前で、既に存在しているVG名は使えない。また、最後のコマンドが、そのVGに格納するPVのデバイスファイル名だ。
二つ目、三つ目が、そのVGの詳細情報を確認するコマンドになる。
また、PVを確認する時の pvdisplay 及び pvs コマンドも、先ほどと若干異なる出力になるはずだ。(属するVGの名前の欄が、先程まで空欄だったのが、vg-testと入っているはずだ)

また、vgcreateには多くのオプションがあり、細かなチューニングが可能だが、デフォルトで特に不都合は無く使えるはずだ。この辺りは、いずれ必要になったら記載する。

これで、VGの作成が完了した。

VGが作られたら、次はLogical Volume(LV)だ。
上の図では、LVは4つ作っているが、今回はあくまでテスト的なものなので、1つだけ作る。
$ sudo lvcreate -L 5G -n lv-test1 vg-test
$ sudo lvdisplay -v vg-test/lv-test1
$ sudo lvs vg-test/lv-test1
例によって、一つ目がLVを作成するコマンドだ。
ここでは、vg-testから5GBの容量で、lv-test1というLVを作成する、というコマンドになっている。
二つ目、三つ目が詳細確認になる。
また、併せてVG確認コマンド、PV確認コマンドも使ってみて欲しい。
若干の変化があるはずだ。

ココまで来たら、今度はファイルシステムを作る流れだ。
ext4で作っておけばいいだろう。
$ sudo mkfs.ext4 /dev/vg-test/lv-test1
$ sudo blkid /dev/vg-test/lv-test1

そこまで行ったら、マウントしてI/O出来るか確認してみよう。
$ sudo mkdir -p /mnt/tmp
$ cat /etc/mtab | grep /mnt/tmp
$ sudo mount -t ext4 /dev/vg-test/lv-test1 /mnt/tmp
$ cat /etc/mtab | grep /mnt/tmp
$ sudo touch /mnt/tmp/hogehoge
$ sudo sh -c 'echo "foobar" >> /mnt/tmp/hogehoge'
$ cat /mnt/tmp/hogehoge
$ sudo rm -i /mnt/tmp/hogehoge
$ sudo umount /mnt/tmp

これで、iSCSI領域をI/Oすることが出来るようになった。

本来ならここで、LVMの活用例として
  • HDDの追加
  • VGの拡張
  • LVの拡張
  • FSの拡張
  • PVの移動
  • LVMミラー
  • FSの縮小
  • LVの縮小
  • VGの縮小
  • PVの取り外し
あたりを書くべきだと思うけど、それはおいおいやっていくことにして、ぼつぼつKVM周りのことを検証していきたい。

2016年6月12日日曜日

iSCSIを利用しようその2

というわけで、Ubuntu LinuxをiSCSIイニシエータ(使用する側)に仕立てあげよう。

まずはNAS側で、10GB程の新規LUN(Logical Unit Number:前回の図で言うところの、仮想HDDだ)を作成、併せてiSCSIターゲットを新規作成し、両者を結びつけておこう。
これは、NASの製品によって手順が違うので、各自NASのマニュアル等を参照して欲しい。

また、その時にiSCSIターゲットのIQNというのもメモしておこう。

IQNというのは、iSCSIターゲット、イニシエータ両方とも持つ特殊な名前で、iSCSIは相手の識別にこのIQNというのを使用する。
IQNという名前は決まったフォーマットで、iqn.YYYY-MM.com文字列:任意の文字列-文字列 みたいなちょっと面倒くさい名前だ。
これは大抵自動生成されるはず。一つのiSCSIネットワーク内でIQNが重複すると危険なので、自動生成されたものをそのまま使おう。

で、Ubuntu Linux側だ。
Ubuntu LinuxでiSCSIイニシエータを実現するパッケージはopen-iscsiというヤツだ。
こちらをインストールしてしまおう。
$ dpkg-query -l open-iscsi
なんと既に入ってたよ。

もしインストールされてなかったら、
$ sudo apt-get update
$ sudo apt-get --simulate install open-iscsi
$ sudo apt-get install open-iscsi
$ dpkg-query -l open-iscsi
でインストールしておこう。

インストール出来たら、自分自身(Ubuntu Linux自身)のiSCSIのIQNを確認しておきたい。
open-iscsiでは自分自身のIQNは、
/etc/iscsi/initiatorname.iscsi
というファイルが自動生成されて、そこに記録されるようだ。
中身を見ておこう。
$ sudo cat /etc/iscsi/initiatorname.iscsi

IQNが確認できたら、NAS側のiSCSIターゲットの設定で、そのIQNからのアクセスを許可しよう。(読み書き両方可能にしておこう)
これも、各NASのマニュアルを参考に。なお、私のNASでは「マスキング」という定義の名前だった。
また、NAS側で「CHAP認証」という機能が使えるかもしれないが、これは使わないようにする。
(ユーザ名・パスワードによるアクセス制御をかけるより、IQNのマスキングでアクセス制御を掛けた方が、遥かに楽だし、CHAPによるアクセス制御を掛けるメリットはほとんど無いはず。)

次は、iSCSIイニシエータ(Ubuntu Linux)側から、iSCSIターゲットを検出させる。
これはiscsiadmコマンドを使うらしい。
$ sudo iscsiadm -m discovery -t sendtargets -p (NASのIPアドレス)
これで、NASのiSCSIターゲットのIQNが表示されるはずだ。

そうしたら、iSCSIターゲットへログインする
$ sudo iscsiadm -m node --targetname (NASのIQN名) --login
これで、NAS側で定義した、10GBのディスクが見えてくるはずだ。

dmesgで確認してみよう。
$ dmesg

私の環境では、scsi 4:0:0:0、デバイスファイル名 /dev/sdb として見えてきた。
本当に /dev/sdb として見えているか確認してみよう。
$ lsblk /dev/sdb
設定した通りの10GBの容量で見えてきているだろうか?

これで、HDDを増設した時と同じように、/dev/sdb を操作することが出来るはずだ。

ちなみに、デバイス認識時にdmesgを実行することで、デバイスIDを確認することが出来る(先ほどの4:0:0:0)が、長期間使っていたらどうせド忘れしてしまうだろう。
その場合、/sys/blockを見ることで、ある程度分かる。
こちらの環境では、/sys/block/sdbというファイル(シンボリックリンク)が存在し、そちらの指し示す先で分かるようだ。
$ ls -l /sys/block/sdb
lrwxrwxrwx 1 root root 0  6月 12 17:46 /sys/block/sdb -> ../devices/platform/host4/session1/target4:0:0/4:0:0:0/block/sdb
これを見ると、4:0.0.0というパスが出てくる。これがデバイスIDのようだ。

とりあえず、iSCSIのディスクが見えるところまでは確認できた。
次回はコレをLVMでボリューム作成、ファイルシステム作成してマウントするところまでやってみたい。

--2016/06/13追記
NAS側で10GBのLUN(仮想HDD)を作っているが、この時「シンプロビジョニング」を指定していたら、後の方でmkfs.ext4が出来ないことが発覚。
恐らく、使っているNASが低価格モデルなので上手く動かなかったのかと。(同メーカーの上位モデルを使っている方は、シンプロビジョニングでも問題なく利用できている模様。)
そのため、私の方では、シンプロビジョニングを使用しない形で作りなおしている。

--2016/07/06追記
iSCSI LUNをシンプロビジョニングで作成したら、mkfs.ext4が上手く行かなかったと書いた。
具体的には、mkfs.ext4はすぐ終わるのだが、syslog(/var/log/syslog)にエラーが記録されていて、マウントしようとしたらエラーが出る、という状態だ。
どうやら、mkfs.ext4 に -D のオプション(direct I/Oのオプションらしい)を付けると、syslogにもエラーは記録されず、普通にマウント出来るようだ。
既に、iSCSI LUNをフルプロビジョニングで作成して利用してしまっているので、今回はこのまま続けていくけど、どこかのタイミングでシンプロビジョニングのLUNと入れ替えようと思う。

--2016/07/21追記
シンプロビジョニングのiSCSI LUNに対して、フォーマットはmkfs.ext4に-Dを付ければヨカッタんだけど、その後ファイルシステムに対してファイルの書き込みをやったらエラーになった。
どうも何かが違うなぁ…。

--2016/07/23追記
少しわかった。
コチラに記載しているけど、次からはLUNの作り方を少し変えることにする。

2016年6月9日木曜日

iSCSIを利用しようその1

私が使っているNASキットは、通常のCIFS(Windowsファイル共有)とNFSだけでなく、iSCSIも利用することが出来る。
これを使って、Ubuntu Linuxにディスク領域を提供し、データ置き場にしてみたい。
(そもそも、NASキットでiSCSIストレージが使えるから、Ubuntu Linuxを搭載するNUCは120GB程度のSSDにしたんだった)

で、「そもそもiSCSIってナニよ?」ってところなんだけど…。
ご存じの方はご存知の通りなので、軽く読み飛ばして欲しい。

ご存知ではない方へ…
iSCSIとは、「Internet Protocol上にSCSIプロトコル(SCSIコマンド)を流す仕組み」だ。
うん、さっぱりワカランね。

SCSIっていうのは、Small Computer System Interfaceの略で、小型コンピュータ(ココでは、一般家庭のPCや、Interl x86系プロセッサを搭載したサーバ機器等)と各種外付デバイスを接続する規格の一種で、コネクタ形状やケーブル形状といった物理規格、当然電気的な規格(電圧等)、そしてその中を流れるコマンド類まで規格化されている、らしい。

また、色々なSCSIデバイスが生み出されてきたが、その特性からHDDやCD-ROM等のブロックデバイスに使用されることが多かった。
#いわゆる記憶媒体だけでなく、SCSIデバイスのスキャナもあった。
#逆に、SCSI接続のマウス、みたいなキャラクタデバイスは見たことが無い。

こういったSCSI規格のうち、ソフトウェア的な部分(コマンド類)を、今までのSCSIケーブルではなく、IP上に載っけてしまおう、というのがiSCSI規格だ。

SCSIに於ける機器の関係は以下のとおり。

PCにSCSIアダプタを搭載し、そこからSCSIケーブルを伸ばし、HDDがつながっているSCSIコントローラに接続する、という形だ、思う。

iSCSIは、上図の「SCSIケーブル」のところがEtherケーブルになっていて、IPネットワーク上に構築される形だ。
多分こんな形

SCSIで「コントローラ」とされていた部分は、ソフトウェアで実装されており、通常のNetworkにデータが流れるようなイメージになっている。
また、HDD側も同様に、ソフトウェアでコントローラが実装されていて、通常のNetworkに接続されている。
(コントローラをハードウェアで実装しているものもある)

そして、PC側のコントローラを「iSCSIイニシエータ」、HDD側のコントローラを「iSCSIターゲット」と呼ぶ…らしい。(詳細はちょっと違うけど)
これ、「iSCSIクライアント」と「iSCSIサーバ」って表現にしてくれたら分かりやすかったのに。

で、HDD側で容量を適当に切り出して、

その領域をターゲットに紐付けて、

ターゲットごと、イニシエータに提供する(アクセス許可を与える)

それによって、PCにあたかも新しいHDDを追加搭載したように見える。


細かくは色々あるんだけど、ざっくりこんな感じだ。

で、上記の設定を施して、Ubuntu LinuxからiSCSIのディスク領域を使えるようにしよう、ってのが今の思い。

長くなったので、一旦ココまで。
次回分から、実装にとりかかる。

2016年6月7日火曜日

WoLでWindows機の遠隔起動

さて、前回(前回は閑話休題なので、前々回か)の予告通り、Wake on LAN(Wake On LANって書いてたけど、どうやら On は小文字の on が正解っぽい)でWindows機の電源を入れられるようにしよう。

とは言え、WoLを使えるようにするには、WoLを受ける側(Windows機)の方の設定も必要だ。
BIOS/uEFI及びOS側で設定を施す必要が有るらしい。この辺りは、機種、OSによって異なるし、機種によっては対応していないものもある。
なので、各自調べてみて欲しい。
基本的には、BIOSメニューに「Wake on LANの項目があるか?」と「OSから見たNetwork Interface Card(NIC)のプロパティに、Wake on LAN(モノに寄ってはWake On Magic Packet)の項目があるか?」辺りがポイントだ。
軽くググッたら、このページが見つかった。これを参考にWindows機を設定すればいいだろう。
http://www.atmarkit.co.jp/ait/articles/0602/25/news014.html

設定が終わったら、合わせてWindows機のMACアドレスを確認しておこう。
コマンドプロンプトからipconfig /allで確認可能だ。
A1-B2-C3-D4-E5-F6
という形式で確認出来ると思う。ただ、ハイフン区切りではなく、:区切りを利用することが多いので、:区切りでメモしておこう。
A1:B2:C3:D4:E5:F6

Windows機側の設定が終わったら、起動を仕掛けるUbuntu Linux側の設定だ。
WoLは、呼び出し元が特殊なパケットを流し、起動する側が(OSが眠っているにも関わらず)そのパケットを受け取って「お、呼ばれた!」って起動し始めるという流れ。
今回の構成の場合、呼び出し元がUbuntu Linuxで、起動する側がWindows機になる。

その呼び出し元であるUbuntu Linuxが、特殊なパケットを投げられるようになっている必要が有る。

で、調べてみたらそういうことが可能なパッケージが複数種類存在するようだ。
  • powerwake
  • etherwake
  • wakeonlan
  • gwakeonlan
それぞれ得手不得手があると思うんだけど良く分からない。
ただ、コマンドバージョンがwakeonlan、GUIバージョンがgwakeonlanという風に、CUI/GUI両方あるうちのコマンドバージョンwakeonlanを使いたいと思う。

さっそくインストールしよう。
$ dpkg-query -l wakeonlan
(まだインストールされていないはず)
$ sudo apt-get update
$ sudo apt-get --simulate install wakeonlan
$ sudo apt-get install wakeonlan
$ dpkg-query -l wakeonlan
(インストールされた)

さっそく使ってみよう。
の前に、対象のWindows機をスリープにしておこう。(休止状態やシャットダウン状態でも可能だと思うが、スリープからの起動が一番確実なので、まずはスリープから。)

そうしたら、Ubuntu Linuxから以下のように実行してみる。
wakeonlan 対象のWindows機のMACアドレス
具体的には以下だ
$ wakeonlan A1:B2:C3:D4:E5:F6
どうだろう?無事にWindows機は立ち上がってきただろうか?

無事に立ち上がってきたら成功だ。

一応、wakeonlanコマンドは他のパターンもある。

例えば、一度に複数のPCにWoLパケットを投げることが出来る。

この場合、単純にMACアドレスを複数並べるだけだ。
$ wakeonlan A1:B2:C3:D4:E5:F6 A6:B5:C4:D3:E2:F1

呼び出し元(今回のUbuntu Linux)が複数のNICを持っていて、起動したい対象がつながっている方にだけMagic Packetを投げたい場合。

wakeonlan -i (投げたい方のBroad Cast Address) 対象のMACアドレス
具体的には以下の通り
$ wakeonlan -i 192.168.0.255 A1:B2:C3:D4:E5:F6

また、MACアドレスを覚えるのでも大変なのに、どの機器のMACアドレスか?を覚えるのも大変だ。
そのため、ファイルに記載しておいて、そのファイルを読み出すオプションもある。
ファイルの書き方は、wakeonlanをインストールした時に一緒に導入されるサンプルファイルを見るとすぐ分かるはずだ。
サンプルファイルの場所:/usr/share/doc/wakeonlan/examples/lab001.wol

私は、Ubuntu Linux上のホームディレクトリに wol というディレクトリを作成し、そこに「起動したい機器のホスト名」のファイルを作成、そのファイルの中にMACアドレスを記載する形にしている。
#要するに、wakeonlan対象機器が増えれば、その分 wol/* が増える、ということだ。

で、そのファイルの指定方法が以下の通り
wakeonlan -f (ファイル名)
具体的には以下
$ wakeonlan -f wol/filename

これで、Wake on LANでWindows機を起動することが出来るようになった。

あと、休止状態とシャットダウン状態のどちらからでも起動出来るかも確認しておこう。
一応、私の環境では

  • スリープからの復帰:OK
  • 休止状態からの復帰:OK
  • シャットダウンからの復帰:NG

だった。Windows機の設定ミスか、ハードウェア的に実施NGなのか…。
とりあえず、シャットダウンしなければいいので、当面はそっちで逃げる。
どうせ古いPCなので、近いうちに作りなおす予定だからね。

あー、ちなみに起動する対象をWindows機に絞った表現だったけど、別にWindows機に限ったことじゃないから…。

2016/06/07追記
シャットダウン状態からのWoLが出来なかったのは、NICの設定漏れだった。
OS(Windows7)からNICのプロパティで、「シャットダウンからの云々」とかいうパラメータを「オン」にすることで、シャットダウンからのWoL起動も出来るようになった。

2016年6月6日月曜日

閑話休題

しかし、色々と技術系ブログを見ていると、みんな更新頻度高いなぁ。
記事一つ書くのにも、絵を書いたりして色々時間がかかるんだけど、みんな手が早いってことかな?
これぐらいのペースで書けるようになりたいよ…。

sshトンネルを使ったリモートデスクトップその2

前回は、軽くポートフォワーディングについて記載した。
んで、自宅内のWindowsマシンに、外出先からリモートデスクトップ(RDP)接続出来るようにしたい。

ただ、「外部からsshでログインその1」でルータに設定を施したように、Windowsマシンへも転送するようにすれば、別にsshを通す必要は無い。

これなら、RDPのポート番号さえ分かっていれば、簡単に実現できる。

ただこの場合、幾つか問題点がある。

  1. WindowsPCが増えるたびに、ルータのポート転送を追加する必要がある
  2. 当然、WindowsPCが減ったら、ルータのポート転送を削除する必要がある
  3. ポートスキャンをかけると、RDPサービスだということがバレる
  4. アクセス制御が、RDPの仕組み(ユーザ認証)しか無い
  5. 生RDP通信であり、暗号強度が不安(どのような暗号アルゴリズムなのか不明)
  6. ルータにたくさんの穴開けをしないといけなくなる(台数分)
1,2,6は、「そもそもそんなにWindowsマシン作らないよ」ということになると思うが、今後Ubuntu Linuxマシンや、Windowsマシン上に仮想マシンを作って、WindowsOSをどんどん作っていったら…?なんてことを考えると、意外と管理に手間がかかる。
(ま、WindowsOSのライセンスが高いので、そんなに作ることは無いと思うが)

3,4,5は、RDPセキュリティに関連するそのことだが、正直RDPの暗号強度が高いとは思えない。
また、「外部からsshログインその1」「その2」で書いたように、外部からのアクセスはユーザID/パスワードの組み合わせ以外の仕組みも使いたい。

そういった点を考慮しつつ、それでもRDPで接続出来るようにならないか?
というところで出てくるのが、先に紹介した「sshポートフォワーディング(ローカルポートフォワーディング)」だ。
ローカルポートフォワーディングを使って、以下のような接続状況を作ればいい。


と言っても、これだけではイマイチ良く分からない。
なので、実際に動かしながらやってみよう。

条件としては、外(The Internet側)から、家の中のUbuntu Linuxへsshログイン出来ること。
Ubuntu Linuxと同じネットワーク内(家のネットワーク)に、RDP接続を許可したWindowsマシンがいること。(そもそも、WindowsのHome EditionではRDP接続出来ないため、Professionalとかそういうエディションを使うこと)
作業用PC(クライアント)は、Windows+teratermでサンプルを書く。
  1. teratermでsshログインする前の設定
    ログインする前に、teratermの設定でSSHポート転送を有効にしておこう

    設定内容は以下の通りだ。
    • ローカルのポート
      13389
    • リッスン
      127.0.0.1
    • リモート側ホスト
      接続先Windows機のIPアドレス
    • ポート
      3389
  2. sshログイン
    上記の設定を施したら、「OK」ボタンで設定を確定し、今まで通りにUbuntu Linux機へsshログインしよう。
  3. RDPクライアントでログイン
    端末側でRDP接続を起動して、以下のようにログイン情報を入力する。

    • コンピュータ
      127.0.0.1:13389 (sshポートフォワードの設定で入れた「リッスン」と「ローカルのポート」を「:」で繋いだもの)
    • ユーザ
      接続先Windows機のユーザアカウント名
    これで接続すると、通常のRDP接続と同様、パスワードを聞いてくるダイアログが出てくる。(証明書関連の警告も出てくると思うが、そちらは普段通りにOKしてくれればいい)
    また、ここで入力するパスワードは、操作用PC(クライアント)のパスワードではなく、接続先の(自宅内の)Windowsマシンのパスワードだ。

    この時のダイアログをよく見てみて欲しい。
    「これらの資格情報は、127.0.0.1(RDP接続先のIPとして指定したIP)への接続に使用されます。」となっているはずだ。
    このアドレスは、自分自身を示すアドレスのため、「遠隔のWindows機ではなく、自分自身へ接続しようとしている」ことになる。
    これが、ローカルポートフォワーディングの基本的な考え方だ。
    つまり「ローカル(自分自身)への接続を、他のマシンへ転送する」ということだ。
  4. リモートデスクトップ接続に成功する
    成功すれば、リモートデスクトップの画面が出てくるはずだ。

    これで普通に操作が可能だ。
    ウィンドウタイトル部分をよく見てみると、接続先が「127.0.0.1:13389」になっていると思う。これは、RDPクライアントとしては「127.0.0.1:13389」へ接続していると思い込んでいる、ということだ。実際には、sshがパケット転送をしてくれて、自宅内のWindows機へ接続している形になっている。
さてこれでRDP接続が出来るのが確認できた。
そこで、一体どのようなフローで接続できたのかを確認しておきたい。

簡単な図に書いてみたが、先にポートフォワードを有効にしてsshログインを行うことで、作業用PCとUbuntu Linuxの間でポート転送の設定が行われる。
その上で、RDP通信を行うと、上記図のようにRDP通信がsshのコネクション内を通って行く形になる。
そして、そのRDP通信を受けたsshd(sshサーバ)が、指定されたIP:ポートへパケットを転送する、という形だ。
TCP通信のため、当然戻りパケットも発生するが、これは同じ経路を通って流れていく。
ちょうど、sshで作成したコネクションをトンネルにして、他の通信(この場合RDP通信)が流れていくため、「sshトンネル」等と呼ばれている。

この図で記載したが、赤い線で示した区間は、sshによる暗号化通信が行われている。そのため、単純にパケットを読み取られても、それがRDP通信であることは分からない。(ssh暗号を解読して、初めてRDPであることが判明する。)
そのため、非常に強固で安全性の高いRDP通信を行うことが出来る。(当然、sshの暗号アルゴリズムは強固なものを使う前提だ)

更に、ブロードバンドルータ側には、RDPのための設定は一切行っていない。ポート転送はsshのみだ。

最初にsshによる認証が必要になり、こちらは既に公開鍵認証方式のみ利用できる設定にしているため、外部からのパスワード推測系の攻撃を受けても、突破されることは無い。

とまぁこのように、セキュリティレベルをある程度維持したまま、宅内のWindows機へRDP接続が出来るようになった。
以後は必要に応じて、このパターンでRDP接続しよう。

となると、普段電源を落としている or スリープモードにしている or ハイバネーション(休止状態にしている)Windowsマシンを、遠隔で電源入れられるようにしたい。Wake On LANだ。
次はWake On LANに挑戦したい。

今回は以上。