こんにちは。SIOS OSSエバンジェリスト/セキュリティ担当の面 和毅です。
ジャンルを今迄よりも広げて、脅威インテリジェンス情報をお届けすることを考えています。
前回まででMISPをインストールしました。今回は、OpenCTIのインストールを取り上げてみます。まずはOpenCTIが立ち上がるところまでをこの記事の区切りにしています。
脅威インテリジェンス連載記事
環境
- プラットフォーム:VM(TIME4VPSを使用)。
- OS: Ubuntu 20.04 (64-bit)
- Processor: 2 x 2.6 GHz
- Memory: 16384 MB (つまり16GB!)
- Storage: 80 GB
- Bandwidth: 1000 Mbps (Monthly limit: 16 TB)
- 1 Gbps port speed ( 12.00 EUR )
TIME4VPSは激安なので、上記のスペックで年間「192EUR = 25,000円程度」になります。使用感としては、スペックは問題ないですし安定しています。ただ、MISPの時に感じたのと同じく、日本からだとネットワークが遅いので、上述の1Gbps port (12.00 EUR)をつけたほうが絶対良いです。
インストール
OpenCTIのインストールですが、Dockerを使いDockerの管理としてPortainerを使用しています。基本的なインストール方法は、こちらを参考にしました。また、特に記載がない場合には(プロンプトが$になっている場合には)実行ユーザは一般ユーザ権限で行っています。
また、基本的にインストールはansibleを用いて行っています。一部、ansibleのファイルも公開しようと思います。
- OS(Ubuntu 20.04)をインストールします。時刻合わせ、ファイアウォールの設定、自動更新の設定を行います。下記のようなymlになっています。
- hosts: all become: yes tasks: - name: install ntpdate module apt: name: - ntpdate - name: cron job for ntpdate cron: name: sync clock minute: "5" job: /sbin/ntpdate -b ntp.nict.jp >%gt; /var/log/ntpdate.log 2>&1 user: root - name: update os with crond cron: name: apt update minute: "10" job: /usr/local/sbin/aptupdate.sh >> /var/log/update.log user: root - name: update system apt: update_cache=yes tags: system - name: upgrade system apt: upgrade=dist tags: system - name: Check if a reboot is required register: file stat: path=/var/run/reboot-required get_md5=no - name: Reboot system command: /sbin/reboot when: file.stat.exists == true
- Docker-ceから新しいDockerを持ってきてインストールします。aptを用いる場合には、直接DockerとDocker Composeを入れて下さい。anibleで使用したymlは以下になります。
- hosts: all become: yes vars: docker_users: - sios tasks: - name: Add Docker GPG apt key apt_key: url: https://download.docker.com/linux/ubuntu/gpg state: present - name: Add Docker Repository apt_repository: repo: deb https://download.docker.com/linux/ubuntu focal stable state: present - name: Update and install docker-ce apt: update_cache=yes name=docker-ce state=latest - name: Update and install docker-ce-cli apt: update_cache=yes name=docker-ce-cli state=latest - name: Update and install docker-compose apt: update_cache=yes name=docker-compose state=latest - name: Add to docker group user: name: "{{ item }}" groups: docker append: yes with_items: "{{ docker_users }}"
- 以降はコマンドで行います。Docker swarmをインストールします。こちらは必要ないようですが、念の為に入れておく程度です。
$ docker swarm init --advertise-addr <MANAGER-IP> Swarm initialized: current node (XXXXXXXXXXXXXXXXXXXXXX) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token YYYYYYYYYYYYYYYYYYYYYYYYYY MANAGER-IP:PORT To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
と出てくるので、下記のようにTokenとIP/Portを入れます。
$ docker swarm join --token YYYYYYYYYYYYYYYYYYYYYYYYYY MANAGER-IP:PORT
- portainerで使用するボリューム: portainer_dataを作成します。
$ docker volume create portainer_data
- dockerを用いてportainerを立ち上げます。Portainerへのアクセスは下記の例の場合19000番になります。
$ docker run -d -p 18000:8000 -p 19000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer
- インストールしたURL(例ではhttp://hogehoge.secureoss.jp:19000)にアクセスしてみます。httpという所はポイントです。ログイン画面が出てきます。
- Stackを作成します。今回は、OpenCTIという名前でStackを作成しました。
- Editorの中にymlファイルを書いていきます。OpenCTIのymlとしては下記のようなものを記入しました。TOKENはこちらを用いてユニークなものを作成しています。下記の設定中では仮に[TOKEN1]としています。各コネクタ毎に一つのUUIDが必要になります。
version: '3' services: redis: image: redis:6.0.10 restart: always volumes: - redisdata:/data elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:7.11.0 volumes: - esdata:/usr/share/elasticsearch/data environment: - discovery.type=single-node restart: always ulimits: memlock: soft: -1 hard: -1 nofile: soft: 65536 hard: 65536 minio: image: minio/minio:RELEASE.2021-02-11T08-23-43Z volumes: - s3data:/data ports: - "9000:9000" environment: MINIO_ACCESS_KEY: [適当な値。説明文中ではMINIO_Aとしておく。] MINIO_SECRET_KEY: [こちらも適当な値。説明文中ではMINIO_Sとしておく。] command: server /data healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 30s timeout: 20s retries: 3 restart: always rabbitmq: image: rabbitmq:3.8-management environment: - RABBITMQ_DEFAULT_USER=guest - RABBITMQ_DEFAULT_PASS=guest volumes: - amqpdata:/var/lib/rabbitmq restart: always opencti: image: opencti/platform:4.5.5 environment: - NODE_OPTIONS=--max-old-space-size=8096 - APP__PORT=8080 - APP__ADMIN__EMAIL=admin@hogehoge.secureoss.jp - APP__ADMIN__PASSWORD=xxxxxxxxx : <-- 自分で設定する。パスフレーズは忘れずに - APP__ADMIN__TOKEN=[TOKEN1] - APP__LOGS_LEVEL=error - APP__LOGS=./logs - APP__REACTIVE=true - APP__COOKIE_SECURE=false - REDIS__HOSTNAME=redis - REDIS__PORT=6379 - ELASTICSEARCH__URL=http://elasticsearch:9200 - MINIO__ENDPOINT=minio - MINIO__PORT=9000 - MINIO__USE_SSL=false - MINIO__ACCESS_KEY=[MINIO_A] - MINIO__SECRET_KEY=[MINIO_S] - RABBITMQ__HOSTNAME=rabbitmq - RABBITMQ__PORT=5672 - RABBITMQ__PORT_MANAGEMENT=15672 - RABBITMQ__MANAGEMENT_SSL=false - RABBITMQ__USERNAME=guest - RABBITMQ__PASSWORD=guest - PROVIDERS__LOCAL__STRATEGY=LocalStrategy ports: - "8080:8080" depends_on: - redis - elasticsearch - minio - rabbitmq restart: always worker: image: opencti/worker:4.5.5 environment: - OPENCTI_URL=http://hogehoge.secureoss.jp:8080 - OPENCTI_TOKEN=[TOKEN1] - WORKER_LOG_LEVEL=info depends_on: - opencti deploy: mode: replicated replicas: 6 restart: always connector-history: image: opencti/connector-history:4.5.5 environment: - OPENCTI_URL=http://hogehoge.secureoss.jp:8080 - OPENCTI_TOKEN=[TOKEN1] - CONNECTOR_ID=[TOKEN2] # Valid UUIDv4 - CONNECTOR_TYPE=STREAM - CONNECTOR_NAME=History - CONNECTOR_SCOPE=history - CONNECTOR_CONFIDENCE_LEVEL=3 - CONNECTOR_LOG_LEVEL=info restart: always connector-export-file-stix: image: opencti/connector-export-file-stix:4.5.5 environment: - OPENCTI_URL=http://hogehoge.secureoss.jp:8080 - OPENCTI_TOKEN=[TOKEN1] - CONNECTOR_ID=[TOKEN2] # Valid UUIDv4 - CONNECTOR_TYPE=INTERNAL_EXPORT_FILE - CONNECTOR_NAME=ExportFileStix2 - CONNECTOR_SCOPE=application/json - CONNECTOR_CONFIDENCE_LEVEL=3 - CONNECTOR_LOG_LEVEL=info restart: always connector-export-file-csv: image: opencti/connector-export-file-csv:4.5.5 environment: - OPENCTI_URL=http://hogehoge.secureoss.jp:8080 - OPENCTI_TOKEN=[TOKEN1] - CONNECTOR_ID=[TOKEN3] # Valid UUIDv4 - CONNECTOR_TYPE=INTERNAL_EXPORT_FILE - CONNECTOR_NAME=ExportFileCsv - CONNECTOR_SCOPE=text/csv - CONNECTOR_CONFIDENCE_LEVEL=3 - CONNECTOR_LOG_LEVEL=info restart: always connector-import-file-stix: image: opencti/connector-import-file-stix:4.5.5 environment: - OPENCTI_URL=http://hogehoge.secureoss.jp:8080 - OPENCTI_TOKEN=[TOKEN1] - CONNECTOR_ID=[TOKEN4] # Valid UUIDv4 - CONNECTOR_TYPE=INTERNAL_IMPORT_FILE - CONNECTOR_NAME=ImportFileStix2 - CONNECTOR_SCOPE=application/json - CONNECTOR_CONFIDENCE_LEVEL=3 - CONNECTOR_LOG_LEVEL=info restart: always connector-import-file-pdf-observables: image: opencti/connector-import-file-pdf-observables:4.5.5 environment: - OPENCTI_URL=http://hogehoge.secureoss.jp:8080 - OPENCTI_TOKEN=[TOKEN1] - CONNECTOR_ID=[TOKEN5] # Valid UUIDv4 - CONNECTOR_TYPE=INTERNAL_IMPORT_FILE - CONNECTOR_NAME=ImportFilePdfObservables - CONNECTOR_SCOPE=application/pdf - CONNECTOR_CONFIDENCE_LEVEL=3 - CONNECTOR_LOG_LEVEL=info - PDF_OBSERVABLES_CREATE_INDICATOR=False restart: always connector-cve: image: opencti/connector-cve:4.5.5 environment: - OPENCTI_URL=http://hogehoge.secureoss.jp:8080 - OPENCTI_TOKEN=[TOKEN1] - CONNECTOR_ID=[TOKEN6] - CONNECTOR_TYPE=EXTERNAL_IMPORT - CONNECTOR_NAME=Common Vulnerabilities and Exposures - CONNECTOR_SCOPE=identity,vulnerability - CONNECTOR_CONFIDENCE_LEVEL=3 - CONNECTOR_UPDATE_EXISTING_DATA=true - CONNECTOR_LOG_LEVEL=info - CVE_IMPORT_HISTORY=true # Import history at the first run (after only recent), reset the connector state if you want to re-import - CVE_NVD_DATA_FEED=https://nvd.nist.gov/feeds/json/cve/1.1/nvdcve-1.1-recent.json.gz - CVE_HISTORY_DATA_FEED=https://nvd.nist.gov/feeds/json/cve/1.1/ - CVE_INTERVAL=7 # In days, must be strictly greater than 1 restart: always connector-mitre: image: opencti/connector-mitre:4.5.5 environment: - OPENCTI_URL=http://hogehoge.secureoss.jp:8080 - OPENCTI_TOKEN=[TOKEN1] - CONNECTOR_ID=[TOKEN7] - CONNECTOR_TYPE=EXTERNAL_IMPORT - CONNECTOR_NAME=MITRE ATT&CK - CONNECTOR_SCOPE=identity,attack-pattern,course-of-action,intrusion-set,malware,tool,report,external-reference-as-report - CONNECTOR_CONFIDENCE_LEVEL=15 - CONNECTOR_UPDATE_EXISTING_DATA=true - CONNECTOR_LOG_LEVEL=info - MITRE_ENTERPRISE_FILE_URL=https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json - MITRE_PRE_ATTACK_FILE_URL=https://raw.githubusercontent.com/mitre/cti/master/pre-attack/pre-attack.json - MITRE_MOBILE_ATTACK_FILE_URL=https://raw.githubusercontent.com/mitre/cti/master/mobile-attack/mobile-attack.json - MITRE_INTERVAL=7 # In days, must be strictly greater than 1 restart: always volumes: esdata: s3data: redisdata: amqpdata:
- ymlファイルを入力したら、一番下(スクロールして下さい)の「Deply the stack」をクリックしましょう。サービスがスタートしていきます。
- 起動にはかなりの時間がかかります(だいたい落ち着くまで体感で10分ぐらいはかかります)。左ペインの「Service」を選択して、メインのサービス類が「replicated 1/1」のようになったら起動しています。最終的には、「opencti/connector-import-file-pdf-observables」以外は1/1になるはずです。
- うまく動作しない場合には、サービスをクリックして、赤くなっている「rejected」などをクリックすると、ログが出力されます。このログを頼りに、デバッグをしていきましょう。
- サービスが全て立ち上がると、OpenCTIにログインできます。ここでのユーザ名・パスワードは、前述のymlで設定したものになります。
ここまでのまとめ
ここまででOpenCTIが立ち上がるところまで行きました。次回はログインしてからの設定と、MISPとの接続を紹介します。
セキュリティ系連載案内
- OSSセキュリティ技術の会による日経Linuxでの連載「IoT時代の最新SELinux入門」がITPro上で読めるようになりました。技術の会代表で第一人者である中村さん等による、最新のSELinuxの情報やコマンド類等も更新されているのでお薦めです。
- OSSセキュリティ技術の会によるThinkITでの連載「開発者のためのセキュリティ実践講座」がThinkIT上で開始しました。技術の会の中の人間で、最新の代表的なOSSセキュリティ技術を紹介していきます。
- OSSセキュリティ技術の会により、ThinkITでLinuxSecuritySummit 2018のレポートが紹介されています。
- OSSセキュリティ技術の会の面により、@ITで「OSS脆弱性ウォッチ」が連載されています。
- OSSセキュリティ技術の会の面により、@ITで「OpenSCAPで脆弱性対策はどう変わる?」が連載されています。
- OSSセキュリティ技術の会のメンバーにより、@ITで「Berkeley Packet Filter(BPF)入門」が連載されています。
- OSSセキュリティ技術の会の面により、Linux セキュリティ対策最新ガイドが執筆・販売されています。
日々のメモを更新しています。
セキュリティ関係ニュースを更新しています。個別で情報出せるようになる前の簡単な情報・リンクなんかも載せていきます。
セミナー情報1
コンピュータセキュリティシンポジウム(CSS)2021併設のワークショップ、 OSSセキュリティ技術ワークショップ(OWS) 2021の企画講演セッション及び、 一般論文セッションをさせていただきます。
今年もオンラインでの開催となり、OWSトラックの一般論文セッションと企画セッションを行いますので,ご参加よろしくお願いいたします。