隨著網路架構日益複雜,手動管理防火牆和 ACL 變得越來越困難,自動化已成為提升效率和降低錯誤的關鍵。本文提供的 Python 指令碼和範例,結合 Netmiko 和 Nornir 等工具,可自動化執行防火牆服務管理、區域組態、服務與埠號設定等任務。此外,文章也示範瞭如何使用 Jinja2 範本引擎,根據預先定義的規則自動生成 ACL 組態,簡化網路安全管理流程,並確保組態的一致性和可維護性。透過自動化,工程師可以更專注於網路安全策略的制定和最佳化,而非繁瑣的重複性手動操作。
自動化管理防火牆服務與設定
在現代的伺服器管理中,自動化是提升效率和減少錯誤的關鍵。本文將介紹如何使用Python和Netmiko函式庫來自動化管理多台伺服器上的防火牆服務,包括啟動或停止firewalld服務、管理系統啟動時的服務狀態,以及組態防火牆區域。
連線伺服器與管理防火牆服務
首先,我們定義了一個server_connection函式,用於建立與伺服器的連線。這個函式接受一個IP位址作為引數,並傳回一個Netmiko連線物件。
def server_connection(ip):
device = {"host": ip, "username": "ubuntu", "password": "ubuntu", "device_type": "linux", "secret": "ubuntu"}
net_connect = Netmiko(**device)
return net_connect
內容解密:
device字典包含了連線伺服器所需的資訊,如主機IP、使用者名稱、密碼、裝置型別和特權密碼。Netmiko(**device)建立了一個到伺服器的連線,並傳回這個連線物件。
啟動或停止firewalld服務
我們定義了兩個函式,start_firewalld和stop_firewalld,用於在連線的伺服器上啟動或停止firewalld服務。這些函式使用server_connection函式建立連線,並透過讀取預先準備的文字檔案來傳送組態命令。
def start_firewalld(ip):
connection = server_connection(ip)
output = connection.send_config_from_file("start_firewalld.txt", read_timeout=1000)
print(output)
def stop_firewalld(ip):
connection = server_connection(ip)
output = connection.send_config_from_file("stop_firewalld.txt", read_timeout=1000)
print(output)
內容解密:
connection.send_config_from_file方法從指定的文字檔案中讀取命令並在伺服器上執行。read_timeout=1000設定了讀取超時時間,以確保命令執行的可靠性。
管理系統啟動時的服務狀態
我們還定義了兩個函式,enable_service_on_boot和disable_service_on_boot,用於在系統啟動時啟用或停用指定的服務。
def enable_service_on_boot(ip):
service = "firewalld"
connection = server_connection(ip)
connection.send_config_set(f"systemctl enable {service}", read_timeout=1000)
output = connection.send_command(f"systemctl list-unit-files --type=service | grep {service}")
print(output)
def disable_service_on_boot(ip):
service = "firewalld"
connection = server_connection(ip)
connection.send_config_set(f"systemctl disable {service}", read_timeout=1000)
output = connection.send_command(f"systemctl list-unit-files --type=service | grep {service}")
print(output)
內容解密:
connection.send_config_set方法用於執行特定的組態命令,如啟用或停用服務。connection.send_command方法用於執行命令並取得輸出,如列出服務的狀態。
平行執行任務
為了提高效率,我們使用了ThreadPoolExecutor來平行執行任務。這允許我們同時對多台伺服器進行操作。
with ThreadPoolExecutor(max_workers=5) as executor:
result = executor.map(enable_service_on_boot, host)
內容解密:
max_workers=5指定了最大工作執行緒數,即同時對5台伺服器進行操作。executor.map方法將指定的函式應用於主機列表中的每一台伺服器。
組態防火牆區域
firewalld服務提供了多個預定義的區域,如public、trusted和drop等,用於不同的網路環境。我們可以使用firewall-cmd命令來管理和查詢這些區域。
root@Server-1:/home/ubuntu# firewall-cmd --get-zones
block dmz drop external home internal nm-shared public trusted work
firewall-cmd 指令詳解與應使用案例項
firewall-cmd 是 Linux 系統中用於管理防火牆的強大工具,透過此指令可以對防火牆進行組態和管理。以下將詳細介紹其常用引數和實際應用案例。
檢查與管理防火牆狀態
首先,我們可以使用以下指令檢查 firewall-cmd 的版本和服務狀態:
firewall-cmd --version
firewall-cmd --state
內容解密:
--version引數用於檢查當前 firewall-cmd 的版本,確保我們使用的工具是最新的或是符合需求的版本。--state引數用於檢查防火牆服務的當前狀態,確認服務是否正在執行。
管理 Zone 與介面
在防火牆組態中,Zone 是用來定義不同網路介面或來源 IP 的信任級別。以下是一些常用的 Zone 管理指令:
firewall-cmd --get-zones
firewall-cmd --list-all-zones
firewall-cmd --get-default-zone
firewall-cmd --set-default-zone=internal
內容解密:
--get-zones列出系統中所有可用的 Zone 名稱。--list-all-zones顯示所有 Zone 的詳細組態資訊。--get-default-zone查詢目前預設的 Zone。--set-default-zone=internal將預設 Zone 設定為 internal。
查詢與設定介面所屬 Zone
若要查詢特定介面所屬的 Zone 或將介面加入特定的 Zone,可以使用以下指令:
firewall-cmd --get-zone-of-interface=ens33
firewall-cmd --zone=home --change-interface=eth0
內容解密:
--get-zone-of-interface=ens33查詢 ens33 介面所屬的 Zone。--change-interface=eth0將 eth0 介面變更至 home Zone。
開啟與關閉服務及埠號
在特定 Zone 中開啟或關閉服務及埠號是防火牆組態中的常見需求。例如,若要允許 HTTP 服務,可以使用以下指令:
firewall-cmd --zone=public --add-service=http
firewall-cmd --zone=public --add-port=80/tcp
內容解密:
--add-service=http在 public Zone 中新增允許 HTTP 服務。--add-port=80/tcp在 public Zone 中新增允許 TCP 協定的 80 埠號。
相對地,若要移除已新增的服務或埠號,可以使用 --remove-service 和 --remove-port 引數:
firewall-cmd --zone=public --remove-service=http
firewall-cmd --zone=public --remove-port=80/tcp
內容解密:
--remove-service=http從 public Zone 中移除 HTTP 服務。--remove-port=80/tcp從 public Zone 中移除 TCP 協定的 80 埠號。
使設定永久生效與重新載入組態
為了確保防火牆的組態在重啟後仍然生效,需要使用 --permanent 引數。同時,使用 --reload 引數可以重新載入防火牆組態,使變更立即生效。
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --reload
內容解密:
--permanent使後續的組態變更永久生效。--reload重新載入防火牆組態,使變更立即生效。
建立新的 Zone 與組態範例
若需要建立新的 Zone,可以使用 --new-zone 引數,並結合 --permanent 使其在重啟後仍然存在。
firewall-cmd --new-zone=test123 --permanent
firewall-cmd --reload
內容解密:
--new-zone=test123建立一個名為 test123 的新 Zone。- 結合
--permanent確保新建立的 Zone 在重啟後仍然存在。
自動化組態範例
以下是一個使用 Jinja2 範本引擎與 YAML 檔案自動化組態防火牆的範例:
- 首先,安裝必要的 Python 模組,包括
netmiko、jinja2和pyyaml。 - 建立
info.yaml檔案,定義所需的變數:
new_zone:
- test interface:
- lo service:
- http
3. 建立 `command_list.txt` 檔案,使用 Jinja2 範本語法:
firewall-cmd –new-zone={{ new_zone[0] }} –permanent firewall-cmd –reload firewall-cmd –get-zones
4. 編寫 Python 指令碼讀取 YAML 檔案並結合 Jinja2 範本生成最終的命令:
```python
from jinja2 import Environment, FileSystemLoader
from yaml import safe_load
def from_jinja():
env = Environment(loader=FileSystemLoader("."))
template = env.get_template("command_list.txt")
with open("info.yaml") as r:
data = safe_load(r)
command = template.render(data).split('\n')
return command
commands = from_jinja()
for cmd in commands:
print(cmd)
內容解密:
此範例展示如何利用 Jinja2 範本引擎和 YAML 組態檔案自動生成 firewall-cmd 指令,用於建立新的 Zone、重新載入組態以及查詢現有的 Zones。透過這種方式,可以輕鬆地實作防火牆組態的自動化管理。
網路裝置防火牆組態與ACL管理
在現代網路架構中,防火牆組態和存取控制列表(ACL)管理是確保網路安全的重要環節。本文將介紹如何使用Python和相關模組(如Netmiko和Nornir)來自動化防火牆組態和ACL管理。
防火牆區域組態
首先,我們來看看如何使用Python指令碼組態防火牆區域。以下是一個範例程式碼,展示瞭如何使用Netmiko模組連線到Linux伺服器並組態防火牆區域。
程式碼範例
from netmiko import Netmiko
from jinja2 import Environment, FileSystemLoader
from yaml import safe_load
def from_jinja():
env = Environment(loader=FileSystemLoader("."))
template = env.get_template("command_list.txt")
with open("info.yml") as r:
data = safe_load(r)
command = template.render(data).split("\n")
return [command, data]
def add_zone(ip):
device = {"host": ip, "username": "ubuntu", "password": "ubuntu", "device_type": "linux", "secret": "ubuntu"}
net_connect = Netmiko(**device)
commands = from_jinja()[0]
net_connect.send_config_set(commands, read_timeout=1000)
return net_connect
def zone_configuration(ip):
interface = "lo"
data = from_jinja()[1]
new_zone = data["new_zone"]
commands = [
f"firewall-cmd --permanent --zone={new_zone} --change-interface={interface}",
"firewall-cmd --reload",
"firewall-cmd --get-active-zones",
f"sudo firewall-cmd --zone={new_zone} --add-service=http",
f"sudo firewall-cmd --zone={new_zone} --add-port=80/tcp",
f"firewall-cmd --zone={new_zone} --add-forward-port=port=80:proto=udp:toport=8080:toaddr=10.10.10.1"
]
connect = add_zone(ip)
connect.send_config_set(commands)
out = connect.send_config_set(f"sudo firewall-cmd --list-all --zone={new_zone}")
print(out)
zone_configuration("192.168.163.135")
內容解密:
from_jinja()函式使用 Jinja2 範本引擎渲染命令,並從 YAML 檔案中讀取資料。add_zone(ip)函式建立到 Linux 伺服器的連線,並傳送組態命令以建立新的防火牆區域。zone_configuration(ip)函式組態新的防火牆區域,包括更改介面、新增服務和埠轉發規則。- 最後,呼叫
zone_configuration("192.168.163.135")函式執行防火牆區域組態。
網路裝置ACL組態
接下來,我們來看看如何使用Nornir框架和Jinja2範本引擎組態網路裝置的ACL。
ACL規則範例
| 序列號 | 允許/拒絕 | 協定 | 源IP | 目標IP | 引數 | 值 |
|---|---|---|---|---|---|---|
| 10 | deny | ip | 10.11.0.0/16 | 192.32.0.0/16 | - | - |
| 20 | deny | ip | 15.12.0.0/16 | 192.12.0.0/16 | - | - |
| 30 | permit | ip | 120.1.0.0/16 | 192.168.0.0/16 | - | - |
| 40 | permit | tcp | 10.1.1.0/24 | 172.16.1.0/24 | eq | telnet |
| 50 | permit | ip | 140.1.0.0/16 | 192.168.0.0/16 | - | - |
| 90 | deny | pim | any | any | dscp | cs1 |
| 100 | deny | ip | any | any | - | - |
程式碼範例(部分)
from nornir import InitNornir
from nornir.plugins.tasks.networking import netmiko_send_config
from jinja2 import Environment, FileSystemLoader
def configure_acl(task):
env = Environment(loader=FileSystemLoader("."))
template = env.get_template("acl_commands.txt")
acl_commands = template.render(data=task.host.data)
task.run(netmiko_send_config, config_commands=acl_commands.split("\n"))
nr = InitNornir(config_file="config.yaml")
nr.run(task=configure_acl)
內容解密:
- 使用 Nornir 初始化網路裝置連線。
- 定義
configure_acl任務,使用 Jinja2 範本引擎渲染 ACL 組態命令。 - 使用
netmiko_send_config外掛傳送 ACL 組態命令到網路裝置。