Ansible 藉由 SSH 連線管理伺服器,簡化了自動化流程。這篇文章將示範如何在 Ubuntu 系統上使用 Ansible 佈署和管理 NGINX 與 WordPress,涵蓋安裝、組態、SSL 證書申請及自動更新等導向,並提供一些實務上的注意事項和技巧。這些方法也適用於 Debian、RHEL 或 Fedora 等其他發行版,只需根據系統差異調整套件管理指令即可。首先,我們會利用 Ansible Playbook 安裝 NGINX,接著設定自動更新機制,確保系統安全。然後,我們會使用 Cloudflare API 取得 SSL 證書並組態 NGINX 以啟用 HTTPS。最後,我們將示範如何設定和安裝 WordPress,並分享一些 PHP 和 MySQL 的最佳實務組態。過程中,我們會使用一些工具和技術,例如 ansible-galaxy 建立角色、acme.sh 申請證書,以及設定 unattended-upgrades 進行自動安全更新。

全方位佈署、管理及自動更新 NGINX 使用 Ansible

在進入組態管理的世界中,我們選擇了 Ansible,這是一個以其簡單性和效率聞名的工具。與其他需要在每個伺服器上安裝代理程式的管理工具不同,Ansible 透過 SSH 操作,最小化了設定開銷並保持輕量級存在。它是一個無代理的協調工具,將簡單性和安全性帶到了伺服器自動化的前沿。雖然我們的教程主要針對 Ubuntu,因為它在行業中廣泛採用,但這些原則和做法可以轉移到其他發行版如 Debian、RHEL 或 Fedora,只需根據不同的套件管理器和系統佈局進行少量調整。

執行你的第一個 Ansible Playbook

Ansible 是一個透過 Playbook 組織的協調工具。每個 Playbook 可以包含多個角色。我們將從安裝 Ansible 開始,並執行我們的第一個 Playbook 來安裝 NGINX。

安裝 Ansible

Ansible 可以在遠端伺服器或本地 Linux 系統上設定,只要能連線到你的 NGINX 伺服器即可。以下是安裝 Ansible 的步驟:

  1. 我們將使用 root 帳戶進行每一步操作:
root@ansible:~# apt install ansible
  1. 檢查 Ansible 是否安裝成功:
root@ansible:~# ansible --version
ansible 2.10.8
  1. 接下來,建立第一個 Ansible 角色來安裝 NGINX。Ansible 角色有標準的目錄結構。使用 ansible-galaxy 命令來建立它:
root@ansible:~# ansible-galaxy init nginx_install

這將建立一個名為 nginx_install 的目錄,其中包含任務、處理程式、範本等子目錄。

  1. 接下來,建立路徑 roles/nginx_install/tasks,使用 mkdir -p roles/nginx_install/tasks 命令,然後建立 roles/nginx_install/tasks/main.yml 檔案,內容如下:
---
- name: Install nginx
  apt:
    name: nginx
    state: latest
    update_cache: yes

這將定義一個單一任務來使用 Ubuntu 的套件管理器安裝 NGINX。

建立 Playbook

  1. 接下來,我們建立一個 Playbook 來使用這個角色。在 nginx_install 專案的根目錄中建立 nginx_install.yml 檔案,內容如下:
---
- hosts: webservers
  become: true
  roles:
    - nginx_install

這將把角色應用到所有設定好的主機(群組:webservers)。

建立 Inventory

  1. 建立 Inventory 檔案來儲存你的機器地址。建立 inventory.ini 檔案,內容如下:
[webservers]
server_ip ansible_ssh_user=root

請確保使用 SSH 鍵並替換 server_ip 為你的伺服器 IP 地址以連線到伺服器。

  1. 在這個 Inventory 中,我們建立了一個名為 webservers 的主機群組。在這個群組中,我們增加了一台伺服器 server_ip。如果涉及多台伺服器,你的 Inventory 必須擴充套件以列出每一台伺服器以進行平行管理。

以下是多台伺服器的示例:

[webservers]
server1.example.com ansible_ssh_user=root
server2.example.com ansible_ssh_user=root

[backend_api]
api1.example.com ansible_ssh_user=root
api2.example.com ansible_ssh_user=root

執行 Playbook

  1. 現在我們已經有了執行第一個 Playbook 需要的所有檔案。讓我們執行 Playbook:
root@ansible:~/nginx_install# ansible-playbook -i inventory.ini nginx_install.yml

