2017年11月6日月曜日

どどっと400(1995)

中野F店J館にて「どどっと400」を発見。1995年に3本セットで発売された「ニコンおもしろレンズ工房」うちの一本だ。詳しくはニッコール千夜一夜の記事を参照されたし。現代のトイレンズはわざとポンコツな描写を狙ったものが主だが、当時のコレは簡素な構造ながら良く写ることを狙ったものであり、そういう意味では今のトイレンズとは訴求方向が異なっている。


ニコンおもしろレンズ工房 どどっと400 (1995)
400mm F8.0

1983年頃、これに似た構造ものでケンコーの「クローズアップ鏡胴セット」というものを持っていた。当時のクローズアップレンズは現在でもまだ持っているが、肝心の鏡胴の方を紛失してしまい、今となってもうは遊ぶことができない。クローズアップ鏡胴セットは52mm径のクローズアップレンズ(AC No.3・AC No.5・No.2)を使い、330mm F6.3と200mm F4、125mmのソフトフォーカスレンズを作ることができた。簡素なレンズとカメラマウントが取り付けられた金属製の筒と、ヘリコイドの代わりに斜めに溝があけられた内部のチューブでフォーカシングするというどどっと400の機構は、クローズアップ鏡胴セットにそっくりだが、どどっと400はクローズアップレンズを流用するのではなく、専用の2群4枚のテレフォトタイプの光学系が最初から組み込まれている。テレフォトタイプなので焦点距離の割に全長が短く、鏡胴を前後に分割してコンパクトに収納することができる構造になっているが、光学系が組み込まれた前部鏡胴は分解することはできない。前玉のフィルター径は52mm・F値はF8.0で、ケンコーのように自作絞りを入れる構造は無い。マウント部分はプラスチックである。

発売時は他の二本のレンズ(ぎょぎょっと、ぐぐっと/ふわっと)とともに、Nikonロゴやエンブレム風のステッカーが同梱されていたらしいが、現在は1000円の値札が奢られており無常観を盛り上げている。

カメラボディにに装着した状態。
週末は丁度良い天気だったのでこのレンズを持って出かけてみる。ファインダーは暗く、ミラー切れで視野枠上方にはカゲリが出る。フォーカスエイドは使えないものの、マット面でフォーカシングをすることができる。フォーカシングチューブの操作は滑らかではないが、クローズアップ鏡胴セットよりはガタも少なく操作がしやすいように思える。
望遠レンズの拡大威力と言っていいのだろうか、そういうものを感じる目的で、50mmで撮影したものとどどっと400の画像を比べてみよう。

f=50mm F8.0
Nikon D800E, AF-S NIKKOR 24-70mm F2.8G ED

f=400mm F8.0相当
Nikon D800E, おもしろレンズ工房 どどっと400

シャープ補正+軸上色収差補正+コントラスト補正

当たり前だが、400mmなので50mmに比べ8倍の倍率で遠方が拡大されて写る。と同時に、ナノクリズームの圧倒的なコントラストにも関心する。どどっと400はレンズ内面が曇っており、ハレ切りはしているものの猛烈にコントラストが低い。解像力は素晴らしいわけではないが、周辺光量不足もなく周辺まで画質が均一で、その点では良く写っている。下の画像は、Caputure NX-Dで現像時に軸上色収差とコントラストを補正し、シャープのパラメータを変更したもの。
Amazonにカニ目レンチを注文したので、内面のクモリを清掃してから、後日また撮ってみようと思う。モノコートレンズとはいえ、2群4枚というシンプルな構成で、鏡胴内も通常のレンズと変わらず丁寧に溝が掘られ艶消し塗装が施されている。レンズを拭けばもっと良く写るに違いない。

2017年9月19日火曜日

台風一過

朝起きると空気のよどみが吹き飛ばされ晴れ渡っている。絶好のシーイングを期待して望遠レンズを担いで出かけてみたが、思いのほか暑くなり、午後になるとややガスっぽくなった。




 Nikon D800E, AF-S NIKKOR 200-500mm f/5.6E ED VR

2017年9月1日金曜日

Raspberry Pi Zero Wでワイヤレスシリアルコンソールサーバー

Raspberry Piを使って、4G LTE回線とインターネット経由で、ワイヤレスアクセスできるシリアルコンソールサーバーを作成した。ルーターやサーバーなどのネットワーク機器のシリアルコンソールにリモートアクセスして、いわゆるOOBM(Out-Of-Band-Management)というオペレーション行うための装置だ。こういった用途には、かつてはアナログモデムと電話回線が使われていたが、専用のアナログ電話回線を用意しなければならず、コスト的にも割高なこの方法は現代では敬遠されつつある。ルーターやサーバーなどのネットワーク機器は、通常TelnetやSSH接続を使ってインバンドで管理されるが、回線障害や設定ミスなどによりリモートログインができなくなってしまった場合や、機器の導入時に専任の担当者が遠隔操作で初期設定を行う場合などは、こういったOOBMの手段が有用となる。3G/4G回線を使う「セルラーモデム」という専用のデバイスがあるそうだが、産業用などに使われる高価な代物のようで、一般のオフィスはもちろんデータセンターなどでもあまりお目にかかったことは無い。代替手段としてはリモートデスクトップ経由でのアクセスや、Ethernet経由のコンソールサーバーなどがあるが、セキュリティ上の事情や責任分界点の関係で、リモートサイトでこういった手段が使えない場合もある。今回は、こういった課題を解決することができる手段の一つとして、安価に手に入るRaspberry Piとモバイルルーターを使ったOOBMデバイスを作成したのでご紹介したい。なお、具体的なビルド方法については、公開するための整理ができていないので、恐縮ながら今回は割愛させてもらう。

リモート側デバイス。今回のシステムでは「モバイルコンソール」と呼ぶ。
Raspberry Pi Zero Wを使ったもの(上)
Raspberry Pi 1 Model Bを使ったもの(下)

最近日本でも入手ができるようになりつつある「Raspberry Pi Zero W」。

