Redmine/MediaWiki/Pleasanter/S3/ファイルサーバを全文検索

# 内容
Redmine、MediaWiki、Pleasanter、Amazon S3、ファイルサーバを一括検索する仕組みをつくってみた

# 背景
* 運用改善の中でいろいろとツールを入れたので運用ツールが増えた
* 各ツールの区分けは出来ているがどこを見るかたまに迷うこともある
* 「情報を探す」という時間を短縮して運用改善につなげたい

# 概要図
* FESSの検索画面からキーワード検索で各システムを一括検索する
* RedmineとPleasanterはPostgresをMediaWikiはMariaDBをデータストアクローラで設定
* S3はそれようのプラグインがあるのでプラグイン追加後、データストアクローラで設定
* ファイルサーバはファイルシステムクローラで設定
* スケジューラ設定で毎日各システムからクローラーで情報を取得してくる

![fess1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/9c4b45f6-93a1-ea96-52fa-93d5a34f4095.png)

# 作成したもの
![fess2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/f15754eb-d0f4-ff68-3d41-c8b6b3410f91.png)


# 環境・前提条件
* AlmaLinux release 8.5 (Arctic Sphynx)
* systemctl disable firewalld

# 手順
## FESSのインストール
### JDKをインストール
```Bash
yum install -y java-11-openjdk
```
### Elasticsearchのインストール
```Bash
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.0-x86_64.rpm
rpm -ivh elasticsearch-7.15.0-x86_64.rpm
```
### Elasticsearchプラグインのインストール
```Bash
/usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-analysis-fess:7.15.0
/usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-analysis-extension:7.15.0
/usr/share/elasticsearch/bin/elasticsearch-plugin install org.codelibs:elasticsearch-minhash:7.15.0
```

### elasticsearch-configsyncのインストール
```Bash
curl -o /tmp/configsync.zip https://repo.maven.apache.org/maven2/org/codelibs/elasticsearch-configsync/7.15.0/elasticsearch-configsync-7.15.0.zip
mkdir -p /usr/share/elasticsearch/modules/configsync
unzip -d /usr/share/elasticsearch/modules/configsync /tmp/configsync.zip
```

### Elasticsearchの設定変更
```Bash:/etc/elasticsearch/elasticsearch.yml
configsync.config_path: /var/lib/elasticsearch/config
```

### FESSのインストール
```Bash
wget https://github.com/codelibs/fess/releases/download/fess-13.15.3/fess-13.15.3.rpm
rpm -ivh fess-13.15.3.rpm
systemctl daemon-reload
```

### FESSの設定変更(下記コメントを外す)
```Bash:/usr/share/fess/bin/fess.in.sh
ES_HTTP_URL=http://localhost:9200
FESS_DICTIONARY_PATH=/var/lib/elasticsearch/config/
```

### Elasticsearch・FESSの起動
```Bash
systemctl enable elasticsearch
systemctl enable fess
systemctl start elasticsearch
systemctl status elasticsearch
systemctl start fess
systemctl status fess
```

### http\://ipaddress:8080/にアクセス
ログイン画面が表示されました
![FESS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/b8347c22-a594-5722-51da-61b47f6ef323.png)

## 自己証明書でSSL化
### Apacheのインストール
```bash
yum install -y httpd
yum install -y mod_ssl
```

### モジュール確認
```bash
httpd -M | grep proxy
 ～
 proxy_module (shared) #プロキシに必要
 proxy_http_module (shared) #プロキシに必要
 ssl_module (shared) #SSL使用時に必要
 ～
```

### ない場合はモジュール追加
```bash:/etc/httpd/conf/httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
```

### リバースプロキシ設定
```bash:/etc/httpd/conf.d/httpd-proxy.conf
ProxyRequests Off
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
```

### Apache再起動
```bash
systemctl restart httpd
```

