2011年5月11日水曜日

emacs TRAMP で、リモート・サーバを sudo で接続する

emacs の 「TRAMP」は大変便利なので、かなり以前から使っていたが、バージョンが「2.1」になってから、多段接続するためのメソッド「multi」が廃止となってしまった。
やりたい事は、
ローカルマシン -> ssh -> リモートサーバ -> sudo
ということで、TRAMPの「2.0」では、以下のようにすればよかった。
/multi:ssh:foo@remote:sudo:root@localhost:/...
これは、例えば、リモートサーバ側に emacs がインストールされておらず、かつ、root で作業したい場合、とても便利だった。

そこで、TRAMPのマニュアル「5.9 Connecting to a remote host using multiple hops」や、色々検索して調べてみたところ、
tramp-default-proxies-alist
に多段接続する条件を追加するらしい。設定方法は、 
(add-to-list 'tramp-default-proxies-alist
                  '("ホスト" "ユーザ" "接続方法")) 
「ホスト」、「ユーザ」には正規表現が使用でき、「nil」を指定すれば、すべての場合にマッチする。
つまり、「/メソッド:ユーザ@ホスト]とした場合、「接続方法」で記述した方法で一旦接続した後に、指定された方法で接続を行なう。
例えば、
(add-to-list 'tramp-default-proxies-alist
                  '("host2" "foo" "/ssh:foo@host1"))
とした場合、
/ssh:foo@host2:/...
に接続すれば、
ローカルマシン -> ssh -> foo@host1 -> ssh -> foo@host2
という経路で接続できる。これば、「host2」へ直接接続できない場合などで有効だが、これならば、ssh の設定でもできる。
  • ~foo/.ssh/config
Host host2
  ProxyCommand ssh foo@host1 nc %h %p
これで、「ssh host2」とすれば、
ローカルマシン -> ssh -> foo@host1 -> nc -> foo@host2
となる。この場合、踏み台にする「host1」から「host2」への接続に「nc」コマンドを使うので負荷も少ない。
ただし、「host1」への接続が、ユーザ「foo」でない場合は、この方法は使いずらい。「host1」から「host2」へは同じユーザで接続するからである。(「nc」を sudo で別ユーザで起動すればできるのかなぁ?)
とにかく、TRAMP では、リモートサーバで sudo (主に root)で作業する事に専念する事とした。したがって、
  • ~/.emacs 
(add-to-list 'tramp-default-proxies-alist
             '(nil "\\`root\\'" "/ssh:%h:"))
(add-to-list 'tramp-default-proxies-alist
             '("localhost" nil nil))
(add-to-list 'tramp-default-proxies-alist
             '((regexp-quote (system-name)) nil nil))
という設定を行なった。
最初の設定は、とにかく、ユーザが「root」なら、まず、ssh で指定ホスト(「%h」で置き換わる)に接続する。
2番目の設定は、ホスト名が「localhost」なら何もしない。
さらに、3番目の設定は、ホスト名がローカルマシンのホスト名なら、やはり、何もしない。
したがって、
/sudo:host1:/...
ならば、
ローカルマシン -> ssh -> host1 -> sudo
 と接続できる。「/sudo」メソッドでユーザ名を省略すると「root」が想定される。
また、
/sudo:localhost:/...
/sudo:myhost@mydomain.co.jp:/..
などとすれば、ローカルマシンで「sudo」が実行される。ちなみに「/sudo::/...」と、ユーザ名、ホスト名共に省略すると、「root@自ホスト名.自ドメイン名」が想定されるので、3番目の設定が、これに対応したものでもある。
ただし、3番目の設定は、emacs のバージョンが「21」ではエラーとなってしまうので注意が必要である。
まあ、横着せずに、ローカルマシンでも、リモートサーバでも、ホスト名はしっかり記述すれば良いのであるが…。

0 件のコメント: