2025-02-05

iOS の iSH -Alpine Linux- で sshd を自動起動化する【2025-02-08 追記】

【2025-02-08 追記】 iOS の sshd への接続エラー対策

 

iOSiSH 強制終了後の最初の起動を「初期起動」とします。


iSHexit 後は「再起動」され「初期起動」とは異なります。


なにが異なるかといいますと「初期起動」時の自動実行と「再起動」時の自動実行が違うのです。


「初期起動」時に自動実行されたプロセスは「再起動」後も有効です。

 

一方「再起動」時の自動実行は「再起動」のたびに実行されますが、すでに起動されているプロセスがある場合、2重・3重にプロセスが立ち上がります。


 

このような動作になるのは iOS のヘンなポリシー(制限といってもいいでしょう)のせいです。

 

Android の場合、アプリの終了は iOS の強制終了と同等なのでこのような違いは生じません。

 

iOS ってややこしいと思いませんか???

 

 

本記事ではこの違いを踏まえた自動実行化について記載します。

 


januszoles/ish: iPad iSH Alpine Linux Notes

 

の中ほどあたりに、

   Welcome to Alpine on iPhone 6! (2023-04-12)

という箇所に sshd に関する記述があります。

 

この中の、Install and config ssh という項目の記述に従い ssh(sshd) の自動起動化のための処理を行います。

 

openssh のインストールと sshd の設定は済んでいるものとします。

 

$ apk update # リポジトリのアップデート
$
apk upgrade #インストール済みパッケージの最新化
$
apk add openrc # systemctl 相当のパッケージインストール


openrc インストールにより、systemctl 相当のことが可能になります。

 

sshd の起動は次のようにします。


$ rc-service sshd start
grep: /proc/filesystems: No such file or directory
 

 

エラーが出ますが sshd は起動されます。

 

エラーメッセージが出るのはバグっぽいのですが、出ないようにする方法は不明です。

 

* You are attempting to run an openrc service on a
*  * another initialization system to boot this system.
* If you really want to do this, issue the following command:
* ERROR: sshd failed to start
 

要約:このシステムを起動するために、別の初期化システムで openrc サービスを実行しようとしています。

本当にこれを行う場合は、次のコマンドを発行してください:

 エラー: sshd の起動に失敗しました

 

「次のコマンドを発行してください」は次のコマンドです

 

$ /usr/sbin/sshd 

 

こちらはエラーがでません。

 

 

sshdiSH 起動時に自動起動するための登録を、次のようにします。 


$ rc-update add sshd # iSH 起動時に自動起動する登録

 

 

次に iSH をバックグラウンド化する処理を自動化します。

 

バックグラウンド化とは、常に動作状態にして sshd などが終わってしまうのを防ぐことです。

 

Google 検索によると、デーモンには次のような種類があります。


・システム管理系

・タスクスケジューリング系

・ネットワーク系

・周辺機器系

・通信プロトコルサーバ

・電子メール関連

・Samba 関連

・分散メモリキャッシュ関連

・データベースサーバ関連

 

systemd / syslogd / sshd / ftpd / smbd / crond / httpd などなど。

 

これらが勝手に終了状態にならないように、大もとの iSH を常駐化するのです。

 

「初期起動」時にバックグラウンド化するには local デーモンを使います。


 

$ apk add local # local デーモンをインストール

 

このインストールにより /etc/local.d ディレクトリができます。

 

ここに、起動時に読み込むファイルを alpine.start とでもして作成します。

 

ファイル名は任意ですが、拡張子は .start の必要があります。

 

中身は

 

cat /dev/location > /dev/null & # バックグラウンド化
[EOF]

 

です。

 

alpine.start には実行権を与え、local デーモンの自動起動登録をします。

 

$ chmod 700 /etc/local.d/alpine.start
$ rc-update add local

 

いったん iSH を強制終了させ、iSH を「初期起動」します。 


プロセス状態を確認します。

 



画面では PID 84iSH のバックグラウンド化ができていて、236sshd が自動起動されているのが確認できます。

 

 

 

