Z.OOL.ネット信託統治領 はてな諸島

こちらは "Z.OOL.ネット信託統治領 はてな諸島" です。

Debian noroot 環境において OpenSSH に基づく SSH サーバを導入する

本稿は、技術的案件の速報的な投稿です。
今後、内容に訂正及び大幅な修正がある場合が
あります。どうか御了承下さい。


[BGM]: New Order - Thieves Like Us

本稿について

本稿は、技術的事項についての速報的で簡易な短信についての Z.OOL.ネット信託統治領 Qrunch 諸島からのクロス投稿です。

本稿は、以下の Qrunch 諸島の投稿から御覧になれます。どうか御了承下さい。

z80oolong.qrunch.io

追記 (2019/03/01)

本稿において、 Debian noroot 環境から SSH クライアントを起動する手法に関する内容を以下の Qrunch 諸島の投稿として独立させました。

z80oolong.qrunch.io

追記 (2019/03/22)

日本語入力に必要な環境変数の受け渡しに関する設定を追記しました。

追記 (2019/04/09)

SFTP サーバに関する設定を追記しました。どうか御了承下さい。

はじめに

Debian noroot とは、 Android OS 上において root 権限を取ることなく Debian 環境を構築するためのアプリケーションです。

CPU の性能とメモリ容量が潤沢にある Android 端末であれば、 Debian noroot の導入によって Android 端末上で非常に軽快な Debian 環境を実現することができます。

Debian noroot 環境上において、各種 Linux ディストリビューションで多く用いられている OpenSSH を導入すると、 SSH クライアントをインストールした遠隔の PC 端末から Debian noroot 環境を容易に操作することが可能となるので、非常に有用です。

しかし、拙稿 "Debian noroot 環境において dropbear に基づく SSH サーバを導入する" において述べた通り、 Debian noroot 環境に、 apt-get コマンドを用いて OpenSSH を導入し、 sshd デーモンを起動しようとすると、 sshd が正常に起動しない問題が発生します。

