NETWORK ENGINEER BLOG

Tips and Reviews for Engineers

VMware Horizon View 7 インスタントクローン構築

インスタントクローンとは

以下、インスタントクローンとリンククローンの比較です。(Horizon 7 で 2020年5月時点での比較です。)
リンククローンは今後廃止となる流れのようです。
f:id:FriendsNow:20200518123408p:plain
※1 どちらもスナップショットから Template VM を作成し、これをコピーした Replica VM から Parent VM を作成します。Parent VM は ESX 毎に作成され、Parent VM をクローンして VDI を展開します。
インスタントクローンでは、この Parent VM からクローンする際、実行中の Parent VM のメモリ内クローンを行うことで仮想マシンを迅速に展開します。*1
この動作のため、Parent VM は以下のように常にサスペンド状態となっています。
f:id:FriendsNow:20200517210429p:plain
※2 VDI はユーザーログオフ後に削除され、更新後のレプリカから再作成されます。

前提条件

  • 以下の OS/ソフトウェアバージョンを使用
    • VMware-VMvisor-Installer-7.0.0-15843807.x86_64
    • VMware-VCSA-all-7.0.0-15952498
    • VMware-Horizon-Connection-Server-x86_64-7.6.0-9823717
  • 事前準備として、対象のサーバをドメイン参加しておきます。

仮想デスクトップのマスター OS 作成

仮想デスクトップ展開用のマスター OS として Windows10 を作成します。
Windows10 上で View Agent のインストーラを実行し、「VMware Horizon Instant Clone Agent」をインストールします。「VMware Horizon View Composer Agent」と「VMware Horizon 7 Persona Management」は、インストール不可となりますのでご注意ください。

VMware-Horizon-Agent-x86_64-7.6.0-9539447.exe

f:id:FriendsNow:20200516232730p:plain

インストール後、マスター OS の「スナップショット」を取得しておきます。

ドメイン管理者の設定

View Administrator の管理画面から、インスタントクローンのドメイン管理者の追加を行います。
f:id:FriendsNow:20200516232828p:plain

インスタントクローンのデスクトッププールを作成します。なお、Composer は不要です。
f:id:FriendsNow:20200516232857p:plain

以上で、サーバ環境の設定は完了です。

VMware Horizon View Client 接続

VMware Horizon View Client で接続先サーバに「VMware View Connection Server」のホスト名を入力して「接続」すると、仮想デスクトップにアクセスできます。
ログオフすると、仮想デスクトップが削除され、再プロビジョニングされます。

イメージの更新

リンククローンでは、再構成(リコンポーズ)で Replica VM を入れ替えますが、インスタントクローンでは、イメージプッシュという機能で、Template VM、Replica VM、Parent VM を更新します。
仮想デスクトップはログオフ後に即削除され、その際に更新イメージを使って再作成されます。
このため、パッチ適用等のアップデートが簡単にできます。
イメージプッシュをするには、プールを選択し「イメージをプッシュ」をクリックします。
f:id:FriendsNow:20200517185344p:plain

更新するスナップショットを選択します。
f:id:FriendsNow:20200517185356p:plain

更新するスケジュールを設定します。緊急の際はユーザーを強制ログオフさせることも可能です。
f:id:FriendsNow:20200517185404p:plain

注意点

マスター OS に「VMware Horizon Instant Clone Agent」がインストールされていないと、以下のエラーがでてプロビジョニングに失敗します。

プロビジョニング中にエラーが発生しました:
Initial publish failed: Fault type is UNKNOWN_FAULT_FATAL - After waiting for 600 seconds internal template VM: vm-2021 still has not finished customization. Giving up!

f:id:FriendsNow:20200516232929p:plain

View Agent のインストーラーのデフォルトは「インストールしない」となっているのでご注意ください。

以上

オープンソースの WAF(ModSecurity)について

WAF とは

