きまぐれほげほげひろば

Linux リモートデスクトップゲートウェイ(guacamole on Rocky Linux 9)

このページでは、RockyLinux9でリモートデスクトップゲートウェイを実現する方法・手順について説明します。

リモートデスクトップゲートウェイとは、ユーザがブラウザを使用してリモートのデスクトップ(コンソール)画面を操作できる仕組みです。 これはApache guacamoleを使用して実現します。実現にあたり、インターネットから利用する事も考慮して、時間ベースのワンタイムパスワードと画面録画機能を追加します。

ブラウザだけでVNCやらRDPだけでなくSSHもできるので、外出先からの自宅サーバのメンテナンスやテレワーク的なこともできちゃいます。
また、操作記録はデフォルトでSSH接続時の標準入力、標準出力、標準エラーを記録することができます。機能追加で画面録画もできます。

末尾におまけでfail2banによる不正アクセス対策も説明します。

この説明は以下に示す環境で確認しました。

またguacamoleは以下の方針でインストールします。

導入手順を順に説明します。
以下の流れになります。

  1. 事前準備
  2. guacamoleサーバ
  3. tomcat
  4. nginx
  5. guacamoleクライアント
  6. postgresql
  7. guacamole微調整
  8. エクステンション
  9. 接続設定

https://guacamole.apache.org/doc/gug/installing-guacamole.htmlの「Required dependencies」に記載されているライブラリを導入するためにepelとrpmfusionのリポジトリパッケージをインストールします。

ffmpegのパッケージはrpmfusionにあります。
# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm # dnf install --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-$(rpm -E %rhel).noarch.rpm

https://guacamole.apache.org/doc/gug/installing-guacamole.htmlの「Required dependencies」に記載されているライブラリをインストールします。

# dnf install --enablerepo=crb,epel,rpmfusion-free-updates \ cairo-devel libjpeg-turbo-devel libjpeg-devel libpng-devel libtool libuuid-devel ffmpeg-devel \ freerdp-devel pango-devel libssh2-devel libtelnet-devel libvncserver-devel libwebsockets-devel \ pulseaudio-libs-devel openssl-devel libvorbis-devel libwebp-devel

Apache guacamoleのサイトよりソースアーカイブをダウンロードして展開します。

# wget https://apache.org/dyn/closer.lua/guacamole/1.5.5/source/guacamole-server-1.5.5.tar.gz?action=download -O guacamole-server-1.5.5.tar.gz # tar zxf guacamole-server-1.5.5.tar.gz # cd guacamole-server-1.5.5

次に、configureスクリプトを実行して前提条件のライブラリインストールチェックを行いmakeファイルを生成します。ここでサービス管理にsystemdとinitどちらを使用するかとインストール先パスと指定します。

出力として前提ライブラリのチェック結果を表示するので、「wsock32」以外全てyesになることを確認します。

noになるものがあれば、そのライブラリが足りてません。

# ./configure --with-systemd-dir=/etc/systemd/system --prefix=/opt/guacamole-1.5.5 ------------------------------------------------ guacamole-server version 1.5.5 ------------------------------------------------ Library status: freerdp2 ............ yes pango ............... yes libavcodec .......... yes libavformat.......... yes libavutil ........... yes libssh2 ............. yes libssl .............. yes libswscale .......... yes libtelnet ........... yes libVNCServer ........ yes libvorbis ........... yes libpulse ............ yes libwebsockets ....... yes libwebp ............. yes wsock32 ............. no Protocol support: Kubernetes .... yes RDP ........... yes SSH ........... yes Telnet ........ yes VNC ........... yes Services / tools: guacd ...... yes guacenc .... yes guaclog .... yes FreeRDP plugins: /usr/lib64/freerdp2 Init scripts: no Systemd units: /etc/systemd/system Type "make" to compile guacamole-server.

makeでコンパイルします。

# make # echo $? 0

make installでコンパイルしたファイルを/opt/guacamole以下にインストールします。

# make install libtool: finish: PATH="/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin" ldconfig -n /opt/guacamole-1.5.5/lib ---------------------------------------------------------------------- Libraries have been installed in: /opt/guacamole-1.5.5/lib If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the '-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to the 'LD_LIBRARY_PATH' environment variable during execution - add LIBDIR to the 'LD_RUN_PATH' environment variable during linking - use the '-Wl,-rpath -Wl,LIBDIR' linker flag - have your system administrator add LIBDIR to '/etc/ld.so.conf' See any operating system documentation about shared libraries for more information, such as the ld(1) and ld.so(8) manual pages. ---------------------------------------------------------------------- make[1]: ディレクトリ '/root/guacamole-server-1.5.5' から出ます # echo $? 0 # ln -s /opt/guacamole-1.5.5 /opt/guacamole # ldconfig

