Vagrant で SSH の接続ポート番号を変えると、けっこう複雑になるという話

この記事は書かれてから1年以上が経過しており、最新の情報とは異なる可能性があります

2015/04/01追記:続き書きました。Vagrant で SSH の接続ポート番号を変える、という発想がそもそも間違ってた

最近は、隙を見つけて(あんまりないけど) Vagrant + Chef で色々検証をしてたりします。

現実のサーバ構築になるべく即した形でレシピを書こうとしたとき、 SSH のポート番号を変更する、といったケースは往々にして出てくるかと思います。(デフォルトは22ですが、そのまま22を使うとアタックを受けやすくなるので変えましょう、という記事は山のようにありますね)

SSH 接続のポート番号を変更 | EasyRamble

ただ、Vagrant で SSH のポート番号を変更すると、ちょっとしたところではまってしまって 思いのほか時間がかかったところがあったので、その部分だけメモっておきたいと思います。

なお、CentOS 6 での検証です。他のディストリビューションで設定ファイルなどが異なる可能性はありますが、考え方などはほぼ共通しているかと思いますので、適宜置き換えて考えていただければと思います。

通常のサーバの設定箇所

まず、Vagrant などを使わずに設定する場合、どのファイルをいじる必要があるかというと、以下のファイルになるかと思います。

  1. /etc/ssh/sshd_config
  2. /etc/sysconfig/iptables

1.は、SSH のポート番号を何番にするか?などの設定ファイルです。(もちろん他にも色々項目ありますが)

こちらに、

Port 22

という設定が書かれているので、これを適当な番号、

Port 12424

などとして、 /etc/init.d/sshd restart で SSH のサービスを再起動することで設定が有効になります。

2.は、そのポート番号の通信を許可するかどうか?などの設定ファイルです。

こちらに、

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

という設定が書かれているので、こちらも先ほどの番号に合わせる形で

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 12424 -j ACCEPT

などとします。 こちらも同様に /etc/init.d/networking restart でネットワークの再起動をすることで設定が有効になります。

ここまでは特に新しいことではなく、”linux ssh ポート 変更” とか、”linux iptables” とかでググればたくさんありますので、紹介程度にとどめておきます。

Vagrant + Chef で行う場合

今までの記事、http://girigiribauer.localhost/archives/1048 などを見てもらえれば分かるように、 各 Resource のうち、以下だけで上記レシピは書くことができるはずです。

  • file(ファイルの設置)
  • service(サービスの起動・停止・再起動)

ですが、結論から言うと、 SSH のポート番号を変えた際に、vagrant コマンド経由で仮想マシンへの接続が出来なくなってしまい、 (正確には、ポート番号を変えてサービスの再起動を行ったタイミングですね) 結果として上手くいきませんでした。

具体的には、vagrant up にて、最初のレシピが実行され、vagrant up の終了までは上手くいきます。 ですが、そこから vagrant halt や、vagrant reload などを行っても、そもそも仮想マシンとの通信が上手くいかなくなってしまい、最終的には vagrant destroy で世界の終わりを迎えるしかなくなってしまいます。

うーん、困りましたね。みなさんどうしているのでしょうか?

vagrant up などで使うポート

vagrant up や、vagrant halt 、または vagrant reload のコマンドで仮想マシンに接続するのですが、 こちらの接続にも(おそらく)SSH が使われています。 デフォルトで22番ポートを使用することになるかと思います。

1回も仮想マシンを動かしておらず、Chef のレシピも実行されていないとき、仮想マシンのセットアップ処理が走ります。

結果として、vagrant という名前のユーザーとともに、すべて初期の設定ファイルが設置されるため、 SSH の接続も、最初は22番ポートでせざるをえないのかなーと思います。

解決方法を色々考えてみた

まず前置きとして、Vagrantfile に書かれていない SSH の設定項目が存在しています。