WAF は、ウェブアプリケーションの脆弱性を悪用した攻撃などからウェブアプリケーションを保護するソフトウェア、またはハードウェアです。
WAF を使用することで以下の効果を期待できます。

  • 脆弱性を悪用した攻撃からウェブアプリケーションを防御する
  • 脆弱性を悪用した攻撃を検出する
  • 複数のウェブアプリケーションへの攻撃をまとめて防御する

また WAF は、検出パターンに基づき通信の中身を機械的に検査するため、実際に人の目で見る場合と異なる判定が生じる場合があります。この判定結果により、ウェブアプリケーションの脆弱性を悪用した攻撃などの悪意ある通信を遮断できない場合や、利用者がウェブサイトを閲覧する正常な通信を遮断してしまう場合があります。WAF の導入を検討する場合、このことを考慮する必要があります。
出典:Web Application Firewall (WAF) 読本 改訂第2版

ModSecurity とは

TrustWave 社が GPLv2 ライセンスのもと提供しているオープンソースの WAF です。
IPA で導入・運用を継続している実績があります。
出典: オープンソース WAF「ModSecurity」導入事例 ~ IPA はこう考えた ~

ModSecurity 構築例

本例では、以下の環境でテストします。

f:id:FriendsNow:20200329180205p:plain

また、本環境で対応する脆弱性は以下の 2 つのみとします。

  • XSS(クロスサイト・スクリプティング)
  • SQL インジェクション

Apache リバースプロキシ設定

以下をコメントアウト

# vi /etc/httpd/conf/httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

以下を最終行に追加

# vi /etc/httpd/conf/httpd.conf
ProxyRequests Off
ProxyPass /WebGoat http://10.1.23.253/WebGoat
ProxyPassReverse /WebGoat http://10.1.23.253/WebGoat
# 上記のように設定すると、例えば、 10.1.12.252/WebGoat のリクエストを http://10.1.23.253/WebGoat へ転送します。

ModSecurity インストール事前準備

EPEL リポジトリ追加

yum install epel-release

リポジトリ設定

# vi /etc/yum.repos.d/epel.repo

# 3 行目コメントイン
baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch
# 4 行目コメントアウト
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch

# 12 行目コメントイン
baseurl=http://download.fedoraproject.org/pub/epel/6/$basearch/debug
# 13 行目コメントアウト
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-6&arch=$basearch

# 21 行目コメントイン
baseurl=http://download.fedoraproject.org/pub/epel/6/SRPMS
# 22 行目コメントアウト
#mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-6&arch=$basearch

ModSecurity インストール

ModSecurity と CRS をインストール

# yum --enablerepo=epel install -y mod_security mod_security_crs
# service httpd restart

XSS と SQL インジェクションのルールのみ適用

# vi /etc/httpd/conf.d/mod_security.conf

# 9 行目コメントアウト
# Include modsecurity.d/activated_rules/*.conf
# 10~11 行目追加
Include modsecurity.d/activated_rules/modsecurity_crs_41_xss_attacks.conf
Include modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf

Apache 再起動

# /etc/rc.d/init.d/httpd restart

WAF のテスト

ModSecurity 無効時

OWASP ZAP の動的スキャンを行うと、SQL インジェクションの脆弱性が見つかります。
※OWSAP ZAP については、こちらをご参照ください。
f:id:FriendsNow:20200329182250p:plain

ModSecurity 有効時

SQL インジェクションの脆弱性が検出されなくなりました。
f:id:FriendsNow:20200329181520p:plain

リアルタイムで診断状況を確認すると、ステータスコードが「Forbidden」となっていることが確認できます。
f:id:FriendsNow:20200329181052p:plain

参考: ModSecurity 無効化

一時的に無効化した場合は、以下の設定をします。

# vi /etc/httpd/conf.d/mod_security.conf

# 13 行目コメントアウト
#SecRuleEngine On
# 14 行目追加
SecRuleEngine Off

Apache 再起動

# /etc/rc.d/init.d/httpd restart

以上

Apache の起動に失敗

Apache 2.2.15 でサービスを再起動した際、起動に失敗する事象に遭遇しました。

# service httpd restart
httpd を停止中:                                            [  OK  ]
httpd を起動中:                                            [失敗]