guacamole server(guacd)のサービスを起動します。

# systemctl start guacd.service # systemctl status guacd.service ● guacd.service - Guacamole Server Loaded: loaded (/etc/systemd/system/guacd.service; enabled; preset: disabl Active: active (running) since Thu 2024-08-08 01:26:33 JST; 3s ago

guacamole server(guacd)のサービスをOS起動時に自動起動するように設定します。

# systemctl enable guacd.service Created symlink /etc/systemd/system/multi-user.target.wants/guacd.service → /etc/systemd/system/guacd.service.

tomcatパッケージをインストールします。

# cd # dnf install tomcat tomcat-webapps

今回はtomcatの設定をいじりません。tomcatの待ち受けポートを変更したい場合はここで弄ります。

tomcatサービスを起動します。

# systemctl start tomcat # systemctl status tomcat ● tomcat.service - Apache Tomcat Web Application Container Loaded: loaded (/usr/lib/systemd/system/tomcat.service; disabled; preset: Active: active (running) since Thu 2024-08-08 01:28:55 JST; 8s ago

tomcatサービスを無事に起動できたら、OS起動時の自動起動を有効にします。

# systemctl enable tomcat Created symlink /etc/systemd/system/multi-user.target.wants/tomcat.service → /usr/lib/systemd/system/tomcat.service.

tomcatサービスが使用する外部受信TCPポートを許可します。(nginxでリバプロする場合は不要)

# ss -anpt | grep java LISTEN 0 1 [::ffff:127.0.0.1]:8005 *:* users:(("java",pid=41042,fd=55)) LISTEN 0 100 *:8080 *:* users:(("java",pid=41042,fd=46)) # firewall-cmd --zone=public --add-port=8080/tcp # firewall-cmd --runtime-to-permanen # firewall-cmd --list-all public (active) services: cockpit dhcpv6-client ssh ports: 8080/tcp

443/TCPおよび80/TCPから8080/TCPに内部転送するために導入。自己署名証明書で暗号化(パーソナルユースなので問題なしと割り切る)。