rc-status で自動起動登録したデーモンの状態を確認します。

 


 

Runlevel: defaultsshdlocal が登録されていて、ともに起動済みとなっているのが確認できます。

 

local が起動されると alpine.start が読み込まれ、cat /dev/location > /dev/null & が実行され、iSH のバックグラウンド化がされます。

 

 

 


.profile に記述のスクリプトは iSH「初期起動」時のみならず、exit による「再起動」時も実行されます。



ここに /usr/sbin/sshdcat /dev/location > /dev/null & を記述してもいいのですが、exit による iSH 「再起動」でこれらが実行されると 2重起動状態になってしまいます。


 

なので .profile には exit「再起動」されても 2重起動にならないフォアグラウンドコマンドのみにした方がよいでしょう。



デーモンパッケージは rc-update「初期起動」時の自動起動対象として登録するように使い分けします。



コマンド系(例えば cat /dev/location > /dev/null &)は /etc/local.d に実行ファイル(本事例では alpine.start)を用意するといいでしょう。



現在、ホームディレクトリの .profile には何も設定していませんが、例えば date コマンドを記述すると、exit で再起動されて次のように時刻表示がされます。

 


 

date コマンドは実行されるとプロセスが終了しますので2重起動にはなりません。

 

 

 

 

【2025-02-08 追記】 iOS の sshd への接続エラー対策

 

自動化したものの、ssh で接続できたものが突然に ssh connection refused となったり、no route to host という接続不可事象が発生します。

 

どちらも ping は通りますので、sshd サーバーである iPhone の IP アドレスを誤っているわけではありません。

 

とするとポートが listen されていない、という事象と考えられます。

 

ポートが何らかの原因で閉じられた、と考えるのが普通ですよね。

 

なのでなぜ閉塞されるか、いろいろ調べてもわかりません。

 

本事象は不定期に発生し、一旦発生すると sshd の再起動が必要になり、面倒ですが、原因がわからなくてお手上げ状態でした。

 

 

随分と悩まされましたが、iPhone を WiFi アクセスポイント接続時の dns に IPv6 アドレスを登録していると発生することがわかりました。

 

ポート閉塞ではなかったのです。

 

 

接続してくるクライアントのアドレスが IPv4 で OK だったのを、sshd サーバーが何らかのタイミングで IPv6 での接続とみなし、IPv6 アドレスではないのでこのようなエラーになるようなのです。

 

いったんこの事象に見舞われると sshd の再起動しか回復しませんが、しばらくすると(1時間程度から 12時間程度)また接続エラーになります。

 

 

 

そこで、次の対策を講じました。

 

1.sshd_config の設定変更

      「# AddressFamily any」行を「AddressFamily inet」に変更   

      初期設定はコメントアウトされているのでデフォルトの any になっている

      any は IPv4 と IPv6 のどちらも接続許可する設定

      ⇨ コメントを外し inet(IPv4 のみ接続許可)にする

 

 

2.iPhone の Wi-Fi 設定で「IP を構成」は「手動」

      アドレスを固定するためでもともと「手動」設定している

 

 

3.「DNSを構成」を「手動」にし DNS サーバから IPv6 アドレスを削除する

       念のため DNS を IPv6 で引かないようにする  

 

 

 

以上の対策によって、ssh connection refused や、no route to host で接続不可となっていた問題がなくなり、安定して接続できるようになりました。

 

 

IPv6 が悪さをしていたなんて、誰が気づくというの?

 

 

 

 

 

ちょいと便利な設定

 

iPhone / iSH の sshd サーバのポートは Standard port ではなく Alternative port にします。

 

例えば 22 ではなく 2222 などに変更しますが、これは sshd_config 中の Port 行のコメントアウトを外し、2222 などを設定します。

 

 

クライアント側の ssh_config の Port 行も同じ設定をすると接続時に -p 2222 としないで済みます。

 

Android Termux の場合、/data/data/com.termux/files/usr/etc/ssd/ssd_config を編集します。

 


 

 

iPhone の場合、/etc/ssd/ssd_config を編集します。

 


 

 

 






0 件のコメント: