はじめに
諸般の事情により、サーバー(コンテナ)を一つ、LAN 外から ssh 接続できるようにする必要が生じたので対応する。ファイル転送は scp , sftp で何とかなる。
外部から接続できるようにするだけなら、ルーターの設定で、公開するコンテナにポートを向ければ作業終了・・・とはならない。ネット上には良からぬ輩が虎視眈々とサーバーを乗っ取ろうとしているから最低限の対策は必要。
一般開放するわけじゃないから、公開鍵認証を使って特定のクライアント PC だけ外部から ssh 接続できるようにすれば目的は達成できる。ただ、それだと(予定はないけど)複数のサーバーに接続したい場合、Buffalo の Wi-Fi ルータなら IP フィルタの透過設定とポート変換をそれぞれサーバーの数だけ追加することになり如何にも芸がない。
なので、今回は ssh 接続用の踏台サーバーを用意して、ルーターで開放するポートは一つで、LAN 内のサーバーには踏台サーバーから接続することにしてみた。今動作しているサーバーの一つを踏台にしてもいいけど、自鯖クラスタにはまだまだ余裕があるから別サーバーを用意する。
・・・踏台サーバーには sudo できるユーザーを追加しておくこと。
踏台サーバーの公開鍵認証の設定
鍵ペアの作成
クライアント PC で作業する。踏台サーバーで鍵ペアを作ることもできるけど、秘密鍵をコピーまたは移動させることになるからお勧めはしない。公開鍵ならそもそも公開しても問題ない。
次のコマンドで ssh 接続するユーザー hoge の~/.ssh に鍵ペアを作る。Windows は調べてない。
$ cd ~/.ssh
$ ssh-keygen
〜〜〜
$ ls
id_rsa id_rsa.pub
ファイルパーミッションの変更
$ chmod 600 id_rsa id_rsa.pub
オプションなしなら RSA 方式で作成される。今お勧めのED25519 で作る場合は
$ ssh-keygen -t ED25519
〜〜〜
$ ls
id_ed25519.pub id_ed25519
踏台サーバーに登録後に見分けがつくようオプションでコメントを追加する場合。
無くても何かしらの記録は残る。
$ ssh-keygen -C comment
公開鍵の登録
作った鍵ペアのうち、公開鍵(ファイル名の後ろが pub)を踏台サーバーに登録する。この時点では ssh のパスワード認証でログインできるハズだけど、最悪でも PVE の管理画面からサーバーのコンソールで作業ができるから便利。
クライアント PC から ssh で踏台サーバー 192.168.1.100 に接続できることを前提とする。
登録は次のコマンドで完了する。
公開鍵の保存先やファイル名を変更(例は file.pub)している場合は -i ~/.ssh/file.pubとすれば良い。デフォルトの id_rsa.pub なら -i オプションは不要。
$ ssh-copy-id -i ~/.ssh/file.pub hoge@192.168.1.100
手作業の場合は、まずユーザー hoge でファイルを踏台サーバーにコピーする。
$ cd ~/.ssh
$ scp ./id_rsa.pub hoge@192.168.1.100:/home/hoge/.ssh/
踏台サーバーに接続して公開鍵を登録する。登録後は id_rsa.pub はいらないから削除する。
hoge@SSH-Proxy:~$ cd ~/.ssh
hoge@SSH-Proxy:~$ ls
id_rsa.pub
追加書き込みする。
hoge@SSH-Proxy:~$ cat ./id_rsa.pub >> authorized_keys
hoge@SSH-Proxy:~$ rm id_rsa.pub
ログアウト
接続テスト
クライアント PC から秘密鍵を使って接続してみる。
オプション -i ~/.ssh/id_rsa はファイル名や保存先を変更していなけれは不要。
鍵ペアを作るときに設定したパスフレーズを使ってログインする。
$ ssh -i ~/.ssh/ssh-proxy/id_rsa hoge@192.168.1.100
Enter passphrase for key '/home/hoge/.ssh/id_rsa': パスフレーズを入力
パスワード認証の無効化
無事に公開鍵認証で接続できたら踏台サーバーにログインして sshd_config を設定する。
デフォルト設定で公開鍵認証は有効となっているところのコメント(#)を外す。併せてパスワード認証、PAM 認証を無効にする。
hoge@SSH-Proxy:~$ sudo vi /etc/ssh/sshd_config
〜〜〜
PubkeyAuthentication yes
PasswordAuthentication no
UsePAM no
〜〜〜
LAN 内 サーバーへの踏台サーバー経由の接続
接続コマンドを省力化する(ProxyJump)
これまでの設定で、踏台サーバー(192.168.1.100)に接続したあと、そこから ssh で LAN 内の別サーバーに接続できるようになっている。
続いて、目的のサーバー(192.168.1.200)に直接接続できるよう、クライアント PC を設定する。
ssh の -J オプション(ProxyJump)を使うと、 ssh -J host_a,host_b host_x で踏台host_a と host_b を経由して host_x に接続できる。これを更に省力化する。
Wi-Fi ルータの設定で、外部から ssh 接続を待ち受けるポートは 20022 に変更済み。また、外部からポート 20022 への接続はポート変換で踏台サーバー 192.168.1.100 のポート 22 に変換している。
最初に、~/.ssh/config ファイルを作る。
$ vi ~/.ssh/config
## 踏台サーバー(Wi-Fi 設定済み)
Host _ssh-proxy
Hostname jisaba.life
User hoge
IdentityFile ~/.ssh/id_rsa
Port 20022
## ssh _http-server で接続
Host _http-server
Hostname 192.168.1.200
User hoge
Port 22
ProxyJump _ssh-proxy
最初の Host _ssh-proxy のところ、Hostname は外部から接続できるよう、名前解決できるものを設定する。ポートはルーターで待ち受けている番号にする。
Host _http-server のところは proxy 経由で接続するため ProxyJump を追加。踏台サーバーと 192.168.1.200 の間は普通のパスワード認証だから IdentityFile の行はない。
_http-server に接続してみる。$ ssh _Host としているのは、"_" に続いて tab キーを押したときに Host の入力候補が出てくるようにするため。
$ ssh _http-server
scp も同じように、
$ scp ./file.name _http-server:/home/hoge/
とかで、クライアント PC のファイルを(踏台を意識せず)目的のサーバーに転送することができる。
sftp も
$ sftp _http-server
で接続可能。
以前の方法(ProxyCommand)
ProxyCommand を使って踏台サーバーを経由しつつ、直接目的のサーバーに接続できる。こちらも同じように秘密鍵のパスフレーズの入力と、192.168.1.200 へのパスワード認証の入力が要求される。
$ ssh -o ProxyCommand='ssh -i ~/.ssh/id_rsa -p 22 -W %h:%p hoge@192.168.1.100' hoge@192.168.1.200
ProxyJump に比べてのメリットは、ちょっと試してみるのに1行で記述できることかな。
毎回入力するのは面倒なので、~/.ssh/config に設定を書き込んで、$ ssh _http-server とかで接続できるようにする(なら ProxyJump で良いよね)。
## 踏台サーバー(Wi-Fi 設定済み)
Host _ssh-proxy
Hostname jisaba.life
User hoge
IdentityFile ~/.ssh/id_rsa
Port 20022
## ssh _http-server で接続
Host _http-server
Hostname 192.168.1.200
User hoge
Port 22
ProxyCommand ssh -W %h:%p _ssh-proxy
ファイルマネージャー(Nautilus)でサーバーとファイル転送する
Ubuntu のファイルマネージャー Nautilus には標準で sftp や smb 、nfs などのプロトコルに対応している。
左ペインの「その他の場所」をクリックすると、画面下にサーバーアドレスを入力する箇所があるから、ここに
sftp://_http-server
と入力すれば、ローカルと同じようにフォルダーが表示される。もちろんコピーや削除も(権限次第で)普通にできる。~/.ssh/config の設定は Nautilus でも有効だから、FileZilla より簡単かもね。
FTP クライアント(FileZilla)を使ってサーバーとファイル転送する
踏台経由の ssh トンネリングで LAN 内のサーバーに接続する
ファイル転送でコマンドから sftp を使う場合は、これまでの設定で直接、LAN 内のサーバーに接続できる。これをFileZilla でもできないかとググってみたら、ssh トンネリングを使えはクライアント PC から LAN 内サーバーまで FileZilla でも直接接続できることがわかった。
まずはトンネルを作るコマンド。
-L はクライアント PC のポート 1234 を、踏台サーバーを経由して、192.168.1.200 のポート 22 に転送する場合。
$ ssh -N -L 1234:192.168.1.200:22 _ssh-proxy
ターミナルを閉じる(または Ctrl+c で終了する)までトンネルは有効なので、それまでは FileZilla で作業することが可能。
FileZilla を設定する
FileZilla を起動して、メニューの「サイトマネージャー」から「新規サイト」で設定する。
先の例だと、
- プロトコル : sftp
- ホスト : localhost
- ポート : 1234
- ログオンタイプ : 通常
- ユーザー : 接続先の ssh ログインユーザー
- パスワード : 接続先の ssh パスワード
これで、ターミナルを閉じるまではファイル転送が可能。
踏台サーバーに FileZilla を使って sftp 接続する
公開鍵認証の設定されているサーバーに FileZilla で接続する場合。
- プロトコル : sftp
- ホスト : jisaba.life
- ポート : 20022
- ログオンタイプ : 鍵ファイル
- ユーザー : 接続先の ssh ログインユーザー
- 鍵ファイル : (鍵ファイルを選択)
FileZilla の場合、選択する鍵ファイルは ppk 方式じゃないとダメらしい。なので、最初に ssh-keygen で作った鍵ペアの秘密鍵を変換する必要がある。
メニュー「編集」の「設定」から、「鍵ファイルの追加」をクリックするとパスフレーズを求められて変換されるから、保存先を選択してファイル名を入力すれば ppk ファイルが出来上がる。これを、サイトマネージャーの画面から選択すればOK。
おわりに
sftp と似て異なるもとのして ftps がある。ssl で通信を暗号化する https みたいなものなので、ログインしようとする人(クライアント PC)を限定できる訳ではない。
でも、接続先の公開ディレクトリなど細かく制御できるから、例えば /home/hoge より上は見えなくする、といったことは特に難しくない(proftpd で普通に可能)。
逆に、sftp だと基本、サーバー内が丸見えなので、アクセス権限を限定した専用ユーザーを作ったりと、何かと手間がかかる。
どちらが良いかは一長一短だけど、自分のケースだとコンテナごと一人で使う前提なので、sftp で良しとした。
コメント