返回文章列表

Ansible 自動化主機安全強化實務

本文探討如何利用 Ansible 自動化強化主機安全性,涵蓋 SSH、時間同步、安全稽核、核心引數調整及使用者許可權管理等導向,並介紹 Nikto 網路掃描工具的安裝與使用,以提升伺服器整體安全性。

DevOps 資安

Ansible 作為常用的自動化組態管理工具,在現代 IT 環境中扮演著重要的角色,尤其在主機安全強化方面,更能展現其效率與一致性。本文除了介紹如何使用 Ansible 設定 SSH、利用 chrony 進行時間同步、設定 auditd 進行安全稽核、調整核心引數外,也涵蓋了使用者與群組帳戶的許可權設定,最後示範如何使用 Nikto 進行網路伺服器安全掃描,以全方位提升主機安全性。透過 Ansible 的自動化組態,可以有效降低人為錯誤,並確保所有主機維持一致的安全設定,大幅提升管理效率及安全性。

自動化主機安全強化:Ansible 的實務應用

在現代化的 IT 環境中,確保主機安全性是維護系統穩定的關鍵因素之一。透過 Ansible 這樣的自動化工具,我們可以有效地強化主機的安全性並簡化管理流程。本章節將探討如何利用 Ansible 進行自動化的主機安全設定與強化。

SSH 組態與安全

SSH(Secure Shell)是遠端管理伺服器的常用協定,其安全性直接影響到伺服器的存取安全。透過 Ansible,我們可以自動化地組態 SSH 服務,以確保其安全性。

設定 SSH 服務

以下是一個範例,展示如何使用 Ansible 設定 SSH 服務:

- name: 顯示法律宣告 banner 以符合合規要求
  copy: src=iss.txt dest=/etc/issue.net owner=root group=root mode=0644

- name: 確保主 SSH 目錄的許可權正確設定
  file: path=/etc/ssh owner=root group=root mode=0755

- name: 明確設定主 SSH 守護程式組態檔案的許可權
  file: path=/etc/ssh/sshd_config owner=root group=root mode=0600

- name: 確保 SSH 服務在重啟後始終執行
  service: name=sshd state=started enabled=yes

程式碼解析

  1. 顯示法律宣告 banner:將自定義的 iss.txt 複製到 /etc/issue.net,並設定適當的許可權,以符合安全合規要求。
  2. 設定 SSH 目錄許可權:確保 /etc/ssh 目錄的擁有者和許可權正確,避免未授權存取。
  3. 設定 SSH 組態檔案許可權:限制 sshd_config 的存取許可權,防止未授權的修改。
  4. 啟用 SSH 服務:確保 SSH 服務在系統重啟後自動啟動。

時間同步與 NTP 設定

時間同步對於許多系統功能和日誌記錄至關重要。使用 chrony 取代傳統的 ntpd 可以提供更輕量和更安全的時間同步解決方案。

設定 chrony

以下範例展示如何使用 Ansible 安裝和組態 chrony

- name: 移除舊的 NTP 軟體包
  package: name=ntp state=absent

- name: 確保 chrony 軟體包已安裝
  package: name=chrony state=present

- name: 複製自定義的 chrony 組態檔案
  copy: src=cust.cfg dest=/etc/chrony.conf owner=root group=root

- name: 確保 chrony 服務始終執行
  service: name=chrony state=started enabled=yes

程式碼解析

  1. 移除舊 NTP 軟體包:解除安裝舊的 ntp 軟體包,以避免衝突。
  2. 安裝 chrony:安裝 chrony 軟體包,提供時間同步功能。
  3. 組態 chrony:複製自定義的 chrony.conf 組態檔案,以滿足特定的時間同步需求。
  4. 啟用 chrony 服務:確保 chrony 服務在系統重啟後自動啟動。

auditd 組態與安全稽核

auditd 是 Linux 核心的稽核工具,可以用來監控系統呼叫和檔案存取。透過 Ansible,我們可以自動化地組態 auditd 以增強系統的安全稽核能力。

設定 auditd

以下是一個範例,展示如何使用 Ansible 組態 auditd

- name: 安裝 auditd 如果系統中不存在
  package: name=auditd state=latest

- name: 確保 auditd 在重啟後啟動
  service: name=auditd state=started enabled=yes

- name: 調整日誌檔案數量
  replace:
    dest: /etc/audit/auditd.conf
    regexp: 'num_logs = 5$'
    replace: 'num_logs = 50'

- name: 設定日誌檔案大小限制
  replace:
    dest: /etc/audit/auditd.conf
    regexp: 'max_log_file = 8'
    replace: 'max_log_file = 100'

- name: 安裝自定義稽核規則
  copy: src=audit.rules dest=/etc/audit/rules.d/audit.rules owner=root group=root mode=0600

