# Vncserver (日本語)

関連記事

- x11vnc

Vncserver は以下のような複数のリモート機能をユーザーが使えるようにするリモートディスプレイデーモンです:

1. ローカルの X セッション (物理モニターで動作している X) の直接制御。
2. マシンの (物理モニターではなく仮想的に) バッググラウンドで動作する並列 X セッション。ユーザーが切断しても、サーバーのアプリケーションは全て実行し続けることができます。

## インストール

Vncserver は tigervnc や AUR の tightvnc に入っています。

## Vncserver を実行する

### 初期設定

#### environment と password ファイルを作成する

Vncserver は最初に起動した時に初期の environment ファイルとユーザーの password ファイルを作成します:

    $ vncserver

    You will require a password to access your desktops.

    Password:
    Verify:

    New 'mars:1 (facade)' desktop is mars:1

    Creating default startup script /home/facade/.vnc/xstartup
    Starting applications specified in /home/facade/.vnc/xstartup
    Log file is /home/facade/.vnc/mars:1.log

vncserver が動作するデフォルトのポートは :1 で、サーバーが動作する TCP ポートと対応しています (5900+n = ポート番号)。この場合、5900+1=5901 で動作します。二度 vncserver を動作させると次の数字でフリーのポート (:2 または 5902) に二番目のインスタンスが作成されます。

Note: Linux システムでは物理メモリが許すかぎりいくらでも VNC サーバーを使うことができます -- それぞれは互いに並行して動きます。

vncserver を終了するには -kill スイッチを使います:

    $ vncserver -kill :1

#### xstartup ファイルを編集する

Vncserver は .xinitrc ファイルのように機能する `~/.vnc/xstartup` を読み込みます。グラフィカル環境を使いたい場合は、少なくとも起動する DE を定義する必要があります。例えば、xfce4 を起動するには:

    #!/bin/sh
    export XKL_XMODMAP_DISABLE=1
    exec startxfce4

Note: `XKL_XMODMAP_DISABLE` 行は仮想化された DE のターミナルで入力するときにキーストロークが組み替えられる問題を解決します。

#### パーミッション

これは必須ではありませんが、`~/.ssh` と同じように `~/.vnc` を保護すると良いでしょう。保護するには次を実行してください:

    $ chmod 700 ~/.vnc

### サーバーを起動する

Vncserver はスイッチを使って柔軟に使うことができます。下の例では、特定の解像度で、複数のユーザーが同時に表示・操作可能に、そして仮想サーバの dpi を 96 に設定して vncserver を起動します:

    $ vncserver -geometry 1440x900 -alwaysshared -dpi 96 :1

Note: vncserver で標準的なモニター解像度を使う必要はありません; 1440x900 は 1429x882 や 1900x200 など普段使われない数字に置き換えることができます。

オプションの完全な一覧を見るには、-help スイッチを vncserver に渡して下さい。

    $ vncserver -help

## 物理ディスプレイで vncserver を実行する (5900 ポート)

### TigerVNC の x0vncserver を使う (推奨)

TigerVNC には x11vnc と同じような機能をもった x0vncserver バイナリが入っている、例:

    x0vncserver -display :0 -passwordfile ~/.vnc/passwd

詳しくは:

    man x0vncserver

### x11vnc を使う (推奨)

物理ディスプレイのリモートコントロールがしたい場合は x11vnc パッケージを使って下さい。詳しくは、X11vnc を見て下さい。

### ダーティハックを使う (非推奨)

#### 基本設定

xorg-server と tigervnc をインストールして Xorg 設定で "vnc" をロードしてください。

例 `/etc/X11/xorg.conf.d/10-vnc.conf`:

    Section "Module"
      Load "vnc"
    EndSection

    Section "Screen"
      Identifier "Screen0"
      Option "SecurityTypes" "None"
    EndSection

パスワード認証をするには、vncpasswd コマンドを実行した後に、下のように "Screen" セクションを置き換えて下さい。

    Section "Screen"
      Identifier "Screen0"
      Option "SecurityTypes" "VncAuth"
      Option "UserPasswdVerifier" "VncAuth"
      Option "PasswordFile" "/root/.vnc/passwd"
    EndSection

#### xorg-server にパッチをあてる

残念ながら xorg-server パッケージにはバグが存在します (15/11/2013)。 ありがたいことに fedora がこのパッチを作成しています。

