跳轉到內容

OpenClinica 安全

來自 Wikibooks,開放世界中的開放書籍

OpenClinica 安全

[編輯 | 編輯原始碼]

安裝、配置和保護 OpenClinica [OC] 社群版 [CE] 無疑是一段冒險,需要具備計算機科學各方面的知識。然而,只要有充足的搜尋和奉獻精神,任何對 Linux 有些瞭解的人都可以做到。我本身不是計算機科學家,但還是承擔了在 Web 伺服器上部署 OC 的任務,最終成功地運行了它。不過,在某些時候,我希望能有一份詳細的指南來指導整個過程。這篇帖子我想填補這個空白,至少在 OC 的安全方面,為嘗試相同任務的任何人提供幫助。

我採取的安全措施是我從多個來源找到的,我不能保證它們是保護 OC 所能做或應該做的所有事情的詳盡清單。正如我之前提到的,我不是該領域的專家,本指南僅僅是我大量搜尋和反覆試驗的結果。這裡的所有內容都要持保留態度,如果你認為你瞭解得更多,請隨時更改其中的一些方面。也請隨時建議改進/新增此過程,以便我們都能從這些集體知識中獲益。

我儘可能認真地對待安全問題,因為截至 2020 年,OC 的 CE 所需的軟體已經過時很久,因此盡一切可能讓它變得安全至關重要,尤其是在處理患者資料時。

我選擇的設定如下:

  • OpenClinica CE 3.15
  • CentOS 8
  • PostgreSQL 8.4.22
  • Tomcat 7.0.52
  • JVM 1.7.0

我遵循了 這個安裝指南,因為我找不到 v3.15 的安裝指南。獲得上面列出的某些特定軟體版本是一個相當大的挑戰,如果我不得不重新開始,我會考慮使用 CentOS 6,因為這個版本天生支援一些這些舊的依賴項。CentOS 6 也從今年開始不再提供支援,因此在選擇它時要仔細考慮。

根據上述指南的說明,執行 OC 所需的所有元件的根目錄位於:/usr/local

閒話少說,我們開始吧

首先,訪問 Web 伺服器(如果是遠端伺服器)應該被保護。每天都有數百次嘗試使用常見的使用者名稱登入 Web 伺服器,因此這確實應該是你的第一道防線。

修改 sshd_config 檔案

[編輯 | 編輯原始碼]

這個檔案可以在 `/etc/ssh/sshd_config` 下找到,它控制著對你的伺服器的 SSH 訪問。在對它進行任何更改之前,請確保你已經備份了它。在檔案中,修改以下引數:

只允許需要訪問伺服器的使用者名稱

  • AllowUsers <username1> <username2>

停用 root 登入

  • PermitRootLogin no
  • ChallengeResponseAuthentication no

將你的 SSH 金鑰複製到伺服器後(使用 ssh-copy-id 或手動,透過複製你的公鑰並將其貼上到伺服器上的 `~/.ssh/authorized_keys` 檔案中),你應該停用密碼身份驗證。這樣,只有透過 SSH 金鑰身份驗證才能登入。

  • PasswordAuthentication no

為了增加安全性,UsePAM 也可以設定為 `no`,但是,這會影響我的 SSH 身份驗證過程,我不得不將其設定回 `yes`。

一切配置完成後,重新啟動 sshd 服務

sudo systemctl restart sshd

這個軟體包透過禁止在 x 次 SSH 身份驗證失敗後嘗試連線的 IP 地址來提高 SSH 安全性。這裡有一個 很棒的指南 來配置 fail2ban。

sudo yum install epel-release

sudo yum install fail2ban

在 `/etc/fail2ban` 中建立一個名為 `jail.local` 的檔案,並將以下內容貼上進去(使用你自己的電子郵件地址)

[DEFAULT]
# Ban hosts for one hour:
bantime = 3600
maxretry = 5

[sshd]
enabled = true

destemail = <your@email.com>
sender = <your@email.com>
sendername = Fail2ban
mta = sendmail
action = %(action_mwl)s

