ClockworkPi uConsole: RDP接続を行うためのxrdp設定方法, ホーム領域のeCryptfsでの暗号化方法

ClockworkPi uConsole: RDP接続を行うためのxrdp設定方法, ホーム領域のeCryptfsでの暗号化方法
Page content

uConsoleを安心してモバイルしたい&楽したい

本記事は次の記事の続きになります。

ClockworkPi uConsoleはストラップも付けられるその形状から、どんどん気軽に持ち歩くべきモバイル端末に思えます (上記Tweetの@highvis_supplyさんはモバイルを極めてらっしゃる)。ならば私は、もしもの時の紛失に備えて内部データを暗号化しておきたいし、uConsoleをGUI操作するときにはどこでも、可能ならば大きい画面やキーボードから遠隔操作して楽をしたい。そこで次の条件を満たすよう、uConsole環境を作り直してみることにしました。

  1. uConsoleの画面ではclockworkPi提供のOS (Raspberry Pi OS) のGUIを利用し、かつuConsoleへRDP接続して同じGUIを利用できること
  2. uConsoleのmicroSD領域の暗号化を可能な限り広い範囲で行うこと (少なくともホーム領域 ($HOME) は暗号化すること)

今回はこれらを実現するための作業手順をメモします。

項目内容
機種ClockworkPi uConsole Kit RPI-CM4 Lite
OSイメージuConsole_CM4_v1.3g_64bit.img.7z
microSDカードこれを機会に添付品32GBから手元にあったSanDiskの高耐久な64GBへ交換
端末名uconsole
初期ユーザuser1
暗号化作業用の一時的なユーザuser2
SanDisk 【 サンディスク 正規品 】メーカー 2年保証 ドライブレコーダー対応 microSDカード 64GB UHS-I Class10 U3 V30対応 SDSQQNR-064G-GH3IA 新パッケージ

SanDisk 【 サンディスク 正規品 】メーカー 2年保証 ドライブレコーダー対応 microSDカード 64GB UHS-I Class10 U3 V30対応 SDSQQNR-064G-GH3IA 新パッケージ

SanDisk

RDP接続できるようにする手順

Step-0. 事前知識: RPi OSのxrdpに関する問題と対策

Raspberry Pi (4系?) に「Raspberry Pi OS (bullseye)」を組み合わせた環境で、xrdpを通常通り導入した後、最初に作られている初期ユーザのデスクトップ環境にはRDP接続できない事情?バグ?があるらしい。原因を突き止めようとした私の実験でも、RDP接続を行うユーザがグループrenderに所属しているか否かでRDP接続の動作が異なることまでは分かりました (調査で数時間を溶かしたのは痛かった)。

「render」というワードも加えて詳しく検索してみると、ラズパイ界隈では以前からある程度知られた問題らしくシンプルな対策方法も見つけたので、今回の手順にはこれを取り込んでいます。

Step-1. OSをインストールして最新状態にする

  1. uConsole/images at master · clockworkpi/uConsole から最新のOSイメージをダウンロードして、EtcherなどでmicroSDカードへ焼く
  2. 最低限の設定を施しながらuConsoleへOSをインストール
    • 「Set Country」では、Country: Japan, Language: Japanese, Timezone: Tokyo, Use English Language: True, Use US Keyboard: True を選択
    • 初期ユーザ名: user1
    • 「Set Up Screen」Reduce…は無効のままNextを選択
    • 「Update Software」ではNextを選択 (更新の実施は任意ですが、今回の手順はここで実施したことを前提に書いています)
  3. OS再起動後、ユーザuser1のGUI画面にAuto Loginして、Wi-Fiが見えていない状態になる
  4. sudo raspi-configを実行
    1. Hostnameを変更: 1 System Options > S4 Hostname > お好みのものを入力
    2. Auto LoginなしのConsoleに切り替え: 1 System Options > S5 Boot / Auto Login > B1 Console
    3. SSHサーバを有効化: 3 Interface Options > I2 SSH > Yes
    4. Wi-Fiが見えていない問題の解消: 6 Advanced Options > AA Network Config > 1 dhcpcd (※dhcpd: 4G/LTEモジュールと併用した場合も問題ないかどうかは未検証です)
  5. OS再起動を実施 (再起動後はSSHログインできるようになっている)