GPIO端子のひとつにステータス表示用のLEDを接続し、サーバーとのSSHトンネリングが完了したらこれを点灯させる仕組みだ。Raspbianを使う動作環境や動作用のスクリプトはRaspberry Pi各モデルに共通なので、有線LANポートのついたこれまでのRaspberry Piモデルも使用できる。最初のデバイスは、デスクの引き出しで眠っていたRaspberry Pi 1 Model Bを使って作成した。リモート側のデバイスは、Raspberry Pi本体と電源、USBシリアル変換ケーブル、それにモバイルルーターによって構成される。このセットを今回は便宜上「モバイルコンソール」と呼ぶ。(もっと素敵な呼び方があれば変更してもいい)
Raspberry Pi 1 Model Bは無線LANを内蔵していないので、Wi-Fiでインターネットに接続するにはUSBの無線LANアダプタが必要になる。Raspberry Pi Zero Wは無線LANはあるが有線LANポートを持たないので、有線接続をしたい場合にはマイクロUSB-RJ45のLANアダプタが必要になる。現在主流のモデル、Raspberry Pi 3 Model Bは有線LANポートと無線LANアダプタを内蔵しているのでこれが望ましいが、消費電力がやや大きいため別途専用のACアダプターが必要になる。

資料用に作成したスライド。

モバイルコンソールのRaspberry Piは、起動後自動的にインターネット上の中継サーバーにSSHトンネルを張る(掘る?)仕組みになっている。今回のシステムでは接続の中継に使うこのサーバーを「Pi Server」と呼ぶことにした。当初、Pi Serverは先日の企画でも使った趣味用途で個人契約しているVPSを使っていたものの、本来このサーバーではパスワード認証を有効にしたくない。しかし、仕事で使うことを想定すると鍵を使っての認証は手順が煩雑すぎ、利便性を優先するとやはりパスワード認証が好ましい。そこで、当初リモート側デバイスとして使っていたRaspberry Pi 1 Model Bのハードウェアを流用し、独立したこの目的専用のサーバーを用意することにした。中継用のPi ServerはSSHDが動作するLinuxシステムなら何でも良いが、インターネットから接続するためのグローバルIPは必要になる。

図中のIPアドレスは架空。

ユーザーがモバイルコンソールへ接続するには、PuTTYやTeratermなどのSSHクライアントを使ってPi ServerのインターネットアドレスへSSH接続をおこなうだけでいい。接続に必要なパラメータは「Pi ServerのIPアドレス」「ユーザー名」「パスワード」「ポート番号(443固定)」だけだ。
Pi Serverへログインする際のユーザー毎に、ループバック接続をするポート番号を各々割り当て、対応するモバイルコンソールデバイスへ接続させる仕組みになっている。これにより、一台のPi Serverを多数のモバイルコンソールの中継に使うことができる。今のところモバイルコンソールと呼んでいるが、多数のリモートサイトに常設するような使用方法を想定してもいい。その場合、同時に稼働できるモバイルコンソール数の上限は、サーバーがSSHトンネリングのTCPセッションを同時にいくつ維持できるかによるため、実際のところは不明だが、数十か数百あたりではないかと思う。SSHサーバー側は公開鍵認証にも対応させているが、利便性を優先しパスワード認証でのログインを有効にしてある。トンネルを張る際のSSHセッションの非対話ログインにはsshpassというプログラムを使っており、このプログラムはSSHサーバー側がパスワード認証でも公開鍵認証のパスフレーズ付きまたはパスフレーズ無しのいずれの場合でも動作するので、サーバー側の認証方式を変更してもモバイルコンソール側のスクリプトに変更の必要は無い。モバイルコンソール側のターミナルソフトにはLinuxの「cu」を使っている。これの代わりに「jerm」というプログラムを使えばシリアルポートをTCP接続に変換することが容易なのだが、jermはTCP接続経由では「ブレーク信号」を送ることができないことがテスト中に分かったため、採用を断念した。ブレーク信号の送信は、CISCOルーターのブート時にROMMONに入るために必要な操作で、これができることは重要である。

モバイルコンソール側とこれにリモート接続する管理者側では、ファイアーウォールやルーター上にポート開放などの設定を追加する必要は一切無い。インターネット上のPi Server(固定IPまたはDDNS)に対してモバイルコンソール側と管理者側の両側から、TCP 443ポートへのTCPセッションを外向きに開始するだけなので、モバイルルーターやブロードバンドルーターのIPマスカレードNATを超えて、また片方あるいは双方がファイアーウォールの内側にあっても接続が可能である。TCP 443ポートはTCP 80番同様、極めて一般的なポートなので、企業内のファイアーウォールでも外向きの接続がブロックされることはほぼ無い。(FWによってはダメな場合はある)

接続の仕組み。

その他の機能。

モバイル回線やインターネット接続が不安定な場合や、DHCPのリース期限切れなどにより、モバイルコンソールとPi Server間のトンネルセッションがダウンする場合がある。その場合に備え、モバイルコンソール側ではスクリプトを使って自動的にトンネルを復旧させる仕掛けを設けてある。実はここが最も苦労した点で、当初はnmapとpgrepを使ってポートが開いているかどうかと、プロセスが存在するかどうかによってチェックをしていたが、トンネルセッションを起動したSSHプロセスが残っているのに通信できない場合があったり、リモート側の回線が切れているのにサーバー側のTCP接続が残留し続け、回線復旧後に自動再接続をしてもポートのバインドに失敗したりなど、通信できないといっても色々なパターンがあり、トンネルのダウンを客観的に検出するのが結構難しかった。確実に異常を検出するために、最終的に行ったのは「トンネルループバックテスト」と呼んでいる方法だ。これは待機時に張っているトンネルとは別に、一時的にチェック用のトンネルをサーバー向けに作成し、ワンラインでSSHコマンドの後ろに追加したコマンドをサーバー側で実行させ、待機中のトンネルを折り返してリモート側のディレクトリにテンポラリファイルを作成させる方法である。コマンド実行後にテンポラリファイルが存在しなければトンネルが機能していない、というわけだ。これにより、トンネルが正常に機能しているかどうかを割と確実に検出することに成功した。
その他の機能としては、モバイルコンソールになるRaspberry Piが有線LANポートを持っている場合は、無線LANでのインターネットアクセスと合わせ、ルーターとして機能させることができる。モバイルコンソールデバイスをサイトに常設することで、メインの通信回線がダウンした場合のバックアップ回線に4G LTEインターネット回線を割り当てる「セルラーフェイルオーバー」用のデバイスとしても同時に使用することができる。Raspberry Piをルーターとして動作させた場合、回線側が高速でも実行スループットは4.5Mbps程度のようなのであまり高速とは言えないが、バックアップ用途であればこれで十分な場合もあるだろう。なお、有線LANポートはトンネルを張るためのインターネット接続にも使用できる。ブロードバンドルーターのLANポートや企業内の既存のイントラネットなどに有線接続し、NATやファイアーウォールを通ってインターネットへ抜けることが出来さえすればトンネルを張ることができる。有線LANポートのIPアドレスは、Raspberry Piの起動時にDHCPでの取得が試行され、DHCPサーバーからの応答がなければあらかじめ設定済みの固定IPアドレスになるようにしてある。モバイルコンソールはFTPサーバーも有効にしてあり、有線LANポートからFTPサーバーへアクセスする際はこの固定IPを使えばいい。