### 接続確認
* http\://xxx.xxx.xxx.xxxでFESSにアクセス出来ることを確認

### 秘密鍵を作成
```bash
cd /etc/httpd/conf
openssl genrsa -des3 -out server.key 2048
```

### CSR作成を作成
```bash
openssl req -new -key server.key -out server.csr
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:XXXX
Locality Name (eg, city) [Default City]:XXXX
Organization Name (eg, company) [Default Company Ltd]:XXXX
Organizational Unit Name (eg, section) []:XXXX
Common Name (eg, your name or your server's hostname) []:XXXX
Email Address []:XXXX
```

### 秘密鍵からパスワード除去
```bash
cp -p server.key server.key.org
openssl rsa -in server.key -out server.key
```

### 設定ファイル修正
```bash
cp /etc/pki/tls/openssl.cnf openssl_san.cnf
vim openssl_san.cnf
[ req ]
req_extensions = v3_req #コメント解除
[ usr_cert ]
authorityKeyIdentifier=keyid,issuer:always #:alwaysを追加
[ v3_req ]
subjectAltName=IP:xx.xx.xx.xx #追加(IPまたはFQDN)
```

### 証明書ファイル作成
```bash
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt -sha256 -extensions v3_req -extfile openssl_san.cnf
```

### SSL設定
```bash:/etc/httpd/conf.d/ssl.conf
SSLEngine on
SSLCertificateFile /etc/httpd/conf/server.crt
SSLCertificateKeyFile /etc/httpd/conf/server.key
```

### 待受けポート追加
```bash:/etc/httpd/conf/httpd.conf
Listen 443
```

### Apache再起動
```bash
systemctl restart httpd
```

### 接続確認
* https\://xxx.xxx.xxx.xxxでFESSにアクセス出来ることを確認

## ファイルサーバ検索設定
### ファイルクロールの設定 
 * 名前は何でも良い
 * パスにsmb://hostname/share<font color="Red">/</font>
 * <font color="Red">※注意：最後の/が必要</font>
 * クロール対象とるすパスにsmb://hostname/share/.*
 * その他はデフォルト
　 
![fess1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/e47dd780-630c-25c4-c769-536b5ba1dca3.png)

### ファイル認証の設定 
 * ホスト名にファイルサーバのホスト名入力
 * スキームにSamba選択
 * ユーザ名、パスワードを入力
 * ファイルクロール設定に先ほど作成したファイルクロール設定を指定
![fess2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/aa60473f-9048-e96c-e2b3-f8e08197f818.png)

### ジョブの設定
 * 先ほど作成したファイルクロール設定画面から新規ジョブ作成
 * スケジュールをCRON形式で指定
![fess3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/25b789c7-6ae2-f28e-f649-ea315af9b659.png)

### ジョブスケジューラの手動起動
 * スケジュールまで待てないため手動実行
![fess4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/4ae9d598-20ed-dc7f-e63d-748c496d8f79.png)

### 検索
 * ファイルサーバ内のドキュメントが検索出来ることを確認
![fess5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/3b5088c4-b405-2128-cb74-0957f195b742.png)

