openssh

UPDATED 2017-02-15: changed docker run command example due to Issue#4


Update Note azuresshconfig-0.2.3

(記事はここから)
以前「azuresshconfigの紹介 – Azure上でのSSH生活を少しだけ快適にする」の投稿でazuresshconfigの紹介をさせていただいたが、ツールをリリースして以来、数少ない貴重な利用者様からインストールがコケるんだけど何とかしろというクレームをいただいていた。そこでインストールマニュアルを充実させようかとか、インストーラーをプラットフォーム別に充実させようかとか考えたものの、ここは流行りのコンテナ実行できるようしたほうがいいだろうということでDocker対応することにした。

今回の対応によりpipインストールや、プラットフォーム別にprerequisiteなランタイム、ヘッダファイル、ライブラリといった面倒なインストールが不要となり、Mac、Windows、Linux(Ubuntu、CentOS、その他distro)関係なくシンプルにdocker runコマンドでの実行が可能となった。

しかも超軽量LinuxディストリビューションであるAlpine Linuxの上にPythonランタイムとツールを載せているだけであるためサイズはたったの155MBとかなり軽め

$ docker images azuresshconfig
REPOSITORY                          TAG                 IMAGE ID            CREATED             SIZE
azuresshconfig                     latest              7488bef4343f        7 minutes ago       155 MB

実行例

$ docker run -v $HOME:/root --rm -it yoichikawasaki/azuresshconfig \
    --output stdout --user yoichika --identityfile ~/.ssh/id_rsa > $HOME/.ssh/config

$HOME/.ssh/config

Dockerfileをダウンロードしてビルド・実行はこちら

$ curl https://raw.githubusercontent.com/yokawasa/azure-ssh-config/master/Dockerfile -o Dockerfile
$ docker build -t azuresshconfig .
$ docker run -v $HOME:/root --rm -it yoichikawasaki/azuresshconfig \
    --output stdout --user yoichika --identityfile ~/.ssh/id_rsa > $HOME/.ssh/config

LINKS

Enjoy SSH life on Azure with dockerized azuresshconfig!

UPDATED 2016-10-31: paramsオプション + Bash Completion追加

みんな大好きSSHとAzureのお話し。物理サーバ、EC2/仮想マシン、コンテナなどなんでもよいがその上にLinuxサーバをたてたらまずやることの1つにSSHログインのためにそのIPアドレス調べて~/.ssh/configにそのエントリーを追加してやることがあるんじゃないかと思います。この作業、エントリー数が少なければ大したことはないものの、追加対象のホストが大量にある場合はかなり面倒な作業になってきます。さらにDHCPなどでアドレスを動的に取得するような設定であればサーバの上げ下げのたびにIPアドレスが変わってくるので~/.ssh/configの更新が必要になってきて、どうしようもなく面倒になってきます。こういった単純でどうしようもなくつまらない作業は自動化したいですよね? ここではそんな皆さんのためにazuresshconfigというツールを紹介させていただきます。

これは皆さんのAzureサブスクリプション下に作られた仮想マシン一覧(ARMに限る)の情報を取得して各仮想マシンごとのエントリー情報(マシン名とIPアドレス)を~/.ssh/configに追加・更新してくれるツール。新規に仮想マシンを追加した際や、仮想マシンのIPアドレスが追加した際にはazuresshconfigを実行してあげることで~/.ssh/configが最新のエントリー情報でアップデートされ、各マシンにマシン名でSSHログインできるようになります。

ちなみに、~/.ssh/configとは何ですか?という人はQiitaの記事「~/.ssh/configについて」がとても分かりやすく書かれているので参考になるかと。

インストール

Pythonパッケージ管理ツールpipを使ってazuresshconfigをインストールしてください。インストール時に何かエラーが発生した場合は、こちらのページを参照いただき特に該当する事象がないか確認ください。

pip install azuresshconfig

設定ファイルの編集(サービスプリンシパル)

vi $HOME/.azure/azuresshconfig.json

{
    "subscription_id": "<YOUR SUBSCRIPTION ID>",
    "client_id": "<YOUR APPLICATION CLIENT IP>",
    "client_scret": "<YOUR APPLICATION CLIENT SCRET>",
    "tenant_id": "<YOUR TENANT ID>"
}

