satakesatakeの日記

2016-01-05

トンネリングを使った公開鍵認証の設定方法

| 10:39

弊社が管理するサーバはどれも、hosts.allowやらiptablesなどで接続元を限定している。

そのため、ssh port forwarding(トンネリング)が必須だ。

今回、新しいサーバを設置したため、公開鍵認証のおさらいをしたい。

サーバ構成

手順

以下の手順で公開鍵認証+トンネリングを実現する。

  1. 接続元(クライアント)にキーペア(公開/秘密鍵)を作る
  2. 公開鍵をポートフォワーディング用の接続先(example.net)にコピーする
    • ここは、ssh-copy-idを使用すると楽
    • 接続先のauthorized_keysに作成した公開鍵が追加される
    • 通常の設定であれば、ここまでをクリアすれば、公開鍵認証が実現できるんじゃないかと思う
  3. 下記のコマンドでクライアントの8022ポートにポートフォワーディングするための接続を開始
    • ローカルの8022ポート経由でexample.com:22への道が開かれる
  4. 公開鍵を目標の接続先(example.com)にコピーする

ちなみに公開鍵認証の設定はそれほど難しくなく、以下の二点を抑えておけばほぼ問題ない。

  • 接続元にキーペアを作成し
  • 接続先の.ssh/authorized_keysに公開鍵をコピーする

※もちろん接続先には公開鍵認証を有効にする適切な設定が必要だ

なお、パスフレーズが必要な場合もあるが、このパスフレーズは、秘密鍵を使う際に必要なもので、ネットワークには流れない。

参考→http://guinan.ten-forward.ws/wiki/doku.php?id=handout:ssh%E3%81%AE%E5%85%AC%E9%96%8B%E9%8D%B5%E8%AA%8D%E8%A8%BC%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%80%83%E3%81%88%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86

コマンド例

ここまで行うと、以下のコマンドで接続できる。

1行目は3番のポートフォワーディング用の接続だ。こいつはlocalhostの8022を開いてずーっと待っている。

2行目はexample.comへの接続。localhostの8022に接続するとexample.com通信が転送される。なお、some_account@localhostは、some_accountというアカウントで目標に接続しようとしている(ポートフォワーディングを行っているため、some_account@example.comとして読みかえるとわかりやすい)。

$ ssh -fNL 8022:example.com:22 -i ~admin/.ssh/id_rsa admin@example.net
$ ssh -p 8022 some_account@localhost

なお、ポートフォワーディング用ポートは放っておくといつまでもリッスン状態なので、手動で閉じてやる必要がある。以下でプロセスを終了させる。(この一文を覚えておくといい)

$ ps aux | awk '/[s]sh -fNL/ {print $2}' | xargs kill

どうでもいい話

キーペアは英語では、private keyとpublic key、日本語では秘密鍵と公開鍵。対義語としては問題ないと思うが、privateを秘密って訳すのもどうかなとか思ったりして。かといって私用鍵とか個人鍵ってのも変?だし。組み合わせとしては、秘密/公開よりも、private/publicのペアが好き。

"https://ja.wikipedia.org/wiki/%E9%8D%B5_(%E6%9A%97%E5%8F%B7)"

私有鍵とも言われるらしい。でもぜんぜんメジャーじゃない言い方だよな。

2012-06-22

コマンドラインでトンネリング(ポートフォワーディング)

| 17:57

$ ssh -fNL [リッスンするポート]:[接続先]:[接続先ポート] [ユーザ]@[経由先]

言葉で書くと少しわかりにくいから解説します。

まあ、要するに、指定したポートでリッスンしているから、そのポートに接続したら、任意サーバ経由して、任意の接続先につながるっていう。文字だけだとイメージしづらいかもしれない。

んで、このあと、こういう風にすると、

$ ssh -p [リッスンするポート] [ユーザ]@localhost

サーバ経由して、任意の接続先に接続できると。

実際の例。

$ ssh -fNL 8022:example.net:22 admin@example.com
$ ssh -p 8022 admin@localhost

これは、example.comを経由して、example.netにadminユーザでsshするっていう感じ。

接続先は「ssh -fNL~」で指定して、ふたつめのsshで実際にログインするということ。

ひとつめのsshは、バックグラウンドで8022ポートでリッスンしているので、ふたつめのsshは、localhostの8022ポートに接続しています。

接続先を制限しているサーバ有効

んで、このままだとバックグラウンドsshが生きたままなので、作業が終わったら落としてやらないといけない。

こんな感じで。

$ ps aux | awk '/[s]sh -fNL/ {print $2}' | xargs kill

sshプロセスIDをどっかに保存してくれるといいんだけど、そういうことはしてくれないみたいなので、力技で探してますorz

権限が770のホームディレクトリを持つユーザで、公開鍵認証を行う方法

| 16:52

sshd_configに以下を追加する(そして、sshdを再起動)。

StrictModes no

デフォルトではyesで、ホームディレクトリが所有者以外の書き込み権限を持っていると

  • Authentication refused: bad ownership or modes for file

こんなエラーを吐いて、ログインできません。.ssh/autorized_keysに所有者以外の書き込み権限がある場合も同様だそう。

ただ、この方法は、「推奨できない」方法だそうで、やむを得ない事情がある場合以外は、おとなしくホームディレクトリには700を設定しておくのが吉(ていうか普通はそうなっているはずだ)。