#はじめに
リモートでX11アプリケーションを起動して、そのウィンドウをローカルのディスプレイに表示させることは、SSHでX11フォワーディングを使えばできますよね。
「じゃあ逆にローカルでX11アプリケーションを起動して、そのウィンドウをリモートのディスプレイに表示させることってできないかな?」と思ってやってみたのですが、罠にはまって苦労したのでメモしときます。
#ローカルからリモートへウィンドウを飛ばす
ここでは、リモートからローカルのディスプレイへウィンドウを飛ばすのではなく、逆にローカルからリモートのディスプレイへウィンドウを飛ばすということを行います。
今回は次のような環境を想定しています。
- ローカルホスト(ホストA) : 192.168.10.10 (ホスト名: hostA)
- リモートホスト(ホストB) : 192.168.10.11 (ホスト名: hostB)
- ホストAでxeyesを起動し、そのウィンドウをホストBのディスプレイ(:0.0)に表示させる
まず、ホストB側でXサーバの設定を行います。
(ホストBでは0番Xサーバと0番スクリーンを使うものとします)
# 環境変数DISPLAYの設定
$ export DISPLAY=hostB:0.0
# ホストAからのXサーバへのアクセスを許可
$ xhost +hostA
次に、ホストA側で環境変数DISPLAYの設定とxeyesの実行を行います。
# 環境変数DISPLAYをリモートのディスプレイに設定
$ export DISPLAY=hostB:0.0
# xeyesを実行
$ xeyes
これでホストBのディスプレイに表示される…はずが
Error: Cant open display: hostB:0.0
と表示されるだけで、ホストBのディスプレイに何も表示されませんでした。ホストBのファイアウォールを止めてやり直してみましたが、それでもやっぱりダメでした。
調べてみると、以下のサイトに原因が書いてあるのを見つけました。
http://blogger.fastriver.net/2016/09/startx-xorg-6000-listen.html
どうやらデフォルトだとstartxを実行する際、-- -nolisten tcpというオプションがついた状態でXサーバが立ち上がるので、Xの通信に使う6000番ポートが閉じてしまっていたようです。
ポートを開いた状態でXサーバを立ち上げるには、以下のようなコマンドを実行すればOKです。(init 3
は起動中のXサーバを起動し直したい場合に実行してください)
# ランレベルを変更して起動中のXサーバを停止(Xサーバを起動し直す場合)
$ init 3
# ポートを開いた状態でXサーバを起動
$ startx -- -listen tcp
ファイアウォールの設定を変更して適切なポートを開けておくのも忘れないようにしましょう。
# 6000番ポートを開ける
$ sudo firewall-cmd --add-port=6000/tcp
2016/11/14:追記
勘違いがあったので追記しときます。上のコマンドで開くポートは6000番とは限らないようです。ディスプレイ番号の値によって、開くポートが変わるようですね。
上のコマンドでstartxを開いたら、まずディスプレイ番号をチェックします。
$ printenv DISPLAY
すると:2
のようにディスプレイ番号が表示されるはずです。これが開いているポート番号の1の位になります。
例えば:2
だった場合は開くポートは6002番になるわけです。
ファイアウォールの設定をする際にはこのことに気をつけてください。
ホストB側で適切なポートを開けた状態のXサーバが立ち上がったら、上と同様にxhost
などの設定を行いましょう。
これでホストAで実行したxeyesのディスプレイがちゃんと開くようになるはずです。
#おわりに
デフォルトで6000番ポートが開かないようになっているのは、セキュリティ上の理由からです。
6000番ポートが開きっぱなしになっていると、外部からディスプレイを操作されたり、スクリーンショットを撮られたりする危険があります。これを防ぐために、デフォルトでは6000番ポートを閉じているのです。
ググってみたところ、6000番ポートを開いた状態をデフォルトにしてXサーバを開くための設定の仕方も出てきました。しかし上記の理由からあまりオススメはしません。(筆者の個人的な意見です)
何か間違ってる点などに気づかれましたら、コメントでお知らせください。