今回、SSHDが作動する中継サーバー「Pi Server」はADSLのインターネット回線に接続した。この回線は、ISPの固定IPアドレスオプションを契約しているが、DDNSを使う方法でも構わない。回線事業者が提供するモデムルーターに設定を追加し、インターネットからTCP 443宛の接続をLAN内のPi Serverに転送するわけだが、今回使ったこのNTTフレッツADSL用のモデムルーター(NVIII)は、ポート番号を指定してLAN内の任意ホストへ転送する機能が無いらしい。プロトコルに関わらずDMZとしたLAN内の任意のホストへ転送することはできるようなので今回はその機能を使うことにした。Pi ServerはSSHD以外のポートは開いていないが、念のためiptablesの設定でTCP 443宛の接続以外はDROPするようにしている。

モバイルコンソールを使用するためにPi Serverに接続したユーザーは、.bash_profileの記述によってログイン後すぐにSSHコマンドが起動されてモバイルコンソールへ転送され、ログイン後にまたすぐに.bash_profileで自動的にcuプログラムが起動される仕組みになっている。仕組み上、Pi Serverからモバイルコンソールへの転送中に^Cを連打すればPi Serverかモバイルコンソール上のコマンドプロンプトに抜け落ちてしまうことは可能で、また、cuプログラムにはシェル経由でコマンドを実行することができてしまう$!エスケープシーケンスがあるため、想定しないシェルコマンドがユーザーによって実行されるのを防止するために、Pi Server側とリモートコンソール側で使用されるユーザーは、rbashによるコマンド制限を行っている。Pi Serverには通常のシェルコマンドを実行することができる管理用のユーザーも用意してあり、トンネルを通ってリモート側のRaspberry Piにログインすることができる。これを使って、新しい無線LANアクセスポイントを使う場合のパラメータ設定や、cuコマンド起動時のシリアルポートのスピード変更などを行う。

バージョンアップ履歴。

SSHトンネリングを使ってNAT/FW超えする機能は当初からあったが、初期バージョンは一台のモバイルコンソールにしか対応していなかった。その後のバージョンアップで、複数デバイスへの対応やトンネル切断時の再接続方法の見直し、GPIOを使ったステータスLEDの実装、パスワードファイルの暗号化や公開鍵認証への対応などを行い、最終的には中継サーバーもRaspberry Piを使う現在の方式にした。
途中のマイナーバージョンアップでは、TTSエンジンとWaveファイルによる音声ステータスの機能をひそかに実装した。これはアナログオーディオジャックのあるRaspberry Piモデルで有効で、起動時にDHCPで取得したインターフェースのIPアドレスやESSID名、トンネルの接続状況や再接続中のステータスなどをイヤホンや小型スピーカーから音声出力させるものである。日本語にはTTSエンジンOpen JtalkとMMD Agentの音響モデル「メイ」、英語にはESPEAK TTSを使っている。なお、Raspberry Pi Zero Wについては、せっかく付いているBluetooth経由での音声出力も実験してみたが、接続が不安定でペアリングの操作もたびたび必要なことから実用的ではなく、実際のところGPIOに接続した一灯のLEDでも十分に用を足すので、Raspberry Pi Zero Wではしゃべる機能は使っていない。
また、最新のバージョンでは、シリアルコンソールを使用中のユーザーが一文字づつタイピングしている様子を、別のセッションからリモートデスクトップの画面共有のようにリアルタイムに表示することができる機能を装備した。ちょっと不思議な機能だが、方法は意外と簡単で、cuコマンドにはログを出力する機能が無いが、scriptコマンドを使えばログの記録が簡単にでき、-f オプションを付けることでファイルがリアルタイムに保存されるので、別のセッションでPi Serverの管理用ユーザーにログインし、記録中のログファイルをtailfコマンドで表示させるだけである。

2017年8月28日月曜日

D850正式発表

ニコンの新型ボディD850が発表になった。D810は購入を見送ったので今回は買う。入手出来次第お知らせする。


週末に「ファンミーティング」なるイベントがあり、物見遊山で行ってはみたものの人がいっぱいでD850には触ることができなかった。

2017年8月20日日曜日

パスワード管理ソフトKeePassのデータベースを自前サーバーに置いてSFTPで同期する

KeePassでパスワード管理する前に、まずはブラウザが保存しているパスワードがないか確認して、あればすべて削除する。
ブラウザが保存しているパスワードを確認するにはこれを使う。
WebBrowserPassView v1.86 
TeamViewerが乗っ取られた際に、このWebBrowserPassViewをインストールされる例もあるらしいので、ブラウザでパスワードを保存していると大変なことになる。
ブラウザが保存しているパスワードがあればこのウィンドウに表示される。

ブラウザが保存しているパスワードを削除する
Chromeの場合
設定→ユーザー・同期→同期の詳細設定で、パスワードの同期をオフにする。