この問題は、前述の投稿において述べた通り、ディレクト/var/run/sshd 及び擬似端末のデバイスファイル /dev/pts/* の所有者及び権限が変更出来ないのが原因であると考えられます。

そこで、前述の問題を修正した OpenSSHソースコードLinuxbrew を用いてビルドして導入を行いました。

次に、 Debian noroot 環境上におけるユーザのパスワードを変更する設定を行った後、 Debian noroot 環境sshd デーモンを一時的に起動して、遠隔の PC 端末から、 Debian noroot 環境へ向けて、パスワード認証を用いた SSH による接続確認及び公開鍵と秘密鍵に基づく公開鍵認証を用いた接続確認を行いました。

そして、 Debian noroot 環境の起動時に sshd デーモンを自動的に起動させる為の設定を行いました。

本稿では、 Debian noroot 環境において、 OpenSSH に基づく SSH サーバの導入手法について述べます。

なお、本稿においては特段の断りのない限り、Debian noroot 環境上に特有の SSH サーバ及び SSH クライアントの設定手法について述べるに止め、各種 Linux ディストリビューションにおける設定と共通する部分については説明を割愛します。

そして、本稿においては特段の断りのない限り、 SSH によるリモートログインの接続先となる Debian noroot 環境及び接続元となる SSH クライアントに関する各種環境設定等に関しては、下記の通りであるとします。

接続先への OpenSSH の導入

本章では、 SSH によるリモートログインの接続先となる Debian noroot 環境OpenSSH を導入する手法について述べます。

本稿では、 Linux の各ディストリビューション上におけるソースコードの取得及びビルドに基づいたパッケージ管理システムである Linuxbrew を用いて Debian noroot 環境に対応した OpenSSH を導入します。

まずは、 "Debian noroot 環境に Linuxbrew を導入する" の投稿及び Linuxbrew の公式ページに基づいて Linuxbrew に依存するパッケージと Linuxbrew 本体のリポジトリを導入します。

 $ sudo apt-get install build-essential curl file git python-setuptools ruby
 $ sudo apt-get install m4 texinfo libbz2-dev libcurl4-openssl-dev libexpat-dev libncurses-dev zlib1g-dev gettext    # 必要に応じて任意に導入する。
 $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install)"

なお、 32 bit ARM アーキテクチャ及び 64 bit x86 アーキテクチャ以外を搭載した携帯端末にインストールされた Debian noroot 環境Linuxbrew を導入する場合、前述の Linuxbrew の本体のリポジトリを導入するコマンドを実行すると、途中で Linuxbrew が使用する ruby 処理系の bottle ファイルの取得に失敗して、導入作業が正常に行われません。

従って、これらの携帯端末における環境の場合は、 "Linuxbrew の自動的なインストールスクリプトが異常終了する場合における代替の導入手法" の投稿に基づき、 Linuxbrew の開発コミュニティによる Linuxbrew のインストールスクリプトに代えて、下記のようにして Linuxbrew を導入する必要が有ります。

 $ sudo apt-get install build-essential curl file git python-setuptools ruby
 $ sudo apt-get install m4 texinfo libbz2-dev libcurl4-openssl-dev libexpat-dev libncurses-dev zlib1g-dev gettext    # 必要に応じて任意に導入する。
 $ sudo apt-get install libssl-dev libreadline6-dev libyaml-dev libgdbm-dev libdb-dev
 $ sh -c "$(curl -fsSL https://raw.githubusercontent.com/z80oolong/linuxbrew-altinstall/master/install.sh)"

そして、 bash の初期化ファイルである ${HOME}/.bashrc について、以下の通りに環境変数の設定を行い、 bashrc を再起動します。

...
# for Linuxbrew

export HOMEBREW_PREFIX="/home/linuxbrew/.linuxbrew"
export PATH="${HOMEBREW_PREFIX}/sbin:${HOMEBREW_PREFIX}/bin:$PATH"
export MANPATH="${HOMEBREW_PREFIX}/share/man:${MANPATH}"
export INFOPATH="${HOMEBREW_PREFIX}/share/info:${INFOPATH}"
export HOMEBREW_NO_AUTO_UPDATE=1
...

次に、以下の通りに brew tap コマンド及び brew install コマンドを実行して、 Debian noroot 環境に対応した OpenSSH を導入します。

 $ brew tap z80oolong/debian-noroot
 $ brew install -dv z80oolong/debian-noroot/openssh

この時、ソースコードコンパイルに時間が掛かると思われますが、我慢強くインストールの完了を待つ必要が有ります。この場合、 Android 端末に CPU の性能とメモリ容量が潤沢にあれば、別に他の必要な Android OS アプリを起動して Linuxbrew でのインストールの完了を待っても構いません。

パスワード認証に基づく SSH による接続の設定

本章では、 接続先となる Debian noroot 環境 に導入した OpenSSH について、パスワード認証に基づいた SSH のリモートログインを行うための設定について述べます。

Debian noroot 環境のユーザのパスワードを変更する

Debian noroot 環境 においては、通常の Debian 環境と同様に sudo 経由で passwd コマンドを用いて任意のユーザのパスワードを変更することが出来ます。

即ち、以下のように passwd コマンドを実行して、ユーザ u0_a200 のパスワードをユーザ自身以外に知り得ないものに変更します。

  $ env LANG=C LC_ALL=C sudo passwd u0_a200
  Changing password for u0_a200
  New UNIX password:            # (ユーザ自身以外に知り得ないパスワードを入力)
  Retype new UNIX password:     # (前に入力したパスワードを再入力)
  passwd: all authentication tokens updated successfully
  $

接続先の $HOMEBREW_PREFIX/etc/ssh/openssh.d を設定する

まず最初に、 sshd デーモンの起動スクリプトである ${HOMEBREW_PREFIX}/etc/ssh/openssh.d を必要に応じて下記のように編集します。編集する箇所は下記の1箇所です。

...
SERVER_OPTION="-f /home/linuxbrew/.linuxbrew/etc/sshd_config
...

即ち、環境変数 SERVER_OPTION において、sshd デーモンに渡すオプションとして、 -f オプションを用いて SSH サーバの設定ファイルの絶対パスを指定する必要があります。

接続先の $HOMEBREW_PREFIX/etc/ssh/sshd_config を設定する

次に、 OpenSSHSSH サーバの設定ファイルである ${HOMEBREW_PREFIX}/etc/ssh/sshd_config の内容を編集します。

ここで、最低限編集が必要となる箇所は以下の通りです。

# ...(略)...
# ポート番号を 15022 に指定
Port 15022
# ...(略)...
# 接続先 SSH サーバのホストキーのパス
HostKey /opt/.linuxbrew/etc/ssh/ssh_host_rsa_key
HostKey /opt/.linuxbrew/etc/ssh/ssh_host_dsa_key
HostKey /opt/.linuxbrew/etc/ssh/ssh_host_ecdsa_key
HostKey /opt/.linuxbrew/etc/ssh/ssh_host_ed25519_key
# ...(略)...
# 日本語入力時に必要な環境変数の受け渡しに関する設定
AcceptEnv XMODIFIERS *_IM_MODULE
# ...(略)...
PermitRootLogin no
# ...(略)...
# 共通鍵暗号認証を一時的に無効化
# PubkeyAuthentication yes # 一時的にコメントアウト
# ...(略)...
# パスワード認証を一時的に有効化
PasswordAuthentication yes
# PasswordAuthentication no # 一時的にコメントアウト
PermitEmptyPasswords no
# ...(略)...
ChallengeResponseAuthentication yes
# ChallengeResponseAuthentication no # 一時的にコメントアウト
# ...(略)...
# X11 forwarding 関連の設定
X11UseLocalhost yes
AllowAgentForwarding yes
AllowTcpForwarding yes
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost yes
# ...(略)...
# sftp サーバプログラムの存在するパスを設定
Subsystem       sftp    /home/linuxbrew/.linuxbrew/opt/openssh/libexec/sftp-server
# ...(略)...

その他、設定が必要となる設定値がある場合は適宜設定値の編集を追加します。

パスワード認証に基づく SSH による接続の確認

まず最初に、 OpenSSH の起動スクリプトである ${HOMEBREW_PREFIX}/etc/ssh/openssh.d を下記のように実行して、接続先となる Debian noroot 環境sshd デーモンを起動します。

  $ $HOMEBREW_PREFIX/etc/ssh/openssh.d start

そして、接続元となる遠隔の PC 端末上にインストールされた SSH クライアントである ssh コマンドを下記のように起動します。

  $ ssh -l u0_a200 -p 15022 192.168.0.1
  The authenticity of host '192.168.0.1 (192.168.0.1)' can't be established.
  RSA key fingerprint is 11:22:33:44:55:66:77:88:99:aa:bb:cc:de:ad:be:ef.
  Are you sure you want to continue connecting (yes/no)?    # (ここでは、そのままリターンキーを入力)
  ...
  u0_a200@192.168.0.1's password:   # (ここで、 Debian noroot のユーザのパスワードを入力)
  
  The programs included with the Debian GNU/Linux system are free software;
  the exact distribution terms for each program are described in the
  individual files in /usr/share/doc/*/copyright.

  Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
  permitted by applicable law.
  $ 

