Chienomi

Linuxでサンドボックス環境を活用する

Live With Linux::tips

先に挙げた「SSDに別のLinux環境をインストールする」の代替手段だ。

私が会社で使っているPCはThinkPad X1 Carbon Gen8 4k Core i7というモデルで、ラップトップとしてはかなり性能が高い部類に入るが、開発部の中では動作が遅く、ミーティングやリリース作業などで遅れがちという問題がある。

これをなんとかしたくて、仕方ないので私物のデスクトップを使おうと考えた。 しかし、そうすると3つのプライバシーポリシーが競合してしまう。

私自身のポリシーは置いておくとして、Mimir Yokohamaは他者が干渉可能な環境からの可視性を認めていない。 会社のほうはこれといった制限はないものの、データは会社のものであり、自身は所持せず、常にその全てを引き渡せる状態である必要がある。

簡単に言えば

  • 会社で使う環境から私のデータが見えるのはNG
  • 会社のデータを私のストレージ上に置くのはNG

ということになる。

問題を切り分ける

デスクトップを使いたい問題の大部分は「GoogleとAtlassianが遅い」という問題にある。 つまりは、ウェブブラウザだ。

Googleを使っている関係上、ブラウザはFirefoxに限るとする。 会社PCではむしろ主にGoogle Chromeを使っているが、Blink系ブラウザはGoogleからは特別なアクセスが可能であるということを否定しきれないので、Googleに特殊なアクセスを許していないと思われるFirefoxを採用する。

開発面も本当はデスクトップでやったほうが効率はずっと高いのだが、デスクトップPCは完全に私物だし、本体代も電気代も特に支給されているわけではないから、基本的にはラップトップを使うという方向性は維持したい(そこで詰まるレベルの成果を求めているなら、会社としてもデスクトップ支給をするだろうし、自分の評価を増すために私物を使うという考え方はあるが、とりあえず今のところそれが必要だとは思っていない)。

問題になるのはリリース作業など他の人と協調して作業するときにページを開くのに数分レベルでかかってしまうからであり、それ以外については全体的なペースの問題にとどまる。 だから解決については

  1. 分離された安全な環境でブラウザを使う
  2. コードを触るときはデータはデスクトップになく、デスクトップで他のユーザープロセスから見えない状態で行えるようにする

で良いだろう。

隔離された環境のブラウザ

仮想環境は適さない

ブラウザを隔離して使う方法としては仮想デスクトップなどがあるが、この場合パフォーマンスがほしいので仮想環境上のブラウザでは不満である。

Firejail

簡易的な方法としてはfirejailを使う方法がある。 この場合、ほぼ単純にホームディレクトリが見えなくなる。 /homeの下に自分のホームディレクトリしかなくて、ホームディレクトリの下にはダウンロードフォルダとデスクトップフォルダしかないように見えるのだ。 また、/mnt, /run/media, /run/mount などのアクセス権はない状態になる。

これで十分ならそれでもいい。 FirejailについてはArchwikiに記事があり、これで十分対応できる。 強いて言うなら、専用にdesktopファイルを作って~/.local/share/applications以下にFirejailを使うエントリを作ってHTMLファイルやウェブアドレスを開くアプリとして関連付けておくとより良いだろう。

systemd-nspawn

まずは使えるところまで

だが、私はこれは十分でない、と考えた。そこで、systemd-nspawnを使うことにした。

systemd-nspawnはSystemdと一体になったコンテナで、Linux名前空間を使うものである。 ただ、この手順は少し複雑になる。また、Manjaroでの解説(Archlinuxでも同じ)だ。 (systemd-nspawnを使っているのはだいたいArchlinuxユーザーな気もする)

とりあえず、専用ユーザーを作る。 ちょっと癪だが、少なくともsystemd-runに対してはrootで実行する権限が必要だ。

workaholic ALL=(ALL:ALL) /bin/systemd-nspawn,/bin/systemd-run

