SSH X11 転送で GUI アプリが起動しない
前回の手順で SSH X11 転送環境を組み、xeyes は無事 Windows 側に表示された。ところが nautilus がどうしても起動しない。DISPLAY は通っているのに、なぜこのアプリだけ落ちるのかを切り分けた記録。
前回の手順で SSH X11 転送環境を組み、xeyes は無事 Windows 側に表示された。ところが nautilus がどうしても起動しない。DISPLAY は通っているのに、なぜこのアプリだけ落ちるのかを切り分けた記録。
Fedora 43 Server は、X サーバもデスクトップ環境も入っていなかった。ここから Windows 機に GUI アプリを表示させたい。デスクトップ環境は入れずに、SSH X11 転送でアプリを転送した備忘録。
WSL2 に OpenSSH Server をインストールします。 それと、sshd サービスを立ち上げます。
# WSL2 側
sudo apt install openssh-server
sudo service sshd start
Windows に公開鍵を登録していない場合は、以下のコマンドを実行します。
# Windows 側
ssh-keygent -t ed25519
次に WSL2 に公開鍵を登録します。
# Windows 側
$pubkey = $(cat $HOME\.ssh\id_ed25519.pub)
wsl -- echo $pubkey `| tee -a `$HOME/.ssh/authorized_keys
Windows から WSL2 に対し、SSH 接続を行います。
# Windows 側
ssh (wsl -- hostname -I).trim() -g -L8081:localhost:8080
コマンドを区切って説明します。
(wsl -- hostname -I).trim() は WSL2 の IP アドレスを取得します-g はポートを LAN にフォワーディングします (外部の端末から 192.168.x.x のようなアドレスで参照可能になります)-L はローカルフォワードのオプションです。サーバーのポートをローカルに転送します8081 と localhost:8080 は ローカルの 8081 にアクセスすると、localhost:8080 に転送されるという意味です。
ここでいう localhost はサーバー側から見た localhost です公開対象となるサーバーを WSL2 上で立ち上げます。
# WSL2 側
ruby -run -e httpd . # ディレクトリ一覧が公開される
http://localhost:8081 または、http://<ipconfig で表示される IP アドレス>:8081 でサービスにアクセスできます。
トンネル接続によるデメリットとしては毎回トンネルを通すのが面倒なことです。
不安定ですが、netsh interface portproxy ~ による設定を行っても同じようにできます。
Windows Terminal と plink を用いたシリアル通信を試すために、 Arduino にシリアル通信のプログラムを書き込みます。
void setup() {
Serial.begin(9600);
}
void loop() {
if(Serial.available() <= 0) return;
char data = Serial.read();
if(data == '\r'){
Serial.print("\n");
}else{
Serial.print(data);
}
}
以下のコマンドで Windows Terminal から plink コマンドを実行してシリアル通信を行います。
plink -serial COM1 -sercfg 9600,8,1,N,N
公開鍵認証とは、暗号化やデジタル署名に使われる技術の一つで、公開鍵と秘密鍵という二つの鍵を使って通信相手の本人確認や暗号化を行う方法です。 SSH とは、Secure Shell の略で、ネットワーク上で安全にコマンドやファイルをやり取りするためのプロトコルです。SSH では公開鍵認証を使って、サーバーにログインすることができます。 具体的にどのように動作するかを説明します。
この記事では、数学についての言及はありません。
公開鍵認証では、公開鍵と秘密鍵という二つの鍵を使います。 公開鍵は名前の通り、誰でも知っていても構わない鍵で、通信相手に送ったり、インターネット上に公開したりします。 秘密鍵は自分だけが持っている鍵で、絶対に他人に知られてはいけない鍵です。 秘密鍵は公開鍵から導くことは数学的に非常に困難なものとなっています。 この性質を利用することで、暗号化やデジタル署名を実現できています。
デジタル署名とは、データの送信者が本人であることを証明するための技術です。 以下の手順でデジタル署名を行います。
デジタル署名は署名を秘密鍵、検証を公開鍵で行っています。
SSH とは、Secure Shell の略で、ネットワーク上で安全にコマンドやファイルをやり取りするためのプロトコルです。 SSH では公開鍵認証を使って、サーバーにログインすることができます。SSH の利点は以下の通りです。
SSH では、以下のように公開鍵認証を行います。
ssh-keygen -t ed25519)~/.ssh/id_ed25519.pub) を事前にサーバーに登録 (~/.ssh/authorized_keys)~/.ssh/id_ed25519) でデジタル署名~/.ssh/authorized_keys)でデジタル署名を検証し、正しい場合はログインを許可以上が、公開鍵認証と SSH についてのまとめです。 公開鍵認証と SSH を使うことで、ネットワーク上で安全にコマンドやファイルをやり取りすることができます。
slappasswd コマンドは OpenLDAP 用のパスワードを生成するコマンドで、 デフォルトでは SSHA を用いて、パスワードをハッシュ化する。
SSHA では生成されたハッシュの末尾 4 バイトがソルトとなっており、 入力されたパスワードと保存されているソルトからハッシュを生成し、 保存されているハッシュと一致するかどうかで認証を行う。
以下のプログラムでは、 適切なパスワード (例: admin) を与えると、元のハッシュと生成されたハッシュが一致する。
require 'base64'
require 'digest'
pass = 'admin'
ssha = '{SSHA}23AUBfRZytVFNpe7onuFhyCSJOHRzCWh'
ssha =~ /{.+}(.+)/
salt256s = Base64.decode64(Regexp.last_match(1)).unpack('C*')[-4..-1]
salt = salt256s.pack('C*')
b_ssha = Digest::SHA1.digest(pass + salt)
Base64.strict_encode64(
(b_ssha.unpack('C*') + salt256s).pack('C*')
)
Permission denied が出る実際に localhost:22 に接続すると、
hikari@localhost: Permission denied (publickey,keyboard-interactive).
とエラーが出る。