設定→一番下の詳細設定→パスワードとフォーム・パスワードを管理で保存されているパスワードをすべて削除し、パスワードの管理をオフにする。
「Chromeにログインし、パスワードを同期させている場合」は、自分が使っている他のPCのChromeにもパスワードが同期されてしまい各PC内に保存されているので、
同期させているPCのChromeでも保存されているパスワードがあれば全て削除する。
ブラウザが保存しているパスワードを全部削除したら、WebBrowserPassViewでふたたび確認して空っぽならOK。


Keepassのデータベースを自前サーバーに置いてSFTPで同期する
Keepassの使い方やDropBoxにデータベースを置く方法については他にも説明をされている方がたくさんいるので割愛させていただきたい。今回は、SSHサーバーとSFTPが使える状態の自前サーバー(VPS)にデータベースを置いてKeepassから参照する方法をやってみる。

KeePass
ダウンロード
http://keepass.info/

SFTPを使うにはKeepassにこのプラグインが必要になる。
IOProtocolExt
ダウンロード

http://keepass.info/plugins.html#ioprotocolext

 ダウンロードしたファイルを展開し、1個のディレクトリと2個のファイルをKeepassのあるフォルダーにコピーする。


Keepassを起動し、「ツール」メニューの「プラグイン」を開いて確認する。

IOProtocolExtが読み込まれていればOK。

次に、ローカルドライブに作成したKeepassdデータベースファイル(.kdbx)をWinSCPプログラムやRLoginプログラムなどを使ってサーバーにあらかじめ転送しておき、Keepass起動時にこれをSFTPで読み込むように指定する。

WinSCPで使うPuTTY形式の秘密鍵(.ppk)を作成する
サーバー側のSSHDがパスワード認証の場合はこの手順はスキップしていただきたい。サーバー側が公開鍵認証の場合、WinSCPが読み込むことができるPuTTY形式の秘密鍵(.ppk)を作成する必要がある。PuTTYのインストールフォルダにあるPUTTYGEN.EXEを使って作成するが、今回は既にOpenSSHで作成した秘密鍵があるので、PUTTYGEN.EXEを使ってPuTTY形式(.ppk)に変換したものを使う。公開鍵(.pub)はサーバー側のユーザーディレクトリ内 ~/.ssh/authrizedkeyファイルに既に登録されているものとする。

PUTTYGEN.EXEをダブルクリックで起動。

 「Load」でOpenSSHで作成した秘密鍵ファイルを読み込む。

OpenSSHを使っている場合、デフォルトではユーザーディレクトリの.sshフォルダ(隠しフォルダ)内に秘密鍵・公開鍵・knownhostsのファイルがある。
 All Filesを選択し、OpenSSHで作成した秘密鍵「id_rsa」を読み込む。

 秘密鍵にパスフレーズが設定されている場合はここで入力する。

 パスフレーズが正しい場合は読み込みが成功する。

 読み込んだ状態で、「Save private key」ボタンを押せばPuTTY形式(.ppk)で保存することができる。

 ここでは、元のファイル名「id_rsa」に.ppkをつけた「id_rsa.ppk」とう名前で保存。

KeepassでSFTPからデータベースファイルを読み込む
「ファイル」メニューの「開く」「URLから開く」を選択。

URL:データベースファイル名をフルパスで入力する。
例)sftp://xxx.xxx.xxx.xxx:22//home/user1/ftp/keepass/MYKEEPASSDB.kdbx
ユーザ名:ユーザー名
パスワード:パスワード認証の場合はここに入力。公開鍵認証の場合は空欄のままにする。(パスフレーズをここに入力すると失敗する)
記憶する:ここは任意に選択。公開鍵認証の場合、ここではパスフレーズは保存できないので「ユーザー名のみ覚える」が選択可能。

公開鍵認証の場合「拡張」タブの中で、秘密鍵のファイル名を指定する。
SSH private key pathのところに秘密鍵のファイル名を指定する。

パスフレーズの入力
FTPS/SCP/SFTPのPassphraseのところ入力する。(ただし、入力すると平文で表示されるので注意)
「OK」ボタンを押し、SFTPでのログインが成功するとKeepassのマスターキーを入力または選択するダイヤログボックスが開く。

マスターキーを入力・選択後「OK」ボタンを押すとKeepassデータベースが読み込まれる。
Keepassウィンドウが表示されれば完了。

エントリーを変更した場合にデータベースを自動的に保存するように設定するように「ツール」「オプション」メニューで設定をおこなう。
「データベースをロックまたは閉じるときに自動的に保存」にチェック。

以上。

2017年8月11日金曜日

SSHでトンネルを掘りVPS経由で実家のPCへVNC接続する(その2)

利便性だけを優先すれば、このような目的にはTeamviewerを使い、アカウントに二段階認証を設定すれば問題ないのかもしれない。だが、二段階認証を設定してないTeamviewerアカウントのパスワードリセットの手順があまりにも脆弱なこと、第三者に侵入される可能性のあるマネジメントコンソールの存在、アカウント情報の流出の懸念など、Teamviewer使うには多くの不安がある。
もちろん、自らバックドアを踏んでしまえは元も子もないが、それはWindows Firewallで対応するなど別の課題となる。今回は、パスワード管理もコネクションフローもすべて自分の管理下にあるより閉じた方法でリモートデスクトップ接続をおこなう方法を試す。
使うもの:
  Windows 10 Home 64bit デスクトップPC(こっち)
  Windows 10 Home 32bit タブレットPC(あっち)
  VPSサーバー CentOS 5.4 (sshdの公開鍵認証が有効になっていること)
  TigerVNC 1.8.0
  Open SSH Win 32/64

