読者です 読者をやめる 読者になる 読者になる

素敵なおひげですね

PowerShellを中心に気分で書いているブログです。

WindowsでFabricで遊ぶ - 再び

Python Windows Fabric PowerShell

以前に、

stknohg.hatenablog.jp

なんて記事を書いたのですが、ちょっと前にMicrosof公式のSSHDが発表されたので、freeSSHdで試していた部分をOpenSSHに変えて遊びなおしてみました。

github.com

WindowsにFabricをインストールする

前回同様Windows 8.1にFabricをインストールしてみます。
基本的に手順は前回と同じでOKです。

残念ながらまだFabricはPython3系には対応していないので、Python 2.7.10をダウンロードしてインストールしてください。
Microsoft Visual C++ Compiler for Python 2.7(http://aka.ms/vcpython27)も併せてインストールしてください。

Pythonをインストールした後はpipからFabricをインストールできます。

# Fabricのインストール
pip install fabric

# 必要に応じてcuisineもインストール
pip install cuisine

現時点でFabricはfabric-1.10.2、cuisineはcuisine-0.7.11です。

WindowsSSHサーバーにする

ここからがメインになります。
サーバーは前回同様Windows Server 2012 R2です。

OpenSSHのダウンロード

現時点でインストーラーは提供されていないので、Githubのリリース(Releases · PowerShell/Win32-OpenSSH · GitHub)から最新のリリースを取得します。 今回は11_09_2015版のOpenSSH-Win32.zipを使用します。

OpenSSHのインストール

インストール手順は Deploy Win32 OpenSSH · PowerShell/Win32-OpenSSH Wiki · GitHub の手順に従うだけです。

OpenSSH-Win32.zipを解凍し、任意のディレクトリに展開します。
(現時点ではパスにスペースが含まれていると正しく動作しない部分があるのでその点だけは注意してください。)
今回はC:\OpenSSHに展開します。

展開後はssh-keygen.exeを使い公開鍵・秘密鍵の生成を行います。
以下のコマンドを実行しパスフレーズは適当に入力してください。

# ディレクトリ移動
PS C:\Users\Administrator> cd C:\OpenSSH

# 鍵生成 - 詳細は省略
PS C:\OpenSSH> .\ssh-keygen.exe -t rsa -f ssh_host_rsa_key
PS C:\OpenSSH> .\ssh-keygen.exe -t dsa -f ssh_host_dsa_key
PS C:\OpenSSH> .\ssh-keygen.exe -t ecdsa -f ssh_host_ecdsa_key
PS C:\OpenSSH> .\ssh-keygen.exe -t ed25519 -f ssh_host_ed25519_key

続けて、以下のコマンドを実行しTCP 22ポートを開けます。

# Firewallのポートを開ける
PS C:\OpenSSH> New-NetFirewallRule -Protocol TCP -LocalPort 22 -Direction Inbound -Action Allow -DisplayName SSH

次に、setup-ssh-lsa.cmdを実行し鍵認証のための設定を行います。
実行後はマシンを再起動します。

# setup-ssh-lsa.cmdの実行
PS C:\OpenSSH> .\setup-ssh-lsa.cmd

C:\OpenSSH>if AMD64 == x86 (set lsadll=C:\OpenSSH\x86\ssh-lsa.dll )

C:\OpenSSH>if AMD64 == AMD64 (set lsadll=C:\OpenSSH\x64\ssh-lsa.dll )

C:\OpenSSH>copy "C:\OpenSSH\x64\ssh-lsa.dll" C:\Windows\system32\
        1 個のファイルをコピーしました。

C:\OpenSSH>reg add HKLM\System\CurrentControlSet\Control\Lsa /v "Authentication Packages" /t REG_MULTI_SZ  /d  msv1_0\0s
sh-lsa.dll -f
この操作を正しく終了しました。

# 再起動
C:\OpenSSH> Restart-Computer

再起動後はSSHDのインストールですが、今回はSFTPも使いたいのでC:\OpenSSH\sshd_configを開き、以下の部分を編集します。

# C:\OpenSSH\sshd_configのSubsystemの部分を以下の様に編集する
Subsystem   sftp    /usr/libexec/sftp-server
↓
Subsystem   sftp    C:\OpenSSH\sftp-server.exe

編集後、sshd.exe installを実行しサービスのセットアップを行います。

# サービスのセットアップ
PS C:\OpenSSH> .\sshd.exe install
Service installed successfully

# サービス起動
PS C:\OpenSSH> (Get-Service "sshd").Start()

# 起動後の状態確認
PS C:\OpenSSH> (Get-Service "sshd").Status
Running

SSHDサービスが起動されれば成功です。

WindowsでFabricで遊ぶ

前回と同じことをして動作を確認してみます。
実行するfabfile.pyとコマンドの実行例は以下の様な感じです。
前回のよりちょっとだけ詳細にしてみました。

fabfile.py例

# -*- coding: utf-8 -*-
from fabric.api import *
from fabric.colors import *

def check_ipaddress_cmd():
    """
    単純なコマンドを実行するサンプル(Cmd.exe)
    """
    # Windows Server相手なのでシェルを変える
    env.shell = "Cmd.exe /C" 

    result = run("ipconfig")
    print result.return_code

def check_ipaddress_ps():
    """
    単純なコマンドを実行するサンプル(PowerShell)
    """
    # Windows Server相手なのでシェルを変える
    env.shell = "PowerShell.exe -Command" 

    # Fabricでは $ が自動でエスケープされてしまうので shell_escape=False にする
    result = run("&{ Get-NetIPAddress | ? { $_.AddressFamily -eq 'IPV4' } }", shell_escape=False)
    print result.return_code

def get_user_dir():
    """
    cd、prefix句を試すサンプル
    """
    env.shell = "Cmd.exe /C"

    # cdやprefixはシェルがCmd.exeなら使える
    with cd("C:\\Users\\"):
        with prefix ("echo Sample Prefix"):
            run("dir")

def upload_sample_file():
    """
    ファイルをアップロード・ダウンロードするサンプル
    """

    # アップロード put( Local, Remote )
    put("C:\\Users\\vagrant\\Documents\\fabfile.py", "C:\\fabfile.py")

    # ダウンロード get( Remote, Local )
    get("C:\\OpenSSH\\sshd_config", "C:\\Users\\vagrant\\Documents\\")

def check_ipaddress_sudo():
    """
    sudoコマンドを実行するサンプル(Windowでは正常に動作しない)
    """
    env.shell = "Cmd.exe /C" 
    result = sudo("ipconfig")
    print result.return_code

def output_color():
    """
    コンソールに色を出力するサンプル(Windowでは正常に動作しない)
    """
    print(green("This text is green!"))

コマンド実行例

fab -H 192.168.0.100 -u use_name -p password check_ipaddress_cmd

遊んだ結果

前回のFreeSSHdの場合から特に変わった点はなく、ちょっと試す分には問題はありませんでした。
SSHDは変わりましたがシェルが変わるわけではないのでWindowsの制約もほとんどそのままです。

  • sudoメソッドは使えません。
  • シェルをPowerShellにした場合、fabric.context_managers.cdfabric.context_managers.prefixは使えません。
  • getputメソッドはSFTPのルート配下のディレクトリに対してのみ使えます。
    • →この制約はSFTPDが変わったことでディレクトリの制約を受けなくなっていました。
  • fabric.colorsは使えません。
  • 多分ほかにもいろいろ制約はあります...

また、前回気が付かなかった点で、Fabricではrunメソッドで実行するコマンドに$があると自動でエスケープされるため、変数定義に$を使うPowerShellのコマンドを実行する場合は注意が必要です。
$を使う場合はshell_escape=Falseとパラメータを明示する必要があります。

全体的な感想としてはMicrosoft公式のSSHDという事で導入の敷居が低いくらいなのがFreeSSHdと比べて良い点でしょうか。

あまり面白い結果は出せませんでしたがこんな感じです。


また、前回の記事を参考*1Djangoのデプロイまでをやっている方がいらっしゃいます。

thinkami.hatenablog.com

runメソッドを連続実行するとエラーになるのに対応されていたりしてかなり面白い内容です。
私が試した時は[20h[?7hの謎のエスケープシーケンス(らしきもの)は同様に出ましたがコマンドがエラーになることはありませんでした。
環境依存の何かがあるのかもしれません...

補足:普通にOpenSSHを試してみる

せっかくなので自分が普段使うTeratermWinSCPを使って"普通"にOpenSSHを試してみます。

SSHDへの接続

Teratermで普通にログインできます。
ログインすると以下の様な画面(vagrantユーザーでログインしています)になります。シェルはcmd.exeでした。

f:id:stknohg:20151201193840p:plain

日本語の表示も特に問題なかったです。
ここからPowerShellを起動するには

powershell.exe -File -

-File -*2をつける必要があります。これをつけないとコマンド実行時にハングします。

f:id:stknohg:20151201194222p:plain

適当にコマンドを実行してみましたが特に問題はありませんでした。

ただ、タブ補完が利かないので結構ストレスは溜まります。 個人的にはコマンド入力の補完も利くPSRemotingの方がまだまだ便利だと感じました。

Linux等をメインに使う方にとってはすべてがSSHで完結する方が便利かもしれません。

SFTPDへの接続

WinSCPを使いSFTPでログインすると以下の様な感じになります。
ホームディレクトリはユーザープロファイル(C:\Users\vagrant\)でした。

f:id:stknohg:20151201194530p:plain

このディレクトリより上位のディレクトリにもアクセス可能なのですが、C:\ドライブ直下にアクセスしようとすると以下のエラーになりました。

f:id:stknohg:20151201194704p:plain

この動作について、OpenSSHクライアントのsftp.exeを使って挙動を試してみたのですが、C:\ドライブ直下にアクセスするのにできる方法とできない方法があり、バグなのか仕様なのかよくわからない感じでした。

sftp.exeを使った動作確認結果

# 現在のディレクトリは C:/Users/vagrant
sftp> pwd
Remote working directory: C:/Users/vagrant

# パス指定ではルート(C:\)に移動できない
sftp> cd c:/
Couldn't stat remote file: No such file or directory
sftp> cd /
Couldn't stat remote file: No such file or directory

# 相対パスで階層を上がるとルート(C:\)に移動できる
sftp> cd ..
sftp> cd ..
sftp> pwd
Remote working directory: C:\

そのうちこの辺の挙動もはっきりしてくるとは思います。

*1:あんなお遊びの記事を見てもらってありがたいやら申し訳ないやらです。

*2:-Fileの後ろの - は標準入力を表しています。牟田口先生ありがとうございます。