nginxをパッケージインストールします
# dnf install nginx
証明書を格納するディレクトリを作成します
# mkdir -p /etc/nginx/ssl
CAの自己署名証明書を作成します
# openssl req -new -x509 -sha256 -newkey rsa:2048 -days 3650 -nodes -subj "/CN=guacammole.local" -out /etc/nginx/ssl/ca.pem -keyout /etc/nginx/ssl/ca.key # ls -l /etc/nginx/ssl/ 合計 8 -rw------- 1 root root 1704 8月 13 23:38 ca.key -rw-r--r-- 1 root root 1119 8月 13 23:38 ca.pem
デフォルトの設定ファイルにhttp通信からtomcatへの、追加の設定ファイルにhttpsからtomcatへの転送(リバースプロキシ)設定を追加します。
# cp -p /etc/nginx/nginx.conf /etc/nginx/nginx.conf.org # vi /etc/nginx/nginx.conf http { server { location /guacamole/ { proxy_pass http://127.0.0.1:8080/guacamole/; proxy_buffering off; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; client_max_body_size 10g; access_log off; } # diff -u /etc/nginx/nginx.conf.org /etc/nginx/nginx.conf --- /etc/nginx/nginx.conf.org 2023-10-17 03:00:04.000000000 +0900 +++ /etc/nginx/nginx.conf 2024-08-08 22:47:25.643947924 +0900 @@ -44,6 +44,17 @@ # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; + location /guacamole/ { + proxy_pass http://127.0.0.1:8080/guacamole/; + proxy_buffering off; + proxy_http_version 1.1; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $http_connection; + client_max_body_size 10g; + access_log off; + } + error_page 404 /404.html; location = /404.html { } # vi /etc/nginx/conf.d/ssl.conf server { listen 443 ssl; server_name guacamole.local; ssl_certificate /etc/nginx/ssl/ca.pem; ssl_certificate_key /etc/nginx/ssl/ca.key; location /guacamole/ { proxy_pass http://127.0.0.1:8080/guacamole/; proxy_buffering off; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; client_max_body_size 10g; access_log off; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
nginxサービスを起動します。設定ファイルに問題ないことを確認します。
# systemctl start nginx.service # systemctl status nginx.service ● nginx.service - The nginx HTTP and reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; preset: d> Active: active (running) since Thu 2024-08-08 22:48:18 JST; 7s ago
OS起動時のnginxサービスの自動起動を有効にします。
# systemctl enable nginx.service Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
nginxで待ち受けしている80/TCPと443/TCPの通信を許可します。
# ss -anpt | grep nginx LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(( nginx",pid=98538,fd=6),("nginx",pid=98537,fd=6),("nginx",pid=98536,fd=6)) LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(( nginx",pid=98538,fd=7),("nginx",pid=98537,fd=7),("nginx",pid=98536,fd=7)) LISTEN 0 511 [::]:80 [::]:* users:(( nginx",pid=98538,fd=8),("nginx",pid=98537,fd=8),("nginx",pid=98536,fd=8)) # firewall-cmd --zone=public --add-service=http # firewall-cmd --zone=public --add-service=https # firewall-cmd --runtime-to-permanent # firewall-cmd --list-all services: cockpit dhcpv6-client http https ssh ports: 8080/tcp
Apache guacamoleのサイトにはサーバ用ソースアーカイブとともにクライアント用ソースアーカイブ(guacamole-client-1.5.5.tar.gz)が置かれてますが、中間コンパイル済みのwarファイル(guacamole-1.5.5.war)も一緒に置かれてますので今回はこちらを利用します。
guacamoleのwarファイルをダウンロードして、tomcatのwebappsディレクトリに配置します。warファイルは自動的に展開されます。
# curl -fsSL https://apache.org/dyn/closer.lua/guacamole/1.5.5/binary/guacamole-1.5.5.war?action=download -o guacamole-1.5.5.war # cp -p guacamole-1.5.5.war /var/lib/tomcat/webapps/guacamole.war # ls -l /var/lib/tomcat/webapps/ 合計 17000 drwxr-xr-x 3 tomcat tomcat 223 8月 8 01:28 ROOT drwxr-xr-x 10 tomcat tomcat 4096 8月 8 23:02 guacamole -rw-r--r-- 1 root root 17401039 8月 8 22:53 guacamole.war
guacamoleの追加機能warファイルを配置するディレクトリを作成します。(後ほど、TOPTと画面録画のwarを配置します。)
# mkdir -p /etc/guacamole/{lib,extensions}
端末ブラウザで「https://サーバのIPアドレスまたはホスト名/guacamole/」にアクセスしてログイン画面を表示することを確認します。(この時点ではデータベースを作成していないのでログインできません)
ユーザ設定を格納するデータベースとしてPostgreSQLをインストールします。ここでは紹介しませんがMySQLも可能です。
PostgreSQLパッケージをインストールします。
# dnf install postgresql postgresql-server
インスタンスを作成します。
# postgresql-setup --initdb --unit postgresql * Initializing database in '/var/lib/pgsql/data' * Initialized, logs are in /var/lib/pgsql/initdb_postgresql.log
ユーザ認証をident(OSから取得) → md5(パスワード入力)に変更します。
# cp -p /var/lib/pgsql/data/pg_hba.conf /var/lib/pgsql/data/pg_hba.conf.org # vi /var/lib/pgsql/data/pg_hba.conf #host all all 127.0.0.1/32 ident host all all 127.0.0.1/32 md5
PostgreSQLサービスを起動して、設定に問題が無いことを確認します。
# systemctl start postgresql.service # systemctl status postgresql.service ● postgresql.service - PostgreSQL database server Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled; pres> Active: active (running) since Thu 2024-08-08 23:13:09 JST; 7s ago
PostgreSQLサービスをOS起動時に自動起動するように設定します。
# systemctl enable postgresql Created symlink /etc/systemd/system/multi-user.target.wants/postgresql.service → /usr/lib/systemd/system/postgresql.service.
データベースは手動で作成します。「guacamole_db」という名前で作成します。
# su - postgres $ createdb guacamole_db $ psql -l データベース一覧 名前 | 所有者 | エンコーディング | 照合順序 | Ctype(変換演算子) | アクセス権限 --------------+----------+------------------+-------------+-------------------+----------------------- guacamole_db | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 |=c/postgres + | | | | |postgres=CTc/postgres template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 |=c/postgres + | | | | |postgres=CTc/postgres (4 行) $ exit
テーブルやビュー、初期データは、apache guacamoleサイトで別途配布しているguacamole-auth-jdbc-1.5.5.tar.gzに含まれるSQLに入っているので、ダウンロード・展開してデータベースに投入します。
# curl -fsSL https://apache.org/dyn/closer.lua/guacamole/1.5.5/binary/guacamole-auth-jdbc-1.5.5.tar.gz?action=download -o guacamole-auth-jdbc-1.5.5.tar.gz # tar zxf guacamole-auth-jdbc-1.5.5.tar.gz # cp guacamole-auth-jdbc-1.5.5/postgresql/schema/*.sql /var/lib/pgsql/ # chown postgres /var/lib/pgsql/*.sql # ls -l /var/lib/pgsql/ 合計 36 -rw-r--r-- 1 postgres root 21749 8月 8 23:19 001-create-schema.sql -rw-r--r-- 1 postgres root 2699 8月 8 23:19 002-create-admin-user.sql drwx------ 2 postgres postgres 6 2月 24 05:15 backups drwx------ 20 postgres postgres 4096 8月 8 23:13 data -rw------- 1 postgres postgres 1455 8月 8 23:08 initdb_postgresql.log # su - postgres $ cat 001-create-schema.sql 002-create-admin-user.sql | psql -d guacamole_db -f -
続いて、tomcat(Webアプリケーション、guacamoleクライアント)で使用するデータベースユーザを作成します。データベースユーザ名は後ほど設定ファイルで変更できますので任意です。
$ psql -d guacamole_db guacamole_db=# CREATE USER guacamole_user WITH PASSWORD 'パスワード'; guacamole_db=# GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA public TO guacamole_user; guacamole_db=# GRANT SELECT,USAGE ON ALL SEQUENCES IN SCHEMA public TO guacamole_user; guacamole_db=# \q
接続確認をします。
$ psql -h 127.0.0.1 -U guacamole_user -d guacamole_db -W パスワード: guacamole_db=> \q $ exit
「127.0.1」を「localhost」とすると、IPv6で接続しに行き接続できません。