VPS=Virtual Private Server なので、「VPSサーバー」と書いたけれどもそれは冗長である。VPSとは要するにLinuxが動作する格安レンタルサーバーだ。具体的には「DTI SERVERSMAN@VPS エントリープラン」を使っている。こういった趣味の実験用途には打って付けのサービスで、格安のたった504円/月(税込み)で自分だけの固定グローバルIPアドレスとルート権限がもらえる。
VNCには色々なバージョンがあるが、本家RealVNCの最新バージョン6はTeamviewerのようにクラウドを使う仕組みのようなので除外する。今回TigerVNCを使っているが、UltraVNCでも構わない。UltraVNCの場合、Mirror Driverという専用のディスプレイドライバをインストールすることで描画の高速性が実現するというのだが、やってみたところ大差ないように感じ、ドライバも古臭くWindows10との相性が不安なため、それを使わないシンプルなTigerVNCを選択した。
WindowsでSSHトンネリングをする場合、クライアントソフトはPuTTYを使う場合が多いが、以下の問題により、今回はVNCサーバー側になるあっち側PCではOpen SSH Winを使う。PuTTYの問題点は以下のとおり。

・リモートデスクトップ上でトンネルを張っているPuTTYのウィンドウをドラッグしたり最小化するためにタイトルバーを左クリックすると、マウス左ボタンが押下状態のままリモート側に制御が奪われ、リモート側でマウス左ボタンを物理操作しない限りコントロールがロックされる。クライアントからVNCを切断してもリモート側は切断されず再接続が不可能になる。TigerVNCだけでなくUltraVNCサーバー・ビューワでも同様。コマンドプロンプトや他のプログラム、接続後に開いた別のPuTTYウィンドウに触れてもこの現象は発生しない)
・タスクスケジューラでシステム起動時にPuTTYを起動したときに、PuTTYプロセスは起動されるもののどうしてもトンネルが張れない。コマンドラインオプションがうまく渡されていないのかもしれない。

OpenSSH Winの場合、トンネルを起動しているウィンドウに触れてもPuTTYのようにハングアップすることはなく、また、タスクスケジューラでWindows起動時にスタートさせたときにはOpenSSHの実行ウィンドウ自体が非表示となり、ウィンドウに触れる心配がない。Windows UpdateでPCが勝手に再起動されてもリモート操作でWindowsへのログイン操作を可能にするため、システム起動時にトンネルを張って(掘って?)おく必要があるのだ。VNCクラアント側PCからのトンネル作成にPuTTYを使用することについてはとくに問題はないが、今回は両側ともOpen SSHというシンプルな方法にする。

TigerVNCの設置(あっち側PC)
ダウンロード
tigervnc-1.8.0.exe
tigervnc64-1.8.0.exe
環境に合わせていずれかのファイルをインストール。

Register VNC Serviceを実行(あっち側PC)
ユーザーがWindowsからログアウトしてもVNCサーバーが終了しないように、ユーザーモードではなくWindows起動時にTigerVNCサーバーをサービスで起動すように設定する。

Register VNC Serviceを実行

Configure VNC Serviceを開く(あっち側PC)


SecurityタブでVNCパスワードを設定する(あっち側PC)

SSHトンネリングで暗号化されるため、VNC間でSession encryptionをするのは冗長なのでNoneにする。

ConnectionタブでAccessControlを設定(あっち側PC)
トンネルからの接続だけを受け入れるように、"Only accept connections from the local machine"をチェックする。VNCサーバーの動作確認のために、同じLAN内の別のPCからトンネルを使わずに接続するには、ここにチェックを入れないか、チェックを入れない上に更にAddで192.168.0.0/8のようにローカルネットワークを追加する。運用時は上の状態にしておき、LAN内の別のPCから接続する場合もVPS経由のトンネルで接続するのが安全。

Desktopタブの設定(あっち側PC)
Remove wallpaperをチェックする。この設定は意外に重要で、VNCサーバーが着信しているときは一目でわかるように、デスクトップの壁紙が削除されるようにしておかなければならない。(ただしVNCではない別のバックドアで侵入された場合は無意味)
When last client disconnectsでVNC切断後の挙動を設定できるので、必要に応じて、Lock workstationやLogoff userを設定しておけばいい。今回の方法ならLoggoff userを行ってもリモートデスクトップ操作でWindowsにログインできる。

Start VNC Serviceを実行(あっち側PC)

ディスプレイのスケーリングが設定されている場合(あっち側PC)
今回VNCサーバー側になるタブレットPCは ASUS T100Chiという機種で、ディスプレイのサイズが10.1インチと小さい割に解像度が1,920×1,200ドット (WUXGA)と高く、デスクトップPCと同じ設定では文字が小さく扱い辛いので、デフォルトでは150%の拡大表示が設定されている。このままVNCサーバーを起動するとリモートデスクトップ時にマウスを動かしてもあっちのPCとカーソルが一致せず、ポイントする位置がずれる現象が起こる。解像度を落としてスケーリングを100%にすればマウスのズレはなくなるがそれでは高解像度ディスプレイの性能がもったいない。

スケーリング設定を変更せずにVNC接続時にマウスカーソルのズレを解決するには、エクスプローラーでVNCサーバー側PCの実行ファイル C:\Program Files\TigerVNC\winvnc4.exeを右クリックし、プロパティを変更する。互換性タブの「高いDPIスケールの動作を上書きします」のチェックを有効にし、拡大縮の実行元「アプリケーション」を選択して適用する。
これでOK。
備考:
TigerVNC Viewerはあっちの画面がこっちのよりもでかい場合、縮小スケーリング表示する機能がないため、あっちの画面がこっち側の画面からはみ出してしまい扱い辛くなる。Viewerについては互換性のある別のVNCクライアントを使う手もある。
また、Tiger VNC ViewerはX11サーバー相手の場合にウィンドウをリサイズするとリモート側のデスクトップサイズをダイナミックに変化させるする機能があるが、WindowsのVNCサーバーが相手の場合は機能しない。

OpenSSH Winを設置(ここではあっち側PCのみ。後程の手順でこっち側PCもおこなう)
ダウンロード
https://github.com/PowerShell/Win32-OpenSSH/releases
OpenSSH-Win32.zip
OpenSSH-Win64.zip
環境に合わせていずれかのファイルをダウンロード。インストーラーは無いので任意のフォルダに展開する。ここではC:\Users\Downloads\OpenSSH-Win32 に展開。