サービスプリンシパルを作る必要があります。サービスプリンシパルの作り方が分からない人、とってもよいドキュメントがあります。こちらを参照ください:「Use Azure CLI to create a service principal to access resources

使い方

azuresshconfig --help

usage: azuresshconfig.py [-h] [--version] [--init] [--profile PROFILE]
                         [--user USER] [--identityfile IDENTITYFILE]
                         [--private] [--resourcegroups RESOURCEGROUPS]
                         [--params PARAMS]

This program generates SSH config from Azure ARM VM inventry in subscription

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --init                Create template client profile at
                        $HOME/.azure/azuresshconfig.json only if there is no
                        existing one
  --profile PROFILE     Specify azure client profile file to use
                        ($HOME/.azure/azuresshconfig.json by default)
  --user USER           SSH username to use for all hosts
  --identityfile IDENTITYFILE
                        SSH identity file to use for all hosts
  --private             Use private IP addresses (Public IP is used by
                        default)
  --resourcegroups RESOURCEGROUPS
                        A comma-separated list of resource group to be
                        considered for ssh-config generation (all resource
                        groups by default)
  --params PARAMS       Any ssh-config params you want to add with query-
                        string format: key1=value1&key2=value2&...

実行する

1. パラメータ指定なしで実行

azuresshconfig

~/.ssh/configには下記のように### AZURE-SSH-CONFIG BEGIN ### ~ ### AZURE-SSH-CONFIG END ###のブロック内にマシン名とそのIPアドレス(デフォルト:パブリック)のエントリー一覧が追加・更新されます。

cat ~/.ssh/config

### AZURE-SSH-CONFIG BEGIN ###

Host myvm1
    HostName 40.74.124.30

Host myvm2
    HostName 40.74.116.134
....

### AZURE-SSH-CONFIG END ###

2. SSHユーザと鍵指定

azuresshconfig --user yoichika --identityfile ~/.ssh/id_rsa

~/.ssh/configには各エントリーにIPアドレスに加えてユーザ名と鍵のパス情報が追加されます。

cat ~/.ssh/config

### AZURE-SSH-CONFIG BEGIN ###

Host myvm1
    HostName 40.74.124.30
    IdentityFile /home/yoichika/.ssh/id_rsa
    User yoichika

Host myvm2
    HostName 40.74.116.134
    IdentityFile /home/yoichika/.ssh/id_rsa
    User yoichika
....

### AZURE-SSH-CONFIG END ###

3. プライベートIPを指定

azuresshconfig --user yoichika --identityfile ~/.ssh/id_rsa --private

privateオプションを付けて実行することで~/.ssh/configの各エントリーにはデフォルトのパブリックIPアドレスではなくてプライベートIPアドレスが追加されます。

4. リソースグループで絞る

azuresshconfig --user yoichika --identityfile ~/.ssh/id_rsa --resourcegroups mygroup1,mygroup2

resourcegroupsオプションを指定することで指定されたリソースグループに所属する仮想マシンのエントリーのみが~/.ssh/configに追加されます。

5. 追加ssh-configパラメータの指定

azuresshconfig.py --user yoichika \
                --identityfile ~/.ssh/id_rsa \
                --params "Port=2222&Protocol=2&UserKnownHostsFile=~/.ssh/known_hosts&ForwardAgent=yes"

paramsオプションを指定することでその他指定可能なssh-configパラメータを追加することができます。上記のようにparamsにssh-configのPort、Protocol、UserKnownHostsFile、ForwardAgentキーと値をセットすることで次のように出力されるssh-configに指定したキーと値がセットされます。

cat ~/.ssh/config

### AZURE-SSH-CONFIG BEGIN ###

Host myvm1
    HostName 40.74.124.30
    IdentityFile ~/.ssh/id_rsa
    User yoichika
    Port 2222
    Protocol 2
    UserKnownHostsFile ~/.ssh/known_hosts
    ForwardAgent yes

Host myvm2
    HostName 40.74.116.134
    IdentityFile /home/yoichika/.ssh/id_rsa
    User yoichika
    Port 2222
    Protocol 2
    UserKnownHostsFile ~/.ssh/known_hosts
    ForwardAgent yes
