目次
- 目次
- やりたいこと
- !注意!
- 環境
- そもそも公開鍵ってなんぞや?って人には。。。
- Step 0 ~Raspberry Pi Imagerを使ってSDに書き込む~
- Step 1 ~RaspberryPiの起動と、ログイン~
- Step 2 ~IPアドレスの固定化~
- Step 3 ~SSHのリッスンポートを変更~
- Step 4 ~ufwを使ってふぁいやーうぉーる
- Step 5 ~Google Authenticatorを使って2段階認証~
- 参考にさせて頂いたところ
やりたいこと
RaspberryPi 4 Model BにUbuntu Server 22.04を入れて、SSHがしたい。
余裕があれば、ログインに公開鍵とGoogle Authenticatorを用いた2段構えにしたい。
どうせなら、自分なりの自宅内ラズパイSSH鯖の初期設定も書いちゃおう
モニタがないので、Windows Terminal上からこれらの設定をしていく。
!注意!
ポート開放をして、外部からSSH出来るようにするHOWTOはこの記事では紹介してません。
ルーターによって設定が異なったり、そもそも契約内容によっては出来なかったりするので、各々調べてみてください。。。m( )m
環境
- ラズパイ:RaspberryPi 4 Model B
- SSHするクライアント:Windows 11にデフォで入ってるsshコマンド
- 入れるOS:Ubuntu Server 22.04 LTS
- OSイメージ焼くソフト:Raspberry Pi Imager1.7.2
そもそも公開鍵ってなんぞや?って人には。。。
以前、共通鍵暗号方式、公開鍵暗号方式について記事を書きました。
原理は同じなので、公開鍵についてよく知らないって方はこちらの記事を読んでみてください。
Step 0 ~Raspberry Pi Imagerを使ってSDに書き込む~
ホスト名の変更や、WiFiの設定、ユーザー名の設定は右下の歯車から変更できます。
後から、コンソール上で変更も出来ますが、自分は面倒くさがりなので、ここで設定しちゃいます。
下に各設定について書いていきます。
ホスト名
設定すると、mDNSに対応してる環境だと、LAN内ならIP直打ちしなくてもアクセスできるようになります。
SSHを有効化する
今回はSSHのログインに公開鍵認証を使いたいので、ちょこっと詳しく書きます。
1. 鍵ペアの作成
ssh-keygen -t ed25519
を叩いて鍵ペアを作ります。
Windows環境だと、C:\Users\ユーザー名\.ssh
以下に鍵が生成されます。Linux環境だと、~/.ssh
以下に生成されると思います。
2. 公開鍵をautorized_keysに登録
詳細な設定欄から、 SSHを有効化->公開鍵認証のみを許可する->ユーザーhogehogeのためのauthorized_keys
に作った鍵ペアの公開鍵を貼り付けてください。
公開鍵は拡張子が.pub
になっているものです。間違っても、秘密鍵を登録しちゃだめですよ?
ssh-ed25519 XXXXXXXXXXXXXXXXX hogehoge@HOGEHOGE
みたいになってたらそれが公開鍵です。
ユーザー名とパスワードを設定する。
見ての通りユーザー名とパスワードを設定できます。 Ubuntu Serverの場合、何も設定しなくても初回ログインの時にパスワードを変更するように言われますが、ここで設定しちゃうのが楽かもしれないです。
Wi-Fiを設定する
これも見ての通りWi-Fiが設定できます。
今回は有線LANを使う予定なので設定しませんでしたが、チェックを入れた時、PCがどこかしらのアクセスポイントに接続してると自動でSSIDとPWを設定してくれるみたいです。
ロケール設定をする
タイムゾーンの設定をしないと、時刻表記かUTCになってしまいます。
また、JISキーボードを使っている人は、ここで設定したほうがいいと思います。
Step 1 ~RaspberryPiの起動と、ログイン~
OSが書き込み終わったらラズパイに電源を投入して、SSHにログインします。
ここからは、以下のようにラズパイの設定をしたと仮定して進めていきます。
ラズパイのIPアドレス:192.168.0.XX ラズパイのホスト名:hogehoge.local ユーザー名:hage 作成した鍵ペアのファイル名:id_ed25519, id_ed22519.pub
ラズパイが起動したことを確認したら、早速ログインしていきます。
初回ログインの場合、SSHはデフォルトの22番ポートでリッスンされてるので、
ssh -i C:/Users/ユーザー名/.ssh/raspberry_ed25519 hage@hogehoge.local
で接続出来ると思います。
もし、mDNS非対応な環境なら
ssh -i C:/Users/ユーザー名/.ssh/raspberry_ed25519 hage@192.168.0.XX
で接続出来ると思います。
初めて接続する時にはこのようにこのホストを信用してもいいか?と聞いてくるので、一応フィンガープリントを確認してyes
とタイプしてください。
ログインに成功すると下のSCのように、ラズパイの状態を表示してくれます。
小咄~パスワードでSSHにログインしようとどうなるか?~
きちんと、SSHのログインに公開鍵のみ使われているか確認してみると
こんな感じに、Permission denied (publickey)
となってしまい、PWではログイン出来ないようになっています。
Step 2 ~IPアドレスの固定化~
/etc/netplan/
以下にあるyamlファイルを弄れば出来ますが、ルーターの方でも設定が必要なことがあります。
各ルーターによって設定が異なると思うので、各自調べてみてください。
sudo nano /etc/netplan/99-netcfg.yaml
を叩いてyamlファイルを作ります。
作ったら以下のように書き込んでください
network: ethernets: アダプタ名: dhcp4: false addresses: [設定したいIPアドレス/24] nameservers: addresses: [1.1.1.1,1.0.0.1] gateway4: ゲートウェイアドレス version: 2 renderer: networkd
アダプタ名などはip addr
コマンドなどを使って調べてみてください。
Step 3 ~SSHのリッスンポートを変更~
ゆくゆくは学校からとかでもSSH出来るようにしたいので、デフォルトの22番ではなく、リッスンポートを適当なものに変更します。
ポート番号は0~65535の中からここに乗っていないものを選びましょう。
もし65535に設定するとしたら
/etc/ssh/sshd_config
の一番下にこのように追記してください。
#User settings port 65535
変更したらsudo service sshd restart
でSSHデーモンを再起動して、設定したポート番号でログイン出来るか試してみてください。
65535番に設定した場合はssh -i C:/Users/ユーザー名/.ssh/raspberry_ed25519 -p 65535 hage@hogehoge.local
でログイン出来ると思います。
ちなみに、ポート番号が間違っていると、port 22: Connection refused
のように表示されます。
Step 4 ~ufwを使ってふぁいやーうぉーる
下にチートシートを作ったので、これを参考にして見て下さい。
設定を間違えると、ログインできなくなったりするので、必ず1セッションは残したまま作業してくださいね?
コマンド | 内容 |
---|---|
sudo ufw enable | ufwの有効化 |
sudo ufw disable | ufwの無効化 |
sudo ufw status | 現在設定されているルールとufwの動作状態 |
sudo ufw default deny | ufwをホワイトリスト方式で運用する、今回はこっち |
sudo ufw defalut allow | ufwをブラックリスト方式で運用する |
sudo ufw allow AAAA | AAAAポートへのアクセスを許可する |
sudo ufw deny AAAA | AAAAポートへのアクセスを拒否する |
sudo ufw allow 192.168.0.YY to any port AAAA | 192.168.0.YYからAAAAポートへのアクセスを許可する |
sudo ufw deny 192.168.0.YY to any port AAAA | 192.168.0.YYからAAAAポートへのアクセスを拒否する |
sudo ufw delete N | N番のルールを削除する |
Step 5 ~Google Authenticatorを使って2段階認証~
ここから、Google Authenticatorを使った2段階認証を導入していきます。
目標は公開鍵の認証とGoogle Authenticatorによる6桁コードの入力による、2段階認証です。
0. 対応アプリをDL
Google Authenticatorを使って2FAするので、もちろん対応アプリが必要です。
AndroidならAegis, Google Authenticator, Microsoft Authenticator
iPhoneならGoogle Authenticator, Authy, Microsoft Authenticatorあたりになるかな?
個人的にはAndorid勢ならAegisがおすすめ、Androidの自動バックアップのなかにデータを入れてくれるので、機種変がすんごく楽
1. パッケージの更新とアップグレード
sudo apt update && sudo apt upgrade
でパッケージの更新とアップグレードをします。
初めて実行するときは、すごい量のパッケージが更新されていくので気長に待ちましょう。
2. libpam-google-authenticatorのインストール
2段階認証用のPAMモジュールをインストールしていきます。PAMというのは、Linuxのあらゆるログイン処理に関わるモジュールです。
sudo apt install libpam-google-authenticator
ちなみに、QRコードを表示させるために、libqrencode4
もついでにインストールされます。
3. Google Authenticatorの設定
google-authenticator
を叩いて2段階認証の設定をしていきます。
Do you want authentication tokens to be time-based (y/n)
これは、時間ベースでコードを生成するか?という質問なのでyを入力します。
入力するとこのようにQRコードが表示され上部に画像へのリンク、下に秘密鍵が表示されます。
これをアプリで読み取ったら、Enter from app
となっているところに6桁の番号を入力します。
成功するとこのように、アプリが使えない場合の非常用コード5個が表示され
Do you want me to update your "/home/dtk-qry/.google_authenticator" file? (y/n)
と聞かれます。
これは、設定ファイルを書き出すか?と聞いてるので、yを入力します。
Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in-the-middle attacks (y/n)
これは、同じコードを複数回使うことを禁止するか?という質問です。yを入れた場合30秒に1回のみのログインになります。
今回は1度に複数のセッションをたてるためにnを入力しました
By default, a new token is generated every 30 seconds by the mobile app. In order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. This allows for a time skew of up to 30 seconds between authentication server and client. If you experience problems with poor time synchronization, you can increase the window from its default size of 3 permitted codes (one previous code, the current code, the next code) to 17 permitted codes (the 8 previous codes, the current code, and the 8 next codes). This will permit for a time skew of up to 4 minutes between client and server. Do you want to do so? (y/n)
これは、アプリとサーバー間で4分の時間のズレを許容するかという質問です。デフォルトは30秒なのでyにしておきました
If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting? (y/n)
これは、3回ログインに失敗すると、この30秒で生成されたコードは無効にするという設定です。
ただ、表示されてる数字を3回も間違えることはないと思うので、yを入力します
4. /etc/ssh/sshd_configの編集
SSHのログインに公開鍵認証とチャレンジレスポンス認証を有効にします。
(Google Authenticatorもチャレンジレスポンス認証の1種になります。)
/etc/ssh/sshd_config/
の末尾に以下を追記します
ChallengeResponseAuthentication yes AuthenticationMethods publickey,keyboard-interactive
また62行目付近にある
# Change to yes to enable challenge-response passwords (beware issues with # some PAM modules and threads) # KbdInteractiveAuthentication no
KbdInteractiveAuthentication no
を必ずコメントアウトしてください。最悪、ログインできなくなります。(1敗)
これで、SSHのログインに公開鍵(publickey),キーボードからの入力(keyboard-interactive)が求められるようになります。
しかし、このkeyboard-interactive
には自動でパスワードの入力を求める機能がついているので、それを無効化していきます。
5. PAMの設定 /etc/pam.d/sshd
先のパスワードが聞かれちゃう事象とそもそもlibpam-google-authenticator
を使うように設定をしていきます。
/etc/pam.d/sshd
の4行目にある
# PAM configuration for the Secure Shell service # Standard Un*x authentication. @include common-auth
@include common-auth
をコメントアウトさせます。これで、パスワードの入力を求められなくなります
# PAM configuration for the Secure Shell service # Standard Un*x authentication. # @include common-auth
こんな感じ
そうしたら、末尾に以下を追記します
# User settings auth required pam_google_authenticator.so nullok
nullok
はGoogle Authenticatorを設定していないユーザーは公開鍵認証のみでログイン出来るようにするためのオプションです。
ちなみに、入力中の6桁コードを表示させたい場合は
# User settings auth required pam_google_authenticator.so nullok echo_verification_code
のように、echo_verification_code
を追加してあげてください。
6. SSHの再起動
設定を更新するためにsudo service ssh restart
でSSHを再起動してあげてください
7. SSHにログインする
ここまでの設定がきちんと出来ていれば、このように、2段階認証用の2桁コードが求められます。
コードを入れてログインができれば、完璧です!!