## S3検索設定
### 備考
* パラメータ、スクリプトの記載方法は下記参照
* [Amazon S3 Data Store for Fess](https://github.com/codelibs/fess-ds-s3)
* AWS側にアクセス用のIAMユーザ作成
* ※コンソールアクセスは無効、ポリシーはAmazonS3ReadOnlyAccessでOK

### プラグインのインストール
* FESSログイン⇒システム⇒プラグイン⇒インストール
* fess-ds-s3-xx.xx.xxを選択してインストール
![S30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/944bf353-93c4-9e7f-58a9-a997a0ed1569.png)

### クローラー設定
* クローラー⇒データストア⇒新規作成
* 名前、ハンドラ、パラメータ、スクリプトを設定
![S31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/57b936f5-3872-cf3c-42a8-402afe0ded10.png)

* ハンドラ:AmazonS3DataStore
* パラメータ
```bash
region=ap-northeast-1
access_key_id=XXXXXXXX
secret_key=XXXXXXXX
```

* スクリプト
```bash
url=object.url
title=object.key
content=object.contents
mimetype=object.mimetype
filetype=object.filetype
filename=object.filename
content_length=object.size
last_modified=object.last_modified
```

### ジョブスケジューラ作成と手動起動
* 「ファイルサーバ検索設定」のジョブ設定・ジョブスケジューラ手動起動参照

### 検索
* S3を検索できました！
![S32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/5dca9e6c-493a-9362-1795-0d2524cb6d12.png)

## Redmine検索設定

### JDBCドライバの配置
* FESSサーバ側の設定です

```bash
wget https://jdbc.postgresql.org/download/postgresql-42.3.2.jar
mv postgresql-42.3.2.jar /usr/share/fess/app/WEB-INF/lib/
```

### 外部からPostgresにアクセス許可設定
* Redmineサーバ側の設定です

```bash:/var/lib/pgsql/data/postgresql.conf
listen_addresses = '*'
```

```bash:/var/lib/pgsql/data/pg_hba.conf
host    redmine         redmine         192.168.1.0/24            md5
```

```bash
systemctl restart postgresql.service
systemctl status postgresql.service
```

### データストアクローラの設定
* FESS管理画面からの設定です
* ハンドラー名：DatabaseDataStore
* パラメーター
```bash
driver=org.postgresql.Driver
url=jdbc:postgresql://"Redmineホスト名":5432/"DB名"
username="DBアクセスユーザ"
password="DBアクセスパスワード"
sql=select * from issues
```

* スクリプト
```bash
url="http://"Redmineホスト名"/issues/" + id
host="Redmineホスト名"
site="Redmineホスト名"
title= subject
content=description
cache=description
digest=description
anchor=
content_length=description.length()
last_modified=updated_on.substring(0,10) + "T" + updated_on.substring(11,23) + "Z"
```

### ジョブスケジューラ作成と手動起動
* 「ファイルサーバ検索設定」のジョブ設定・ジョブスケジューラ手動起動参照

### ログ確認
* 何回かアクセスエラーなどで上手く行かなかったため、ログ確認

```bash
tail -f /var/log/fess/fess-crawler.log
```

### 検索
* FESSで検索してRedmineのチケットが検索できるか確認

## プリザンター検索設定
### Postgresに接続
```bash
psql -h localhost -p 5432 -U postgres -d Implem.Pleasanter
```
### テーブル確認
* Itemsテーブル内にチケットの情報が入っています
```bash
Implem.Pleasanter=# \dt
                          List of relations
 Schema |           Name            | Type  |          Owner
--------+---------------------------+-------+-------------------------
 ～～～～省略～～～～
 public | Items                     | table | Implem.Pleasanter_Owner
 public | Items_deleted             | table | Implem.Pleasanter_Owner
 public | Items_history             | table | Implem.Pleasanter_Owner
 ～～～～省略～～～～
```

### テーブル構造確認
```bash
Implem.Pleasanter=# \d "Items";
                                               Table "public.Items"
         Column         |              Type              | Collation | Nullable |             Default
------------------------+--------------------------------+-----------+----------+----------------------------------
 ～～～～省略～～～～
 ReferenceType          | character varying(32)          |           | not null |
 SiteId                 | bigint                         |           | not null | 0
 Title                  | character varying(1024)        |           |          |
 FullText               | text                           |           |          |
 ～～～～省略～～～～
 UpdatedTime            | timestamp(3) without time zone |           | not null | CURRENT_TIMESTAMP
```

### データ確認
* 必要そうなデータだけSelectしたクエリで確認

```bash
Implem.Pleasanter=# select "Title","ReferenceId","FullText","UpdatedTime" from "Items";
Title| ReferenceId |FullText|UpdatedTime
-----------------------------------------------+-------------
【プリザンタチケット】顧客管理 |1 | 【プリザンタチケット】顧客管理 顧客管理 test plesanter Administrator  | 2022-02-10 08:39:03.857
```
### データストアクローラ設定
* FESS管理画面からの設定です
* ハンドラー名：DatabaseDataStore
* パラメーター

```bash
driver=org.postgresql.Driver
url=jdbc:postgresql://"プリザンタホスト名"/Implem.Pleasanter
username=postgres
password="パスワード"
sql=select "Title","ReferenceId","FullText","UpdatedTime" from "Items";
```

* スクリプト
```bash
url="http://"プリザンタホスト名"/items/" + ReferenceId
host="プリザンタホスト名"
site="プリザンタホスト名"
title=Title
content=FullText
cache=FullText
digest=FullText
anchor=
```

### ジョブスケジューラ作成と手動起動
* 「ファイルサーバ検索設定」のジョブ設定・ジョブスケジューラ手動起動参照

### ログ確認
* 何回かアクセスエラーなどで上手く行かなかったため、ログ確認

```bash
tail -f /var/log/fess/fess-crawler.log
```

### 検索
* FESSで検索してプリザンタのチケットが検索できるか確認

## MediaWiki検索設定
### 備考
* [MediaWikiデータベースのレイアウト](https://www.mediawiki.org/wiki/Manual:Database_layout/ja)

### MariaDBに接続
```sql
mysql -u root -p
MariaDB [(none)]> use my_wiki;
```
### テーブル確認
* pageテーブルのpage_latestにページの最新リビジョンを持っています
* 実際のデータはtextテーブルにあります

```sql
MariaDB [(none)]> use my_wiki;
MariaDB [my_wiki]> select page_title,page_latest from page;
+--------------------------------------+-------------+
| page_title                           | page_latest |
+--------------------------------------+-------------+
| Wikiテスト1                       |          15 |
| Wikiテスト2                       |          16 |
| Wikiテスト3                       |          13 |
| Wikiテスト4                       |          14 |
+--------------------------------------+-------------+
MariaDB [my_wiki]> select old_id,old_text from text where old_id=15;
+--------+----------------------------+
| old_id | old_text                   |
+--------+----------------------------+
|     15 | Wikiテスト１
編集１ |
+--------+----------------------------+
```

### FESSで使用するSQL作成
* pageテーブルのpage_latestとtextテーブルのold_idを外部結合して最新リビジョンのデータを取り出します

```sql
MariaDB [my_wiki]> select page.page_title,text.old_id,text.old_text from page LEFT OUTER JOIN text ON page.page_latest = text.old_id;
```

### プラグインインストール
* FESSの管理画面「システム」⇒「プラグイン」から**mysql-connector-java**を追加した

### データストアクローラ設定

* FESS管理画面からの設定です
* ハンドラー名：DatabaseDataStore
* パラメーター

```bash
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://"MediaWikiホスト名":3306/my_wiki?useUnicode=true&characterEncoding=UTF-8
username="WikiDB接続ユーザ"
password="WikiDB接続パスワード"
sql=select page.page_title,text.old_id,text.old_text from page LEFT OUTER JOIN text ON page.page_latest = text.old_id;
```

* スクリプト
```bash
url="http://"MediaWikiホスト名"/wiki/index.php?title=" + page_title
host="MediaWikiホスト名"
site="MediaWikiホスト名"
title=page_title
content=old_text
```

### ジョブスケジューラ作成と手動起動
* 「ファイルサーバ検索設定」のジョブ設定・ジョブスケジューラ手動起動参照

### ログ確認
* 何回かアクセスエラーなどで上手く行かなかったため、ログ確認

```bash
tail -f /var/log/fess/fess-crawler.log
```

### 検索
* FESSで検索してMediaWikiの記事が検索できるか確認