....

### AZURE-SSH-CONFIG END ###

Shell Completion

Bashでの補完

次のようにbash/azuresshconfig_completion.bashをbash起動時に読み込ませてあげることでazuresshconfigのパラメータ補完ができるようになります.

# copy this under either of following directories
cp azuresshconfig_completion.bash (/etc/bash_completion.d | /usr/local/etc/bash_completion.d | ~/bash_completion.d)

# or append 'source /path/to/azuresshconfig_completion.bash' to .bashrc like this
echo 'source /path/to/azuresshconfig_completion.bash' >> .bashrc

次のようにtabでazuresshconfigのパラメータ補完を行います。

$ azuresshconfig -[tab]
-h                --identityfile    --params          --profile         --user
--help            --init            --private         --resourcegroups

$ azuresshconfig --i[tab]
--identityfile  --init

$ azuresshconfig --p[tab]
--params   --private  --profile

$ azuresshconfig --user [tab]
$ azuresshconfig --user <ssh_user>
$ azuresshconfig --user <ssh_user> --identityfile [tab]
$ azuresshconfig --user <ssh_user> --identityfile <ssh_identity_file>

その他

インストール時のエラーや実行時のエラーについてはこちらに見つけ次第事象とその対応方法を追加しています。
https://github.com/yokawasa/azure-ssh-config/blob/master/Issues.md

もしバグを見つけたり、追加機能のリクエストがある場合にこちらにIssue追加ください。頑張って時間をみつけて対応します。
https://github.com/yokawasa/azure-ssh-config/issues

LINKS

azuresshconfig makes your SSH life on Azure easy!

UPDATED 2017-03-22: Added SOCKS Proxy Configuration for Internet Explorer

外部からの接続(SSH、HTTPなど)を受け付けていないAzure 仮想ネットワーク(以下VNET)内のリソースにSOCKSプロキシを経由して外部からアクセスしましょうというお話。本記事ではAzure VNET内の外部からのアクセス許可していないVMへのSSHログインとHTTPサーバコンテンツへのブラウジングの2つの方法を紹介する。
SOCKS(RFC1928) とはさまざまなアプリケーションが間にファイアーウォールを挟んでいても安全に快適にやり取りができるようにすることを目的として作られたプロトコルのことで、SOCKSプロキシはSOCKSプロトコルを受け取りファイアウォール内外との接続を可能にするものである。エンドポイントやNetwork Security Group (NSG)によりネットーワーク分離設定されたAzure VNET内のリソースに対して一時的に本来直接アクセス許可しないネットワークからアクセスが必要な状況はあるかと思う。そのような時に毎回設定変更で必要なプロトコル、アクセス先に対して穴をあけるのは非常に面倒であり、またサイト間VPN、ポイント対サイトVPNとなるとさらに手間がかかる。お手軽に、もしくは定常的ではないが一時的に内部リソースにアクセスしたい場合にSOCKSプロキシ経由でのアクセスを検討してみてはいかがだろうか。以下はSOCKSプロキシ経由によるAzure VNET内のプライベートリソースへのアクセスイメージである。


Accessing-AzureVNET-via-SOCKSProxy

SOCKSプロキシの作成

まずはOpenSSHのダイナミックポートフォワード機能を使ってSOCKSプロキシを作成する。ダイナミックポートフォワードはSSHをSOCKSプロキシとして振舞うことを可能にする。SSHでアクセス先ホストと DynamicFoward(-D)でポートを指定することでlocalhostにSOCKSプロキシが立ち上がり指定のTCPポート(SOCKSプロキシサーバは基本的は1080だが、割り当て可能なポートであればどのポートでもOK)をlocalhost側からログイン先ホストのSSHサーバに転送することができるようになる。もちろん経路は暗号化される。現状のサポートプロトコルはSOCKS4とSOCKS5。
例えば上図でいうとJump Server(踏み台)にDynamicFoward(-D)1080でログインすると、Jump Serverにポート1080を転送するSOCKSプロキシが localhostに立ち上がり、そのlocalhost:1080に対してSOCKS4またはSOCKS5プロトコルで接続することでJump Serverを経由して通信を行うことができるようになる。
localhost ポート1080のJump Serverへのダイナミックフォワードは次のように-Dオプションで行う。

