どっかの高専生の技術備忘録

10割自分の備忘録用のブログ。

RaspberryPiにUbuntuサーバーを入れて公開鍵とGoogle Authenticator使ってSSHするまで

目次

やりたいこと

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に書き込む~

Raspberry Pi Imager
ホスト名の変更や、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とタイプしてください。

SSH Login
ログインに成功すると下のSCのように、ラズパイの状態を表示してくれます。
SSH Loged in

小咄~パスワードでSSHにログインしようとどうなるか?~

きちんと、SSHのログインに公開鍵のみ使われているか確認してみると こんな感じに、Permission denied (publickey)となってしまい、PWではログイン出来ないようになっています。

SSH Login Denied

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 restartSSHデーモンを再起動して、設定したポート番号でログイン出来るか試してみてください。
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

nullokGoogle Authenticatorを設定していないユーザーは公開鍵認証のみでログイン出来るようにするためのオプションです。
ちなみに、入力中の6桁コードを表示させたい場合は

# User settings
auth required pam_google_authenticator.so nullok echo_verification_code

のように、echo_verification_codeを追加してあげてください。

6. SSHの再起動

設定を更新するためにsudo service ssh restartSSHを再起動してあげてください

7. SSHにログインする

ここまでの設定がきちんと出来ていれば、このように、2段階認証用の2桁コードが求められます。
コードを入れてログインができれば、完璧です!!

参考にさせて頂いたところ

hana-shin.hatenablog.com

luciferous-report.hatenablog.com

デュアルブートしていたマシンで、OSを削除したのにブートオプションが残っている場合の対処法

目次

何が起こったか

Linux mintとのデュアルブート環境でLinux mintが入っていたパーティションを削除し、
その分をWindowsに割り当てたけど、起動オプションにLinux mintが残り続ける。
その起動オプションから起動すると GNU GRUBminimal bash like is supportedと表示される状態。
別に起動するときWindowsを選べばいいんだけど、気持ち悪いから消したい。
注意
UEFIブートなマシンなので、それ前提で書いています。その点、注意してください。

原因

Linux mintが入っていたパーティションは消したけど、ブートローダまでは消せてなかった模様。
てっきり、ブートローダLinux用に作ったパーティションに入ってると思ったら
Windowsブートローダと同じブートセクターに入っていた
インストールのときにミスった可能性がある。。。

解決方法

今回、Windowsとのデュアルブートだったので、
Windowsの回復オプションを起動させて、コマンドプロンプトからブートローダを消していく方法をやってみる。
(bootrecで直らないかなぁ、ってやってみたけど駄目だったOTL)
もし、LinuxLinuxとのデュアルブートだったり、Windowsの回復オプションが起動できない場合は

  • Windowsの起動メディアを作ってそこから起動
  • LinuxのはいったLive USBから起動

こんな感じで、別の方法を取る必要があると思う。
ちなみに、Windowsの回復オプションを表示する方法はShift キーを押しながら、GUIのPCを再起動をすると回復オプションが表示される

コマンドプロンプトの表示

回復オプションが表示できたらコマンドプロンプトを起動していく。
オプションの選択->トラブルシューティング->詳細オプション->コマンドプロンプト から起動できる。
起動するとカレントディレクトX:/windows/system32で起動する。
ドライブレターがXなのは回復用パーティションで起動しているからなので問題ない。

diskpartを使ってドライブレターの割り当て

diskpartを使ってブートセクターを操作できるようにする。
おそらく、初期のままだとブートローダのあるパーティションにドライブレターが割あたってなく、操作できないのでここから始めていく。
コマンドプロンプトが起動できたら、diskpartコマンドを実行してdiskpartを起動させる。
起動できると

Microsfot DiskPart バージョン XXXX

Copyright (C) Microsoft Corporation.
コンピューター: XXXXX

DISKPART>

と表示される。
そうしたら、list volumeを実行して、そのディスク上にあるパーティションもといボリュームを表示する。
そうすると

DISKPART> list volume

 Volume ###  Ltr  Label  Fs    Type       Size   Status  Info
 ----------  ---  -----  ----  ---------  -----  ------  ----
 Volume 0     C   OS     NTFS  Partition  XXXGB  正常
 Volume 1         ESP    FAR32 Partition  250MB  正常    非表示
 以下略

な感じで表示される。
ブートローダが入っているのはESP (EFI System Partition)なのでこのボリュームに対してドライブレターを割り当てていく。
ESPについてはここにわかりやすく載っている。
今回はこのVolume 1 に対してEを割り当てていく。
select volume=1を実行するとボリューム 1 が選択されましたと表示され、volume 1を選択状態にできる。
試しにlist volumeをしてみると
そうすると