- name: 過載稽核規則
  command: /sbin/augenrules --load

程式碼解析

  1. 安裝 auditd:確保 auditd 軟體包已安裝並為最新版本。
  2. 啟用 auditd 服務:確保 auditd 在系統重啟後自動啟動。
  3. 調整日誌檔案數量和大小:修改 auditd.conf 以增加日誌檔案數量和大小限制,便於管理和儲存稽核日誌。
  4. 安裝自定義稽核規則:複製自定義的稽核規則到指定位置,並設定適當的許可權。
  5. 過載稽核規則:使用 augenrules 命令過載稽核規則,使其生效。

自動化主機安全性的強化與工具應用

核心變更與安全性強化

調整 Linux 核心引數是一種常見的強化主機安全的方法,但必須清楚瞭解所做的變更會如何影響系統。CIS(Center for Internet Security)基準測試提供了詳細的建議,解釋了為何需要這些變更。然而,由於資訊科技場景的多樣性,仍需謹慎操作以避免意外的後果。

以下是一個使用 Ansible 調整核心引數的範例(kernel.yaml):

- name: 關閉 IPv6 網路堆積疊(如果未使用)
  lineinfile:
    dest: "{{ old-var }}"
    line: "{{ item.line }}"
    state: present
  with_items:
    - { line: 'net.ipv6.conf.all.disable_ipv6 = 1' }
    - { line: 'net.ipv6.conf.default.disable_ipv6 = 1' }

- name: 忽略未知 IP 的封包
  lineinfile:
    dest: "{{ old-var }}"
    line: "{{ item.line }}"
    state: present
  with_items:
    - { line: 'net.ipv4.conf.all.log_martians = 1' }
    - { line: 'net.ipv4.conf.default.log_martians = 1' }

- name: 減緩 spoofing 攻擊
  lineinfile:
    dest: "{{ old-var }}"
    line: 'net.ipv4.tcp_syncookies = 1'
    state: present

- name: 防止 ICMP廣播
  lineinfile:
    dest: "{{ old-var }}"
    line: 'net.ipv4.icmp_echo_ignore_broadcasts = 1'
    state: present

內容解密:

  1. net.ipv6.conf.all.disable_ipv6 = 1net.ipv6.conf.default.disable_ipv6 = 1 用於關閉 IPv6 網路堆積疊,如果系統未使用 IPv6,這可以減少潛在的安全風險。
  2. net.ipv4.conf.all.log_martians = 1net.ipv4.conf.default.log_martians = 1 用於記錄來自未知 IP 的封包,有助於檢測潛在的攻擊。
  3. net.ipv4.tcp_syncookies = 1 用於啟用 SYN cookies,以減緩 TCP SYN flood 攻擊。
  4. net.ipv4.icmp_echo_ignore_broadcasts = 1 用於防止系統回應 ICMP廣播請求,減少被利用於 DDoS 攻擊的風險。

使用者與群組帳戶管理

正確設定使用者和群組帳戶的檔案許可權對於 Linux 系統的安全至關重要。以下是一個使用 Ansible 設定這些檔案許可權的範例(account.yaml):

- name: 設定 /etc/passwd 的許可權
  file:
    path: /etc/passwd
    owner: root
    group: root
    mode: '0644'

- name: 設定 /etc/passwd- 的許可權
  file:
    path: /etc/passwd-
    owner: root
    group: root
    mode: '0644'

- name: 設定 /etc/group 的許可權
  file:
    path: /etc/group
    owner: root
    group: root
    mode: '0644'

- name: 設定 /etc/shadow 的許可權
  file:
    path: /etc/shadow
    owner: root
    group: root

- name: 設定 SElinux 為 "enforcing" 模式
  replace:
    path: /etc/selinux/config
    regexp: 'SELINUX=permissive'
    replace: 'SELINUX=enforcing'

內容解密:

  1. 正確設定 /etc/passwd/etc/passwd-/etc/group/etc/shadow 等檔案的擁有者和許可權,可以防止未授權的存取和修改。
  2. 將 SElinux 設定為 “enforcing” 模式,可以強制執行安全策略,提高系統的安全性。

Nikto:一個強大的 Web 伺服器掃描工具

Nikto 是一個開源的 Web 伺服器掃描工具,可以檢測多達 6700 個可能造成安全問題的檔案和程式。它還可以檢查伺服器的版本是否過時,並提供修復建議。

使用 Nikto 時需要注意,它會產生大量的日誌記錄和網路活動,因此只應在您自己的主機或獲得明確許可的主機上執行掃描。

Nikto 網路掃描工具安裝與使用

Nikto 是一款開源的網路掃描工具,用於檢測網路伺服器的安全問題和組態錯誤。它能夠掃描伺服器,找出潛在的安全威脅和漏洞,並提供相關的建議以改善伺服器的安全性。