$ ssh -2 -D 1080 -l [Account] [Jump Server]

毎回-Dオプション指定が面倒な場合は、次のようにconfg(ssh_config)にDynamicForwardの記述することも可能。

~/.ssh/config

Host JumpServer
   User         [Account名]
   HostName/IP  [Jump Serverホスト/IPアドレス]
   Protocol 2
   ForwardAgent  yes
   DynamicForward 1080

上記OpenSSHの設定は、Linux/Macの場合は標準Terminalを使えばよいが、Windowsの場合はCygwin、XmingなどX端末エミュレータソフトをインストールしていただく必要がある。またX端末エミュレーターをインストールしなくともWindowsでは有名なSSHクライアントソフトPuttyがダイナミックポートフォワードに対応しているためPuttyを使ってSOCKSプロキシ作成することも可能。詳しくは「Dynamic Port Forwarding with SOCKS over SSH」が参考になるかと。

SOCKSプロキシを使ったSSH接続

次に上記で作成したSOCKSプロキシを経由してVNET内のサーバにSSH接続をする。 netcatでSOCKSプロキシを経由してlocalhostから目的のVNET内サーバ(ServerX)間にnetcatトンネルを作成してServerXにはそのnetcatトンネルを通じて接続する。

local$ ssh -2 -l [Account] -o 'ProxyCommand nc -x localhost:1080 %h %p' [ServerX]

netcat のプロキシ指定は-xオプションで行う。 ここでは事前に作成したSOCKSプロキシ(localhost:1080)を指定。 netcatトンネルの作成コマンドはProxyCommandに記述する。こちらも毎回長いオプション入力を避けるために config(ssh_config)設定すると便利である。

~/.ssh/config

Host ServerX
   User        [Account]
   Protocol 2
   ForwardAgent  yes
   ProxyCommand nc -x localhost:1080 -w1 %h %p

注意点として、netcatにはGNU本家版とそれ以外にいくつか派生があるが-x オプションの利用可能なnetcatである必要がある。オリジナルのnetcatやGNU netcatには-xオプションはない。ここで使用しているnetcatはIPv6に対応しているOpenBSD netcat。

もちろんVNET内のVMへのSSH接続の別解としてProxyCommandでJump ServerからServerXへnetcatトンネルを作成してlocalからServerXにログインすることも可能。

local$ ssh -2 -o 'ProxyCommand ssh [Jump Server] nc -w1 %h %p' [ServerX]

実はこの方法のほうがProxyCommand でプロキシ設定を行うため事前に別コンソールで何かを用意する必要がなく間違いなくSOCKSプロキシ経由での接続よりも楽。ではSOCKSプロキシ経由で接続する理由は何か? 理由は単純で、通常Jump Serverはセキュリティ設定上の理由でログインしてもほとんど何もできないようにするために機能を無効化していることが多く、よってnetcatが使えない(ncはおろかsshコマンド以外ほとんど何も使えない)環境だったりする。この場合、上記で説明したようにSOCKSプロキシ経由でのSSHログインが有効な手段となる。

SOCKSプロキシ経由でのブラウジング

ブラウザーにSOCKSプロキシ対応のプラグインを 入れることでブラウザーによるプライベートリソース(内部ネットワーク内のアプリ・ミドルウェア等のウェブUIを持った管理ツールなど)の閲覧も可能となる。有名なものにSwitchySharp(Google Chrome)やFoxyproxy(Firefox)などがある。以下簡単な設定スクリーンショットを乗せておく。共に「http://yoichika-*.cloudapp.net*」なURIパターンの時にのみSOCKSプロキシlocalhost:12345経由でアクセスする設定となっている。

Google Chrome – SwitchySharp


GoogleChrome-SwitcySharp

Firefox – Foxyproxy


Firefox-FoxyProxyStandard

Internet Explorer – Out-of-box feature
As answered in Stack Overflow, Internet Explorer does support SOCKS proxies.
Tools > Internet Options > Connections > LAN Settings > Proxy Server > Advanced


IE-SOCKS-PROXY

Enjoy Accessing private resources with SOCKS Proxy!