SSH接続用の公開鍵を作成する(ここではあっち側PCのみ。後程の手順でこっち側PCもおこなう)
鍵の作成にはOpenSSH-Win32 を展開したフォルダ内にあるssh-keygen.exeを使う。
元々サーバーへログインするために使っている鍵がpassphrase無しの場合は、新しい鍵やサーバ側に新しいユーザーを作成せずに、それをそのままトンネル用に使ってもいい。
元々サーバーへログインするために既に使っている鍵がこのフォルダーにある場合は、新しい鍵を上書きしてしまうとサーバーへログインできなくなり大変なことになる。既存の鍵をバックアップし、新しい鍵を作成する前にはPuTTYやTeratermなどであらかじめサーバーのコンソールへログインしておいた方がいい。
ssy-keygen.exeコマンドは、既存の鍵を上書きしないように、コマンドラインから-fオプションをつけて、作成される鍵のファイル名を指定して実行する。
例)C:\Users\Downloads\OpenSSH-Win32\ssh-keygen -f tunnel1_id_rsa
この場合、カレントディレクトリにtunnel1_id_rsaとtunnel1_id_rsa.pubが作成されるので、Windowsのユーザーフォルダー内の.sshフォルダ内へ2つのファイルをコピーする。
現在サーバーへの接続にパスワード認証だけを使っている場合には、新しく鍵を作成する。展開したフォルダ内のssh-keygen.exeをダブルクリックで実行れば、鍵のペアがWindowsのユーザーフォルダー内の.sshフォルダ内に作成されるのでこれを使う。

いずれの場合も、ssh-keygen実行時にpassphraseは無しに設定する。


ssh-keygen.exeを実行
(既存の鍵がない場合のみ)

エクスプローラーの表示オプションで隠しファイルを表示させる




id_rsa   が秘密鍵
id_rsa.pub が公開鍵
秘密鍵はサーバー側に登録する必要は無く、自分がサーバーに接続する際にSSHクライアントに読み込ませて使う。

トンネル専用ユーザーの作成(VPSサーバー)
普段サーバーで使っているユーザーでトンネルを張るのでも構わないが、サーバー側にトンネル専用ユーザーを作成しておいた方が良い気がする。
[root]$ useradd tunnel1
Pwassword:  これは公開鍵認証でログインする際のpassphraseとは別なので、ユーザーのパスワードを任意に指定する。別のユーザーでログインし、cu -コマンドでこのユーザーになるときにこのパスワードを使う。
シェルコマンドの実行ができないようにrbashが起動されるタイプのユーザーにすればより安心だが、サーバー側のsshd_configでpassword認証を禁止してしまえば、第三者が秘密鍵を持っていない限りSSHログインすることはほぼ不可能と考えられるので、rbashにする設定は必ずしも必要ないと思う。
備考:
PuTTYを使えばコマンドラインオプションにパスワード/パスフレーズを指定し、非対話でログインできるが、前述の事情により今回PuTTYが使えない。sshpassというプログラムを使えば、ユーザー名とパスワードまたはパスフレーズを指定して、一行でssh接続をすることができるが、これのWindows版を探してみたものの見つからなかった。

authorized_keysファイルへの追加(VPSサーバー)
id_rsa.pubはテキストファイルなので、id_rsa.pubファイルをメモ帳で開いてクリップボードにコピーし、VPSサーバー側の端末ウィンドウ内で開いたviエディタに張り付ける。
サーバーに自分のユーザー名または作成したトンネル専用ユーザーでログインし、

$ vi ~/.ssh/authorized_keys
~./.ssh/authorized_keys ファイルの最後にクリップボードにコピーしたものをペーストして追加する。
ファイルの最後にid_rsa.pubの内容をペーストしてセーブする。

トンネル専用のユーザーを今回作成したばかりの場合や、これまでパスワード認証だけを使っていたユーザーの場合は、~/.ssh/authorized_keys ファイルがないので作成し、パーミッションを644にする。

$ touch ~/.ssh/authorized_keys
$ chmod 644 ~/.ssh/authorized_keys 
$ls -la ~/.ssh/
drwx------ 2 user1 user1 4096 Aug  6 13:16 .
drwx------ 3 user1 user1 4096 Aug  5 23:48 ..
-rw-r--r-- 1 user1 user1  816 Aug  6 13:16 authorized_keys

後ほど、「こっち側PC」でも同様にssh-keygen.exeを使用して鍵を作成し、公開鍵の文字をこのファイルの最後にそれを追加する。

備考:
sshdで公開鍵認証を有効にするためには
 /etc/ssh/sshd_config の設定でPubkeyAuthentication yes になっている必要がある。
パスワード認証を禁止するために PasswordAuthentication no にするのが安全。

うまくログインできない場合は、/var/log/secure ファイルを確認する。
成功した場合:
Aug 12 11:10:52 myserver sshd[14223]: Connection from 202.101.103.114 port 51701
Aug 12 11:10:52 myserver sshd[14223]: Found matching RSA key: 86:3d:25:67:9f:4f:86:83:ec:cb:0b:8f:71:fa:aa:aa
Aug 12 11:10:52 myserver sshd[14224]: Postponed publickey for tunnel1 from 202.101.103.114 port 51701 ssh2
Aug 12 11:10:52 myserver sshd[14223]: Found matching RSA key: 86:3d:25:67:9f:4f:86:83:ec:cb:0b:8f:71:fa:aa:aa
Aug 12 11:10:52 myserver sshd[14223]: Accepted publickey for tunnel1 from 202.101.103.114 port 51701 ssh2
Aug 12 11:10:52 myserver sshd[14223]: pam_unix(sshd:session): session opened for user tunnel1 by (uid=0)

パスワード認証が無効なサーバーにパスワード認証でログインして失敗した場合:
Aug 12 11:12:01 myserver sshd[14228]: Connection from 202.101.103.114 port 51703
Aug 12 11:12:02 myserver sshd[14229]: Received disconnect from 202.101.103.114: 1: User Auth Failure


