2017/10/20

Flash 27.0.0.170 で WebClient がクラッシュする

普段使ってない vSphere 6.5 の vCenterServer アクセス、WebClient を使おうとした時に、ブラウザ内で「プラグインがクラッシュしました」などと表示され WebClient がいつまでもあがってこず難儀してしまったのでメモ。

これは、WebClient 側の問題で、VMware の KB (2151945) にも記載がある。
残念ながら現時点では解決策はない。ワークアラウンドとしては
  • Flashプラグインのβ版を導入する
  • 前のバージョンの Flash プラグインに無理矢理ダウングレードする
  • HTML5の vSphere Client ないしは C# の vSphere Client を使う
の三つだ。正直どの対応もいかがなものかと思うのだが、vSphere 6.5 の場合これまで使っていた Windows アプリ(C#) の vSphere Client も使えないし、HTML5版はまだばまだメインで使うには辛いのでダウングレードを試してみた。

macOS の Macbook Pro のため、
  1. Adobe のサイトから Flash のアンインストーラをダウンロード、実行
  2. こちらのサイトから 27.0.0.159 の Flashプラグインをダウンロード、インストール
  3. システム環境設定の Flash Playerペインから Flash の自動アップアップデートを禁止
という手順になった。
なお、1. のアンインストーラーは PPAPI の Flash も NPAPI の Flash もどちらも消してしまうので要注意だ。また、上記にリンクされている 27.0.0.159 の Flashプラグインは各OS版がまとめて入っているので少々大きい。使うのは「27_0_r0_159」フォルダのなかの「flashplayer27_0r0_159_mac.dmg」と「flashplayer27_0r0_159_macpep.dmg」だけだ。flashplayer27_0r0_159_mac.dmg が NPAPI 版のプラグインで、flashplayer27_0r0_159_macpep.dmg が PPAPI 版プラグインだ。

NPAPI はもはや Firefox しか使ってない古いインターフェイスのもので、PPAPI は Chrome および Safari が使っているより新しいインターフェイスになる。

私は Chrome を使っていないのと、普段使いの Safari と WebClient へのアクセス用のFirefox を分けていたのもあり、NPAPI 版の「flashplayer27_0r0_159_mac.dmg」飲みをインストールした。

結果、WebClient が使えるようになったが、Flash の利用には制限をかけておいた方がいいのかも知れない。










2017/08/31

仮想マシンとハードウェアクロック

PCの中には時間を刻むハードウェアが内蔵されており、今が何月何日の、何時何分何秒かを把握しております。歴史的な事情からこのハードウェアは単一ではなく、複数のものが存在していたりします。かつては RTC (Real Time Clock)という仕組みだけでしたが、これがあまり精度が良くなかった、使い勝手が悪かったなどの理由で HPET が登場し、CPU には TSC というタイマーが用意されたのでこれを使って時刻を図ることが行われ、また ACPI には ACPI PMT というこれまた時間を計る機能が存在します。

ともあれ、OS は起動時にPCハードウェアのこれらの時計から時間を取得、カウンターを利用して、取得後どれぐらい経過したかを知り、OS自身で時間を管理しております。
例えば Linux の場合は、OSの終了時に hwclock コマンドを使ってPCのハードウェア側にOSが把握している時間をかき込みます。Windows などの場合もおそらくOS終了時に時刻を書き戻しているでしょう。この理由は、PCのハードウェア上の時刻はずれていることがままあるためです。

この PC上のハードウェアの時計は「どの時間帯」の時間を記録しているでしょうか?実はこれは決まっていません。ほとんどの場合、ハードウェアの時計はローカルタイム、現地時間を記録してます。一方、ハードウェアの時計が UTC(世界標準時) であることを前提としているシステムもあります。例えば ESXi がそうです。ESXi は物理ホスト上のハードウェアの時計に UTC での時間をかき込み、起動時も UTC であることを前提に読み込みをします。

一方、Windows や Linux では、OSの内部では UTC をベースに構成されていますが、時刻の表示時には指定されたタイムゾーンを加味して現地の時間を表示しております。ハードウェアの時計に対しても、ローカルタイムがかき込まれているものと考えるのがデフォルトとなってます。先の hwclock コマンドも、OSから読み出した時間を /etc/localtime ファイルの示す時間帯を考慮した現地時間でかき込みます。


● 仮想マシンの時間

VMware の場合、初回起動時には ホストOSの時間がそのまま使われます。VMware Player や Workstation, Fusion では、新しい仮想マシンを作成して起動、BIOS設定画面に入ると現地時間での時刻が表示されます。
かつての ESX でもそうでした。ESX の場合、COS(サービスコンソール) の Linux 上の /etc/localtime を参照して仮想マシンの仮想的なハードウェアの時計に「ローカル時間」をかき込んでました。
ESXi の場合、/etc/localtime のようなタイムゾーンを把握する枠組みがありません。vSphereClient などで時間を見ると現地時間が表示されますが、これらはクライアントソフトウェア側で変換して表示しているもので、ESXi との時間のやりとりは UTC をベースとしています。

このため、ESXi で仮想マシンを作成、初回の起動時にBIOS時間を見ると、UTCで表示されます。日本の場合、9時間前の時刻が表示されていることになります。

新規に作成した仮想マシン
17:42 頃のものだが、8:42となっており、初回起動時は9時間ずれてるのが分かる
二度目以降の起動では少々事情が異なります。ゲストOSが終了時に(仮想の)ハードウェアの時計に時間を設定した時、VMware はそのかき込まれた時間と自身が把握している時間を比較、「差分」を検知します。ESXi の場合、上のOSが「日本時間」をかき込んでくると、9時間早い時間がかき込まれたことを検知します。この差分は nvram ファイルに保存されます。

二度目以降の起動時は、自身の時刻にこの差分を加味した時刻を、仮想マシンのハードウェアの時計としてセットします。先の例の場合、UTCに9時間を加えた時刻をハードウェアの時計とします。これは日本時間になります。ゲストOSはこの時間を読み込みますので、結果として正しい時間になります。
この挙動は VMware のこのドキュメントの「Virtual CMOS RTC」に記載されています。


● 他のハイパーバイザの仮想マシン

Hyper-V の場合は Windows の時刻管理に準じるためあまり深いことを考える必要がありません。

今回、この記事を書く動機になったのは KVMについてのハードウェアの時計がどうなってるかを調べたことからでした。KVM では、仮想マシンのモニタである qemu-kvm コマンドの引数 -rtc にどう設定するかによって決まります。主に以下2つのオプションが使われます。

  • clock : 時刻を何処で管理するか
    • clock=vm : 仮想マシン側で独自に時刻を管理する
    • clock=host : ホストの時間をそのまま利用する
  • base : 仮想マシンの起動時、(仮想の)ハードウェアの時計を何処に設定するか
    • base=2010-12-03T01:02:00 : 2010/12/03 01:02:00 に設定する
    • base=utc : UTCでの現在時間に設定する
    • base=local : ホストOSのタイムゾーンを加味した現地時間に設定する

OpenSUSE のドキュメントの例をみると
qemu-kvm [...] -rtc clock=vm,base=2010-12-03T01:02:00
となってますが、これは「時刻は仮想マシンで独自に管理」「2010 12/03 1:02:00 をハードウェアの時計の開始時間」として設定することを意味します。

(AHVについては記述が誤っていたため一旦削除しました。あらためて正しい情報を書きます。)

2017/04/06

【余談】Hammerspoon に移行

手元の Mac の OSをアップデートしたら Karabiner が利用できなくなってしまった。
どうも  macOS Sierra に非対応のとのこと。Karabiner はカーネルにモジュール(KEXT)を読み込ませ、カーネル内部のキーイベントを操作することでキーバインドの変更を実現している模様だが、そのためカーネルの変更に弱い面がある。

一方の Apple はセキュリティ面やOSの安定稼働の面から、KEXT による拡張を抑制する方向にある。Microsoft も 64bit 移行やOSのアップグレードの機会を通じて電子署名されていないデバイスドライバはロードできないようにしているし、iOS のようなモバイルデバイスのOSでは、もはやカーネルにモジュールを追加することすら不可能になっている。

幸い、Karabiner では Karabiner Elements という新しいキーリマップソフトウェアを開発、そこから従来の Karabiner の機能を追加していく形で刷新するようで、これは期待が持たれる。とはいえ、一からの作り直しなのでしばらくは Karabiner なしの生活に耐えなければならないようだ。

私が Karabiner を使ってる理由は、実のところ「Microsoft Office で Emacs キーバインド(のサブセット)が使いたい」 につきる。Karabiner Elements では現在のところアプリケーションごとのキーマップというのは実装されてないので、これは対応できないことになる。

いい加減 面倒になってきたので色々探して試した結果、Hammerspoon を利用することに落ち着いた。Hammerspoon はキー入力などのイベントを Lua という言語を使ってカスタマイズするもので、単なるキーリマップ以上の操作もできるようだ。
また、Accessibility API を通じてキーイベントを取得、操作を行う。公式のAPI を通しているため、OSのアップデートによる影響も(KEXTを使うのに比べると)低い訳だ。

Hammerspoon は ~/.hammerspoon/init.lua というスクリプトを読み、これに応じて処理をおこなう。私のスクリプトは以下の通りだ。

詳細は、この gist のコメントを見てほしい。

2017/02/18

【TIPS】外付けSSD

普段は Macbook Air (2012) で VMware Fusion を使っていますが、本体のストレージ容量が256GBしかないのでやりくりには苦労します。仮想マシンもインストール用ISOイメージもGB単位で容量を食うので、こまめに掃除しないとあっという間にあふれてしまいます。

そこで、前職の頃から外付けSSDを接続してこちらに仮想マシンを配置、使用しております。
こんな感じです。

外付けSSDドライブ。下の袋は函館に旅行したときに買ってたものを利用

Transcend の TS512GESD400K という 512GB の外付けSSDで、今だと 25,000円程度で入手できます。前職では会社に買ってもらって利用していたのですが退職時に会社支給の Macbook Air と共に返却、ただ使い勝手が良く気に入ってたので退職後、自分でも買い直した次第です。(なお、Macbook Air はたまたま知己が買い換えで余らせてたものを引き取ったのですが、奇しくも前職で使ってたのと同じ2012年ものとなりました。)

仮想マシンやISOイメージはこちらに格納して、Fusionを利用するときだけドライブを接続して使ってます。小さく軽いため鞄に入れてても気になりませんし、USB3.0のポートに繋いでいる限りは、内蔵SSDで仮想マシンを起動しているとの体感的な速度差は感じません。

唯一の注意点は、付属のUSB3.0ケーブルを使うこと、って事ですか。高速通信をがんがんかけるので、品質の良くないケーブルを使うとたちまち不安定になります。
付属品は太くて取り回しが少々不便なのですが、そのぶん安定しております。

検証ごとにリンククローンで仮想マシンを作ってるせいもあるのですが、この中に常時20ないしそれ以上の仮想マシンが入ってます。

Macbook Air の場合(というか最近の Mac のノート全般で) 本体のストレージ交換は酷く面倒な上、交換用のドライブも高価です。

若干はかさばりますが、リーズナブルな価格での増量ができる、外付けSSDは悪くない選択肢かと思われます。





Windows Server 2016 仮想化ベースのセキュリティ

Windows Server 2016 では様々なレイヤーでのセキュリティの強化が実装されていますが、その中の一つに「仮想化ベースのセキュリティ」と呼ばれる一連の機能があります。

機能名としては「Device Guard」や「Credential Guard」など呼ばれるものです。その詳細についてはマイクロソフトのこちらのページをご参照頂ければと思います。

ポイントとしては上記ページの以下の図が分かりやすいかと思います。

https://technet.microsoft.com/ja-jp/library/mt483740(v=vs.85).aspx より引用


これは Credential Guard の例ですが、ドメイン環境でのサインイン時に、ActiveDirectory から得られた認証情報(Credentials)は、通常ですと OS のメモリ空間のどこかに存在します。このため、カーネル内を含めメモリを読むことができる特権を得られれば、それをメモリから読み取り、奪い取ることができてしまいます。そのアカウントのパスワードを知らずとも、得られた認証情報をつかうことでそのユーザーとしてドメイン内のリソースへアクセスできてしまいます。

Credential Guard を有効にすると、Hyper-V による仮想化を利用して認証情報が切り離されます。 (厳密には異なりますが)ざっくりとしたイメージとしては本来の Windows Server を実行する仮想マシンと、認証情報だけを抱えた小さな仮想マシンの2つが Hyper-V にのっかっているという感じです。

仮想マシン同士のメモリ空間はハイパーバイザーによって分断されており、ある仮想マシンのメモリ空間の端から端までアクセスしても、他の仮想マシンのメモリ空間にはアクセスできません。これらは Intel-VT や SLAT といったハードウェアの機構により実現されており、ハイパーバイザー上のゲストOSやアプリケーションでは越えることができません。
つまり、別空間に切り離された認証情報を従来と同じ方法では盗めない、切り離された秘匿情報は正当なAPIを通じてのみアクセスが許可されます。

これが、Credential Guard です。また、仮想化ベースのセキュリティの一例となります。


要件は冒頭のページを見て頂ければと思いますが、ざっくりとは以下の感じです。
  • OS: Windows 10 Enterprise ないしは Windows Server 2016
  • CPU: 64bit CPU, Intel VT (AMD-V)および SLAT対応
  • TPM: 1.2 ないし 2.0 対応 (1.2の場合は Windows10 1511以降)
あと、セキュアブートも必要となってきます。

物理PC上での利用が前提(Windows 10 の場合仮想マシン上はサポート外)ですが、Windows Server 2016 と Windows 10 で可能となった、nested Hyper-V を使えば仮想マシン上でも試すことはできます。

そこで、実際に仮想マシンで Credential Guard を有効にしてみました。


● 事前準備

まず、Hyper-V 上で G2 仮想マシンを作成します。
従来型の G1仮想マシンは BIOSベースのファームウェアで、ブートドライブとしてIDEのエミュレーションが、デフォルトのNICもエミュレーションベースのものになります。物理PCとの互換性は高いのですが、性能的に制約がある次第です。

G2 仮想マシンは UEFIベースのファームウェアで稼働し、IDEやNICのエミュレーションをしません。高性能の代わりに Hyper-V に対応していないOSはインストールできません。もっとも、Windows ならば Vista 以降、Linux でも最近のものなら標準で Hyper-V 向けのデバイスドライバーを持っており後から統合サービス(IC)をインストールしなくても良くなってます。

あと、重要なポイントとして、G2仮想マシンは UEFI上でのセキュアブートを実現しているという点です。今回はセキュアブート環境を用意したいために、G2を選択しています。


Windows Server 2016 をインストールして、Windows Update の実行など一般的な処理をおこなっておきます。別に ServerCore でも構わないのですが、後での動作確認を楽にするためにデスクトップエクスペリエンスありを利用しております。

一旦シャットダウン後、Enable-NestedVM.pl を利用して仮想マシン上での Hyper-V の実行を許可します。方法がよく分からない場合は、こちらの動画を参照してください。

その後、仮想マシンを再び起動し、Hyper-V の役割を有効化します。
以前の Windows10 ではこのときに「分離ユーザーモード」 の機能も有効化する必要がありました。
が、Windows Server 2016 および最近の Windows10 では分離ユーザーモードの選択肢が存在しません。OSに標準組み込みになったので特に選択する必要眼漠なったようです。

Hyper-V の役割のインストールに伴い再起動が発生するので、一回再起動しておきます。

これで、Credential Guard を有効化するための準備は完了です。


● Credential Guard の構成

Credential Guardの設定はグループポリシーを通じて行います。今回はドメインに参加していない1台だけのため、mmc.exe を起動、スナップインの追加でグループポリシーの編集を追加、ローカルコンピューターポリシーを編集しますが、ドメイン環境下の場合、GPOを配布することでドメイン下のメンバーサーバなどにまとめて一気に設定をすることもできます。

ともあれ、設定するポリシーは以下になります。



「コンピューターの構成」->「管理テンプレート」->「システム」->「DeviceGuard」の下に、「仮想化ベースのセキュリティを有効にする」があります。これをダブルクリックしてます。



まずは上のラジオボタンを未構成から「有効」にします。

次に、「プラットフォームのセキュリティレベルを選択する」を今回は「セキュアブートと DMA保護」から、「セキュアブート」だけにします。前者のDMA保護は VT-d (ないしは IOMMU) で実現されていますが、Hyper-V上の仮想マシンではVT-d/IOMMUのエミュレーションは行われていないためです。

OKをおして保存後、ポリシーを確実に読み込ませるために、OSを再起動しておきます。
ドメイン環境でGPOをドメインコントローラから配信している場合は、再起動前に gpupdate /force を実行しておくといいかもしれません。
(GPOは更新されて即時に展開されるわけではなく、ある程度時間をかけて浸透していきます。クライアント側から gpupdate を実行することで、強制的に最新のポリシーをドメインコントローラに取りに行かせるわけです。もちろん、検証や数台のサーバからの実施ならばいいのですが、大量のサーバから gpupdate で即時取得を繰り返すのはドメインコントローラに負荷がかかるのでご注意ください。)
 
これで構成は完了です。


● Credential Guard の確認

では実際にメモリをダンプして Credentail を読み取れなくなったか確認してみましょう...、ではさすがに洒落にならないので、UIから動作確認します。

コマンドラインなどから msinfo32.exe を実行すると、システム情報というウィンドウが立ち上がります。左側のツリーでは標準選択されてている「システムの要約」をそのまま、右側の一覧をスクロールダウンしてくと、最後の方に Device Guard から始まる情報がいくつか記載されています。



まず、「Device Guard 仮想化ベースのセキュリティ」 が「実行中」になっているかがポイントだ。構成されていない場合はこれが「無効」になっており、構成されていても条件が整わなくて起動していない場合は「有効(停止中)」などになります。

次の、「Device Guard の必要セキュリティプロパティ」 が、仮想化ベースのセキュリティを実行させるにあたり必要となる機能で、その次の「Device Guard の利用可能なセキュリティプロパティ」が、実行している環境が提供できる機能の一覧になります。

つまり、必要側に書かれてる機能が利用可能側に記載がない場合、仮想化ベースのセキュリティは機能不足で稼働しないものになります。

構成済みの Device Guard セキュリティサービス が、GPOなどで構成したサービスです。ここでは Credential Guard が記載されていることが分かります。一方、その下の「実行中の Device Guard セキュリティサービス」が実際に稼働しているサービスを指します。こちらも Credential Guard の記載がある、つまりは Credential Guard が有効である事が分かります。

また、上から9行目ほどに「セキュアブート」がありますが、これが「有効」なものは、UEFIからはじまりブートローダー、OS、デバイスドライバと起動時から順に読み込まれていったモジュールがすべて有効な電子署名が施されている、改ざんされていないことを示します。


●うまく構成できていない例

たとえば Hyper-V は有効にしたものの、GPOをまだ設定していない場合には、以下のように「仮想化ベースのセキュリティ」 が単に「無効」と表示されます。




プラットフォームのセキュリティレベルを「セキュアブートとDMA保護」にしたにも関わらず、VT-d, IOMMU などがない場合は、以下のようになります。


必要なセキュリティプロパティに「DMA保護」 が入っていますが、その下の利用可能なセキュリティプロパティに「DMA保護」はありません。条件を満たさなかったためセキュリティサービスとして Credential Guard が表示されていないのが分かります。


また、VMware Fusion で構成を試してみた例がこちらです。Fusion でも nested VM を有効にして、Hyper-V をインストールしたのですが、Credential Guard が有効になってません。よくよく見るとDMA保護だけではなく、仮想化の基本サポート以降の機能がまったくありません。従って、Credential Guard は元より、仮想化ベースのセキュリティも実行されていません。


そもそも、VMware の仮想マシンではセキュアブートが使えません。
例の上から9行目のセキュアブートの項目を見ても「サポートされていません」になっているのが分かります。

セキュアブートが有効でない都言うことは、OS起動時のブートローダを改ざんしたり、間にプロセスを介入させることで仮想化ベースのセキュリティを有効化する前に悪意あるコードを混ぜ込むことが可能となってしまいます。いくらハイパーバイザーでセキュリティを保とうとしても、あく怒るコードの方が先にハイパーバーザーとして起動されてしまう恐れがある訳です。

そのためか、これまでみてきたように仮想化ベースのセキュリティでは、セキュアブートが「必要なプロパティ」として要求されています。

2017/02/09

vExpert 2017 受賞しました

vExpert 2017 受賞しました。どうもありがとうございます。

https://blogs.vmware.com/vmtn/2017/02/vexpert-2017-award-announcement.html

昨年1年を振り返るとやはりあまり活発な活動をしてたとは言えないので、今年はもう少し活動できれば、とか思っております。

2017/01/18

[TIPS] VMware Fusion で無差別モード時の認証を行わないようにする

VMware Fusion Professional の場合、環境設定にあるネットワークの設定にて、「無差別モードに入るには認証が必要です」のチェックを外すことで、仮想マシンが Promiscous Mode に入ろうとしたときに表示される認証を省くことができる。

ネットワークの設定
このパネルは Professional でのみ表示される

チェックを外すと、警告が出るので「続ける」を押す
この警告にもあるとおり、無差別モードを仮想マシンに許すと、その仮想ネットワーク内の通信や、ブリッジの場合はそのネットワークを流れる通信を確認することが可能になり、さらには偽装したパケットの送信もできるようになる。非常に危険なので通常は無差別モードを設定しようとした瞬間に認証がかかって、Fusion の利用者にあらかじめ確認を取るようになっている。

しかし、たとえば ESXi をFusion 上の仮想マシンとして実行する場合、「そのネットワークからくる ESXi 上の仮想マシンのMACアドレスのパケットを受け取る」「そのネットワークに ESXi 上の仮想マシンのパケットを送り出す」という操作、つまりは仮想マシン自身以外のMACアドレスのパケットの読み書きが必要になり、無差別モードが必須となる。

毎回確認されるのも面倒な場合は、このチェックを外すのもいいだろう。


なお、チェックを「外す」事で、/Library/Preferences/VMware Fusion 以下に、 promiscAuthorized という空のファイルが作成される。

promiscAuthorized ファイルが存在する
言い換えれば、この空のファイルを作れば無差別モード時の認証は行われなくなる。

このため、ネットワークの設定パネルのない、通常の VMware Fusion でも以下のコマンドで無差別モード時の認証をなくすことができる。

sudo touch "/Library/Preferences/VMware Fusion/promiscAuthorized"

パスが空白を含むので、ダブルクォートでくくるのを忘れないこと。