建立這個檔案而不是直接在 `jail.conf` 中配置是首選,因為 fail2ban 更新會覆蓋你的配置。現在,當一個 IP 地址在 5 次失敗的登入嘗試後被禁止或 fail2ban 被停止/啟動時,你將收到電子郵件通知。

重新啟動 fail2ban 服務:sudo systemctl restart fail2ban

如果你想接收更多關於被禁止 IP 的資訊,可以安裝 `whoami.x86_64` 軟體包。

你可以透過以下方式檢視 sshd 監獄狀態:sudo fail2ban status sshd

雖然這聽起來很明顯,但維護伺服器上的強壯且唯一的密碼仍然至關重要。我建議使用 KeePass 來跟蹤它們,因為它還可以讓你自動生成非常強大的密碼。

保護 Tomcat 與保護 Web 伺服器一樣重要,因為它是你的外部世界接觸點。我從以下網站收集了下面列出的安全措施: [1] [2] [3] [4]

訪問控制

[編輯 | 編輯原始碼]

這是為了確保即使攻擊者可以控制 Web 伺服器,她所能造成的破壞也是最小的。首先,永遠不要以 root 使用者的身份執行 Web 伺服器,建立一個名為 `tomcat` 的新使用者,該使用者擁有執行伺服器所需的最小許可權。

將資料夾 `tomcat` 及其所有內容的所有者設定為使用者 tomcat 和組 tomcat

chown -R tomcat:tomcat /usr/local/tomcat

(不帶 -R 標誌,你只會更改資料夾的所有權,而不會更改內容)

給資料夾的所有者讀寫和執行許可權

chmod -R 700 /usr/local/tomcat