/var/log/httpd/error_log を確認すると以下のエラーが出力されていました。

 [alert] (EAI 2)Name or service not known: mod_unique_id: unable to find IPv4 address of "lablog01"
Configuration Failed

原因は、hostname と /etc/hosts が一致していないことのようです。

# hostname
lablog01
# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

/etc/hosts に lablog01 を追加すると無事起動できました。

# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 lablog01
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

以上

Apache でリバースプロキシ時に 503 エラー

CentOS 6.3 に Apache 2.2.15 をインストールして、リバースプロキシを有効にした際、503 エラーとなる事象に遭遇しました。

クライアントからリバースプロキシ経由で Web サーバにアクセスした際のエラー

503 Service Temporarily Unavailable

リバースプロキシの /var/log/httpd/error_log

 [error] (13)Permission denied: proxy: HTTP: attempt to connect to 10.1.23.253:8080 (10.1.23.253) failed

原因は、SELinux でした。対策は以下のとおりです。

SELinux 設定の変更(httpd プロセス許可)

/usr/sbin/setsebool -P httpd_can_network_connect 1

もしくは、SELinux の無効化(/etc/sysconfig/selinux)

SELINUX=disabled

以上

Linux で特定ポートで実行されているプロセスを強制終了する

CentOS 6.3 の例になります。
WebGoat を起動しようとすると以下のエラーが出力されました。

***************************
APPLICATION FAILED TO START
***************************
Description:
Web server failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.

ポート 8080 使用されているようです。
使用しているプロセスは以下のコマンドで確認できます。

# lsof -i:8080
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    16915 root   26u  IPv6  53443      0t0  TCP *:webcache (LISTEN)

Java の webcache が使用しているようです。
以下のコマンドで強制終了します。

# kill $(lsof -t -i:8080)

もしくは、

#kill -9 $(lsof -t -i:8080)

再度ポート 8080 の使用状況を確認します。

# lsof -i:8080

正常に終了できていれば、表示されなくなります。

以上

OWASP ZAP による脆弱性診断について

OWAP ZAP とは

無料で Web アプリケーションの脆弱性をチェックできるセキュリティ診断ツール「OWASP ZAP」は、The Open Web Application Security Project(通称 OWASP、オワスプ)という国際的なコミュニティがつくりました。OWASP を運営しているのはアメリカの The OWASP Foundation(OWASP 財団)という団体で、2001年に設立されています。
出典:CyberSecurityTIMES

OWASP ZAP インストール

Java のダウンロード・インストール

OWASP ZAP は Java 1.8 以上が必要なのでこちらから最新版をダウンロードしてインストールしておきます。

OWASP ZAP のダウンロード・インストール

こちらからインストーラーをダウンロードして実行します。
本例では、WIndows 64bit 版を使用しています。
インストーラーを実行すると JRE を「配置する」ボタンがでてきますので、事前にインストールした「java.exe」を指定します。
f:id:FriendsNow:20200322171041p:plain

あとは、「次へ」ボタンをクリックして完了です。

OWASP ZAP 設定

セッションの保持方法を指定します。本例では、「現在のタイムスタンプでファイル名を付けてセッションを保存」を選択します。
f:id:FriendsNow:20200322171220p:plain

必ず「プロテクトモード」を指定します。詳細は後述します。
f:id:FriendsNow:20200322171233p:plain

「ツール」->「オプション」からローカルプロキシを設定します。ポートは本例では「18080」を指定します。
f:id:FriendsNow:20200322171302p:plain

次に、対象サイトから各ページの URL 情報を取得するスパイダー機能を設定します。
本例では、以下のとおり設定します。

  • クロールする最大の深さ(対象サイトをどこまで深く検索するか):19
  • 並列スキャンスレッド数(並列処理数):2
  • 新しい URI の SVN のメタデータを解析(診断対象ファイルの指定):ON
  • 新しい UR Iの Git のメタデータを解析(診断対象ファイルの指定):ON
  • OData 固有のパラメータを処理(診断対象ファイルの指定):ON