ホストOSとゲストOSを SSH で接続する際、ホストOSの22番ポートを使わず、代わりに別の番号(2222番とか)を使用する、ポートフォワーディングの設定が暗黙的に行われています。

  • host:2222 => guest: 22

この設定が暗黙的に行われることで、ホスト側の2222番ポートでアクセスすると、ゲスト側である仮想OSの22番ポートに接続される、といった仕組みです。

今回やりたいのは、初回のレシピが実行され、SSH のポート番号が変更された時点で、

  • host: 2222 => guest: 12424

という接続ポート番号の変更を行いたいわけです。

無理っぽくね?

Vagrantfile が解釈されるのは、vagrant up などのコマンドが入力された時点になるかと思います。

その後レシピが実行されて SSH のポート番号が変更になっても、初回実行時はまだ22番ポートで普通に接続しているので、 レシピの実行が終わり、vagrant halt もしくは vagrant reload で再度仮想マシンに接続し直すと、 もうすでにポート番号が変わっていて、22番で接続できなくなっているという状態に陥ります。

Vagrantfile 上での SSH のポート番号の変更

ちなみに、Vagrantfile 上で SSH のポート番号の変更をするには、以下のように書けば良いっぽいです。

ssh_port = 12424

Vagrant.configure("2") do |config|
  config.vm.box = "CentOS_6.4_x86_64_Minimal"

  config.ssh.guest_port = ssh_port

  config.vm.define :vmclient1 do |vmclient|

    vmclient.vm.hostname = "vmclient1"
    vmclient.vm.network :private_network, ip: "192.168.100.11"
    vmclient.vm.network :forwarded_port, guest: ssh_port, host: 2222, id: "ssh"
(以下略)

ゲスト側、つまりレシピが実際に動いている仮想OS上の SSH ポート番号を、変数 ssh_port としてありますが、当然直に書いても動きます。

forwarded_port の設定で、 id: “ssh” と付け加えてやることで、SSH のデフォルトで動くポートフォワーディングの設定の上書きが出来るようです。

レシピ実行中に SSH のポート番号を変える・・・?

Vagrantfile 上でなんとかレシピの実行中にポート番号変えられないかと色々調べてもみましたが、やはり無理そうです。

となると、 Vagrantfile 上でポート番号を変えるまでは、サービスの再起動などをしてはいけないことになります。

初回だけは、22番ポートを使って接続しつつ、設定ファイルのみ書き換えておき、サービスの再起動は後回し。 その後仮想OSをシャットダウンさせ(vagrant reload だと、この後 Vagrantfile を書き換えるタイミングを見失うので、ここでは vagrant halt でシャットダウンさせる)、 Vagrantfile の、さっきの ssh_port の変数のところを 22 から 12424 などに変え、vagrant up でゲストOSを立ち上げます。

こうすれば、SSH のポート番号の変更が可能になるわけですが、非常にめんどくさい話ですね。

まとめ

本当に何から何まで自動化したい場合は、vagrant コマンドの外側を管理する何かが必要になるんじゃないかなーとか思ってます。 (1回目の起動は22番使って、そこから自動で vagrant halt して、Vagrantfile のポート書き換えて再度 vagrant up してくれる何か)

とはいっても、そこまで厳密にワンストップですべて自動化したいかと言われると、そうでもなかったりするので、 SSH のポート番号を変えたいときは、以下の手順でやろうと思いました。

  1. 初回だけ22番で動かし、ssh の設定を走らせる(サービスの再起動はしない
  2. vagrant halt で一旦シャットダウンする
  3. Vagrantfile のポート部分書き換え
  4. 普通に vagrant up

逆になんかいい方法あれば教えてほしいです。ぜひ。

この記事は書かれてから1年以上が経過しており、最新の情報とは異なる可能性があります

もし記事内に誤りなどございましたら、 @girigiribauer @girigiribauer.com までご一報いただけると助かります。

Related articles