DISKPART> list volume

 Volume ###  Ltr  Label  Fs    Type       Size   Status  Info
 ----------  ---  -----  ----  ---------  -----  ------  ----
 Volume 0     C   OS     NTFS  Partition  XXXGB  正常
*Volume 1         ESP    FAR32 Partition  250MB  正常    非表示
 以下略

こんな感じで、先頭にアスタリスクが表示されるようになる。
そうしたらassign letter=Eを実行し、ドライブレターを割り当てる。

DISKPART> assign letter=E

DiskPartはドライブ文字またはマウントポイントを正常に割り当てました。

と表示されたのを確認してから、もう一回list volumeをしてみると

DISKPART> list volume

 Volume ###  Ltr  Label  Fs    Type       Size   Status  Info
 ----------  ---  -----  ----  ---------  -----  ------  ----
 Volume 0     C   OS     NTFS  Partition  XXXGB  正常
*Volume 1     E   ESP    FAR32 Partition  250MB  正常    非表示
 以下略

と表示され、実際にEが割り当てられたことが確認できる。
これができたら、exitしてdiskpartは終了させて、
Linux mintブートローダを削除していく。

コマンドプロンプトからブートローダの削除

コマンドプロンプトに戻ってきたら、E:を実行して、カレントディレクトリをE:/に切り替える。
そこでdirしてみるとEFIというディレクトリがあるはずなので、そこに移動する。
そうしたら、MicrosoftDellubuntuやら色々ディレクトリがあるが、
今回消したいのはLinux mintブートローダなので、このubuntuディレクトリをまるまる削除する。
ちゃんと中身を確認して、目的のディレクトリなのを確認してから削除して下さい
自分の環境の場合、ubuntuディレクトリ内は

E:/EFI/ubuntu>dir
 ドライブEnoボリューム ラベルはESPです
 ボリュームのシリアル番号はXXXX-XXXXです

YYYY/MM/DD HH:MM  grubx64.efi
YYYY/MM/DD HH:MM  shimx64.efi
YYYY/MM/DD HH:MM  mmx64.efi
YYYY/MM/DD HH:MM  BOOTX64.CSV
YYYY/MM/DD HH:MM  grub.cfg

このディレクトリを中のファイルまるごと再帰的に削除するには
rd /s E:/EFI/ubuntu と実行すればよい、このとき確認が入るのでYを入力してEnterを押せば削除される。

割り当てたドライブレターを削除する

無事にブートローダが削除できたら、先程ESPに割り当てたドライブレターEを割り当て解除する。
不用意な事故を防ぐためにやっておいた方がいいと思う。。
もう一度diskpartを起動させて、ボリュームの選択、そうしたらremvoe letter=Eを実行する。

DISKPART> remove letter=E
DiskPartはドライブ文字またはマウントポイントを正常に削除しました。

と表示されたのを確認してからlist volumeをしてみると

DISKPART> list volume

 Volume ###  Ltr  Label  Fs    Type       Size   Status  Info
 ----------  ---  -----  ----  ---------  -----  ------  ----
 Volume 0     C   OS     NTFS  Partition  XXXGB  正常
*Volume 1         ESP    FAR32 Partition  250MB  正常    非表示
 以下略

となり、正常にドライブ文字が削除されているのを確認できる。
ここまでくれば、GNU GRUBが表示されることなく、Windowsが起動するようになる。

結論

大人しく、仮想マシンで我慢しておけばよかった。

Termuxを使って面倒な広告無しで動画をDLしてくる方法

yt-dlpを使うように変更しました

youtube-dlに速度制限がかけられています、また開発もyt-dlpのほうが活発なのでこちらを使用するように記事を書き換えました。

Attension!!!

違法に公開された音楽や映像とわかっていながらダウンロードする行為は刑事罰の対象となります。参考違法ダウンロードについて知っておきたいこと
この記事に書かれている内容を真似する場合は自己責任でお願いします。m( )m

目次

やりたいこと

Termux(ターミナルエミュレータ)とyt-dlp(様々なサイトから動画をDLできるスクリプト)を使って、広告無し、面倒なアプリ起動無し、好きな場所へ保存を実現したい

2022-01-06追記