f:id:FriendsNow:20200322201348p:plain

次に、対象サイトの診断を行う動的スキャンを設定します。
本例では、以下のとおり設定します。

  • 並列スキャンするホスト数:1
  • 並列スキャンスレッド数:1
  • スキャン中にミリ秒単位の遅延:1000

f:id:FriendsNow:20200322201406p:plain

「OK」をクリックします。

「ポリシー」->「スキャンポリシー」を選択し、「追加」をクリックします。
任意のポリシー名を設定し、適用を「Off」「低」を選択してから「開始」をそれぞれクリックします。*1
f:id:FriendsNow:20200322201557p:plain

左ペインの「インジェクション」を選択し、テストのしきい値と強度を変更します。
本例では、以下のポリシーを設定します。

  • SQL インジェクション-しきい値:低
  • SQL インジェクション-強度:高
  • クロスサイト・スクリプティング(反射型)-しきい値:低
  • クロスサイト・スクリプティング(反射型)-強度:高

f:id:FriendsNow:20200322201844p:plain
しきい値はアラートをあげる判定値で、”Low” ではあいまい、"Hign" では完全に NG の場合にアラートをあげます。強度はテストの精度で、"High" はより細かなテストを行ってくれます。

ブラウザ設定

ブラウザから OWASP をプロキシとして経由して、対象サイトへアクセスすることで診断します。
本例では、Firefox を使用して OWASP を指定します。
f:id:FriendsNow:20200322190535p:plain

WebGoat とは

ブラウザの設定が終わったら、診断テストが可能となります。
診断テストするために、WebGoat というわざと脆弱性を持たせた Web アプリケーションがありますので、あわせて紹介します。

WebGoat ダウンロード・インストール

本例では、CentOS 6.3(GUI)にインストールします。

Java のインストール

# Download JDK 11
cd /tmp && wget https://download.java.net/java/ga/jdk11/openjdk-11_linux-x64_bin.tar.gz

# Switch to the root user, type root password
su

# Create the folder /usr/lib/jvm
mkdir /usr/lib/jvm

# Extract the downloaded archive
tar xzvf /tmp/openjdk-11_linux-x64_bin.tar.gz --directory /usr/lib/jvm

# Create a symlink to the java binary 
ln -s  /usr/lib/jvm/jdk-11/bin/java /usr/bin/java

# exit from root user
exit

# Verify that you have the right version running
java -version

# Remove the downloaded archive
rm /tmp/openjdk-11_linux-x64_bin.tar.gz

WebGoat のダウンロードと実行

# Download the latest WebGoat release jar
wget https://github.com/WebGoat/WebGoat/releases/download/v8.0.0.M26/webgoat-server-8.0.0.M26.jar

# Run WebGoat using java
java -jar webgoat-server-8.0.0.M26.jar --server.address=0.0.0.0

出典:thehackerish

診断テスト

本例では、以下の環境でテストします。
リバースプロキシの構築例は後述しますので、興味があればご参照ください。

f:id:FriendsNow:20200322190628p:plain

ブラウザで対象サイトへアクセス

本例ではリバースプロキシがありますので、以下の URL へアクセスします。

http://10.1.12.252/WebGoat

アクセスした後、OWASP ZAP の左ペインに対象サイトが追加されます。
f:id:FriendsNow:20200322202428p:plain

サイトを右クリックして、「コンテキストに含める」->「既定のコンテキスト」を選択し、対象サイトを選択します。
f:id:FriendsNow:20200322204108p:plain

「認証」をクリックして、認証方法、およびログインユーザーの情報を入力します。
これは、WebGoat のログイン画面の先へクロールするために必要となります。
本例では、Form-based Auhentication を使用し、以下のパラメータを指定します。

http://10.1.12.252/WebGoat
username={%username%}&password={%password%}
\Q/WebGoat/login\E

「\Q/WebGoat/login\E」は、ログアウト状態を判定するために必要なパラメータです。
f:id:FriendsNow:20200322202717p:plain

