DockerでSimutransオンライン

(2021/8/9) いろいろ改良しました。

# はじめに

わざわざローカルでSimutransの環境構築をせずとも、インターネット上でブラウザ一つでSimutransを遊びたい...
と思ったので、ブラウザでSimutransを遊べるようにしてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198202/5e66bf4a-5ed0-39a4-37b8-0f15f32523c2.png)

やっていることは、DockerでUbuntuの仮想デスクトップ環境を用意してそこでSimutransを動かしているだけです。どんなデスクトップアプリケーションでもわりと汎用的に使える手法だと思います。

# Dockerコンテナを立ち上げる

今回は、ベースとしてこのdocker imageを用います。簡単な設定でUbuntu Desktop環境をブラウザから利用できるようにしてくれるスグレモノです。

https://hub.docker.com/r/dorowu/ubuntu-desktop-lxde-vnc/

Dockerfileを以下のように書きます． `ENV` で設定しているパラメータの詳しい意味は、元イメージのDocker Hubを参照してください。

```dockerfile:Dockerfile
FROM dorowu/ubuntu-desktop-lxde-vnc
# httpアクセスまわりの設定
ENV RELATIVE_URL_ROOT mapViewer
ENV USER simutrans
ENV HTTP_PASSWORD Password
# このPASSWORDはlinuxユーザのパスワード。直接使うことはないので、ランダム文字列を用いる
ENV PASSWORD xQhu944hiSwUuMui
EXPOSE 80

# Simutransの動作に必要なライブラリをインストール
# ブラウザやターミナルは不要なので削除しておく
RUN apt-get -y remove firefox google-chrome-stable lxterminal  &&  \
apt-get -y update && apt-get -y upgrade &&  \
apt-get -y install zlib1g-dev libbz2-dev libpng-dev libsdl2-dev libminiupnpc-dev libfreetype6

# copy simutrans data
# Dockerfileと同じディレクトリにsimutransディレクトリを配置し、中にUbuntuで実行可能なバイナリを入れる
COPY simutrans/ /home/simutrans/Desktop/simutrans/
RUN chmod u+x /home/simutrans/Desktop/simutrans/sim-linux-OTRPv29_6

# デスクトップのランチャーは、Simutransを起動する項目だけにする
RUN rm /usr/share/applications/*.desktop
COPY simutrans.desktop /usr/share/applications/
```

デスクトップのランチャーにSimutransを起動する項目を追加するため、 `Dockerfile` と同じディレクトリに `simutrans.desktop` を用意します。アイコンはとりあえず計算機アイコンを割り当てておきます。このファイルはコンテナビルド時にコンテナ内にコピーされます。

```simutrans.desktop
[Desktop Entry]
Version=1.0
Name=Simutrans
Exec=/home/simutrans/simutrans/sim-linux-OTRPv29_6 -fullscreen
StartupNotify=true
Terminal=false
Icon=galculator
Type=Application
```

Dockerfileと同じディレクトリにsimutransディレクトリを配置し、中にUbuntuで実行可能なバイナリを入れます。
以下のコマンドでビルドすると、 `simutrans-online` という名前のdocker imageができます。

```shell
docker build -t simutrans-online .
```

`viewer-container` という名前をつけて、コンテナを立ち上げます．

```shell
docker run -d -p 6080:80 --name viewer-container simutrans-online
```

http://localhost:6080/mapViewer/ にアクセスすると、basic認証を求められるので、

- id: `simutrans`
- password: `Password`

としてログインすると、下のようにデスクトップ環境が現れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198202/629cb63a-3888-1b86-9ee7-d3894ba9d7f4.png)

このデスクトップ環境内で手動でSimutransを立ち上げます。画面左下のスタートボタン（？）をクリックし、Other→Simutrans を選択すると、Simutransが全画面で起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198202/eb816dce-cbbd-f111-bf5c-3a07fe0b582f.png)

ブラウザでSimutransを立ち上げることができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198202/5e66bf4a-5ed0-39a4-37b8-0f15f32523c2.png)

# いたずら対策
ひとまずSimutransをブラウザ上で遊ぶことが可能になりましたが，この状態でインターネットに公開することは非常に危険です．なぜならば， `simutrans` ユーザはroot昇格可能で，もしLinuxユーザのパスワードが漏れれば任意のコマンドを実行できてしまうからです．
そこで， `simutrans` ユーザに対して以下の対策を行います．

- sudo, admグループから外す
- シェルに `rbash` を用いて，実行できるコマンドを制限する。（既にlxterminalは削除済みですが）

`docker exec -it viewer-container /bin/bash` などでコンテナのシェルに入って，以下のコマンドを実行します．（ついでにアクセス権とタイムゾーンの設定も行っています。）

```shell
chown -R simutrans:simutrans /home/simutrans/Desktop/simutrans
cp /usr/share/zoneinfo/Japan /etc/localtime
gpasswd -d simutrans sudo
gpasswd -d simutrans adm
chsh -s /bin/rbash simutrans
echo export PATH=/home/simutrans >> /home/simutrans/.bashrc
chown root:root /home/simutrans/.bashrc
chmod 755 /home/simutrans/.bashrc
```

Simutransをプレイする以外のすべての操作を禁止するまでには至りませんが，ひとまず危険な操作を防止することはできるでしょう．
本来はこれらのコマンドをDockerfile中に記述できれば良いのですが，コンテナを実際に起動するまでは `simutrans` ユーザが生成されないらしく，実行することができません．

なお、ファイルマネージャーの `pcmanfm` を削除したいところですが、これを削除すると `openbox` がデスクトップから見えてしまい、デスクトップ上を右クリックすると様々なアプリケーションをrootで実行できてしまいます。`openbox` を削除すると、Simutransは起動しますが、キーボード入力を受け付けなくなります。よって、今回は `pcmanfm` を削除せずにそのままにしてあります。


# まとめ
デスクトップ環境が必要なアプリケーションをブラウザから手軽に利用するための方法についてまとめました．今回行ったいたずら対策は最低限のものなので、もう少し強力な制限を導入したいものです。
今回はSimutransというゲームを題材にしましたが，どんなデスクトップアプリケーションでもわりと汎用的に使える方法なので皆さんもぜひお試しください．