在局域網中的Linux服務器集群,為了保障運維安全,只能從堡壘機登錄到各個Linux服務器。那么需要對Linux服務器集群進行安全加固,限制訪問權限。在堡壘機上可以部署腳本來記錄用戶操作的審計日志(詳情參考筆者的文章),那么整個局域網的Linux服務器集群的安全性就可以大大提高。
創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供巴南網站建設、巴南做網站、巴南網站設計、巴南網站制作等企業(yè)網站建設、網頁設計與制作、巴南企業(yè)網站模板建站服務,十多年巴南做網站經驗,不只是建網站,更提供有價值的思路和整體網絡服務。
堡壘機作用明顯,其提供運維統(tǒng)一入口和安全審計功能,切斷直接訪問和事后審計定責,解決“運維混亂”變得“運維有序” 。
下面是三種方法總結。分別從服務端,系統(tǒng)端、防火墻端來完成只允許堡壘機SSH登錄的功能。
1、/etc/ssh/sshd_config
修改添加AllowUsers到ssh配置文件/etc/ssh/sshd_config? :
AllowUsers myuser@20.132.4.*
然后重啟?sshd服務:systemctl restart sshd
2、hosts.allow與hosts.deny
修改/etc/hosts.deny中添加設置 sshd : ALL ,拒絕所有的訪問;
修改/etc/hosts.allow,添加設置sshd : 20.132.4.* ,單獨開啟某個IP地址 。
這兩個文件優(yōu)先級為先檢查hosts.deny,再檢查hosts.allow。
更加詳細信息參考筆者的文章-Linux中hosts.allow與hosts.deny? 。
3、iptables防火墻
tcp協(xié)議中,禁止所有的ip訪問本機的22端口。
iptables -I INPUT -p tcp--dport 22 -j DROP
只允許20.132.4.*?訪問本機的22端口
iptables? -I? INPUT? -s? 20.132.4.*? ?-ptcp? --dport? 22? -j? ?ACCEPT
另外/etc/pam.d/sshd也可以提供訪問控制功能,調用的pam_access.so模塊是根據主機名、IP地址和用戶實現(xiàn)全面的訪問控制,pam_access.so模塊的具體工作行為根據配置文件/etc/security/access.conf來決定。但是囿于資料過少,待以后遇到再解決把。
擴展、可靠性、異步通信和高吞吐率等特性而被廣泛使用。目前越來越多的開源分布式處理系統(tǒng)都支持與Kafka集成,其中Spark
Streaming作為后端流引擎配合Kafka作為前端消息系統(tǒng)正成為當前流處理系統(tǒng)的主流架構之一。
然而,當下越來越多的安全漏
洞、數(shù)據泄露等問題的爆發(fā),安全正成為系統(tǒng)選型不得不考慮的問題,Kafka由于其安全機制的匱乏,也導致其在數(shù)據敏感行業(yè)的部署存在嚴重的安全隱患。本
文將圍繞Kafka,先介紹其整體架構和關鍵概念,再深入分析其架構之中存在的安全問題,最后分享下Transwarp在Kafka安全性上所做的工作及
其使用方法。
Kafka架構與安全
首先,我們來了解下有關Kafka的幾個基本概念:
Topic:Kafka把接收的消息按種類劃分,每個種類都稱之為Topic,由唯一的Topic Name標識。
Producer:向Topic發(fā)布消息的進程稱為Producer。
Consumer:從Topic訂閱消息的進程稱為Consumer。
Broker:Kafka集群包含一個或多個服務器,這種服務器被稱為Broker。
Kafka的整體架構如下圖所示,典型的Kafka集群包含一組發(fā)布消息的Producer,一組管理Topic的Broker,和一組訂閱消息的
Consumer。Topic可以有多個分區(qū),每個分區(qū)只存儲于一個Broker。Producer可以按照一定的策略將消息劃分給指定的分區(qū),如簡單的
輪詢各個分區(qū)或者按照特定字段的Hash值指定分區(qū)。Broker需要通過ZooKeeper記錄集群的所有Broker、選舉分區(qū)的Leader,記錄
Consumer的消費消息的偏移量,以及在Consumer Group發(fā)生變化時進行relalance.
Broker接收和發(fā)送消息是被動的:由Producer主動發(fā)送消息,Consumer主動拉取消息。
然而,分析Kafka框架,我們會發(fā)現(xiàn)以下嚴重的安全問題:
網絡中的任何一臺主機,都可以通過啟動Broker進程而加入Kafka集群,能夠接收Producer的消息,能夠篡改消息并發(fā)送給Consumer。
網絡中的任何一臺主機,都可以啟動惡意的Producer/Consumer連接到Broker,發(fā)送非法消息或拉取隱私消息數(shù)據。
Broker不支持連接到啟用Kerberos認證的ZooKeeper集群,沒有對存放在ZooKeeper上的數(shù)據設置權限。任意用戶都能夠直接訪問ZooKeeper集群,對這些數(shù)據進行修改或刪除。
Kafka中的Topic不支持設置訪問控制列表,任意連接到Kafka集群的Consumer(或Producer)都能對任意Topic讀取(或發(fā)送)消息。
隨著Kafka應用場景越來越廣泛,特別是一些數(shù)據隱私程度較高的領域(如道路交通的視頻監(jiān)控),上述安全問題的存在猶如一顆定時炸彈,一旦內網被黑客
入侵或者內部出現(xiàn)惡意用戶,所有的隱私數(shù)據(如車輛出行記錄)都能夠輕易地被竊取,而無需攻破Broker所在的服務器。
Kafka安全設計
基于上述分析,Transwarp從以下兩個方面增強Kafka的安全性:
身份認證(Authentication):設計并實現(xiàn)了基于Kerberos和基于IP的兩種身份認證機制。前者為強身份認證,相比于后者具有更好的安全性,后者適用于IP地址可信的網絡環(huán)境,相比于前者部署更為簡便。
權限控制(Authorization):設計并實現(xiàn)了Topic級別的權限模型。Topic的權限分為READ(從Topic拉取數(shù)據)、WRITE(向Topic中生產數(shù)據)、CREATE(創(chuàng)建Topic)和DELETE(刪除Topic)。
Broker啟動時,需要使用配置文件中的身份和密鑰文件向KDC(Kerberos服務器)認證,認證通過則加入Kafka集群,否則報錯退出。
Producer(或Consumer)啟動后需要經過如下步驟與Broker建立安全的Socket連接:
Producer向KDC認證身份,通過則得到TGT(票證請求票證),否則報錯退出
Producer使用TGT向KDC請求Kafka服務,KDC驗證TGT并向Producer返回SessionKey(會話密鑰)和ServiceTicket(服務票證)
Producer
使用SessionKey和ServiceTicket與Broker建立連接,Broker使用自身的密鑰解密ServiceTicket,獲得與
Producer通信的SessionKey,然后使用SessionKey驗證Producer的身份,通過則建立連接,否則拒絕連接。
ZooKeeper需要啟用Kerberos認證模式,保證Broker或Consumer與其的連接是安全的。
Topic的訪問控制列表(ACL)存儲于ZooKeeper中,存儲節(jié)點的路徑為/acl/topic/user,
節(jié)點數(shù)據為R(ead)、W(rite)、C(reate)、D(elete)權限的集合,如/acl/transaction/jack節(jié)點的數(shù)據為
RW,則表示用戶jack能夠對transaction這個topic進行讀和寫。
另外,kafka為特權用戶,只有kafka用戶能夠賦予/取消權限。因此,ACL相關的ZooKeeper節(jié)點權限為kafka具有所有權限,其他用戶不具有任何權限。
構建安全的Kafka服務
首先,我們?yōu)锽roker啟用Kerberos認證模式,配置文件為/etc/kafka/conf/server.properties,安全相關的參數(shù)如下所示:
其中,authentication參數(shù)表示認證模式,可選配置項為simple, kerberos和ipaddress,默認為simple。當認證模式為kerberos時,需要額外配置賬戶屬性principal和對應的密鑰文件路徑keytab.
認證模式為ipaddress時,Producer和Consumer創(chuàng)建時不需要做任何改變。而認證模式為kerberos時,需要預先創(chuàng)建好相應的principal和keytab,并使用API進行登錄,樣例代碼如下所示:
public class SecureProducer extends Thread {
private final kafka.javaapi.producer.ProducerInteger, String producer;
private final String topic;
private final Properties props = new Properties();
public SecureProducer(String topic) {
AuthenticationManager.setAuthMethod("kerberos");
AuthenticationManager.login("producer1", "/etc/producer1.keytab");
props.put("serializer.class", "kafka.serializer.StringEncoder");
props.put("metadata.broker.list",
"172.16.1.190:9092,172.16.1.192:9092,172.16.1.193:9092");
// Use random partitioner. Don't need the key type. Just set it to Integer.
// The message is of type String.
producer = new kafka.javaapi.producer.ProducerInteger, String(
new ProducerConfig(props));
this.topic = topic;
}
. . .
Topic權限管理
Topic的權限管理主要是通過AuthorizationManager這個類來完成的,其類結構如下圖所示:
其中,resetPermission(user, Permissions, topic) 為重置user對topic的權限。
grant(user, Permissions, topic) 為賦予user對topic權限。
revoke(user, Permissions, topic) 為取消user對topic權限。
isPermitted(user, Permissions, topic) 為檢查user對topic是否具有指定權限。
調用grant或revoke進行權限設置完成后,需要commit命令提交修改到ZooKeeper
Kerberos模式下,AuthorizationManager需要先使用AuthenticationManager.login方法登錄,與ZooKeeper建立安全的連接,再進行權限設置。示例代碼如下所示:
public class AuthzTest {
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("authentication", "kerberos");
props.setProperty("zookeeper.connect", "172.16.2.116:2181,172.16.2.117:2181,172.16.2.118:2181");
props.setProperty("principal", "kafka/host1@TDH");
props.setProperty("keytab", "/usr/lib/kafka/config/kafka.keytab");
ZKConfig config = new ZKConfig(props);
AuthenticationManager.setAuthMethod(config.authentication());
AuthenticationManager.login(config.principal(), config.keytab());
AuthorizationManager authzManager = new AuthorizationManager(config);
// reset permission READ and WRITE to ip 172.16.1.87 on topic test
authzManager.resetPermission("172.16.1.87",
new Permissions(Permissions.READ, Permissions.WRITE), "test");
// grant permission WRITE to ip 172.16.1.87 on topic test
authzManager.grant("172.16.1.87", new Permissions(Permissions.CREATE), "test");
// revoke permission READ from ip 172.16.1.87 on topic test
authzManager.revoke("172.16.1.87", new Permissions(Permissions.READ), "test");
// commit the permission settings
authzManager點抗 mit();
authzManager.close();
}
}
ipaddress認證模式下,取消和賦予權限的操作如下所示:
public class AuthzTest {
public static void main(String[] args) {
Properties props = new Properties();
props.setProperty("authentication", "ipaddress");
props.setProperty("zookeeper.connect",
"172.16.1.87:2181,172.16.1.88:2181,172.16.1.89:2181");
ZKConfig config = new ZKConfig(props);
// new authorization manager
AuthorizationManager authzManager = new AuthorizationManager(config);
// reset permission READ and WRITE to ip 172.16.1.87 on topic test
authzManager.resetPermission("172.16.1.87",
new Permissions(Permissions.READ, Permissions.WRITE), "test");
// grant permission WRITE to ip 172.16.1.87 on topic test
authzManager.grant("172.16.1.87", new Permissions(Permissions.CREATE), "test");
// revoke permission READ from ip 172.16.1.87 on topic test
authzManager.revoke("172.16.1.87", new Permissions(Permissions.READ), "test");
// commit the permission settings
authzManager點抗 mit();
authzManager.close();
}
}
Rancher 2.3正式發(fā)布已經一年,第一批使用Rancher 2.3的用戶可能會遇到Rancher Server證書過期,但是沒有自動輪換的情況。這會導致Rancher Server無法啟動,并且日志出現(xiàn)報錯:
請注意:
Rancher Server無法啟動不會影響下游集群,下游集群依然可以通過kubeconfig去操作。
為了讓大家更好的理解這個問題,下面將以手動修改系統(tǒng)時間的形式來重現(xiàn)這個問題。
當前時間: 2020年10月30日 星期五 10時37分59秒 CST
1、啟動Rancher v2.3.1,并且添加下游集群,操作步驟可以參考官網:
2、啟動Rancher 之后,從瀏覽器上查看到的過期時間: 2021年10月30日 星期六 中國標準時間 10:29:35
3、查看Rancher Server容器內的K3s證書過期時間為 Oct 30 02:28:49 2021 GMT
4、將服務器時間調整為證書過期后5天的日期,比如: 20211105
此時,Rancher UI 已經無法訪問:
并且Rancher 容器由于內置的K3s證書過期而不斷重啟。
以上現(xiàn)象是因為Rancher Server內置的K3s證書過期,導致K3s無法啟動,從而導致Rancher Server容器無法啟動。
為了可以繼續(xù)操作Rancher Server容器,需要將系統(tǒng)時間調整到K3s證書過期之前。
接下來我們就可以進入到容器內手動刪除K3s證書,然后重啟Rancher,重啟成功后將重新生成K3s證書。
Rancher Server如果出現(xiàn)以下日志,那么需要再重啟一次Rancher Server:
1、將服務器時間再次調整為證書過期后5天的日期,比如: 20211105
證書更新之后,我們需要確認K3s證書是否更新成功,還需要檢查下游集群是否會有影響。
2、確認K3s證書已經更新
K3s證書過期時間已經從 Oct 30 02:28:49 2021 GMT 更新到了 Oct 24 16:00:54 2022 GMT
3、確認瀏覽器證書已經更新
瀏覽器上的證書過期已經從 2021年10月30日 星期六 中國標準時間 10:29:35 更新到了 2022年10月25日 星期二 中國標準時間 00:01:34
4、確認下游集群不受影響
從Rancher 2.3開始,Rancher Server容器中內置了K3s作為local集群來支撐Rancher Server運行。
而K3s內部自動簽發(fā)的證書有效期是1年,正常情況下如果證書已過期或剩余的時間少于90天,則在重新啟動K3s時將輪換證書。參考官方文檔:
實際上由于K3s的bug導致在證書已過期或剩余的時間少于90天時重啟Rancher,沒有將K3s證書輪換,所以才會出現(xiàn)上述問題。
不過無需擔心,在后續(xù)的K3s v1.19版本中已經解決了這一問題,請參考:
一直認為redis3.x 集群有自己的安全措施.比如密碼,然而在此版本并不會用.
那么就采用了linux防火墻指定了開放端口的訪問權限 編輯iptables文件 添加可以訪問的IP. 那么只有添加了的IP才能連接上redis服務器端口,也就沒有了安全性問題!解決OK
詳細可對iptables -s 參數(shù)進行了解.