guacamole client(Webインターフェース)用 JDBCエクステンションは先ほどダウンロードしたguacamole-auth-jdbc-1.5.5.tar.gzに含まれるのでエクステンションディレクトリにコピーします。

# cp guacamole-auth-jdbc-1.5.5/postgresql/guacamole-auth-jdbc-postgresql-1.5.5.jar /etc/guacamole/extensions/

JDBCドライバはパッケージインストールします。インストールしたモジュールをguacamoleのライブラリディレクトリにシンボリックリンクします。

# dnf install postgresql-jdbc # ln -s /usr/share/java/postgresql-jdbc.jar /etc/guacamole/lib/postgresql-jdbc.jar

guacamole client(Webインターフェース)の設定ファイルに、データベース接続設定を定義します。この時点でguacamole client(Webインターフェース)の設定ファイルはありませんので新規作成となります。

# cat > /etc/guacamole/guacamole.properties <<EOF postgresql-hostname: 127.0.0.1 postgresql-port: 5432 postgresql-database: guacamole_db postgresql-username: guacamole_user postgresql-password: パスワード EOF

PostgreSQLとguacamoleサーバを再起動します。

# systemctl restart tomcat.service guacd.service

端末ブラウザで「https://サーバのIPアドレスまたはホスト名/guacamole/」にアクセスしてログイン画面を表示することを確認します。
ユーザ「guacadmin」でログイン試行します。初期パスワードは「guacadmin」。
この時点ではTOTPは有効ではありません。

即行で、[設定]>[ユーザ設定]>[パスワード変更]にてパスワード変更します。

マニュアルに書かれているのはここまでですが、このままでは使用できません。

管理画面までアクセスできるようになりましたが、今のままではリモートデスクトップ接続した際に接続エラーとなります。guacamoleサーバとクライアント、それぞれの設定ファイルに、IPv4ローカルホストに接続するように設定を投入します。

# cat > /etc/guacamole/guacd.conf <<EOF [server] bind_host = 127.0.0.1 bind_port = 4822 EOF # cat >> /etc/guacamole/guacamole.properties <<EOF guacd-hostname: 127.0.0.1 guacd-port: 4822 EOF