[http://pkgs.fedoraproject.org/cgit/xorg-x11-server.git/plain/0001-include-export-key_is_down-and-friends.patch?h=f19&id=06e94667faa0cd1f9f32cf54e9e447ef50fde635 ]

abs コマンドを実行して、パッチファイルを配置して PKGBUILD を編集してください。

PKGBUILD サンプル:

    source = vnc.patch
    sha256sums = '1bbbe70236dc70b5e35572f2197d163637100f8c58d0038bdc240df075eb5726'
    prepare() {
      cd "${pkgbase}-${pkgver}"
      # patch for vnc module
      patch -Np1 -i ../vnc.patch

パッチ (リンクが死んでいる場合)

    +++ b/include/input.h
    @@ -244,12 +244,12 @@  typedef struct _InputAttributes {
     #define KEY_POSTED 2
     #define BUTTON_POSTED 2

    -extern void set_key_down(DeviceIntPtr
    diff --git a/include/input.h b/include/input.h
    index 350daba..2d5e531 100644
    --- a/include/input.h
    +++ b/include/input.h
    @@ -244,12 +244,12 @@  typedef struct _InputAttributes {
     #define KEY_POSTED 2
     #define BUTTON_POSTED 2

    -extern void set_key_down(DeviceIntPtr pDev, int key_code, int type);
    -extern void set_key_up(DeviceIntPtr pDev, int key_code, int type);
    -extern int key_is_down(DeviceIntPtr pDev, int key_code, int type);
    -extern void set_button_down(DeviceIntPtr pDev, int button, int type);
    -extern void set_button_up(DeviceIntPtr pDev, int button, int type);
    -extern int button_is_down(DeviceIntPtr pDev, int button, int type);
    +extern _X_EXPORT void set_key_down(DeviceIntPtr pDev, int key_code, int type);
    +extern _X_EXPORT void set_key_up(DeviceIntPtr pDev, int key_code, int type);
    +extern _X_EXPORT int key_is_down(DeviceIntPtr pDev, int key_code, int type);
    +extern _X_EXPORT void set_button_down(DeviceIntPtr pDev, int button, int type);
    +extern _X_EXPORT void set_button_up(DeviceIntPtr pDev, int button, int type);
    +extern _X_EXPORT int button_is_down(DeviceIntPtr pDev, int button, int type);

    extern void InitCoreDevices(void);
    extern void InitXTestDevices(void);

## vncserver に接続する

vncserver に接続できるクライアントは多数存在します。下は 10.1.10.2 のポート 5901 (:1) で動作している vncserver の略記法の例です:

    $ vncviewer 10.1.10.2:1

### パスワードなしで認証

`-passwd` スイッチを使うことでサーバーの `~/.vnc/passwd` ファイルの場所を定義することができます。サーバー上のこのファイルには SSH か物理的なアクセスによってユーザーがアクセスすることが期待されています。どちらの場合でも、クライアントのファイルシステム上の安全な場所、つまり特定のユーザーだけが読み込みアクセスできる場所にファイルを置いて下さい。

    $ vncviewer -passwd /path/to/server-passwd-file

### GUI ベースのクライアント

- gtk-vnc
- kdenetwork-krdc
- rdesktop
- vinagre
- remmina
- vncviewer-jar

## SSH トンネルで VNC サーバーをセキュアにする

### サーバー側

LAN の保護の外から vncserver にアクセスしたいときは平文パスワードやビューア・サーバの暗号化されないトラフィックに配慮する必要があります。Vncserver は ssh トンネリングによって簡単にセキュアにすることができます。さらに、この方法を使えば外側に他のポートを開く必要はありません。トラフィックは文字通りユーザーが既に WAN のために開いている SSH ポートを通過するからです。この場合 vncserver を使用する際は -localhost スイッチを使うことが強く推奨されます。このスイッチはローカルホストからの接続だけを許可します -- さらに類推によって物理的に ssh を使ってマシンの認証を受けたユーザーも許可されます。

    $ vncserver -geometry 1440x900 -alwaysshared -dpi 96 -localhost :1

### クライアント側

サーバーはローカルホストからの接続だけを許可しているので、-L スイッチを使ってトンネルを有効にして ssh で接続します。例えば:

    $ ssh IP_OF_TARGET_MACHINE -L 8900/localhost/5901

これはサーバーポート 5901 をクライアントのポート 8900 に転送します。SSH で接続されると、xterm やシェルウィンドウが開いたままになります; これはサーバーのセキュア化されたトンネルとして働きます。vnc で接続するには、新しく xterm を開いてリモートの IP アドレスではな、セキュア化されたトンネルを使ってクライアントのローカルホストに接続します:

    $ vncviewer localhost::8900

ssh の man ページより [1]: -L [bind_address:] port:host:hostport

ポート与えられたローカル (クライアント) ホスト上のポートが、与えられたリモートホスト上のポートに転送されるよう指定します(ローカル→リモートのポート転送)。これはローカル側でポート に listen (接続受け付け) 用のソケットを割り当てることによりおこなわれます。さらにbindするアドレス が与えられている場合は、ソケットはこのアドレスに bind されます。このポートに向けておこなわれた接続はつねに安全な通信路を経由してリモートマシン上に到達し、そこからホスト のポートホスト側ポート に接続されるようになります。ポート転送は設定ファイルによっても指定できます。IPv6 アドレスは他の形式でも指定することができます:

[bind_address/] port/host/ hostport もしくはブラケット [ ] で囲むことで指定できます。 特権ポートを転送できるのはスーパーユーザだけです。デフォルトでは、ローカル側のポートはGatewayPortsの設定に従って bind されますが、bindするアドレス を明示的に指定することで、特定のアドレスに接続をふり向けることができます。bindするアドレス として"localhost"を指定すると、ポートを listen するのはローカルな使用のみに限ることになります。いっぽう、空のアドレスまたは `*' を指定すると、そのポートはすべてのインターフェイスに対して使用可能になります。

### SSH で Android デバイスから VNC サーバーに接続する

Android デバイスを使って SSH で VNC サーバーに接続するには:

    1. 接続するマシン上で SSH サーバーを動作させる。
    2. 接続するマシン上で VNC サーバーを動作させる (上述のように -localhost フラグでサーバーを起動する)。
    3. Android デバイスで SSH クライアントを使う (ConnectBot が人気があります、この外では例としてこれを使います)。
    4. Android デバイスで VNC クライアントを使う (androidVNC)。

固定 IP アドレスを持たないマシンではダイナミック DNS サービスを使うことを考慮してください。

ConnectBot で、IP を入力してマシンに接続してください。オプションキーをタップして、Port Forwards を選択し新しいポートを追加してください:

    Nickname: vnc
    Type: Local
    Source port: 5901
    Destination: 127.0.0.1:5901 (it did not work for me when I typed in 192.168.x.xxx here, I had to use 127.0.0.1)

保存してください。

androidVNC で:

    Nickname: nickname
    Password: the password used to set up the VNC server
    Address: 127.0.0.1 (we are in local after connecting through SSH)
    Port: 5901

接続してください。

## Tips and Tricks

### 起動時・シャットダウン時に VNC サーバーを起動・停止する

`/usr/lib/systemd/system/vncserver.service` のファイルを探して下さい

    /etc/systemd/system/vncserver@:1.service

    # The vncserver service unit file
    #
    # 1. Copy this file to /etc/systemd/system/vncserver@:x.service
    #  Note that x is the port number on which the vncserver will run.  The default is 1 which
    #  corresponds to port 5901.  For a 2nd instance, use x=2 which corresponds to port 5902.
    # 2. Edit User=
    #   ("User=foo")
    # 3. Edit  and vncserver parameters appropriately
    #   ("/usr/bin/vncserver %i -arg1 -arg2 -argn")
    # 4. Run `systemctl --system daemon-reload`
    # 5. Run `systemctl enable vncserver@:<display>.service`
    #
    # DO NOT RUN THIS SERVICE if your local area network is untrusted!
    #
    # See the wiki page for more on security
    # https://wiki.archlinux.org/index.php/Vncserver

    [Unit]
    Description=Remote desktop service (VNC)
    After=syslog.target network.target

    [Service]
    Type=forking
    User=

    # Clean any existing files in /tmp/.X11-unix environment
    ExecStartPre=-/usr/bin/vncserver -kill %i
    ExecStart=/usr/bin/vncserver %i
    ExecStop=/usr/bin/vncserver -kill %i

    [Install]
    WantedBy=multi-user.target

### リモートマシンからローカルにクリップボードの内容をコピーする

リモートマシンからローカルマシンへのコピーが動作しない場合、サーバー上で以下のように autocutsel を起動して下さい [参照]:

    $ autocutsel -fork

F8 を押して VNC メニューのポップアップを表示し、`Clipboard: local -> remote` オプションを選択してください。

上記のコマンドを `~/.vnc/xstartup` に記述することで vncserver の起動時に自動で動作するようにすることができます。

### マウスカーソルが表示されない問題

`x0vncserver` の使用時にマウスカーソルが表示されない場合、以下のように vncviewer を起動して下さい:

    $ vncviewer DotWhenNoCursor=1 <server>

もしくは tigervnc の設定ファイルに `DotWhenNoCursor=1` を記述してください。デフォルトでは `~/.vnc/default.tigervnc` に存在します。

Categories:

- Security (日本語)
- Remote Desktop (日本語)