執行結果應該類別似於:

PLAY [all]
TASK [Gathering Facts]
ok: [testvm.lxd]
TASK [nginx_install : Install nginx]
changed: [testvm.lxd]
PLAY RECAP
testvm.lxd: ok=2 changed=1

太好了!我們的第一個 Ansible Playbook 已經成功安裝了 NGINX。如果再次執行 Playbook,它會識別 NGINX 已經安裝並不會嘗試重新安裝。

檢查 NGINX 安裝

你現在可以透過 port 80 存取你的 Web 優先順序以檢查 NGINX 是否可用。

組態 NGINX 使用 Ansible

在上一節中,我們建立了一個名為 nginx_install 的專案。我們將繼續這個專案讓 Ansible 幫我們編寫 nginx.conf 檔案。

  1. 首先,建立一個目錄 roles/nginx_install/files,使用命令 mkdir -p roles/nginx_install/files,然後將你的 nginx.conf 檔案新增到此資料夾中。
  2. 接著,建立一個新任務來複製 nginx.conf 檔案。編輯現有的 roles/nginx_install/tasks/main.yml 檔案並新增以下內容:
- name: Copy nginx configuration file
  copy:
    src: nginx.conf
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: '0644'
  notify: restart nginx

這將把 nginx.conf 檔案從你的檔案目錄傳送到遠端伺服器上的 /etc/nginx/ 資料夾。

內容解密:

  • apt 模組:這是用於 Ubuntu 的套件管理系統模組。它允許我們定義要安裝或更新的套件。
  • state: latest:確保 NGINX 安裝的是最新版本。
  • update_cache: yes:更新本地套件索引。
  • notify: restart nginx:當組態檔改變時觸發重啟 NGINX 功能。
  • copy 模組:這是用於複製檔案到遠端主機的一個模組。它可以指設定檔案來源、目的地以及許可權。

這些步驟確保了組態檔案在遠端伺服器上被正確地複製和應用。接下來我們可以進一步最佳化和擴充套件這些組態以適應更複雜的需求。

使用 Ansible 設定自動更新

在 Ansible 中設定自動更新是保障系統安全的一個重要步驟。這不僅能夠確保系統在面對安全漏洞時能夠及時更新,還能減少人工干預,提升維運效率。以下是玄貓的詳細指引,幫助你利用 Ansible 來實作這一目標。

設定 NGINX 自動重啟

首先,我們需要定義一個 handler(處理程式)來重啟 NGINX。這個 handler 會在 NGINX 組態檔案發生變更時觸發。

建立 Handler

  1. 我們首先建立一個新的目錄來存放 handler:
    mkdir -p roles/nginx_install/handlers
    
  2. roles/nginx_install/handlers 目錄下建立一個名為 main.yml 的檔案,並新增以下內容:
    - name: restart nginx
      service:
        name: nginx
        state: restarted
    

執行 Playbook

接下來,我們執行 Playbook 來測試這個 handler 是否正常工作:

ansible-playbook -i inventory.ini nginx_install.yml

執行結果如下:

PLAY [all]

TASK [Gathering Facts]
ok: [testvm.lxd]

TASK [nginx_install : Install nginx]
ok: [testvm.lxd]

TASK [nginx_install : Copy nginx configuration file]
changed: [testvm.lxd]

RUNNING HANDLER [nginx_install : restart nginx]
changed: [testvm.lxd]

PLAY RECAP
testvm.lxd: ok=4 changed=2

從結果可以看到,當我們複製 NGINX 組態檔案時,handler 被觸發並重啟了 NGINX。如果再次執行 Playbook,由於 NGINX 已經安裝且組態檔案未變更,這些操作將不會重複執行。

安裝並組態 unattended-upgrades

unattended-upgrades 是一個非常有價值的工具,它能夠自動應對系統中的安全漏洞,例如 CVE 漏洞。對於像 NGINX 這樣的關鍵應用程式來說,這樣的自動更新機制尤其重要。

安裝 unattended-upgrades

我們可以透過編輯 roles/nginx_install/tasks/main.yml 來安裝 unattended-upgrades:

- name: Install unattended-upgrades
  apt:
    name: unattended-upgrades
    state: present

執行 Playbook 來安裝這個套件:

ansible-playbook -i inventory.ini nginx_install.yml

執行結果如下:

[...]

TASK [nginx_install : Install unattended-upgrades]
ok: [testvm.lxd]