(使用 chmod 的指南:https://www.lifewire.com/uses-of-command-chmod-2201064)警告:要能夠開啟資料夾,你需要對其擁有執行許可權。我也是透過艱難的方式學到的。

從配置資料夾中刪除寫入和執行許可權。這可以防止攻擊者修改 Tomcat 的配置檔案

chmod -R u-wx /usr/local/tomcat/conf

但是,Tomcat 需要能夠開啟該資料夾,因此為資料夾(= 不帶 -R 標誌)新增執行許可權

chmod u+x /usr/local/tomcat/conf

從 openclinica.config 和 openclinica-ws.config(如果已安裝)資料夾中刪除讀取許可權

chmod -R u-w openclinica*.config

從 logs 資料夾中刪除讀取許可權

chmod -R u-r /usr/local/tomcat/logs

從 oldwebapps 資料夾中刪除所有許可權,因為在部署期間,Tomcat 不必對這些資料夾進行任何操作

chmod -R u-rwx /usr/local/tomcat/oldwebapps

將 `datainfo.properties` 檔案設定為只讀(如果已安裝,對 OpenClinica-ws 進行相同的操作)

chmod 400 /usr/local/tomcat/webapps/OpenClinica/WEB-INF/classes/datainfo.properties

這樣,你就完成了 Tomcat 的訪問控制方面。

您可以做的另一件事是將您的使用者新增到 tomcat 組,並授予該組對 usr/local/tomcat 資料夾的讀寫執行許可權。這樣,您仍然可以方便地編輯所有內容,而無需使用 root/sudo。我對它的安全性不太確定,請自行承擔風險使用。並且不要忘記在所有配置完成後從組中刪除自己並刪除許可權。

HTTPS

[edit | edit source]

如上所述,Tomcat 的 SSL 設定指南應該是您執行的第一步 (https://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html)。您需要確保本指南中列出的所有步驟都是使用使用者 `tomcat` 完成的,因為如果以其他方式完成,.keystore 檔案將在該使用者的 home 目錄下建立,tomcat 將無法找到並讀取它。理論上,您也可以將 HTTP 聯結器註釋掉,因為對 OC 強制使用 HTTPS 是最佳實踐。埠轉發將在防火牆級別啟用,因此理論上 Tomcat 不應該接收埠 8080 的請求,但我還沒有實際測試過。

配置完成後,您應該能夠使用 HTTPS 與您的 Web 伺服器通訊(在 https://:8443/OpenClinica 上)。如果您使用的是自簽名證書,您的瀏覽器會報錯,但您仍然可以訪問網站。您可以透過在 `tomcat/conf` 下的 web.xml 檔案末尾新增以下內容(在 </web-app> 標籤之前)來強制在 Tomcat 中使用 HTTPS

<security-constraint>
  <web-resource-collection>
    <web-resource-name>Protected Context</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
</security-constraint>

Cookies、自定義錯誤頁面、停用列表 ..

[edit | edit source]

這些都是良好的實踐,但並非必需的。這些包括從錯誤頁面隱藏伺服器版本或停用檔案系統列表以更好地防止 DDoS 攻擊。

以下所有內容都需要新增到 `web.xml` 檔案中。

安全且僅限 HTTP 的 cookie 以防止 XSS 攻擊

[edit | edit source]

(貼上到 </web-app> 標籤之前)

<cookie-config>
<http-only>true</http-only>
<secure>true</secure>
</cookie-config>

自定義錯誤頁面

[edit | edit source]

(貼上到 </web-app> 標籤之前) (Tomcat 無法找到錯誤頁面檔案,因此不會顯示任何錯誤頁面,但這可以透過隱藏版本號來完成。如果您遇到問題,請跳過此步驟。)

<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page>

<error-page>
<error-code>403</error-code>
<location>/error.jsp</location>
</error-page>

<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>

<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.jsp</location>
</error-page>

<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsp</location>
</error-page>

只讀資源和無列表

[edit | edit source]

(貼上到檔案中的 **DefaultServlet** 部分)

<init-param>
<param-name>readonly</param-name>
<param-value>true</param-value>
</init-param>

<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>

server.xml

[edit | edit source]

刪除伺服器橫幅

[edit | edit source]

如果您在聯結器的引數列表中新增引數 `Server=" "`,這將隱藏 HTTP 標頭中的版本號。它應該看起來像這樣

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" Server =" " address="<webserver IP address or localhost>" clientAuth="false" sslProtocol="TLS" keystoreFile="${user.home}/.keystore" keystorePass="<your keystore pass>" />

更改關閉命令

[edit | edit source]

為了防止攻擊者能夠關閉您的伺服器,您應該考慮更改關閉埠以及關閉命令。您可以在 `server.xml` 檔案開頭 <Server> 標籤內完成此操作

<Server port="任何未使用的埠" shutdown="<長且安全的字串>">

AJP 聯結器

[edit | edit source]

如果 OC 是唯一將在 Tomcat 中部署的 Web 應用程式,您可以安全地註釋掉 AJP 聯結器行,因為 OC 沒有使用此聯結器。

可能良好的實踐,但對我造成了問題

[edit | edit source]

停用自動部署

[edit | edit source]

為了防止有人在您的 Tomcat 例項中自動部署他們自己的惡意 Web 應用程式,您可以在 `server.xml` 檔案中透過在 <Host> 標籤中將以下引數設定為 false 來關閉自動部署。

autoDeploy="false" deployOnStartup="false" deployXML="false"

這樣,如果您重新啟動伺服器,您必須手動部署 OC,您將需要弄清楚如何操作。

安全容器

[edit | edit source]

使用 Tomcat,您可以選擇在容器中啟動您的例項,這確保即使在最壞的情況下有人破壞了伺服器,他們也只能訪問此容器內的資源和檔案。但是,您將需要花費時間才能使 OC 正常工作,因為它已知會(並且對我來說)破壞安裝。如果您有時間和知識使其正常工作,這可能是值得的。

其他用法非常簡單,在啟動 Web 伺服器時新增 -secure 標誌

/usr/local/tomcat/bin/startup.sh -secure

這就是 Tomcat 的全部內容。

PostgreSQL

[edit | edit source]

在安全性方面,您無法為 PostgreSQL 配置很多內容,但您也可以在這裡進行一些訪問控制。

更改 pgsql 資料夾的所有權

sudo chown -R postgres:postgres /usr/local/pgsql

更改許可權

sudo chmod -R 700 /usr/local/pgsql

您還應該仔細配置 `/usr/local/pgsql/data/` 中的 pg_hba.conf 檔案。此檔案控制對資料庫的不同訪問許可權。您需要授予 clinica 使用者本地連線 openclinica 資料庫的許可權,但阻止所有其他連線嘗試。身份驗證方法應設定為 `md5`,永遠不要使用 `password`,因為它以明文形式傳送這些方法。如果您將直接從遠端機器訪問資料庫,則必須在此處新增相應的行。

# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
# allow user clinica to connect to openclinica locally, using encrypted password based authentication (needed to automate backups)
local   openclinica clinica                           md5
# IPv4 local connections:
host    openclinica clinica     127.0.0.1/32          md5
# "local" is for Unix domain socket connections only
local   all         all                               reject
# IPv6 local connections:
host    all         all         ::1/128               reject

此配置對於將在下面描述的自動備份也很重要。

防火牆

[edit | edit source]

為任何 Web 伺服器設定防火牆都是必須的。這使您可以限制和監控發生在您的伺服器和外部世界之間的所有流量。這裡的主要目標是隻留下 Web 應用程式執行所必需的那些埠開啟。在這種情況下,這意味著

  • 埠 80/tcp,預期傳入 HTTP 流量,
  • 埠 443/tcp,預期傳入 HTTPS 流量,
  • 埠 22/tcp,SSH 流量正在進行。

您可能需要進行一些試錯,以檢視關閉某個埠是否會破壞任何東西,但對我來說,只允許這 3 個埠開啟就足夠了。

FirewallD

[edit | edit source]

如果您已經習慣使用 FirewallD,您可以跳到下一節(**設定 FirewallD**)。

CentOS 預裝了 FirewallD,它是一個強大的工具,可以管理這些連線。網上有很多資源可以幫助您瞭解更多資訊,比如這個

(更新:本文中描述的一種現象已過時。無法由其分配區域處理的資料包不會“向上踢”到下一個區域(“區域漂移”的概念)。它被認為是不安全的,將在未來版本的 FirewallD 中刪除。如果您確實想擁有這種行為,您可以在 FirewallD 的配置檔案中啟用區域漂移)

首先,確保 firewalld 已安裝並在您的系統上啟用。啟用的預設區域是 `Public`,您可以為了我們的目的保持這種方式。您可以檢查在此區域中預設啟用了哪些服務

sudo firewall-cmd --zone=public --list-all

服務並不是一些特殊的實體,它們僅僅代表了給定服務正常執行所需開啟的埠。這些埠定義在`/usr/lib/firewalld/services`目錄下,以自解釋的xml檔案形式存在。如果你想定義自己的服務,可以將這些xml檔案中的一個複製到`/etc/firewalld/services`目錄,並根據自己的需求進行自定義。你可以透過以下命令將任何服務新增到防火牆區域:

sudo firewall-cmd --zone=public --add-service=<你的服務> --permanent

你也可以透過以下命令移除任何不需要的服務:

sudo firewall-cmd --zone=public --remove-service=<不需要的服務> --permanent

你也可以直接新增或移除需要的埠:

firewall-cmd --zone=public --add-port=<你的自定義埠號>/tcp --permanent

如果沒有使用`--permanent`標誌,則一旦FirewallD被重新載入或重啟,更改將會被重置。你可以在沒有使用標誌的情況下嘗試使用規則,一旦你找到了適合你的規則,就可以透過新增`--permanent`標誌來最終確定這些規則。

設定FirewallD

[編輯 | 編輯原始碼]

以下配置假設你使用ssh訪問你的遠端伺服器,但是,如果不是這種情況,你可以跳過設定內部區域。

防火牆將設定三個區域:public、internal和trusted。public區域應該處理來自任何請求IP地址的http/s請求。internal區域應該新增一個源,該源包含你的IP或MAC地址,因此(理論上)只有當你的機器與伺服器通訊時,這個區域才會處理資料傳輸。這也是啟用ssh服務(=開啟埠22)的區域。

在開始配置FirewallD之前,你應該確保iptables被停用,並透過遮蔽它來阻止它啟動。否則它可能會干擾FirewallD,導致一些奇怪的行為。

systemctl mask iptables

systemctl disable iptables

首先,從public和internal區域移除任何不需要的服務。使用`--list-all`標誌檢視當前允許的內容。你應該只保留(或新增,如果需要)http/https服務。在internal區域中,還要新增ssh服務。

你應該將你的外向網路介面分配到public區域(這樣所有來自外部的請求都會由這個區域處理)。你可以透過以下命令列出所有可用的介面:

ip link show

你可以使用`--add-interface=<介面>`標誌新增介面。

不幸的是,這些介面的命名並不簡單(至少對我來說是這樣,我的介面叫做`ens192`),所以你可能需要做一些研究才能弄清楚它們是什麼。

你還應該將自己的IP/MAC地址新增到internal區域的源中,這樣只有來自這個IP/MAC地址的請求才會由這個區域處理,例如:

sudo firewall-cmd --zone=internal --permanent --add-source=154.112.12.18

如果你想讓ssh可以從某個特定的VPN網路訪問,你也可以將這個IP地址設定得更通用,例如:

sudo firewall-cmd --zone=internal --permanent --add-source=154.112.0.0/16

這將允許來自154.112.0.0-154.112.255.255的任何人使用ssh。(請注意,只有當至少有一個介面或源分配給區域時,區域才處於活動狀態!)

public區域的目標應該設定為DROP,這會在請求到達無效埠時返回空訊息,而不是傳輸拒絕訊息。這被認為更加安全。

sudo firewall-cmd --permanent --zone=public --set-target=DROP

接下來,建立埠轉發規則,以限制通訊到https,並適應Tomcat的埠約定(它使用8080而不是80,8443而不是443)。

sudo firewall-cmd --zone=public --permanent --add-forward-port=port=443:proto=tcp:toport=8443
sudo firewall-cmd --zone=public --permanent --add-forward-port=port=80:proto=tcp:toport=8443

sudo firewall-cmd --zone=internal --permanent --add-forward-port=port=443:proto=tcp:toport=8443
sudo firewall-cmd --zone=internal --permanent --add-forward-port=port=80:proto=tcp:toport=8443

為了使埠轉發工作,你還需要啟用偽裝 (https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-port_forwarding)

sudo firewall-cmd --zone=public --add-masquerade --permanent

sudo firewall-cmd --zone=internal --add-masquerade --permanent

現在這一步我不太確定,因為我沒有找到關於它的太多資訊。我將lo(迴環)介面分配給了trusted區域。這是從同一臺機器(本地主機,127.0.0.1)與你的Web伺服器通訊的介面。理想情況下,這是從外部世界無法訪問的,因此我假設trusted區域適合它,但同樣,我可能錯了。

如果你需要ping功能,請執行以下命令(將區域替換為你需要ping功能的區域):

sudo firewall-cmd --permanent --zone=<你的ping區域> --add-rich-rule='rule protocol value="icmp" accept'

你必須重新載入firewalld才能使更改生效。

sudo firewall-cmd --reload

現在你已經配置了FirewallD,它只允許與外部世界的http/s通訊,但仍然允許從你的個人機器/你的VPN網路進行ssh連線。

你可以使用nmap包測試你的防火牆,檢視哪些埠是開啟的。

OpenClinica

[編輯 | 編輯原始碼]

你已經做了大部分能做的事情來使OC安全,但是,你仍然可以在OC本身做一些事情。如果你以root使用者身份登入到Web介面,導航到`任務/管理/使用者/配置密碼要求`,那裡會有幾個選項,你可以開啟/關閉並調整它們以滿足你的需求。你也應該絕對啟用嘗試次數過多後的使用者鎖定(`任務/管理/使用者/鎖定`)。作為root使用者,如果你鎖定了這些帳戶,你可以在Web介面上解鎖它們。我自己採取的另一個措施(但我不知道它是否必要):要求我的OpenClinica例項的使用者將他們的密碼挑戰問題設定為一個長字串(不可猜測的)。我這樣做是因為我不確定OC是如何傳送密碼重置郵件的,以及這個郵件是否會被潛在的攻擊者劫持。一個更安全(但承認更不方便,甚至如果你有太多使用者的話也不切實際)的解決方案是,以root使用者身份,從Web介面重置他們的密碼並自己傳送給他們。

這實際上也應該是一個必須。我在這裡分享的解決方案只是一種方法,如果你知道更好的方法,請不要猶豫,用你自己的方法去做。

這裡有一份指南是關於如何在OC中實施備份的指南。基本上,你需要定期儲存你的OC配置檔案、你的研究目錄($TOMCAT_ROOT/openclinica.data)和你的PostgreSQL資料庫。

我已經附加了一個指令碼,如果執行它,它應該備份所有這些檔案,將它們打包成一個tarball檔案並儲存到`/usr/local/OpenClinica_backups`。你可以(並且應該)透過編輯指令碼中的BCKP_path變數將備份位置更改到伺服器外部。此外,你還需要為它建立一個.pgpass檔案,更多詳細資訊見下文。

我對上面連結的指南的補充是,使這些備份自動發生,例如每天一次。為此,我使用了`cron`服務,該服務預裝在CentOS 8上。

要讓你的指令碼每天執行,請將其放在`/etc/cron.daily/`目錄下。通常,要能夠獲取pg_dump,你需要你的openclinica資料庫的密碼。要允許自動更新,你需要在`/var/lib/pgsql/`目錄下建立一個.pgpass檔案。它的內容應如下所示:

localhost:5432:openclinica:clinica:<你的資料庫密碼>

為了讓Postgres能夠使用這個檔案,它必須由postgres擁有

sudo chown postgres:postgres .pgpass

並且它的許可權必須設定為0600

sudo chmod 0600 .pgpass

如果你在身份驗證方面遇到任何問題,請參閱pgpass的文件[5]

為了能夠建立pg_dump,postgres需要能夠寫入你的備份資料夾。將資料夾的組更改為postgres,並賦予組rwx許可權。

sudo chown root:postgres <你的備份資料夾>

sudo chmod g+rwx <你的備份資料夾>

你應該練習恢復你的資料庫,看看它是如何實際完成的。上面提到的指南可以幫助你完成這些工作。

防病毒

[編輯 | 編輯原始碼]

有一個很棒的GitHub倉庫,它可以讓你每天執行掃描來檢測各種惡意軟體,包括特洛伊木馬、病毒或rootkit。如果你將克隆的倉庫中的指令碼放在` /etc/cron.daily`目錄下,它將每天與自動備份指令碼一起執行。

最後一件事

[編輯 | 編輯原始碼]

為了做個明確的工作,最好停用tomcat、clinica和postgres使用者的登入

usermode -L tomcat
usermode -L clinica
usermode -L postgres

就是這樣

[編輯 | 編輯原始碼]

恭喜您,您剛剛使您的 OpenClinica 安裝更加安全!不幸的是,您必須牢記我們一直在加固的軟體是過時的軟體(非常過時),因此您只能做很多事情,並寄希望於一切順利。我所能給出的最好的建議是,如果可能,不要包含可識別您的研究物件的任何資訊。這樣,即使一切都失敗了,至少您的研究物件不必擔心個人身份被盜。

自動備份指令碼

[編輯 | 編輯原始碼]
#!

BCKP_path='/usr/local/OpenClinica_backups'
DATE=`date +"%Y-%m-%d"`

cd $BCKP_path
# create a database dump with pg_dump
sudo -u postgres /usr/local/pgsql/bin/pg_dump -U clinica openclinica -w > pg_dump
# backup the data directory of OC with CRF, XML, etc.. data
sudo tar -cf oc_data.tar /usr/local/tomcat/openclinica.data
# backup OC configuration
sudo cp /usr/local/tomcat/openclinica.config/datainfo.properties datainfo.properties

# tar all the above created files and assign a date
sudo tar -czf ${DATE}_openclinica_backup.tar.gz datainfo.properties  oc_data.tar  pg_dump

# remove created temporary files
sudo rm datainfo.properties
sudo rm oc_data.tar
sudo rm pg_dump

# add a bit of security
sudo chmod 400 *.tar.gz
  1. http://tomcat.apache.org/tomcat-7.0-doc/security-howto.html
  2. http://wiki.owasp.org/index.php/Securing_tomcat
  3. http://upguard.com/articles/15-ways-to-secure-apache-tomcat-8
  4. http://geekflare.com/apache-tomcat-hardening-and-security-guide
  5. https://postgres.tw/docs/current/libpq-pgpass.html
華夏公益教科書