接続テスト (あっち側PC)
パスフレーズ無しでログインできれば成功。
C:\Users\ore\Downloads\OpenSSH-Win32\ssh.exe tunnel1@123.123.123.12 -p 22 -i C:\Users\ore\.ssh\tunnel1_id_rsa
Last login: Sun Aug  6 13:19:49 2017 from xxx.xxx.xxx.xxx
-rbash-3.2$

・-i オプションで、秘密鍵のファイル名をフルパスで指定する。
・-p オプションはサーバー側sshdのポート番号。SERVERS@MANの場合、sshは標準の 22ではなく3843になる。

トンネルを張るコマンドをテスト
C:\Users\ore\Downloads\OpenSSH-Win32\ssh.exe -N -R 6666:localhost:5900 tunnel1@123.123.123.12 -p 22 -i C:\Users\ore\.ssh\tunnel1_id_rsa
新しく黒いウィンドウが開いてそのままになればOK。切断するにはウィンドウ右上のバッテンをクリックする。
・-N オプションをつけることで、サーバー側のコマンドラインを表示しないようにする。(notty)
・-R 6666 サーバー内で中継に使用する任意のリッスンポート番号。使われていないポート番号を任意で決める。このポートはサーバー内部でループバック接続に使われるだけなので、ファイアーウォール(iptables)に外部からの接続ルールを追加する必要は無い。
・localhost このまま記入。
・5900 WindowsPC VNCサーバーのリッスンポート番号。5900はデフォルトの値で、VNC Server ConfigのConnectionタブで変更することができる。

トンネルを張るコマンドをタスクスケジューラーに登録(あっち側PC)
これはをやるのは後でも構わない。差し当たりコマンドプロンプトでトンネルを張るコマンドを手動で実行し、こっち側PCからVNC Viewerを使っての接続テストを先にやるのがいいかもしれない。

タスクスケジューラを起動する。

タスクスケジューラの右側ウィンドウ内のメニューで「タスクの作成」を選択。
タスクの名前は任意。ここではtunnel_vncという名前にしている。
「全般」タブの設定

「ユーザーがログオンしているかどうかにかかわらず実行する」を選択し、「最上位の特権で実行する」にチェックを入れる。Windows 10 Homeは、Windows Updateの際に強制的に再起動が実行されるため、VNCを使ってWindowsにユーザーがログイン(ログオン?)するにはこのようにしてシステム起動時にトンネルを張っておく必要がある。

「トリガー」タブの設定

ネットワークへの接続が完了していないと、トンネルを張るのに失敗してしまう。Wi-Fiの接続が完了し、DHCPサーバーからアドレスの取得が完了するまで少し時間がかかることを想定し、「遅延時間を指定する」にチェックを入れ、「30秒間」を指定する。もしインターネット接続やWi-Fi接続が切れた場合はプロセスが終了してしまうため、プロセスが自動的に再起動されるように「繰り返し間隔」に「30分間」にチェックを入れ、定期的にコマンドが実行されるように設定する。プロセスを重複起動しないための設定は、この後の「設定」タブでおこなう。

「操作」タブの設定
「プログラム/スクリプト」のボックスにSSHコマンドをフルパスで入力。
C:\Users\ore\Downloads\OpenSSH-Win32\ssh.exe
「引数の追加」のボックスにコマンドラインオプションを入力。
 -N -R 6666:localhost:5900 user1@123.123.123.12 -p 22 -i C:\Users\ore\.ssh\tunnel1_id_rsa

「条件」タブの設定
電源の項目は任意に設定する。今回はAC電源でもバッテリー動作時でも挙動を違わせる必要は無く、いずれの場合も実行して構わないと思う。
ネットワークの項目は、チェックを入れないことにした。システム起動時にネットワーク接続が完了していなければトリガー条件で設定した30分後に再度プロセスが起動される。

「設定」タブの設定

プロセスが重複起動されないように、一番下で「新しいインスタンスを開始しない」を選択する。
「タスクが失敗した場合の再起動の間隔」を指定することができるが、トリガータブの設定で30分毎に繰り返されるので、ここで設定すると冗長なためチェックをOFFにする。
全てのタブを設定し終えたら、PCを再起動し自動的にトンネルが張られているか確認する。スケジューラでssh.exeを起動すると、手動でテストした際のような黒いウィンドウは現れずにバックグラウンドでssh.exeが起動する。
Windowsにログインし、タスクマネージャーで「ssh.exe」が起動していることを確認する。
タスクマネージャーの表示



TigerVNC Viewerのインストール(こっち側PC)
ダウンロード
vncviewer-1.8.0.exe
vncviewer64-1.8.0.exe
環境に合わせていずれかのファイルをインストール。

OpenSSH Winを設置(こっち側PC)
ダウンロード
https://github.com/PowerShell/Win32-OpenSSH/releases
OpenSSH-Win32.zip
OpenSSH-Win64.zip
環境に合わせていずれかのファイルをダウンロード。インストーラーは無いので任意のフォルダに展開する。

SSH接続用の公開鍵を作成する(こっち側PC)
先にやった、あっち側PCでの作成手順と同じ。サーバーへログインするために既に公開鍵認証を使っている場合は既存のユーザーと鍵が使える。トンネル専用に新しいユーザーを作成する場合は、そのユーザー用に新たにssh-keygen.exeを使って接続用の鍵のペアを作成する。
あっち側PCではタスクスケジューラーにより非対話でSSHログインをおこなう必要があるため、Passphrase無しの鍵を使う必要があるが、こっち側PCでトンネルを張るのは手動操作なので、鍵はPassphrase付きのものでも構わない。

authorized_keysへの追加(VPSサーバー)
サーバーへログインするために既に公開鍵認証を使っている場合はこの手順は不要。
これまでパスワード認証だけを使っていた場合や、トンネル専用に新しいユーザーを作成した場合におこなう。
先にやった、あっち側PCの公開鍵を追加する手順と同じ。サーバー側で先ほどあっち側PCの公開鍵を追加したのと同じ~./.ssh/authorized_keysファイルの最後に、こっち側PCの公開鍵(.pub)の内容を追加してセーブする。

OpenSSH Winの起動(こっち側PC)
VNC Viewerで接続を開始する前に、こっち側PCからもサーバーにトンネルを張っておく必要がある。
コマンドプロンプトでSSHコマンドを実行する。