Administrators グループ、つまり「管理者ユーザー」はデフォルトで、C:\ProgramData\ssh\administrators_authorized_keys の公開鍵を
参照して認証しているようだ。
これを、$env:userprofile\.ssh\authorized_keys に変更する。
管理者権限で C:\ProgramData\ssh\sshd_config を開き、以下のように下の二行をコメントする。

- Match Group administrators
- AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
+ #Match Group administrators
+ # AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
保存が終わったら、サービスを再起動する。
Restart-Service sshd
pkg install openssh
Android 版の termux で実行するとエラーが起こるので、 既存の termux を削除し Github から termux をインストールすることをおすすめします。
sshd
クライアントの公開鍵 (~/.ssh/id_*.pub) を
termux の ~/.ssh/authorized_keys に追加する。
公開鍵はメールで自分宛てに送ったり、twitter の DM で自分宛てに送ったりして、コピペすると楽。
# 例:
echo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKYztjZfIVMl5o0J2DrigTsl1XgbSKMUgYCpfOfhMtmw hikari@B450M-K >> ~/.ssh/authorized_keys
# スマホの ip アドレスを確認
ip a
ssh 192.168.x.x -p 8022
設定ファイルを編集するために管理者権限が必要なため、管理者権限でターミナルを開く。
ターミナルのアイコンを右クリックして、ターミナルを右クリックして、「管理者として実行」


notepad C:\ProgramData\ssh\sshd_config
を実行。

- # PasswordAuthentication yes
+ PasswordAuthentication no

を

に変更し上書き保存する。
ターミナルに戻り、以下のようにコマンドを実行し、SSH サーバーを再起動する。
Restart-Service sshd
設定が有効になっているかテストする。
ssh localhost
を実行し、
user@localhost: Permission denied (publickey,keyboard-interactive).
のようになっていれば OK
ssh -L [クライアントのポート]:[転送したいホスト]:[転送したいホストのポート]
クライアント A、SSH サーバー B、転送ホスト C があり
C:8080を A のポート 80 に転送したい場合。
ssh -L80:C:8080 B
この転送で、A から http://localhost へアクセスすると、
B の http://C:8080 と同じ内容が表示される。
まとめると、 A から C は見えなくても、A から B へ SSH が接続でき、 B から C が見える場合、B を経由して C のポートを A へ転送可能。
-g をつけると、A のホスト名で A のネットワークにあるパソコンから
C:8080 へアクセスができる。
家のネットワーク上にあるポートを外部に転送したいとき、 とりあえず 22 番だけ外部に開放している状態であれば、 ssh 経由で家のネットワークにアクセス可能。
ssh -R [クライアントのポート]:[転送したいホスト]:[転送したいホストのポート]
ローカル転送と異なり、 接続先から見えるポートを転送するのではなくクライアント側から見える ポートを転送する。
クライアント B、SSH サーバー A、転送ホスト C があり
C:8080を A のポート 80 に転送したい場合。
ssh -R80:C:8080 A
この転送で、A から http://localhost へアクセスすると、
B の http://C:8080 と同じ内容が表示される。
B が外からアクセスできない場合でも、
B と A の接続を確立させれば、
C の内容を A に転送可能。
B を直接操作できない場合に使うことが多く、
B と A の接続が切れるトラブルが発生した場合、A から C へのアクセスが不可能になるので、B と A の接続が切断された場合に自動的に再接続するツール
autossh が使われることが多い。