以下の作業を一括で出来るようにスクリプトを作成しました。
以下のコマンドを実行すれば使い方だけ見ていただければ問題ありません。

 sh <(curl -s https://raw.githubusercontent.com/datsuka-qwerty/Sublimetext3-Backup/master/Others/usercommand/termux-install)

Termuxのダウンロード

PlayStore版F-Droid版の2つがありますが、現在サポートされているのはF-Droid版になります
今回のためだけに使うならPlayStore版でもOK
2021/12/01追記
どうやら、PlayStore版の方ではapt updateを実行したさい、リポジトリからエラーが返ってくるそうです。
もし、PlayStore版で動かす場合は、apt updateコマンドを除外して、実行してください。

Termuxの初期設定

aptの更新

以下のコマンドを実行して、パッケージを更新します。
スマホでいう、アップデートみたいなものです

 apt update && apt upgrade -y

ストレージへのアクセス許可

デフォルトの状態だと、動画をDLしても、Termuxからでないとアクセス出来ない状態になってしまいます。なので、スマホの内部ストレージへのアクセス許可を与えてあげます。
そのためのコマンドが用意されているので実行してください。

 termux-setup-storage

許可すると以下の表のように内部ストレージへアクセスができるようになります。 間違ってもrm -rf /とかやらないようにしましょう。
最悪全部データが飛びます。

実際の場所 Termux上での表示
/storage/emulated/0/DCIM ~/storage/dcim/
/storage/emulated/0/Movies ~/storage/moives/
/storage/emulated/0/Music ~/storage/music/
/storage/emulated/0/Pictures ~/storage/pictures/
/storage/emulated/0/Download ~/storage/downloads/
/storage/0000-0000/Android/data/com.termux/files ~/storage/external-1/
/storage/emulated/0 ~/storage/shared/

必要なパッケージのインストール

コマンドを実行すれば、必要なパッケージ(アプリ)がインストールされます。

 apt update && apt install -y nano curl python ffmpeg

yt-dlpのインストール

各種サイトから動画・音声をDLできるスクリプト youtube-dlをpip経由でインストールします。

 pip install youtube-dl

共有画面から使えるようにする

Termuxでは~/bintermux-url-openerというファイルを作ると、
共有画面からTermuxを選択したとき、URL等を第一引数としてtermux-url-openerを実行してくれます。
以下のコマンドで私が使ってるスクリプトを~/bin/へコピーします

 mkdir ~/bin && curl https://raw.githubusercontent.com/datsuka-qwerty/Sublimetext3-Backup/master/Others/termux-url-opener -o ~/bin/termux-url-opener && chmod +x ~/bin/termux-url-opener

このスクリプトは動画や、音声をスマホのDownloadフォルダにyoutube-dlというフォルダ名で保存します。
変更したい場合は、以下のコマンドでtermux-url-openerを開いて、この表のTermux上での表示を参考に画像にあるSAVE_PATHを変更してください。 nano ~/bin/termux-url/opener もし、Moviesフォルダの中のYouTubeというフォルダに保存したい場合はSAVE_PATH="~/storage/movies/YouTube/"という風に変更してください。
また、保存して終了するときは、CTRLをタップした後に、Oを入力し、その後にまたCTRLをタップし、Xを入力してください。
実行後は念の為一度アプリを終了し、また起動させてあげてください。
(通知バーで生き残ってるかもしれないので、よく見てあげてください。)

使い方

ここでDLする動画は私が作成し、YouTubeにうpしている動画です。

  1. 共有画面を開く
  2. 動画の種類を選択する
    画面に表示されている数字を、キーボードを使って入力してください。
    音声としてDLしたい場合は、4です。
    11, 22のNormalというのは、youtube-dlにそのままURLを渡すだけです。
    (自分のスクリプトは、チャンネル単位や、プレイリストをDLしたさい、アップロード日が若い順にファイルを命名するような形にイジってあります)
  3. 放置
    Dlが終わるまで、放置してください、Short動画や、ニコニコ動画など、youtube-dl側が対応してないサイトなどはエラーが帰ってきます。
    詳しくはここを見てください。
  4. 確認
    ZArchiver等で確認してみると、キチンとDownloadフォルダの中のyoutube-dlフォルダに動画が保存されているのがわかります。
  5. アップデート
    先程のこの画面で99を選択すると、自動でyoutube-dlをアップデートします。

おわりに

初心者向けに、コピペをすれば動くような形で書いてみましたが、Termuxというアプリの特性上、ファイルとフォルダの違いくらいは理解してないと難しいかもしれないです。
質問等あれば、お気軽にコメントしていってください!

追記を見るにはクリックして下さい 2021/11/29 コマンドのスペルミスを修正しました。
2021/12/01 PlaySotre版がサポートされなくなった件を書き足しました。 2022/01/06 作業を一纏めにしたスクリプトを使用するように変更。また、yt-dlpを使うように変更

参考

ytdl-org.github.io

qiita.com

xtech.nikkei.com