SSHコンソールに接続した際に、デフォルトのままだとフォント表示が乱れますので、日本語固定幅フォントをインストールします。

# dnf install vl-gothic-fonts.noarch # systemctl restart tomcat.service guacd.service
SSH接続設定の[ディスプレイ]>[フォント名]で「vlgothic」を指定します。

guacamoleに時間ベースのワンタイムパスワード機能を追加します。guacamoleクライアントがインターネットから接続できなくても実装可能です。
時間ベースのワンタイムパスワードはワンタイムパスワードを発行するAuthenticatorと認証するサーバが同じ時刻であることを前提としてワンタイムパスワードを照合するので、時刻同期できていることはとても重要です。
ですので、NTPサーバと時刻同期できていること(^*で始まるサーバレコードがあること)を確認します。
# chronyc sources MS Name/IP address Stratum Poll Reach LastRx Last sample =============================================================================== ^- time-b-wwv.nist.gov 1 10 377 971 +78us[ +82us] +/- 70ms ^* 2001:a7ff:102::a 1 10 377 45 +78us[ +69us] +/- 2932us ^+ 2001:a7ff:102::b 1 10 377 997 -443ns[+3689ns] +/- 2925us ^+ 2001:a7ff:102::c 1 10 377 136 +37us[ +30us] +/- 2971us
guacamoleのサイトよりソースアーカイブをダウンロード・展開し、warファイルをエクステンションディレクトリに配置します。最後にtomcatとguacdを再起動します。
# curl -fsSL https://apache.org/dyn/closer.lua/guacamole/1.5.5/binary/guacamole-auth-totp-1.5.5.tar.gz?action=download -o guacamole-auth-totp-1.5.5.tar.gz # tar zxf guacamole-auth-totp-1.5.5.tar.gz # cp guacamole-auth-totp-1.5.5/guacamole-auth-totp-1.5.5.jar /etc/guacamole/extensions/ # systemctl restart tomcat.service guacd.service
端末ブラウザで「https://サーバのIPアドレスまたはホスト名/guacamole/」にアクセスして、ユーザ「guacadmin」または作成したユーザでログインします。
ログイン後、QRコードを表示するので、スマホの任意AuthenticatorアプリでQRコードを読み取り、表示した認証コードで認証します。
次回以降のログインからはQRコードの読み取りの手順は無く、ユーザ認証後はOTP認証コードのみです。

リモート接続後の画面操作を録画する機能を追加します。記録した動画はguacamoleの管理画面から参照可能です。記録保存先のデフォルトは /var/lib/guacamole/recordingsです。

参考:https://guacamole.apache.org/doc/gug/recording-playback.html

guacamoleのサイトよりソースアーカイブをダウンロード・展開し、warファイルをエクステンションディレクトリに配置します。最後にtomcatとguacdを再起動します。
# curl -fsSL https://apache.org/dyn/closer.lua/guacamole/1.5.5/binary/guacamole-history-recording-storage-1.5.5.tar.gz?action=download -o guacamole-history-recording-storage-1.5.5.tar.gz # tar zxf guacamole-history-recording-storage-1.5.5.tar.gz # cp -p guacamole-history-recording-storage-1.5.5/guacamole-history-recording-storage-1.5.5.jar /etc/guacamole/extensions/ # systemctl restart tomcat.service guacd.service
画面録画用ディレクトリを作成します。
ここポイントです。記録した動画はdaemonユーザで出力しますが、管理画面からの参照はtomcatユーザで読み取ろうとします。
セキュリティ的にtomcatユーザのセカンダリグループにdaemonは設定したくないので、作成したディレクトリに対して、所有者daemon所有グループtomcatを設定し、かつパーミッションにsetgidを有効にして、以降このディレクトリ配下に作成されるディレクトリとファイルは所有グループtomcatを継承するようにします。
このsetgidの有効ができてないと、接続履歴画面に録画再生リンクを表示しません。
# mkdir -p /var/lib/guacamole/recordings # chown daemon:tomcat /var/lib/guacamole/recordings # chmod 2750 /var/lib/guacamole/recordings # ls -ld /var/lib/guacamole/recordings drwxr-s--- 18 daemon tomcat 4096 8月 10 10:55 /var/lib/guacamole/recordings
guacamoleクライアント(Webアプリケーション)に、画面録画の記録パスを設定します。設定後、tomcatとguacdを再起動します。
# cat >> /etc/guacamole/guacamole.properties<<EOF recording-search-path: /var/lib/guacamole/recordings EOF # systemctl restart tomcat.service guacd.service