次に「ユーザー」をクリックして、ログイン可能なユーザー登録します。
f:id:FriendsNow:20200322202734p:plain

スパイダー実行

対象サイト内の各ページの URL 情報を収集するためにスパイダーを実行します。
対象サイトを右クリックして、「攻撃」->「スパイダー」をクリックし、作成した「ユーザー」を選択します。
その後、「スキャンを開始」をクリックします。
※前述の「プロテクトモード」は、対象サイトのみを診断対象とします。
スパイダータブに結果が表示されます。緑は対象、赤は対象外の URL を示します。
f:id:FriendsNow:20200322203831p:plain

動的スキャン

対象サイトに対して、様々なパターンの攻撃コードを仕掛けます。
対象サイトを右クリックして、「攻撃」->「動的スキャン」をクリックし、「ポリシー」「ユーザー」で作成したユーザーを選択します。その後、「スキャンを開始」をクリックします。
f:id:FriendsNow:20200322204021p:plain

結果は「アラート」タブに表示されます。
「赤」は危険度高、「オレンジ」は危険度中、「黄色」は危険度低を示します。
f:id:FriendsNow:20200322203839p:plain

参考:リバースプロキシ設定

squid.conf 設定

# 59 行目追記
http_access allow all

#60 行目コメントアウト
# http_access deny all

# 64行目追記(転送元サーバーの IP アドレスを指定)
http_port 80 accel ignore-cc defaultsite=10.1.12.252

# 最終行に追記(転送先 Web サーバーの IP アドレスを指定)
cache_peer 10.1.23.253 parent 8080 0 no-query originserver

# 最終行に追記(メモリキャッシュサイズ)
cache_mem 256 MB

# 最終行に追記(ホスト名定義)
visible_hostname prox.srv.world

squid 再起動

# /etc/rc.d/init.d/squid restart

以上

*1:全ての診断を無効化します。

リバースプロキシ(Squid)簡易構築手順

リバースプロキシとは

クライアントからのサーバーへの通信に対して、代理(Proxy)で応答しつつ、通信を中継する機能、あるいはその役割を担うサーバー
出典:@IT リバースプロキシ(Reverse Proxy)

リーバスプロキシの主な特徴

セキュリティ

DMZ に設置したリバースプロキシを配置すれば、(重要なデータを扱っている)Web サーバー/アプリは直接インターネットに接する必要がない。
また、リバースプロキシ上で SSL や WAF(Web アプリケーションファイアウォール)などのセキュリティ対策をすれば、Web サーバ/アプリに直接手を加えることなく安全性を高められる。

負荷分散

同じ処理をする Web サーバー/アプリを複数用意しておき、リバースプロキシによってリクエストを分散させることができる。
クライアントからは単一サーバー構成と変わらず、大量のアクセスをさばけるシステムを構築できる。

リバプロお試し

テスト環境

f:id:FriendsNow:20200321210829p:plain

Web サーバ設定(CentOS 8.1)

# systemctl start httpd
# firewall-cmd --add-service=http --zone=public --permanent
# firewall-cmd --reload
# firewall-cmd --list-all | grep http
  services: cockpit dhcpv6-client http ssh

リバースプロキシ設定(CentOS 6.3)

squid.conf 設定

# 59 行目追記
http_access allow all

#60 行目コメントアウト
# http_access deny all

# 64行目追記(転送先 Web サーバーの IP アドレスを指定)
http_port 80 defaultsite=10.1.23.253

# 最終行に追記(転送先 Web サーバーの IP アドレスを指定)
cache_peer 10.1.23.253 parent 80 0 no-query originserver

# 最終行に追記(メモリキャッシュサイズ)
cache_mem 256 MB

# 最終行に追記(ホスト名定義)
visible_hostname prox.srv.world

squid 再起動

# /etc/rc.d/init.d/squid restart

クライアントからリバースプロキシへアクセス

クライアントから、リバースプロキシサーバーに Web アクセスすると、リバースプロキシサーバーが Web サーバーの代理で応答を行い、Web ページが参照可能となります。
f:id:FriendsNow:20200321210725p:plain

以上