現在你的系統已經組態好了自動安全更新。如果你想要進行更全面的更新設定,可以參考 unattended-upgrades 的官方檔案來進行調整。

安全自動化更新

在實務中,玄貓使用了 unattened-upgrades 構建各式各樣大型基礎設施。但需要注意的是,每家公司都有其獨特的需求和環境。因此需要結合自身的實際情況來做針對性調整。以下是玄貓的一些實務建議:

  1. 測試環境:在正式應用之前,一定要在測試環境中進行充分測試。
  2. 日誌監控:開啟並定期檢查自動更新日誌,確保所有更新都已正常執行。
  3. 備份:在進行任何自動化操作之前,確保有完整的系統備份。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title Ansible 自動化佈署與更新 NGINX 和 WordPress

package "安全架構" {
    package "網路安全" {
        component [防火牆] as firewall
        component [WAF] as waf
        component [DDoS 防護] as ddos
    }

    package "身份認證" {
        component [OAuth 2.0] as oauth
        component [JWT Token] as jwt
        component [MFA] as mfa
    }

    package "資料安全" {
        component [加密傳輸 TLS] as tls
        component [資料加密] as encrypt
        component [金鑰管理] as kms
    }

    package "監控審計" {
        component [日誌收集] as log
        component [威脅偵測] as threat
        component [合規審計] as audit
    }
}

firewall --> waf : 過濾流量
waf --> oauth : 驗證身份
oauth --> jwt : 簽發憑證
jwt --> tls : 加密傳輸
tls --> encrypt : 資料保護
log --> threat : 異常分析
threat --> audit : 報告生成

@enduml

內容解密:

此圖示展示了 unattended-upgrades 在系統安全維護中的角色。它透過自動應用安全更新來增強系統安全性,進而提升自動化維護的效率。整個流程從安裝 unattended-upgrades 開始,透過定期應用安全更新來保持系統安全性,最終達到提高維護效率的目的。

未來趨勢與技術選型

隨著技術的不斷進步,Ansible 將會成為更多企業選擇的自動化工具。未來可能會有更多關於系統監控、安全掃描及災難還原等功能被整合進來。因此建議大家密切關注 Ansible 的官方資訊及社群活動。

錯誤教訓與改進點

在實務中玄貓遇到過一些錯誤經驗:

  1. 組態錯誤:由於手動編輯組態檔案容易出錯,因此建議使用版本控制工具(如 Git)來管理組態檔案。
  2. 測試不足:很多問題都是因為沒有進行充分測試導致的。強烈建議在正式環境中佈署之前先在測試環境中進行充分測試。
  3. 日誌監控:有時候問題並不容易被發現,因此需要設定良好的日誌監控機制。

總結而言玄貓認為玩家在面對複雜基礎設施時必須考慮到安全性及可靠性。希望本文對大家有所幫助!

使用 Cloudflare API Key 取得 SSL 証書並佈署 WordPress 網站

單一憑證管理與 NGINX 組態

在實務中,使用 Cloudflare 的 DNS 驗證來取得 SSL 証書是相當常見的做法。以下是玄貓整理的實務經驗,希望能對各位有所幫助。首先,我們需要獲得 Cloudflare 的 API Key。

取得 API Key

首先,前往 Cloudflare 的使用者資料頁面,選擇「檢視全域 API Key」,這樣就可以獲得你的 API Key。假設我們的 API Key 是 abcd1234,然後將它儲存在 /root/.acme.sh/account.conf 檔案中,同時也包含用於你 Cloudflare 帳戶的電子郵件地址:

SAVED_CF_Key='abcd1234'
SAVED_CF_Email=my-cloudflare-account@personal.email

發布簽署的 SSL 証書

接著,我們開始發布第一個簽署的 SSL 証書。我們已經安裝了 acme.sh,並且給予它許可權來存取我們的網域 example.com。現在,我們使用 acme.sh 來發布証書:

root@nginx:~# acme.sh --issue --dns dns_cf -d example.com -d *.example.com

這個指令會讓 acme.sh 與 Cloudflare 聯絡以建立臨時子網域,然後由憑證授權機構(預設為 zerossl)簽署生成的証書,最後刪除臨時子網域。

此圖示展示了 acme.sh 生成並發布了一個簽署的萬用字元証書。

中央化 NGINX 的 SSL 組態

在上一步中,我們學會瞭如何取得簽署的証書。接下來,我們要將這些証書應用到 NGINX 的組態中。由於這些証書可能需要在多個子網域上使用,為了避免重複組態並且簡化管理,我們會寫一個組態檔案來包含在其他組態檔案中。