そしてまずは、コンテナを作る。正規な場所もあるが、ここはworkaholicユーザーのディレクトリの下に作っておこう。

# cd ~workaholic
# pacman -S arch-install-scripts
# pacstrap -c containerholic base base-devel firefox alacritty otf-ipafont zsh grml-zsh-config

好みの問題からAlacrittyを使っているけれど、別にxtermやurxvtを使っても構わない。 Gnome TerminalやKonsole, XFce4 Terminalなどは依存関係が重い。

rootとしてコンテナを起動する。次回起動時もここからやる。

% sudo systemd-nspawn -D containerholic --bind-ro=/tmp/.X11-unix -b

これでログイン画面になるが、それは放置。 そして、端末を起動する。セッションごとにここからやる。

まずはxhostによる許可。再起動すると設定は戻る、ということは忘れがち。

% xhost +local:

Xauthorityを使う必要は多分ない(xhostでもlocalだけだから許されると思う)。 コンテナ上でプログラムを実行。

% sudo systemd-run -M containerholic --serenv=DISPLAY=:0 --setenv=GTK_IM_MODULE=fcitx --setenv=QT_IM_MODULE=fcitx --setenv=XMODIFIERS=@im=fcitx /bin/alacritty

ibusの人はもちろんfcitxでなくibusを指定する。

-Mで指定するコンテナ名はmachinectlで確認できる。 ディレクトリ名から_などは消えるので注意が必要だ。

このままrootとして使えるのだが、ホストのファイルも一部bindされているので、コンテナ環境で一般ユーザーを作っておく。 この作業は初回のみ。

# useradd -m -U -s /bin/zsh haruka
# passwd

ユーザーとしてログイン。suを使うとXアプリが起動できなくなるので注意。 (rootのXセッションに相乗りしているため)

# sudo -u haruka zsh -l
% cd

あとはコンテナのユーザーシェルから普通に起動する。

% firefox

試した限りだとDiscord, Codeはうまく動作しない。 Discordはweb版で。エディタはAtomならいける。あとはXedとか。

sudoでsystemd-runを許可しない

systemd-runはGUIアプリならなんでも起動できてしまうので、この設定はセキュリティ的に有効に働かない。

なので、専用のスクリプトを用意し、それだけを許可するように設定したほうが良いだろう。

#!/bin/zsh

case $1 in
  start)
    systemd-nspawn -D ~workaholic/containerholic --bind-ro=/tmp/.X11-unix -b
    ;;
  login)
    systemd-run -M containerholic --serenv=DISPLAY=:0 --setenv=GTK_IM_MODULE=fcitx --setenv=QT_IM_MODULE=fcitx --setenv=XMODIFIERS=@im=fcitx /bin/alacritty
    ;;
esac

GUIアプリも使いやすく

少しこれだと話が荒いので、こんな感じのスクリプトを書いて実行できるようにしておく。

#!/bin/zsh

sudo -u workaholic alacritty --working-directory ~workaholic

systemd-runで実行するプログラムをalacrittyではなくこのプログラムにしておく。

Alacrittyでセッションを増やせるようにしておくと使い勝手が上がる。 ~/.config/alacritty/alacritty.yml

key_bindings:
  - { key: Return,   mods: Control|Shift, action: SpawnNewInstance }

とか書いておく。

Firefoxで日本語入力

まず、前提としてだが、一般的な入力関係環境変数においてFirefoxが必要とするのは$XMODIFIERSである。

じゃあ、Fcitxを入れてFcitxをスタートして、

% XMODIFIERS=@im=fcitx firefox

とかやればいいのかというと、それは違う。

Chromiumもそうだが、これらに関してはLC_CTYPEの値を見る。 もう思い切ってLC_ALLLANGでも良いかと思う。

じゃあ

% LC_ALL=ja_JP.UTF-8 LANG=ja_JP.UTF-8 XMODIFIERS=@im=fcitx firefox