安裝 Nikto

首先,從 Nikto 的 GitHub 儲存函式庫下載原始碼:

$ git clone https://github.com/sullo/nikto
Cloning into 'nikto'..
remote: Enumerating objects: 66, done.
remote: Counting objects: 100% (66/66), done.
remote: Compressing objects: 100% (49/49), done.
remote: Total 6077 (delta 30), reused 46 (delta 15), pack-reused 6011
Receiving objects: 100% (6077/6077), 3.81 MiB | 897.00 KiB/s, done.
Resolving deltas: 100% (4401/4401), done.

下載完成後,進入 nikto/program 目錄:

$ cd nikto/program

目錄內容

$ ls
databases docs nikto.conf.default nikto.pl
plugins replay.pl templates

執行 Nikto 的主程式:

$ ./nikto.pl -h http://127.0.0.1
- Nikto v2.1.6
———————————————————————————————————-
+ No web server found on 127.0.0.1:80
———————————————————————————————————-
+ 0 host(s) tested

內容解密:

  • 上述指令是檢查本機是否執行網頁伺服器,由於本機未執行網頁伺服器,因此 Nikto 無法掃描到任何結果。
  • -h 引數指定了目標主機的 URL。

使用 Docker 建置 Nikto 容器

進入上一層目錄並使用 Docker 建置 Nikto 容器映像:

$ cd ..; docker build -t sullo/nikto .

Dockerfile 分析

FROM alpine:3.10.0
LABEL version="2.1.6" \
author="Author Paul Sec (https://github.com/PaulSec), Nikto User https://github.com/drwetter" \
docker_build="docker build -t sullo/nikto:2.1.6 ." \
docker_run_basic="docker run --rm sullo/nikto:2.1.6 -h http://www.example.com" \
docker_run_advanced="docker run --rm -v $(pwd):/tmp sullo/nikto:2.1.6 -h http://www.example.com -o /tmp/out.json"
COPY ["program/", "/nikto"]
ENV PATH=${PATH}:/nikto
RUN echo 'Selecting packages to Nikto.' \
&& apk update \
&& apk add --no-cache --virtual .build-deps \
perl \
perl-net-ssleay \
&& echo 'Cleaning cache from APK.' \
&& rm -rf /var/cache/apk/* \
&& echo 'Creating the nikto group.' \
&& addgroup nikto \
&& echo 'Creating the user nikto.' \
&& adduser -G nikto -g "Nikto user" -s /bin/sh -D nikto \
&& echo 'Changing the ownership.' \
&& chown -R nikto.nikto /nikto \
&& echo 'Creating a random password for root.' \
&& export RANDOM_PASSWORD=`tr -dc A-Za-z0–9 < /dev/urandom|head -c44` \
&& echo "root:$RANDOM_PASSWORD" | chpasswd \
&& unset RANDOM_PASSWORD \
&& echo 'Locking root account.' \
&& passwd -l root \
&& echo 'Finishing image.'
USER nikto
ENTRYPOINT ["nikto.pl"]

內容解密:

  • Dockerfile 使用 Alpine Linux 作為基礎映像,並安裝所需的 Perl 軟體包。
  • 建立了一個名為 nikto 的使用者和群組,並將 /nikto 目錄的所有權變更為 nikto
  • root 使用者設定隨機密碼並鎖定 root 帳戶,以提高安全性。
  • 設定容器啟動時預設執行的指令為 nikto.pl

使用 Nikto 容器掃描目標主機

執行以下指令以掃描本機:

$ docker run --rm sullo/nikto -h http://localhost
- Nikto v2.1.6
—————————————————————————————————————
+ No web server found on localhost:80
—————————————————————————————————————
+ 0 host(s) tested

掃描遠端主機

建立一個 Apache 容器並取得其 IP 位址:

$ docker run -dit --name my-apache-app -p 8080:80 -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
$ docker inspect my-apache-app | grep -i "IPAddress"

使用 Nikto 容器掃描遠端主機:

$ docker run --rm sullo/nikto -h http://remotehost.tld

範例輸出

- Nikto v2.1.6
————————————————————————————————————
+ Target IP: 123.123.123.123
+ Target Hostname: remotehost.tld
+ Target Port: 80
+ Start Time: 2020–07–29 18:45:11 (GMT0)
————————————————————————————————————
+ Server: nginx/1.14.2
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined.
This header can hint to the user agent to protect against some forms of XSS.
+ The X-Content-Type-Options header is not set.

內容解密:

  • Nikto 掃描了遠端主機並回報了一些安全問題,例如缺少 X-Frame-OptionsX-XSS-ProtectionX-Content-Type-Options 等安全標頭。
  • 這意味著目標主機可能容易受到點選劫持、跨站指令碼(XSS)等攻擊。