C:\Users\kotti\Downloads\OpenSSH-Win64\ssh.exe -N -L 7701:123.123.123.12:6666 tunnel1@123.123.123.12 -p 22 -i C:\Users\kotti\.ssh\tunnel1_id_rsa

・-N オプションをつけることで、サーバー側のコマンドラインを表示しないようにする。(notty)
・-L 7701 こっち側PCの内のポート番号を任意で決める。
・-i オプションで、秘密鍵のファイル名をフルパスで指定する。
・-p オプションはサーバー側sshdのポート番号。
サーバーのIPアドレスとポート番号、サーバーへログインするユーザー名は「あっち側PC」と同じ。
このコマンドはVNC Viewerで接続する前に毎回実行することになるので、バッチファイルにしてショートカットをTigerVNC Viewerアイコンの隣にでも置いておけばいい。

tunnel_client.bat
CD /C %~dp0
START /MIN C:\Users\kotti\Downloads\OpenSSH-Win64\ssh.exe -N -L 7701:123.123.123.12:6666 tunnel1@123.123.123.12 -p 22 -i C:\Users\kotti\.ssh\tunnel1_id_rsa

TigerVNC Viewerの起動
TigerVNC Viewerを起動する。

Real VNC 5.3.3のViewerも使える
ダウンロード
https://www.realvnc.com/download/file/vnc.files/VNC-5.3.3-Windows.zip
TigerVNCは縮小スケーリングができないが、Real VNCのViewerは可能なので、向こうの画面の方がでかいという今回場合はこちらの方が適している。
TigerVNC Serverへ接続する場合、Encryptionの互換性がないようでNoneにしかできないが、今回の環境の場合SSHトンネリングを使っているのでEncryptionの必要は無い。
Real VNCのインストールファイルにはVNC ServerとVNC Viewerの両方が含まれているが、インストール時にはVNC Viewerだけを選択し、VNC Serverのチェックボックスは外す。Real VNCのバージョン5.x.xはVNCサーバーを起動するためのトライアルライセンス配布が終了しており、VNCサーバーをインストールしても起動することができない。(VNC Connectライセンスなるものを購入すると5.x.xのライセンスをもらえるようだが)

TigerVNC Viewerで接続
接続先に「localhost:7701」を入力し、Connectボタンを押す。

VNC Authenticationのウィンドウがすぐに表示されれば接続は成功している。
あっち側PCのConfigure VNC Serverの手順で、Securityタブで設定したVNCパスワードを入力し、OKボタンを押す。
あっち側PCの起動時にトンネルを張るのが成功していれば、Windowsにログインしていない状態でも接続することができる。


 ログイン時はデスクトップの壁紙が削除される設定にしてある。

接続中は、F8 キーを押すとコンテキストメニューが表示され、特殊キーの送信などができる。

コンテキストメニューではIMEをON/OFFできるキーを送ることができず、日本語が入力できない。こちらのメモ帳に記入した日本語をコピーしてVNC Viewerウィンドウ内にペーストすると、???となり、クリップボード経由では送ることができないようだ。あっち側PC全角/半角キーを手動で押してIME ONの状態にしてやるとVNC Viewerから日本語入力ができるようになる。なので、あっち側PCのIMEのキー割り当てを変更しておけばVNC ViewerからIMEのON/OFF操作をすることができる。送れるキーは英語版キーボードに存在するキーだけだと思わるので、あまり使うことのないファンクションキーの一つを割り当てることにする。

IMEのキー割り当て追加(あっち側PC)
タスクトレイのIMEアイコンを右クリックしてプロパティを表示させる。
詳細設定を押す。

全般タブの「編集操作」の変更ボタンを押す。

キー設定タブを選択。
既存の「全角/半角」を選んでから「キー追加」ボタンを押すと、同じ機能をコピーして別のキーに割り当てることができる。

元々一体なんの機能があるのかわからない「F12」キーを割り当てることにする。

これでF12キーでIMEのON/OFFを切り替えることができるようになった。

トンネルがダウンしている場合はPCを再起動する
タスクスケジューラーを使ってssh.exeのプロセスが存在するか30分間隔でチェックするようにしたものの、この方法はどうも不完全なようで、接続できなくなってしまうことがある。トンネルがダウンしてもプロセスが消えない場合があったり、ssh.exeが重複起動されてしまう場合もあるようで、これらの原因はよくわからない。
なので、別の方法でもチェックすることにした。つまり、netstatコマンドでトンネル接続がESTABLISHEDでなければPCごと再起動する、というバッチファイルを作成し、1時間間隔で実行するようにタスクスケジューラーに登録する。
tunnel_check.bat
@echo off
CD /D %~dp0

netstat -tn | find "123.123.123.12:22    ESTABLISHED" > nul
if ERRORLEVEL 1 goto tunneldown
goto tunnelok

:tunneldown
echo Tunnel Down
echo %date% %time% Tunnel is Down. PC will be rebooted in 1 min  >> tunnel_chek_log.txt 
shutdown /r /t 60
goto end

:tunnelok
echo Tunnel OK
echo %date% %time% OK >> tunnel_chek_log.txt
:end

このバッチファイルのタスクスケジューラーへの登録方法は、先に作成したプロセスチェックのタスク「tunnel_vnc」とほとんど同じ。
インターネット接続に問題がある場合に、システム起動後すぐにリブートを繰り返してしまい、タスクを無効にしようにも手が付けられなくなるのを防ぐため、スタートアップから30分後にタスクが開始されるように「トリガー」の中で遅延時間を30分に指定することにした。
トンネルを復旧させる目的だけならシステムごと再起動する必要はなく、ssh.exeもこのバッチファイルを使ってSTARTコマンドで起動する方法も考えられるが、プロセスが存在するかどうか確認してKILLする仕組みも入れる必要があり、少し面倒になるので今回はこの方法で行ってみることにした。まだ数日の運用だが、いまのところ順調に動作しているようだ。

「SSHでトンネルを掘りVPS経由で実家のPCへVNC接続する」は以上で終了です。