上記のように OpenSSH の banner が表示され、リモートログインシェルが起動すれば、設定が正常に行われていることが判ります。

公開鍵認証に基づく SSH による接続の設定

本章では、 接続先となる Debian noroot 環境 に導入した OpenSSH について、公開鍵認証に基づいた SSH のリモートログインを行うための設定について述べます。

まず、公開鍵と秘密鍵の生成と、接続先への公開鍵の転送及び接続元の ${HOME}/.ssh/config の設定について、拙稿 "Debian noroot 環境において dropbear に基づく SSH サーバを導入する" の以下の節の記述と同様に設定を行います。

次に、接続元の SSH クライアントの設定ファイルである ${HOME}/.ssh/config を以下の通りに編集します。

Host noroot    # 接続先の端末を識別するための任意の名前
  HostName               192.168.0.1        # 接続先の端末の IP アドレス
  User                   u0_a200            # 接続先の端末上でのユーザ名   
  PasswordAuthentication no                 # パスワード認証による接続を行わない
  PubkeyAuthentication   yes                # 公開鍵認証による接続を行う
  IdentityFile           ~/.ssh/id_rsa.foo  # 公開鍵認証方式での認証に用いる公開鍵と対になる秘密鍵が存在するパス
  RequestTTY             yes                # 標準入力が TTY の場合は TTYを要求する
  X11Forwarding          yes                # ← X11Forwarding yes の行を追記する
  X11ForwardingTrust     yes                # ← X11ForwardingTrust    yes の行を追記する
  SendEnv                XMODIFIERS *_IM_MODULE   # ← 日本語入力時に必要な環境変数の受け渡しに関する設定