でいけるかというと、またそれも違う。 なぜならば、指定するだけじゃなくロケールがいるからだ。

Manjaroのpacstrapで作った場合、ロケールファイル自体はできているので、/etc/locale.genja_JP.UTF=8な行をアンコメントして、

# locale-gen

する。 あとは、systemd-runの引数にさらに

--setenv LC_ALL=ja_JP.UTF-8 --setenv LANG=ja_JP.UTF-8

とか足しておけば良い。

会社用データを扱う

コンテナ内から否かはおいといて、とりあえずユーザーとしてSSH鍵を作る。

% ssh-keygen -t ed25519

ラップトップに登録する。ログインは許さないので、command="internal-sftp"を指定しておく。 /etc/ssh/sshd_configに宅内のネットワークでのみ利用できるように指定する。 この場合、IPアドレス192.168.100.64のマシンからharukaユーザーへのログインのみ許可している。

AddressFamily inet

#...

AuthenticationMethods publickey
AllowUsers *@127.0.0.1 haruka@192.168.100.64

sshdを起動する。

% sudo systemctl start sshd
% sudo systemctl enable sshd

デスクトップから作業フォルダをマウントする。1

% sshfs haruka@laptop.local:Documents/projects Documents

あとは普通に作業できる。

おまけ 会社の仕事を私物PCでやることについて

まず前提としてセキュリティポリシーというものがわからないのであればやるべきでないのは明らかだ。 この説明で自分がどのようなポリシーを構築し、どうするのはOKでなにが駄目なのかわからない人もやるべきではない。

制約の厳しい会社PCを使うよりは、自由に自分にとって効率が良いように組み立てられる私物PCのほうが(程度は置いといて)効率が良いのは間違いないだろう。 だが、その必要性というか有意性に対しては疑義もないではない。

ただ、与えられた条件で言われたことだけをすれば良いのであれば、会社PCというのは前提条件になるものだからそれで可能な効率で良い。 それは、時間外での努力を強いられない、というのと同じ話だ。

だが、純粋な成果主義であるならば効率の悪い機材を使うというのはハンデになるから、お構いなしに使ったほうが良い。

それ以外には、会社から「何を求められているか」にもよると思うけれど、私は成果は求められているけれども、デスクトップを使ったパフォーマンスの上乗せは一度rejectされているし、そこまでは求められていない。PCの性能による遅延も「仕方ない」という見方だ。

ただ、ミーティング中に私だけ置き去りになるのは単純に私が困るので、その場合は意固地にラップトップを使い続けると私の不利益になるのでデスクトップを使う。

常にデスクトップを使う必要はそんなにはない。 効率にはだいぶ差があるとしても、主に差が出るのはGoogleやAtlassianを使っている時であり、ブラウザを使っているとき(調べもの)とかに限られ、コード書きは「書いている」状態なら差は少ない(調べているときは見比べる必要があるため、14インチのディスプレイでは小さく、差がつく)。

こうしたことから、私のケースでは求められる成果と持続性(短距離のペースで長距離走れないのと同じで、デスクトップを使うことで差がつくレベルでの効率は常時使えるわけではない)を考えると「ここぞ」というときに使う程度で良いと思う。

実際、1日の中で最高のパフォーマンスが出るのは1時間程度だから、1日の中でじっくり高めてその1時間だけデスクトップで全力、という方法もあるのだけど。

この話は結構複雑なのだけど、私のスタンスはそんな感じ。 まぁ、できればデスクトップでやらせてほしいと思っているけど、ボスはそれを好まないスタンスだし、だからこそトップパフォーマンスを求めているわけではないだろうとも思っている。 「安定したパフォーマンスを長期間出し続ける」という観点なら短時間効率は悪くてもあまり変わらなくなってくるし、短時間効率がほしいタイミングで効率を重視する、という考え方でいい。