成功していれば、リモートデスクトップ接続終了後、[設定]>[履歴]画面の[Logs]列に[View]というリンクを表示します。このリンクをクリックすると接続中の操作録画を再生できます(接続設定でスクリーンレコーディングを設定している場合のみ)。

いよいよリモート接続の設定を行います。
[設定]>[接続]画面にて[接続の追加]ボタンをクリックします。
設定項目 設定値
接続の編集
 名前(任意)
 プロトコルSSH
パラメータ
 ネットワーク(任意)
  ホスト名(SSHサーバホスト名)
  ポート(SSHサーバポート番号)
ディスプレイ
 フォント名vlgothic
タイプスクリプト
 タイプスクリプトの保存ディレクトリ/var/lib/guacamole/recordings/${HISTORY_UUID}
 タイプスクリプト名${GUAC_USERNAME}-${GUAC_DATE}-${GUAC_TIME}-${GUAC_CLIENT_ADDRESS}.log
 タイプスクリプトの保存ディレクトリを自動的に作成する有効
設定項目 設定値
接続の編集
 名前(任意)
 プロトコルVNC
パラメータ
 ネットワーク(任意)
  ホスト名(VNCサーバホスト名)
  ポート(VNCサーバポート番号)
スクリーンレコーディング
 ログ保存ディレクトリ/var/lib/guacamole/recordings/${HISTORY_UUID}
 ログファイル名${GUAC_USERNAME}-${GUAC_DATE}-${GUAC_TIME}-${GUAC_CLIENT_ADDRESS}.dmp
 キーイベントの取得有効
 ログの保存ディレクトリを自動的に作成する有効
  • スクリーンレコーディングはリモートデスクトップ接続終了後、[設定]>[履歴]画面の[Logs]列に[View]というリンクから参照可能
  • マニュアルには保存ディレクトリのパスに${HISTORY_UUID}を含めることを推奨と記載している。
  • パス設定に使用できる変数はhttps://guacamole.apache.org/doc/gug/configuring-guacamole.html#parameter-tokensを参照
  • 記録される録画ファイルは独自形式のダンプファイルで、guacencコマンドでm4vフォーマットに変換可能
  • SSHコンソールはコピペ可能(設定でコピペ無効も可)、日本語表示可能
  • 接続エラーになる場合は/var/log/messagesにエラーメッセージを出力している
  • コンソール表示中の設定メニュー表示はcrtl+alt+shift
インターネットに公開するサーバですのでfail2banを使用してのguacamoleログイン画面に対するディクショナリーアタック対策を説明します。
fail2banをパッケージインストールします
# dnf install fail2ban python3-inotify

デフォルト設定をjail.localで上書きします。

# cat > /etc/fail2ban/jail.local <<EOF [Init] blocktype = DROP [DEFAULT] # 10分以内に10回不審なアクセスがあったら3時間BAN findtime = 600 maxretry = 10 bantime = 10800 #サービス管理はsystemd backend = systemd # メール通知時の設定(ご自分の環境に合わせて) destemail = 通知先@メールアドレス sender = 送信者@メールアドレス # UDPも有効にする protocol = all # banしないホスト ignoreip = 127.0.0.1/8 192.168.1.0/24

不正アクセス検知時の接続拒否制御をDROP(応答なし)にします。今回はiptablesで制御しますが念のためfirewalldのほうの制御も変更します。

# cp -p /etc/fail2ban/action.d/iptables.conf /etc/fail2ban/action.d/iptables.conf.org # vi /etc/fail2ban/action.d/iptables.conf #blocktype = REJECT --reject-with icmp-port-unreachable blocktype = DROP # cp -p /etc/fail2ban/action.d/firewallcmd-common.conf /etc/fail2ban/action.d/firewallcmd-common.conf.org # vi /etc/fail2ban/action.d/firewallcmd-common.conf #blocktype = REJECT --reject-with blocktype = DROP

