# rsyslog server (tls) 架設與使用 ## 配置環境介紹 * LogServer 跑 ubuntu server , 預計佈署 rsyslog server 收計 AP 送來的Log資料。 * AppServer 透過 Docker 佈署的 Net Core 網站或跑其他應用程式,預計將 Docker 相關的 Log 轉送到上面的 LogServer。 ## 前置準備 * ubuntu server 預設就有安裝 rsyslog 套件了,不過如果要支援 tls 傳輸的話需要在多裝一個套件。 `apt install rsyslog-gnutls` 這個動作 LogServer 跟 AppServer 都要安裝。 * 產生相關憑證 * 建立一個憑證中心的 ca 證 , 這邊假定是 `EriCaRoot.crt` 這檔案需要佈署到 LogServer 跟 AppServer * 用上面憑證中心發行兩張憑證出來 * For LogServer * `LogCert.crt` (憑證), `LogPrivkey.key` (私鑰) * For AppServer * `AppCert.crt` (憑證), `AppPrivkey.key` (私鑰) * 佈署憑證檔案 這邊把憑證相關檔案都放到 `/etc/rsyslog.d/tls` 下面,後續設定檔會需要指定憑證的完整路徑,所以這路徑只是我喜歡放這邊,不是一定要放這邊,佈署完成後兩個主機上的狀況太概會是。(檔案權限都設定為 644) * LogServer 的 /etc/rsyslog.d/tls 有三個檔案 `EriCaRoot.crt` 、 `LogCert.crt` 、 `LogPrivkey.key` * AppServer 的 /etc/rsyslog.d/tls 有三個檔案 `EriCaRoot.crt` 、 `AppCert.crt` 、 `AppPrivkey.key` ## rsyslog 設定調整 * LogServer 部分 * 新增設定檔 /etc/rsyslog.d/01-tls.conf ```conf module(load="imtcp" # TCP listener StreamDriver.Name="gtls" StreamDriver.Mode="1" # TLS-only 模式 StreamDriver.Authmode="x509/certvalid" # 驗證客戶端證書是否有效 ) # make gtls driver the default and set certificate files global( DefaultNetstreamDriver="gtls" DefaultNetstreamDriverCAFile="/etc/rsyslog.d/tls/EriCaRoot.crt" DefaultNetstreamDriverCertFile="/etc/rsyslog.d/tls/LogCert.crt" DefaultNetstreamDriverKeyFile="/etc/rsyslog.d/tls/LogPrivkey.key" ) # start up listener at port 6514 input( type="imtcp" port="6514" ) # 定義模板:按主機名貯存日誌 template(name="DynFileByHostname" type="string" string="/var/log/clients/%HOSTNAME%.log") # 定義模板:按 IP 地址貯存日誌 template(name="DynFileByIP" type="string" string="/var/log/clients/%FROMHOST-IP%.log") # 或者按 IP 地址存储 *.* ?DynFileByIP & stop ``` * AppServer 部分 * 新增設定檔 /etc/rsyslog.d/01-tls.conf ```conf global( DefaultNetstreamDriver="gtls" DefaultNetstreamDriverCAFile="/etc/rsyslog.d/tls/EriCaRoot.crt" DefaultNetstreamDriverCertFile="/etc/rsyslog.d/tls/AppCert.crt" DefaultNetstreamDriverKeyFile="/etc/rsyslog.d/tls/AppPrivkey.key" ) ``` * 新增設定檔 /etc/rsyslog.d/01-tls.conf ```conf template(name="DockerLog" type="string" string="/var/log/docker.log") if $programname startswith 'docker-' then { action(type="omfile" dynaFile="DockerLog") # 本地寫入一份 action(type="omfwd" # 設定送往遠端 LogServer queue.type="linkedlist" # 設定用記憶體當駐列,黨 LogServer 暫時離線時候 資料會緩存在記憶體中後續再重送 queue.size="10240" # 最大駐列的紀錄筆數 action.resumeRetryCount="-1" # 重新傳送失敗上限限制(-1為無限次) queue.saveOnShutdown="on" # rsyslog 服務停止時,駐列如果有東西沒送先存到檔案. queue.filename="docker_fwd" # 拿來暫存的檔案名稱 protocol="tcp" # 走 tcp 傳輸 target="LogServer.eri.com.tw" # 對應 LogServer 的 IP 或 域名 port="6514" # 對應 LogServer 的 Port StreamDriver="gtls" # 設定 tls 傳輸 StreamDriverMode="1" # tls 模式 StreamDriverAuthMode="x509/certvalid") # 驗證伺服器端證書是否有效 # 上面的 action 可以寫很多個,以這邊的案例就是本地寫一份,異機在送一份 , # 如果有多台 LogServer , 要同時送到多台就是 action 繼續給他家下去就對啦 # 要設定成 App => LogServer1 => LogServer2 .... => LogServerN 這種多層傳輸也是可以的 # 端看實際場景有沒有需要搞到這麼複雜。 & stop # 結束相關紀錄的處理 } ``` * 重啟 rsyslog 服務 ``` systemctl restart rsyslog.service ``` ## 調整 docker 的 Log 設定 docker 沒特別設定預設啟動 container 時,Log是會送到本地的 json,每個 container 各自立的資料,位置在 `/var/lib/docker/containers/...` 下面,可以透過設定 `/etc/docker/daemon.json` 把所有的 log 都送往本地的 rsyslog 處理。設定範例如下: ```json { "log-driver": "syslog", "log-opts": { "tag": "{{.DaemonName}}-{{.Name}}" } , //..........略 } ``` 調整後透過 `systemctl restart docker.service` 讓設定生效。 這邊注意調整過 `daemon.json` 影響的只有調整後啟動的容器,之前啟動的 Log 還是維持在 json 模式,需要把容器銷毀重啟才會改用新的設定。如果是用 docker-compose.yaml 啟動的容器,處理上就很簡單,先 down 在 up 就搞定了。 `docker compose down && docker compose up -d` ## 設定日誌輪替(logrotate) 完成上面設定後 AppServer , 所有的 Docker Container 的 Log 應該就都會往本機 rsyslog 發送然後寫入 /var/log/docker.log 裡面了。然後再轉送到 LogServer 的 /var/log/clients/...下面,但預設 log檔會一直長大,這時候就需要另外一個機制日誌輪替(logrotate),這大部分的 Linux 發行版預設都有安裝了,我們只要調整設定讓他多去處理我們新增的日誌檔案目標就好。 ### 調整範例 * LogServer 編輯 `/etc/logrotate.d/rsyslog` 加入 `/var/log/clients/*.log` ``` ...略 /var/log/clients/*.log { rotate 4 weekly ...略 ``` * AppServer 編輯 `/etc/logrotate.d/rsyslog` 加入 `/var/log/docker.log` ``` ...略 /var/log/clients/*.log { rotate 4 weekly ...略 ``` ### 後續處理 `/etc/logrotate.d/rsyslog` 預設是一週切一個檔案(weekly)保留4份(rotate 4),大約就保留一個月左右的紀錄量。如果要改變保留份數或 改變切割方式例如要一天切一個,用日期當檔名,設定的內容可能就會變成。 ``` ....略 daily missingok rotate 180 dateext dateformat -%Y-%m-%d ....略 ``` ## 使用心得 * 容器化佈署是現在的趨勢,一整個系統可能被分割為多個容器,甚至於會分散部署在多台的伺服器上。 1. 透過上面的配置過程,可以有效的將日誌做集中的管理。 2. 透過 TLS 憑證的授權確保 rsyslog server不會被濫用。 3. rsyslog server 提供的操作只有單向的寫入,以資安層面來說就算 AppServer 被攻陷,駭客也最多也只能清除 AppServer 上那份 Log,LogServer 上的不會被破壞。 4. 透過 日誌輪替(logrotate) ,可以針對 AppServer、LogLogServer 做不同的保留策略。例如 AppServer 保留7天 (做短期緩衝), LogLogServer 保留半年(或更長)。 後續日誌存放空間是否充足的問題,就只要把關注點放在 LogLogServer 處理就可以。 * 上面簡化略過了一些憑證產生與logrotate的細部說明,這些部分有需要可以另外在研究。