Step-2. RDP接続できるようにする

  1. uConsoleにSSHログインする: ssh -l user1 uconsole
  2. xrdpをインストールする: sudo apt update; sudo apt install xrdp
  3. ユーザxrdpが証明書ファイル/etc/xrdp/key.pemを読み取れるように、ユーザxrdpをグループssl-certに所属させる:
    $ id xrdp
    uid=116(xrdp) gid=124(xrdp) groups=124(xrdp)
    
    $ sudo adduser xrdp ssl-cert
    Adding user `xrdp' to group `ssl-cert' ...
    Adding user xrdp to group ssl-cert
    Done.
    
    $ id xrdp
    uid=116(xrdp) gid=124(xrdp) groups=124(xrdp),118(ssl-cert)
    
  4. 前述の「RPi OSのxrdpに関する問題と対策」として設定ファイルを一部変更する
    ## Ref: https://github.com/neutrinolabs/xrdp/issues/2060#issuecomment-980071431
    $ sudo cp -a /etc/X11/xrdp/xorg.conf{,.original}
    $ sudo vi /etc/X11/xrdp/xorg.conf
    $ diff /etc/X11/xrdp/xorg.conf{.original,}
    54c54,55
    <     Option "DRMDevice" "/dev/dri/renderD128"
    ---
    >     #Option "DRMDevice" "/dev/dri/renderD128"
    >     Option "DRMDevice" ""
    
  5. OS再起動を実施 (再起動後はユーザuser1でRDP接続ができるようになっている)
  6. (任意) uConsoleへ直接ログインする時の画面をDesktopへ変更する:
    • sudo raspi-configを実行してAuto LoginなしのDesktopに切り替え: 1 System Options > S5 Boot / Auto Login > B3 Desktop
  7. 実際にmacOS環境からuConsoleへのRDP接続を試すとこうなります

Step-3. ついでにその他の私的な設定

  1. Tailcaleをインストールする: https://tailscale.com/download
    • Tailscale経由だとネットワーク的な境界を全く気にせず、uConsoleへSSH接続やRDP接続できるようになる
  2. 他へのアクセス用に、SSH鍵をPassphrase付きで生成する: ssh-keygen -t ed25519
  3. lsの表示順を好みどおりにするためlocale設定を変更する: sudo update-locale LC_COLLATE=C

ホーム領域をeCryptfsで暗号化する手順

eCryptfsという便利な仕組みがあり、ユーザのホーム領域を未使用時には暗号化した状態にして、ユーザがログインするときに復号化状態のホーム領域としてマウントするという動作が簡単に実現できるとのこと。uConsoleの紛失への備えとしては、内部データ全て (microSD領域全体) を暗号化することがセキュリティ的にベターであろうが、今回はeCryptfsを使ったホーム領域の暗号化のみを目標とします。

なお、今回の手順のようにeCryptfsでホーム領域を暗号化した場合、「起動後のuConsoleでホーム領域がまだ復号化されていないときには、uConsoleへのSSHログインで公開鍵認証が利用できない」という弊害が生まれます。ユーザの秘密鍵が通常はホーム領域内 (~/.ssh/) に保存されているためです。パスワード認証でのSSHログインは従来通り可能です。

上記の弊害と暗号化のメリットのバランスを理解したうえで進めるとして、作業手順は次の通りです。

Step-1. 作業用ユーザを準備する

  1. 作業前に現時点のファイルシステム状態を確認する
    user1@uconsole:~ $ df -h
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/root        60G  5.8G   51G  11% /
    devtmpfs        1.7G     0  1.7G   0% /dev
    tmpfs           1.9G     0  1.9G   0% /dev/shm
    tmpfs           760M  1.3M  758M   1% /run
    tmpfs           5.0M  4.0K  5.0M   1% /run/lock
    /dev/mmcblk0p1  253M   43M  210M  17% /boot
    tmpfs           380M   20K  380M   1% /run/user/109
    tmpfs           380M   24K  380M   1% /run/user/1000
    
  2. eCryptfsのユーティリティパッケージをインストールする: sudo apt install ecryptfs-utils
  3. 暗号化作業を行う一時的なユーザuser2を作成して、グループsudoに所属させる: sudo adduser user2 && sudo adduser user2 sudo
  4. 初期ユーザuser1を完全にログアウトさせる
  5. user2としてログインする: ssh -l user2 uconsole
  6. 暗号化作業を行う準備が整っているか確認する
    ## user2がrootになれることの確認
    user2@uconsole:~ $ sudo whoami
    [sudo] password for user2: 
    root
    
    ## user1が実行しているプロセスがないことの確認
    user2@uconsole:~ $ pgrep -u user1
    (なにも表示されない)
    