接続拒否後もアクセスを繰り返す場合の拒否期間を延長する設定です。検知条件はデフォルトで用意されています。
この時点では/var/log/fail2ban.logが存在していないので、いったん「enabled = false」にしておきます。
# cat > /etc/fail2ban/jail.d/recidive.conf <<EOF [recidive] #enabled = true enabled = false filter = recidive logpath = /var/log/fail2ban.log bantime = 1209600 findtime = 86400 maxretry = 3 backend = pyinotify action = iptables-allports sendmail-whois-lines[name=recidive, dest=通知先@メールアドレス] EOF
デフォルトで用意されている再販防止の振る舞い設定はコメントアウトしておきます。
# cp -p /etc/fail2ban/jail.conf /etc/fail2ban/jail.conf.org # vi /etc/fail2ban/jail.conf #[recidive] # #logpath = /var/log/fail2ban.log #banaction = %(banaction_allports)s #bantime = 1w #findtime = 1d

guacamoleログイン失敗時に/var/log/messagesに出力する以下のログメッセージを拒否するように検知条件を記載します。

Aug 12 21:08:21 guacamole server[71324]: 21:08:21.389 [http-nio-8080-exec-6] WARN o.a.g.r.auth.AuthenticationService - Authentication attempt from [123.123.123.123, 127.0.0.1] for user "guacadimin" failed.
TOTPの失敗は何故かログイン成功で記録されるので、検知できません。
# cat > /etc/fail2ban/filter.d/guacamole-loginfail.conf <<EOF [Definition] failregex = ^.+ server\[.+\[http-nio-8080-exec-[0-9]+?\] WARN o.a.g.r.auth.AuthenticationService - Authentication attempt from \[,.+failed\. EOF

この検知条件が正しく記載されているかはfail2ban-regexコマンドを使用して確認できます。ログイン失敗のメッセージを正しく拾えている場合はmatchedをカウントアップして表示します。

# fail2ban-regex /var/log/messages /etc/fail2ban/filter.d/guacamole-loginfail.conf Running tests ============= Use failregex filter file : guacamole-loginfail, basedir: /etc/fail2ban Use log file : /var/log/messages Use encoding : UTF-8 Results ======= Failregex: 1 total |- #) [# of hits] regular expression | 1) [1] ^.+ server\[.+\[http-nio-8080-exec-[0-9]+?\] WARN o.a.g.r.auth.AuthenticationService - Authentication attempt from \[,.+failed\. `- Ignoreregex: 0 total Date template hits: |- [# of hits] date format | [280] {^LN-BEG}(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)? `- Lines: 280 lines, 0 ignored, 1 matched, 279 missed [processed in 0.02 sec] Missed line(s): too many to print. Use --print-all-missed to print all 279 lines

先述の検知条件で検出した際の振る舞いを設定します。
# cat > /etc/fail2ban/jail.d/guacamole-loginfail.conf <<EOF [guacamole-loginfail] enabled = true port = http,https filter = guacamole-loginfail banaction = iptables-allports sendmail-whois[name=guacamole-loginfail, dest=通知先@メールアドレス, sender=送信元@メールアドレス, sendername="Fail2Ban"] logpath = /var/log/messages # 1分以内に3回不審なアクセスがあったら3時間BAN findtime = 60 maxretry = 3 bantime = 10800 backend = pyinotify EOF
fail2banが起動することを確認します。設定にエラーがあると起動しません。
# systemctl start fail2ban # systemctl status fail2ban
fail2banのOS起動時自動起動を有効にします。
# systemctl enable fail2ban Created symlink /etc/systemd/system/multi-user.target.wants/fail2ban.service → /usr/lib/systemd/system/fail2ban.service.
fail2banを初めて起動した後でログファイルを出力しているので、再犯防止を有効にします。
# vi /etc/fail2ban/jail.d/recidive.conf enabled = true #enabled = false # systemctl restart fail2ban # systemctl status fail2ban
# iptables -L Chain f2b-recidive (1 references) target prot opt source destination DROP all -- 172-104-107-206.ip.linodeusercontent.com anywhere DROP all -- 154.216.18.123 anywhere DROP all -- 154.216.16.52 anywhere DROP all -- 83.97.73.245 anywhere DROP all -- 80.94.92.135 anywhere DROP all -- vps-6004e571.vps.ovh.net anywhere DROP all -- 178.215.236.217 anywhere RETURN all -- anywhere anywhere Chain f2b-guacamole-loginfail (1 references) target prot opt source destination DROP all -- 64.226.120.211 anywhere RETURN all -- anywhere anywhere
# fail2ban-client set guacamole-loginfail unbanip 解除するIPアドレス
なげー
お疲れ様でした。