そして、接続先となる Debian noroot 環境において sshd デーモンが起動しているかどうかを ps awxu | grep sshd コマンドを用いて確認します。

  $ ps awxu | grep sshd
  ...(略)...
  u0_a200  25137  0.0  0.0   5820   104 ?        Ss    1月 07   0:00 /opt/.linuxbrew/opt/openssh/sbin/sshd -f /opt/.linuxbrew/etc/ssh/sshd_config -E /var/log/openssh.log
  ...(略)...

もし sshd デーモンが起動していなければ、 OpenSSH の起動スクリプトである ${HOMEBREW_PREFIX}/etc/ssh/openssh.d を下記のように実行して、接続先となる Debian noroot 環境sshd デーモンを改めて起動し直します。

  $ ${HOMEBREW_PREFIX}/etc/ssh/openssh.d start

そして、接続元となる遠隔の PC 端末上にインストールされた SSH クライアントである ssh コマンドを下記のように起動します。

  $ ssh noroot
  ...(ここで、秘密鍵と公開鍵の対にパスワードを設定していれば入力を促され、設定していなければそのままログインプロンプトが表示される。)...
  The programs included with the Debian GNU/Linux system are free software;
  the exact distribution terms for each program are described in the
  individual files in /usr/share/doc/*/copyright.

  Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
  permitted by applicable law.
  $ 

上記のように OpenSSH の banner が表示され、リモートログインシェルが起動すれば、設定が正常に行われていることが判ります。

また、接続元の $HOME/.ssh/config の設定において、X11フォワーディングの機能を有効にしている場合についても、拙稿 "Debian noroot 環境において dropbear に基づく SSH サーバを導入する" と同様にリモートログインシェルから xeyes コマンドを起動し、X11フォワーディングの動作確認を行います。

最後に、安全のために sshd デーモンがパスワードを用いた SSH によるリモートログインを抑止するように、 OpenSSHSSH サーバの設定ファイルである ${HOMEBREW_PREFIX}/etc/ssh/sshd_config を下記のように修正します。

# ...(略)...
# 共通鍵暗号認証を有効化
PubkeyAuthentication yes
# ...(略)...
# パスワード認証を無効化
PasswordAuthentication no
PermitEmptyPasswords no
# ...(略)...
ChallengeResponseAuthentication no
# ...(略)...

接続先の sshd デーモンの起動の自動化

本章では、 Debian noroot 環境を起動した直後に OpenSSHSSH サーバである sshd を自動的に起動することが出来るように設定する手法について述べます。

ここで、 SSH によるリモートログインの接続環境を Debian noroot 環境を起動した直後に自動的に起動するには、 Debian noroot 環境においてウィンドウマネージャを起動し、デスクトップ環境を整えるためのシェルスクリプトである /startx.sh に下記のような設定を追記します。

...
fakeroot-tcp /usr/bin/env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin dbus-daemon --system
# ↓ ${HOMEBREW_PREFIX}/etc/ssh/openssh.d を起動するコマンドを追加。念の為に末尾の & を忘れないこと。
/home/linuxbrew/.linuxbrew/etc/ssh/openssh.d start &
...
# ↓ xfce-session の直後に /home/linuxbrew/.linuxbrew/etc/ssh/openssh.d を停止するコマンドを追加。
dbus-launch --exit-with-session sh -c 'xfce4-session ; /home/linuxbrew/.linuxbrew/etc/ssh/openssh.d stop; setsid sh -c "cd /proc/ ; for f in [0-9]* ; do [ \$f = \$\$ ] || kill -9 \$f ; done"' &
...

即ち、 dbus-daemon デーモンを起動している行の直後に、 OpenSSH を起動する為のシェルスクリプト ${HOMEBREW_PREFIX}/etc/ssh/openssh.d を start によって起動し、 Debian noroot 環境をログアウトさせて xfce-session コマンドが終了した直後に、シェルスクリプト ${HOMEBREW_PREFIX}/etc/ssh/openssh.d を stop によって停止させる設定を追記します。