UbuntuにAnsibleでxrdpをインストールする。

# はじめに
私が普段使用しているPCはWindows機なのですが、ごくたまにサーバにGUIでリモートログインしたくなる時があります。

ただ、たまにログインするといった用途のためだけに`VNC`を入れるのも面倒なのでWindows機から手軽にGUIでリモートログインができる`xrdp`をよく使っています。

今回は`xrdp`のインストール＆セットアップを`Ansible`の`Playbook`にしたので紹介したいと思います。

# 参考にさせて頂いたページ
以下のページを参考にさせて頂きました。

https://gihyo.jp/admin/serial/01/ubuntu-recipe/0621
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10190946705

# xrdpをインストールするサーバ環境
今回は`Ubuntu Server 20.04`にインストールを行います。


# Ansible Playbookの作成
今回は以下2つのロールを作成したいと思います。

尚、rootユーザでリモートログインしないなら`setup_desktop-rootlogin`ロールは不要です。

|ロール名|説明|
|:--|:--|
|setup_xrdp|xrdpのセットアップ用ロール|
|setup_desktop-rootlogin|rootログイン用ロール|

## ロールの作成
`Ansible`の[ベストプラクティス](https://docs.ansible.com/ansible/2.9_ja/user_guide/playbooks_best_practices.html)の構成で作成します。

`ansible-galaxy`コマンドの`init`オプションでベストプラクティス構成のロールの雛形が作成できるため、適当な場所に`roles`ディレクトリを作成した後、`ansible-galaxy`コマンドで雛形を作成します。

```shell:ansible-galaxyコマンドでのロール雛形作成
mkdir roles
cd roles/
ansible-galaxy init setup_xrdp
```

## tasksの作成
`tasks`ディレクトリにある`main.yml`に実行するタスクを記述していきます。

上記で紹介させて頂いたページではシェルにして実行しておりますが、`Playbook`で実行するため、シェルで実行している内容をそれぞれ別個に設定するよう記載しています。

`45-allow-colord.pkla`、`46-allow-update-repo.pkla`、`startubuntu.sh`については予め作成しておき、`Playbook`実行時にコピーするようにします。

また、設定変更されたら、`xrdp`のサービスを起動・再起動する処理を行うため、`notify`で`restart_xrdp`という名前の処理を呼び出すようにします。

```yml:roles/setup_xrdp/tasks/main.yml
---
# tasks file for setup_xrdp
- name: xrdpインストール
  apt:
    name: xrdp
    state: present
    update_cache: yes

- name: sessman.ini startwm置換
  replace:
    path: /etc/xrdp/sesman.ini
    regexp: startwm
    replace: startubuntu
  notify:
    - restart_xrdp

- name: sessman.ini FuseMountName置換
  replace:
    path: /etc/xrdp/sesman.ini
    regexp: FuseMountName=thinclient_drives
    replace: FuseMountName=shared-drives
  notify:
    - restart_xrdp

- name: Xwrapper.config置換
  replace:
    path: /etc/X11/Xwrapper.config
    regexp: allowed_users=console
    replace: allowed_users=anybody
  notify:
    - restart_xrdp

- name: startubuntu.shコピー
  copy:
    src: startubuntu.sh
    dest: /etc/xrdp/startubuntu.sh
    owner: root
    group: root
    mode: 0755
  notify:
    - restart_xrdp

- name: 45-allow-colord.pkla配置
  copy:
    src: 45-allow-colord.pkla
    dest: /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla
    owner: root
    group: root
    mode: 0644
  notify:
    - restart_xrdp

- name: 46-allow-update-repo.pkla配置
  copy:
    src: 46-allow-update-repo.pkla
    dest: /etc/polkit-1/localauthority/50-local.d/46-allow-update-repo.pkla
    owner: root
    group: root
    mode: 0644
  notify:
    - restart_xrdp
```

## コピーするファイルの作成
`45-allow-colord.pkla`、`46-allow-update-repo.pkla`、`startubuntu.sh`のファイルを`files`ディレクトリの下に作成しておきます。

```shell:roles/setup_xrdp/files/45-allow-colord.pkla
cat << _EOF_ > roles/setup_xrdp/files/45-allow-colord.pkla
[Allow Colord all Users]
Identity=unix-user:*
Action=org.freedesktop.color-manager.create-device;org.freedesktop.color-manager.create-profile;org.freedesktop.color-manager.delete-device;org.freedesktop.color-manager.delete-profile;org.freedesktop.color-manager.modify-device;org.freedesktop.color-manager.modify-profile
ResultAny=no
ResultInactive=no
ResultActive=yes
_EOF_
```

```shell:roles/setup_xrdp/files/46-allow-update-repo.pkla
cat << _EOF_ > roles/setup_xrdp/files/46-allow-update-repo.pkla
[Allow Package Management all Users]
Identity=unix-user:*
Action=org.freedesktop.packagekit.system-sources-refresh
ResultAny=yes
ResultInactive=yes
ResultActive=yes
_EOF_
```

```shell:roles/setup_xrdp/files/startubuntu.sh
cat << _EOF_ > roles/setup_xrdp/files/startubuntu.sh
#!/bin/sh
export GNOME_SHELL_SESSION_MODE=ubuntu
export XDG_CURRENT_DESKTOP=ubuntu:GNOME
exec /etc/xrdp/startwm.sh
_EOF_
```

## handlersの作成
先ほど`tasks`で指定した`restart_xrdp`という名前のハンドラを作成します。

ハンドラは`notify`で指定したタスクの処理で変更が加えられた場合にのみ実行される処理となります。

```yml:roles/setup_xrdp/handlers/main.yml
---
# handlers file for setup_xrdp
- name: restart_xrdp
  systemd:
    name: xrdp
    state: restarted
    enabled: yes
```

## インベントリファイルの作成
`Ansible`で`xrdp`をインストールする対象のサーバのアドレスを登録します。

```shell:hosts-all
cat << _EOF_ > hosts-all
[ubuntu]
ubuntu01 ansible_host=[接続先IPアドレス]
_EOF_
```

## 実行Playbookの作成
ベストプラクティスに従って、実行に必要となる`Playbook`を作成します。

```shell:server.yml
cat << _EOF_ > server.yml
---
- become: true
  hosts: ubuntu
  roles:
    - setup_xrdp
_EOF_
```

```shell:site.yml
cat << _EOF_ > site.yml
---
- import_playbook: server.yml
_EOF_
```

# Ansibleの実行
作成した`Playbook`を実行します。

`site.yml`で`server.yml`をインポートして、`server.yml`で`setup_xrdp`ロールを実行するようにしているため、`site.yml`を指定すれば作成した`setup_xrdp`ロールが実行されます。

今回はユーザ設定等行っていないため、`Playbook`を実行する際、SSHログインするためのユーザ、SSHログインパスワード、sudoする際のパスワードも指定するようオプションを加えます。

```shell:Playbookの実行
ansible-playbook -i hosts-all -u [ログインユーザ] site.yml -k -K
```

# (rootでログインしたい人のみ)rootログインの設定
あまりやってはいけないですが、リモートログインする際にroot権限で作業したい場合もあるかと思うので、rootでログインするための`Playbook`を以下で作成します。

## ロールの作成
先ほどと同様、ロールの雛形を作成します。

```shell:ansible-galaxyコマンドでのロール雛形作成
cd roles/
ansible-galaxy init setup_desktop-rootlogin
```

## tasksの作成
デスクトップへのrootログインは`Ubuntu`では許可されていないため、パスワードの設定もされていません。

パスワードを設定すれば、`xrdp`でrootログインすることは可能ですが、待機状態(スリープモード)になってしまうと、パスワードを入力してもログインが失敗します。

これは、初回ログイン時は`xrdp`用のPAM設定で認証され、rootログインできますが、待機状態（スリープモード）から復帰する際は`xrdp`用のPAM設定ではなく`gdm-password`というPAM設定で認証されます。

ただ、`gdm-password`ではデスクトップへのrootログインは許可されていないため、rootパスワードを設定しただけでは待機状態から復帰できなくなります。

そのためrootログインの許可設定も併せて行います。

```yml:roles/setup_desktop-rootlogin/tasks/main.yml
---
# tasks file for setup_desktop-rootlogin
- name: AllowRoot設定
  lineinfile:
    path: /etc/gdm3/custom.conf
    regexp: "^AllowRoot"
    insertafter: "^\\[security\\]"
    line: "AllowRoot=true"

- name: gdm-password pam_succeed_ifコメントアウト
  replace:
    path: /etc/pam.d/gdm-password
    regexp: "^auth\trequired\tpam_succeed_if.so"
    replace: "#auth\trequired\tpam_succeed_if.so"

- name: rootパスワード設定
  user:
    name: "root"
    password: "{{ root_pass }}"
```

## ホスト変数ファイルの作成
`tasks`でrootパスワードを変数にしたので、変数を設定していきます。

`roles`の`vars`に変数を記載しても良いですが、各ホストごとにパスワードは異なるかと思うので、`host_vars`ディレクトリを作成し、配下にホスト用の変数を記載したファイルを作成します。

また、パスワードをそのまま入力すると`Playbook`実行時に警告が出るため、前もってパスワードのハッシュ値を確認し、ハッシュ化したパスワードを入力します。

ホスト用の変数ファイルは、「**インベントリファイルで指定したホスト名.yml**」という形式で`host_vars`ディレクトリ配下に作成すると、`Playbook`実行時に呼び出されるため、今回の場合は「**ubuntu01.yml**」というファイル名で作成します。

```shell:ハッシュ値の確認（パスワードをubuntuとした場合の例）
sudo openssl passwd -6 ubuntu
$6$lAehWscCdig1vM0/$LGbcSM3iv4ho.NrRpOJZbOZwXsWDt6xHYnuIAUYAqm/u.1r9UAejaXg/CcU7TLtcQWC78QTm5eQeVFj4OibPF/
```

```shell:ホスト変数ファイル格納ディレクトリの作成
mkdir host_vars
```

```shell:ホスト変数ファイルの作成（host_vars/ubuntu01.yml)
root_pass: "$6$lAehWscCdig1vM0/$LGbcSM3iv4ho.NrRpOJZbOZwXsWDt6xHYnuIAUYAqm/u.1r9UAejaXg/CcU7TLtcQWC78QTm5eQeVFj4OibPF/"
```

## ロール実行ファイルへの追加
先ほど作成した`server.yml`に`setup_desktop-rootlogin`ロールを追加します。

追加後の`Playbook`実行方法は先ほどと同じ。

```yml:server.yml
---
- become: true
  hosts: ubuntu
  roles:
    - setup_xrdp
    - setup_desktop-rootlogin
```

# おわりに
`xrdp`はWindows標準のリモートデスクトップクライアントで接続できるため、手軽に使えますが、インストール後の設定がいつも面倒だと感じていたため、今回`Ansible`の`Playbook`化してみました。

今回の各種コードはGitHubにも置きましたので良かったら参考にどうぞ。
https://github.com/sakai00kou/qiita