NICTのEXISTをインストールしてみた

2019/03/15に[NICT][NICT]のサイバーセキュリティ研究室が公開した *[EXIST][EXIST]* をインストールしてみたので、その記録です。  

# はじめに

## EXISTとは

[EXIST][EXIST]は、[NICT][NICT]のNICTER解析チームが開発したWebアプリケーションで、NICTER解析チームが日々の調査・解析業務に使用しているツールです。
コミュニティーやセキュリティベンダーなどが提供する、サイバー脅威情報を自動集約することができます。

> EXISTは，サイバー脅威情報を集約し，様々な情報源を横断的に検索することができるWebアプリケーションです． 様々な情報源からサイバー脅威情報をフィードやAPI経由で取得し，EXIST上のデータベースに集約します． 利用者はWebUIもしくはWebAPIで，サイバー脅威情報を特定のキーワードで横断的に検索することが出来ます．
> 引用：[NICTER Blog][NICTER] より）

![png1](https://raw.githubusercontent.com/nict-csl/exist/images/EXIST_overview.png)

## 環境構成

```text
- OS: CentOS 7.6  
- DB: MariaDB 10.3.13
- Python 3.6.7
```

# インストール

[GitHub][EXIST]の手順を参考に、インストールしていきます。
OSがプロキシ下の環境にある場合は、事前に`/etc/profile`にプロキシ設定を追加しておいてください。

## OSの最新化

```
# sudo yum update -y  
# sudo yum upgrade -y
# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
```

## Gitのインストール

```
# yum install git -y

# プロキシの設定は必要に応じて実施
# git config --global http.proxy http://proxy.example.com:port
# git config --global https.proxy http://proxy.example.com:port
```

## Python3のインストール

Yumリポジトリを追加し、Python3.6をインストールします。

```
# yum install -y https://centos7.iuscommunity.org/ius-release.rpm
# yum install python36u python36u-libs python36u-devel python36u-pip -y
# yum groupinstall 'development tools' -y
# python3.6 --version
Python 3.6.7
```

## pipのバージョンアップ

Python に付属している pip のバージョンは古い状態のため、`--upgrade` オプションを使用して、最新バージョンに更新します。
プロキシ環境下の場合は、`--proxy http://proxy.example.com:port` オプションを追加します。

```
# pip3.6 install --upgrade pip
# pip3.6 --version
pip 19.0.3 from /usr/lib/python3.6/site-packages/pip (python 3.6)
```

## ソースのクローン

```
# cd /opt
# git clone https://github.com/nict-csl/exist.git
```

## Pythonモジュールのインストール

プロキシ環境下の場合は、pipコマンドに`--proxy http://proxy.example.com:port`を追加します。

```
# cd /opt/exist
# pip install -r requirements.txt
```

## MariaDBのインストール

プロキシ環境下の場合は、`~/.curlrc`にプロキシ情報を記載しておきます。

```bash:~/.curlrc
proxy-user=username:password
proxy=http://proxy.example.com:port
```

```
# curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
[info] Repository file successfully written to /etc/yum.repos.d/mariadb.repo.
[info] Adding trusted package signing keys...
[info] Succeessfully added trusted package signing keys.

# yum install MariaDB-server MariaDB-client -y
# systemctl start mariadb
# systemctl enable mariadb
```

## mysql_secure_installation

MariaDBの最小限のセキュリティ設定を行います。

```
# mysql_secure_installation

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none): //初期インストール時はパスワードがないため、そのままEnter押下
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

Set root password? [Y/n] Y
New password: //新しいパスワードを入力
Re-enter new password: //再度、新しいパスワードを入力
Password updated successfully!
Reloading privilege tables..
 ... Success!


By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] Y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] Y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] Y
 - Dropping test database...
 ... Success!
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] Y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!
```

## MariaDBの再起動

```
# systemctl restart mariadb
```

## MariaDBの設定

MariaDBに`mysql -u root -p`コマンドでログインし、EXISTのための設定を行います。

```sql
MariaDB [(none)]> CREATE DATABASE intelligence_db;
MariaDB [(none)]> CREATE USER 'exist'@'localhost' IDENTIFIED BY 'Passw0rd';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON intelligence_db.* TO 'exist'@'localhost';
MariaDB [(none)]> quit
```

## Djangoの設定

テンプレートファイルをコピーして、設定ファイルを作成します。

```
# cp -p /opt/exist/intelligence/settings.py.template /opt/exist/intelligence/settings.py
```

`settings.py` ファイル内の情報を更新します。
更新するのは、以下の内容です。

- ALLOWED_HOSTS : FQDNの情報
- DATABASES  : [#MariaDBの設定](#mariadbの設定) で設定した情報

```bash:/opt/exist/intelligence/settings.py
ALLOWED_HOSTS = [
     'localhost',
     'xxx.xxx.xxx.xxx', # インストールサーバーのIPアドレス etc.
]

...(中略)...

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'intelligence_db',
        'USER': 'exist',
        'PASSWORD': 'Passw0rd',
        'HOST': '',
        'PORT': '',
        'OPTIONS': {
            'charset': 'utf8mb4',
            'init_command': 'SET character_set_connection=utf8mb4;'
                            'SET collation_connection=utf8mb4_unicode_ci;'
                            "SET NAMES 'utf8mb4';"
                            "SET CHARACTER SET utf8mb4;"
        },
    }
}
```

## Djangoのマイグレーション

```
# cd /opt/exist
# python3.6 manage.py makemigrations exploit reputation threat threat_hunter twitter twitter_hunter
# python3.6 manage.py migrate
```

## Redis serverのインストール

```
# yum install redis -y
# systemctl start redis
# systemctl enable redis
```

## Celeryの設定

```bash:/etc/sysconfig/celery
# Name of nodes to start
# here we have a single node
CELERYD_NODES="localhost"
# or we could have three nodes:
#CELERYD_NODES="w1 w2 w3"

# Absolute or relative path to the 'celery' command:
CELERY_BIN="/bin/celery"

# App instance to use
# comment out this line if you don't use an app
CELERY_APP="intelligence"
# or fully qualified:
#CELERY_APP="proj.tasks:app"

# How to call manage.py
CELERYD_MULTI="multi"

# Extra command-line arguments to the worker
CELERYD_OPTS="--time-limit=300 --concurrency=8"

# - %n will be replaced with the first part of the nodename.
# - %I will be replaced with the current child process index
# and is important when using the prefork pool to avoid race conditions.
CELERYD_PID_FILE="/var/run/celery/%n.pid"
CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
CELERYD_LOG_LEVEL="INFO"
```

## Celeryの自動起動設定

```text:/etc/systemd/system/celery.service
[Unit]
Description=Celery Service
After=network.target

[Service]
Type=forking
User=root
Group=root
EnvironmentFile=/etc/sysconfig/celery
WorkingDirectory=/opt/exist
ExecStart=/bin/sh -c '${CELERY_BIN} multi start ${CELERYD_NODES} \
-A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} \
--logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}'
ExecStop=/bin/sh -c '${CELERY_BIN} multi stopwait ${CELERYD_NODES} \
--pidfile=${CELERYD_PID_FILE}'
ExecReload=/bin/sh -c '${CELERY_BIN} multi restart ${CELERYD_NODES} \
-A ${CELERY_APP} --pidfile=${CELERYD_PID_FILE} \
--logfile=${CELERYD_LOG_FILE} --loglevel=${CELERYD_LOG_LEVEL} ${CELERYD_OPTS}'

[Install]
WantedBy=multi-user.target
```

## ファイアウォールの設定

```
# firewall-cmd --zone=public --add-service=http --permanent
# firewall-cmd --zone=public --add-service=https --permanent
# firewall-cmd --zone=public --add-port=8000/tcp --permanent
# firewall-cmd --reload
```

## EXISTの起動

```
# mkdir -p /var/log/celery; chown root:root /var/log/celery
# mkdir -p /var/run/celery; chown root:root /var/run/celery
# systemctl start celery.service
# systemctl enable celery.service
# python3.6 /opt/exist/manage.py runserver 0.0.0.0:8000
```

Webブラウザで `http://<EXISTサーバーのIPアドレス>:8000` にアクセスし、下記の画面が出てきたら起動完了です。  

![exist.png](https://qiita-image-store.s3.amazonaws.com/0/348116/f31a7f4d-4e01-9dc6-0495-4daba1e0565c.png)

# 関連リンク

- [独立行政法人情報通信研究機構 (NICT)][NICT]
- [GitHub][EXIST]
- [NICTER Blog - サイバー脅威情報集約システム EXIST][NICTER]

# 参考情報

- [CentOS7にPython3系をインストールする手順][RefLink1]
- [NICTの公開したサイバー脅威情報を自動集約できるEXISTをつくってみた(インストール編)][RefLink2]
- [curlコマンドにてproxy設定][RefLink3]
- [MariaDBのインストール/初期設定 [CentOS7]][RefLink4]
- [サイバー脅威情報集約システム EXIST を構築してみた #exist](RefLink5)

[NICT]:http://www.nict.go.jp/  
[EXIST]:https://github.com/nict-csl/exist
[NICTER]:https://blog.nicter.jp/2019/03/exist/
[RefLink1]:https://qiita.com/shu1rou/items/3fac0fc0fcdafec051b7
[RefLink2]:https://qiita.com/bule_or_red/items/cbe4adb8be375a6fda08
[RefLink3]:https://qiita.com/tkj/items/c6dad4efc0dff4fecd93
[RefLink4]:https://qiita.com/ponsea/items/9578659009b434c60959
[RefLink5]:https://dev.classmethod.jp/etc/nict-exist/