首先,我們在 NGINX 的組態資料夾(例如 /etc/nginx/)中建立一個名為 ssl.conf 的檔案:

ssl_certificate /root/.acme.sh/example.com/fullchain.cer;
ssl_certificate_key /root/.acme.sh/example.com/example.com.key;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;

這樣一來,當我們佈署新專案時,只要包含這個 ssl.conf 檔案即可節省時間。

啟用 HTTP/2 與 SSL

HTTP/2 是 HTTP 協定的一大進步,旨在提升網頁效能和效率。它引入了多工技術(multiplexing),允許在單一連線上進行多個請求和回應;同時還有標頭壓縮技術(header compression),減少開銷。另外還有一個關鍵功能是伺服器推播(server push),伺服器可以主動將資源推播給客戶端,進一步最佳化載入時間。

以下是如何在伺服器區塊中啟用 HTTP/2:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ...
}

確保在設定 SSL 的同時啟用 HTTP/2,因為現代瀏覽器都支援這項技術,但需要安全連線。

儘管 HTTP/3 提供了更多的進步,但目前還不適合大規模生產環境使用。玄貓建議持續關注其發展,相信它在完全成熟後會帶來更多驚喜。

搭建 WordPress 網站

WordPress 是目前最受歡迎的內容管理系統(CMS),根據 Kinsta 的資料顯示,其市場佔有率高達 42%。對於許多伺服器管理員來說,無論是個人還是專業用途,搭建 WordPress 網站或部落格都是常見任務。

準備伺服器與取得 WordPress

在這個章節中,我們將準備好伺服器以下載和安裝 WordPress 應用程式。接下來會有一些組態檔案需要處理以確保 WordPress 能夠順利執行。

系統需求

首先要確保你的伺服器安裝並更新了必要的元件:推薦使用 PHP 8.1 和 MySQL Server 8。如果還沒有安裝這些元件,可以使用以下指令在 Debian 或 Red Hat 基礎的 Linux 作業系統上安裝:

# Debian-based systems
apt install mysql-server php8.1-fpm php8.1-mysql php8.1-gd php8.1-xml php8.1-mbstring php8.1-curl php8.1-zip

# Red Hat-based systems
dnf install mysql-server php8.1-fpm php8.1-mysqlnd php8.1-gd php8.1-xml php8.1-mbstring php8.1-curl php8.1-zip

如果你的系統上已經安裝了較舊版本的 PHP 或 MySQL Server,建議升級到最新版本。

PHP 組態

確認伺服器元件滿足最低需求後,需要編輯一些 PHP 組態以確保 WordPress 能夠順利執行。PHP 的預設組態檔(php.ini)中包含了一些需要更新的指令:

  • cgi.fix_pathinfo: 建議設定為 0 以提升安全性。
  • post_max_size: 預設為 8 MB,如果需要上傳大檔案則應增加此值。
  • upload_max_filesize: 預設為 2 MB,如果允許上傳大檔案則應增加此值。
  • date.timezone: 建議設定正確的時間區域以避免警告。

另外一個需要處理的是 PHP-FPM 的組態。主要的 php-fpm.conf 檔案不需要立即更改,但需要建立一個組態集(pool):這些集合適用於特定網站或應用程式。這樣可以讓 PHP 工作程式執行在特定使用者帳戶下。

建立一個新的集合:

[wordpress]
user=wordpress
group=wordpress
listen=127.0.0.1:9000
allowed_clients=127.0.0.1
chroot /home/wordpress/www;

這樣可以提升安全性:即使發現 WordPress 的安全漏洞,攻擊者也只能影響到指定路徑內的檔案和目錄。

MySQL 組態

安裝 MySQL Server 的同時會要求設定管理員(root)憑證。這些憑證具有完全存取 SQL 伺服器許可權,因此不能用於任何 PHP 應用程式中。最佳做法是建立一個獨立的 MySQL 帳戶並分配相應許可權:

mysql> CREATE DATABASE wordpress;
mysql> CREATE USER 'wordpressuser'@'localhost' IDENTIFIED BY 'password';
mysql> GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpressuser'@'localhost';
mysql> FLUSH PRIVILEGES;

以上就是使用 Cloudflare API Key 取得 SSL 認證並佈署 WordPress 網站的一些實務經驗和技巧分享。希望對大家有所幫助。