Step-2. ホーム領域を暗号化する

  1. user1のホーム領域の暗号化を行う: sudo ecryptfs-migrate-home -u user1
    user2@uconsole:~ $ sudo ecryptfs-migrate-home -u user1
    INFO:  Checking disk space, this may take a few moments.  Please be patient.
    INFO:  Checking for open files in /home/user1
    lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/109/gvfs
    	Output information may be incomplete.
    Enter your login passphrase [user1]: 
    
    ************************************************************************
    YOU SHOULD RECORD YOUR MOUNT PASSPHRASE AND STORE IT IN A SAFE LOCATION.
    ecryptfs-unwrap-passphrase ~/.ecryptfs/wrapped-passphrase
    THIS WILL BE REQUIRED IF YOU NEED TO RECOVER YOUR DATA AT A LATER TIME.
    ************************************************************************
    
    
    Done configuring.
    
    chown: cannot access '/dev/shm/.ecryptfs-user1': No such file or directory
    INFO:  Encrypted home has been set up, encrypting files now...this may take a while.
    sending incremental file list
    ./
    .Xauthority
    			110 100%    0.00kB/s    0:00:00 (xfr#1, ir-chk=1025/1027)
    .bash_history
    		1,360 100%  664.06kB/s    0:00:00 (xfr#2, ir-chk=1024/1027)
    (途中省略)
    Could not unlink the key(s) from your keying. Please use `keyctl unlink` if you wish to remove the key(s). Proceeding with umount.
    
    ========================================================================
    Some Important Notes!
    
    1. The file encryption appears to have completed successfully, however,
    	user1 MUST LOGIN IMMEDIATELY, _BEFORE_THE_NEXT_REBOOT_,
    	TO COMPLETE THE MIGRATION!!!
    
    2. If user1 can log in and read and write their files, then the migration is complete,
    	and you should remove /home/user1.dDSN7Xlq.
    	Otherwise, restore /home/user1.dDSN7Xlq back to /home/user1.
    
    3. user1 should also run 'ecryptfs-unwrap-passphrase' and record
    	their randomly generated mount passphrase as soon as possible.
    
    4. To ensure the integrity of all encrypted data on this system, you
    	should also encrypt swap space with 'ecryptfs-setup-swap'.
    ========================================================================
    
    user2@uconsole:~ $
    
  2. 気持ちを落ち着ける (※ここではまだuConsoleのOS再起動をしてはならない)
  3. 1の最後「Some Important Notes!」に表示されている作業を行う
    1. 別の端末画面を開き、user1としてuConsoleにログインする: ssh -l user1 uconsole
    2. user1として自分のホーム領域でファイルの読み書きが正常に行えるかを確認する
      • ファイルの読み書きが異常であればホーム領域をバックアップから戻す
    3. user1としてecryptfs-unwrap-passphraseを実行して、表示される32文字の文字列を大切にメモしておく
  4. user1のホーム領域の暗号化は問題ないと確認できたとして、OS再起動する

Step-3. ログイン時のホーム領域の状態を確認して、作業ユーザを削除する

  1. user2としてログインしてファイルシステム状態を確認する (特に変わったところはない)
    user2@uconsole:~ $ df -h
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/root        60G  5.9G   51G  11% /
    devtmpfs        1.7G     0  1.7G   0% /dev
    tmpfs           1.9G     0  1.9G   0% /dev/shm
    tmpfs           760M  1.3M  758M   1% /run
    tmpfs           5.0M  4.0K  5.0M   1% /run/lock
    /dev/mmcblk0p1  253M   43M  210M  17% /boot
    tmpfs           380M   20K  380M   1% /run/user/109
    tmpfs           380M   20K  380M   1% /run/user/1001
    
  2. user1としてログインしてファイルシステム状態を確認する → /home/user1/にマウントが増えている
    user1@uconsole:~ $ df -h
    Filesystem            Size  Used Avail Use% Mounted on
    /dev/root              60G  5.9G   51G  11% /
    devtmpfs              1.7G     0  1.7G   0% /dev
    tmpfs                 1.9G  4.0K  1.9G   1% /dev/shm
    tmpfs                 760M  1.3M  758M   1% /run
    tmpfs                 5.0M  4.0K  5.0M   1% /run/lock
    /dev/mmcblk0p1        253M   43M  210M  17% /boot
    tmpfs                 380M   20K  380M   1% /run/user/109
    tmpfs                 380M   20K  380M   1% /run/user/1001
    tmpfs                 380M   20K  380M   1% /run/user/1000
    /home/user1/.Private   60G  5.9G   51G  11% /home/user1
    
  3. user2はもう不要なので、user1でログインしている状態でuser2を削除する: sudo deluser --remove-home --remove-all-files user2
  4. 問題なければバックアップされていたホーム領域 (例: /home/user1.dDSN7Xlq) を削除する

ちなみに、eCryptfsで暗号化されたファイルの実体は/home/.ecryptfs/$USER/.Private/に保存されています。そこを覗いてみると、暗号化がファイル名・ディレクトリ名と中身のデータに対して実行されていることが分かります (ファイルをfileコマンドやhexdumpコマンドにかけると楽しい)。

課題: 暗号化したいものがホーム領域外にある場合

今回のeCryptfsを使用する方法では、暗号化の対象がユーザのホーム領域のみです。したがってたとえば、Wi-Fi (無線LAN) のパスワードが直に書かれているファイル/etc/wpa_supplicant/wpa_supplicant.confは暗号化されないままです (wpa_passphraseというコマンドはあるが、これは人間に対する難読化を行うのみだという認識)。このファイルを暗号化領域に置くうまい方法がないか、一種のパズルを解くような感覚で少し思案中……。

参考リンク