1. 程式人生 > >讓 Linux 防火牆新秀 nftables 為你的 VPS 保駕護航

讓 Linux 防火牆新秀 nftables 為你的 VPS 保駕護航

上篇文章 給大家介紹了 nftables 的優點以及基本的使用方法,它的優點在於直接在使用者態把網路規則編譯成位元組碼,然後由核心的虛擬機器執行,儘管和 iptables 一樣都是基於 netfilter,但 nftables 的靈活性更高。

之前用 iptables 匹配大量資料時,還得需要 ipset 配合,而 nftables 直接內建了集合和字典,可以直接匹配大量的資料,這一點比 iptables 方便多了,拿來練練魔法真是極好的,不多解釋,請直接看 Linux全域性智慧分流方案。

本文將會教你如何配置 nftables 來為伺服器實現一個簡單的防火牆,本文以 CentOS 7 為例,其他發行版類似。

1. 安裝 nftables

首先需要安裝 nftables:

$ yum install -y nftables

由於 nftables 預設沒有內建的鏈,但提供了一些示例配置,我們可以將其 include 到主配置檔案中。主配置檔案為 /etc/sysconfig/nftables.conf,將下面一行內容取消註釋:

# include "/etc/nftables/inet-filter"

然後啟動 nftables 服務:

$ systemctl start nftables

現在再次檢視規則,就會發現多了一張 filter 表和幾條鏈:

$ nft list ruleset

table inet filter {
    chain input {
        type filter hook input priority 0; policy accept;
    }

    chain forward {
        type filter hook forward priority 0; policy accept;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

在 nftables 中,ipv4ipv6 協議可以被合併到一個單一的地址簇 inet 中,使用了 inet 地址簇,就不需要分別為 ipv4 和 ipv6 指定兩個不同的規則了。

2. 新增 INPUT 規則

和 iptables 一樣,nftables 的 filter 表包含三條鏈:INPUTFORWARDOUTPUT,一般配置防火牆只需要配置 INPUT 鏈就好了。

迴環介面

首先允許訪問 localhost:

$ nft add rule inet filter input iif "lo" accept
$ nft add rule inet filter input iif != "lo" ip daddr 127.0.0.0/8 drop

可以再優化一下,加上註解(comment)和計數器(counter):

$ nft add rule inet filter input \
   iif "lo" \
   accept \
   comment \"Accept any localhost traffic\"

$ nft add rule inet filter input \
   iif != "lo" ip daddr 127.0.0.0/8 \
   counter \
   drop \
   comment \"drop connections to loopback not coming from loopback\"

檢視規則:

$ nft list chain inet filter input

table inet filter {
    chain input {
        type filter hook input priority 0; policy accept;
        iif "lo" accept comment "Accept any localhost traffic"
        iif != "lo" ip daddr 127.0.0.0/8 counter packets 0 bytes 0 drop comment "drop connections to loopback not coming from loopback"
    }
}

連線跟蹤模組

接下來的規則用到一個核心模組叫 conntrack(connection tracking),它被用來跟蹤一個連線的狀態。最常見的使用場景是 NAT,為什麼需要跟蹤記錄連線的狀態呢?因為 nftables 需要記住資料包的目標地址被改成了什麼,並且在返回資料包時再將目標地址改回來。

和 iptables 一樣,一個 TCP 連線在 nftables 中總共有四種狀態:NEWESTABLISHEDRELATEDINVALID

除了本地產生的包由 OUTPUT 鏈處理外,所有連線跟蹤都是在 PREROUTING 鏈裡進行處理的,意思就是, iptables 會在 PREROUTING 鏈裡從新計算所有的狀態。如果我們傳送一個流的初始化包,狀態就會在 OUTPUT 鏈裡被設定為 NEW,當我們收到迴應的包時,狀態就會在 PREROUTING 鏈裡被設定為 ESTABLISHED。如果收到迴應的第一個包不是本地產生的,那就會在 PREROUTING 鏈裡被設定為 NEW 狀態。綜上,所有狀態的改變和計算都是在 nat 表中的 PREROUTING 鏈和 OUTPUT 鏈裡完成的。

還有其他兩種狀態:

  • RELATED : RELATED 狀態有點複雜,當一個連線與另一個已經是 ESTABLISHED 的連線有關時,這個連線就被認為是 RELATED。這意味著,一個連線要想成為 RELATED,必須首先有一個已經是 ESTABLISHED 的連線存在。這個 ESTABLISHED 連線再產生一個主連線之外的新連線,這個新連線就是 RELATED 狀態了。
  • INVAILD : 表示分組對應的連線是未知的,說明資料包不能被識別屬於哪個連線或沒有任何狀態。有幾個原因可以產生這種情況,比如,記憶體溢位,收到不知屬於哪個連線的 ICMP 錯誤資訊。我們需要 DROP 這個狀態的任何東西,並列印日誌:
$ nft add rule inet filter input \
   ct state invalid \
   log prefix \"Invalid-Input: \" level info flags all \
   counter \
   drop \
   comment \"Drop invalid connections\"

檢視規則:

$ nft list chain inet filter input

table inet filter {
    chain input {
        type filter hook input priority 0; policy accept;
        iif "lo" accept comment "Accept any localhost traffic"
        iif != "lo" ip daddr 127.0.0.0/8 counter packets 0 bytes 0 drop comment "drop connections to loopback not coming from loopback"
        ct state invalid log prefix "Invalid-Input: " level info flags all counter packets 0 bytes 0 drop comment "Drop invalid connections"
    }
}

令牌桶

為了防止有惡意攻擊者利用 ping 泛洪(ping flood)來進行攻擊,可以利用令牌桶模型來對 ping 包限速。ping 泛洪的原理很簡單,就是採用多執行緒的方法一次性發送多個 ICMP 請求報文,讓目的主機忙於處理大量這些報文而造成速度緩慢甚至宕機。

先來介紹一下令牌桶模型。

熟悉 iptables 的朋友應該知道,iptables 通過 hashlimit 模組來實現限速的功能,而 hashlimit 的匹配方式就是基於令牌桶(Token bucket)的模型,nftables 也類似,
令牌桶是一種網路通訊中常見的緩衝區工作原理,它有兩個重要的引數,令牌桶容量 n令牌產生速率 s

  • 令牌桶容量 n:可以把令牌當成是門票,而令牌桶則是負責製作和發放門票的管理員,它手裡最多有n張令牌。初始時,管理員開始手裡有 n 張令牌,每當一個數據包到達後,管理員就看看手裡是否還有可用的令牌。如果有,就把令牌發給這個資料包,limit 就告訴nftables,這個資料包被匹配了,而當管理員把手上所有的令牌都發完了,再來的資料包就拿不到令牌了;這時,limit 模組就告訴 nftables ,這個資料包不能被匹配。
  • 令牌產生速率 s:當令牌桶中的令牌數量少於 n,它就會以速率 s 來產生新的令牌,直到令牌數量到達 n 為止。

通過令牌桶機制,可以有效的控制單位時間內通過(匹配)的資料包數量,又可以容許短時間內突發的大量資料包的通過(只要資料包數量不超過令牌桶 n),真是妙哉啊。

nftables 比 iptables 做的更絕,它不僅可以基於資料包來限速,也可以基於位元組來限速。為了更精確地驗證令牌桶模型,我們選擇基於位元組來限速:

$ nft add rule inet filter input \
   ip protocol icmp icmp type echo-request \
   limit rate 20 bytes/second burst 500 bytes \
   counter \
   accept \
   comment \"No ping floods\"

上面的規則表示:

  • 為所有 echo-request 型別的 ICMP 包建立一個匹配項;
  • 匹配項對應的令牌桶容量為 500 個位元組;
  • 令牌產生速率為 20 位元組/s

再新增一條規則,拒絕不滿足上訴條件的資料包:

$ nft add rule inet filter input \
   ip protocol icmp icmp type echo-request \
   drop \
  comment \"No ping floods\"

同時還要接收狀態為 ESTABLISHED 和 RELATED 的資料包:

$ nft add rule inet filter input \
   ct state \{ established, related \} \
   counter \
   accept \
   comment \"Accept traffic originated from us\"

下面來做個實驗,直接 ping 該伺服器的 IP 地址,ping 包大小設定為 100 位元組,每秒傳送一次:

$ ping -s 92 192.168.57.53 -i 1

PING 192.168.57.53 (192.168.57.53) 92(120) bytes of data.
100 bytes from 192.168.57.53: icmp_seq=1 ttl=64 time=0.402 ms
100 bytes from 192.168.57.53: icmp_seq=2 ttl=64 time=0.373 ms
100 bytes from 192.168.57.53: icmp_seq=3 ttl=64 time=0.465 ms
100 bytes from 192.168.57.53: icmp_seq=4 ttl=64 time=0.349 ms
100 bytes from 192.168.57.53: icmp_seq=5 ttl=64 time=0.411 ms
100 bytes from 192.168.57.53: icmp_seq=11 ttl=64 time=0.425 ms
100 bytes from 192.168.57.53: icmp_seq=17 ttl=64 time=0.383 ms
100 bytes from 192.168.57.53: icmp_seq=23 ttl=64 time=0.442 ms
100 bytes from 192.168.57.53: icmp_seq=29 ttl=64 time=0.464 ms
...

首先我們能看到前 5 個包的迴應都非常正常,然後從第 6 個包開始,我們每 6 秒能收到一個正常的迴應。這是因為我們設定了令牌桶的容量為 500 個位元組,令牌產生速率為 20 位元組/s,而發包的速率是每秒鐘 100 個位元組,即每個包 100 個位元組,當發完 5 個包後,令牌桶的容量變為 0,這時開始以 20 位元組/s 的速率產生新令牌(和前面提到的令牌桶演算法不太一樣,只有當令牌桶容量為 0 才開始產生新的令牌),5 秒鐘之後,令牌桶的容量變為 100 個位元組,所以 6 秒鐘後又能收到正常回應。

ICMP & IGMP

接收其他型別的 ICMP 協議資料包:

$ nft add rule inet filter input \
   ip protocol icmp icmp type \{ destination-unreachable, router-advertisement, router-solicitation, time-exceeded, parameter-problem \} \
   accept \
   comment \"Accept ICMP\"

接收 IGMP 協議資料包:

$ nft add rule inet filter input \
   ip protocol igmp \
   accept \
   comment \"Accept IGMP\"

分別處理 TCP 和 UDP

這一步我們將 TCP 和 UDP 的流量拆分,然後分別處理。先建立兩條鏈:

$ nft add chain inet filter TCP
$ nft add chain inet filter UDP

然後建立一個命名字典:

$ nft add map inet filter input_vmap \{ type inet_proto : verdict \; \}

字典的鍵表示協議型別,值表示判決動作。

往字典中新增元素:

$ nft add element inet filter input_vmap \{ tcp : jump TCP, udp : jump UDP \}

最後建立一條規則拆分 TCP 和 UDP 的流量:

$ nft add rule inet filter input meta l4proto vmap @input_vmap

其中,meta l4proto 用來匹配協議的型別。

最後再瞄一眼規則:

$ nft list ruleset

table inet filter {
    map input_vmap {
        type inet_proto : verdict
        elements = { tcp : jump TCP, udp : jump UDP }
    }

    chain input {
        type filter hook input priority 0; policy accept;
        iif "lo" accept comment "Accept any localhost traffic"
        iif != "lo" ip daddr 127.0.0.0/8 counter packets 0 bytes 0 drop comment "drop connections to loopback not coming from loopback"
        ct state invalid log prefix "Invalid-Input: " level info flags all counter packets 95 bytes 6479 drop comment "Drop invalid connections"
        icmp type echo-request limit rate 20 bytes/second burst 500 bytes counter packets 17 bytes 2040 accept comment "No ping floods"
        icmp type echo-request drop comment "No ping floods"
        ct state { established, related } counter packets 172135 bytes 99807569 accept comment "Accept traffic originated from us"
        icmp type { destination-unreachable, router-advertisement, router-solicitation, time-exceeded, parameter-problem } accept comment "Accept ICMP"
        ip protocol igmp accept comment "Accept IGMP"
        meta l4proto vmap @input_vmap
    }

    chain forward {
        type filter hook forward priority 0; policy accept;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }

    chain TCP {
    }

    chain UDP {
    }
}

3. 處理 TCP 流量

這一步我們來處理 TCP 流量,首當其衝的就是 ssh 了,必須得給這位大哥放行啊:

$ nft add rule inet filter TCP \
   tcp dport 22 \
   ct state new \
   limit rate 15/minute \
   log prefix \"New SSH connection: \" \
   counter \
   accept \
   comment \"Avoid brute force on SSH\"

其次需要放行 Web 服務,和上面一樣,為了易於管理,方便後續動態新增埠,需要先建立一個命名集合:

$ nft add set inet filter web \{ type inet_service \; flags interval \; \}

檢視集合:

$ nft list set inet filter web

table inet filter {
    set web {
        type inet_service
        flags interval
    }
}

向集合中新增元素:

$ nft add element inet filter web \{ 80, 443 \}

檢視集合:

$ nft list set inet filter web

table inet filter {
    set web {
        type inet_service
        flags interval
        elements = { http, https }
    }
}

放行 Web 服務:

$ nft add rule inet filter TCP \
   tcp dport @web \
   counter \
   accept \
   comment \"Accept web server\"

如果你還有其他不可描述的應用,比如 xxx 之類的代理,可以按照上面的方式新增規則,先建立集合:

$ nft add set inet filter xxx \{ type inet_service \; flags interval \; \}

再新增元素:

$ nft add element inet filter xxx \{ 9000-9005, 9007 \}

檢視集合:

$ nft list set inet filter xxx

table inet filter {
    set xxx {
        type inet_service
        flags interval
        elements = { 9000-9005, 9007 }
    }
}

現在體會到 nftables 集合的強大了吧,可以是區間,可以是單個元素組成的集合,也可以混合,iptables 麻煩讓一讓。

放行不可描述的服務:

$ nft add rule inet filter TCP \
   tcp dport @xxx \
   counter \
   accept \
   comment \"Accept xxx\"

4. 處理 UDP 流量

這一步我們來處理 UDP 流量,比如上面舉例的不可描述的應用,除了 TCP 埠還有 UDP 埠,具體用處我就不解釋了,自己面向谷歌找答案吧。

到了這一步,連集合都不用建立, 直接複用之前建立的集合,放行不可描述應用的 UDP 資料:

$ nft add rule inet filter UDP \
   udp dport @xxx \
   counter \
   accept \
   comment \"Accept xxx\"

檢視規則:

$ nft list chain inet filter UDP

table inet filter {
    chain UDP {
        udp dport @xxx counter packets 0 bytes 0 accept comment "Accept xxx"
    }
}

其他 UDP 資料都可按此套路模組化,簡直不要太賞心悅目。

為了使系統或 nftables 重啟後能夠繼續生效,我們需要將這些規則持久化,直接將規則寫入 /etc/nftables/inet-filter

$ echo "#! /usr/sbin/nft -f" > /etc/nftables/inet-filter
$ nft list ruleset >> /etc/nftables/inet-filter

開機自動載入 nftables 服務:

$ systemctl enable nftables

5. 在 rsyslog 中記錄日誌

預設情況下,開啟日誌記錄後,日誌會直接進入 syslog,和系統日誌混在一起,不好讀取。最好的辦法是將 nftables 的日誌重定向到單獨的檔案。

以本文為例,我們只開啟了 ct state invalidssh 的日誌記錄,先在 /var/log 目錄中建立一個名為 nftables 的目錄,並在其中建立兩個名為 invalid.logssh.log 的檔案,分別儲存各自的日誌。

$ mkdir /var/log/nftables
$ touch /var/log/nftables/{ssh.log,invalid.log}

確保系統中已安裝 rsyslog。現在進入 /etc/rsyslog.d 目錄並建立一個名為 nftables.conf 的檔案,其內容如下:

:msg,regex,"Invalid-Input: " -/var/log/nftables/invalid.log
:msg,regex,"New SSH connection: " -/var/log/nftables/ssh.log

最後,為了確保日誌是可管理的,需要在 /etc/logrotate.d 中建立一個 nftables 檔案:

$ cat /etc/logrotate.d/nftables

/var/log/nftables/* { rotate 5 daily maxsize 50M missingok notifempty delaycompress compress postrotate invoke-rc.d rsyslog rotate > /dev/null endscript }

重新通過 ssh 連線伺服器,就能看到日誌了:

$ tail -f /var/log/nftables/ssh.log

Dec 19 17:15:33 [localhost] kernel: New SSH connection: IN=ens192 OUT= MAC=00:50:56:bd:2f:3d:00:50:56:bd:d7:24:08:00 SRC=192.168.57.2 DST=192.168.57.53 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=43312 DF PROTO=TCP SPT=41842 DPT=22 WINDOW=29200 RES=0x00 SYN URGP=0

6. 總結

本文教你如何使用 nftables 搭建一個簡單的防火牆,並通過集合和字典將規則集模組化,後續可動態新增埠和 IP 等元素,而不用修改規則。更復雜的規則將會在後面的文章介紹,下篇文章將會教你如何使用 nftables 來防 DDoS 攻擊,敬請期待。

微信公眾號

掃一掃下面的二維碼關注微信公眾號,在公眾號中回覆◉加群◉即可加入我們的雲原生交流群,和孫巨集亮、張館長、陽明等大佬一起探討雲原生技術

相關推薦

Linux 防火牆新秀 nftables VPS 保駕護航

上篇文章 給大家介紹了 nftables 的優點以及基本的使用方法,它的優點在於直接在使用者態把網路規則編譯成位元組碼,然後由核心的虛擬機器執行,儘管和 iptables 一樣都是基於 netfilter,但 nftables 的靈活性更高。 之前用 iptables 匹配大量資料時,還得需要 ipset 配

Linux中的gedit變為的程式設計利器!!!

在使用了一段時間的Linux後,一直使用終端和VIM來編輯程式、編譯程式,一些前輩長時間使用會覺得順手,因為使用終端可以擺脫滑鼠,完成滑鼠可以完成的幾乎所有的操作。 但是一些朋友初次使用Linux還是

噼裡啪智慧·財稅產品技術 VP 張芳:DI 和 AI 雙引擎智慧財稅保駕護航

圖為噼裡啪智慧·財稅產品技術VP 張芳(中間),高階產品經理張晶(左三),高階產品經理 陳浩(右三),產品經理 李慧凝(左二),架構師 朱孟欣(右二),高階研發經理 李忠敏(左一),架構師 郭煥猛(右一) 說起噼裡啪智慧·財稅,大多數人很容易會聯想到噼裡啪啦的算盤聲,而噼

移動終端安全管理,築泰防務云警務辦公保駕護航

在國家推動智慧新警務的大環境下,各地區開始不斷的將“智慧新警務”深入到實際應用中,移動終端以強大的靈活 性、便捷性、功能性成為此次國家政策推動下的重要載體。但隨著移動終端的普及和大規模應用,移動警務終端安全出現了一系列的問題。 移動終端公面臨六大安全風險: 員工主動洩密,給企業帶來資料洩露的損失 根

移動終端安全管理,築泰防務雲警務辦公保駕護航

政策 數據查詢 理念 企業應用 移動安全 不能 roi 公司 隱患 在國家推動智慧新警務的大環境下,各地區開始不斷的將“智慧新警務”深入到實際應用中,移動終端以強大的靈活 性、便捷性、功能性成為此次國家政策推動下的重要載體。但隨著移動終端的普及和大規模應用,移動警務終端安全

阿里雲ECS彈性裸金屬(神龍)伺服器雙11保駕護航

每年阿里巴巴天貓雙11購物節,既是一次全民的狂歡,也是阿里技術人的一次大考和閱兵場,對阿里雲ECS彈性計算團隊更是如此,作為IaaS層最核心的產品,每年雙11承擔的業務交易量也越來越大,阿里巴巴電商核心交易鏈路系統穩定、峰值交易效能、每筆交易的服務響應延遲等都對ECS彈性計算有著苛刻地要求。為了保障雙11核心

Java高併發(六)——ThreadLocal執行緒保駕護航

       前邊我們講述多執行緒互動,多執行緒引起的安全問題,多執行緒安全的問題解決同步(synchronized、lock、CAS)……這一切的一切起源就是共享資源,共享臨界區的資料安全引起的。那我們從另外一個角度想想呢?每個執行緒有自

OCR私有云識別,企業安全保駕護航

隨著科技日益發展進步,許多新鮮的名詞出現在人們的視野當中。比如說‘雲’,‘區塊鏈’,的概念,再細分可能有什麼公有云,私有云,很多人就直接懵了,覺得很複雜,但其實也很簡單,打個比方,咱們坐車,公交地鐵相當於公有云,轎車自行車相當於私有云。咱們今天要說的主角就是文通

東莞中科藍海智慧視覺科技有限公司——軌道交通保駕護航

12月25日上午,中國中車株洲電機有限公司軌道交通本部副總經理袁明亮率團考察調研,中科藍海創始人譚良與CEO李清順熱情接待並帶領考察團一行參觀了中科藍海旗下的工程實驗室、中央研究院,展示了中科藍海目前所取得的階段性成果,期間雙方就具體的合作達成了共識。 期間,考察團參觀了中科藍海旗下的工

拼多多釋出商家信用管理規則,守信經營者保駕護航

近日,拼多多釋出了《拼多多商家信用管理規則》,該規則將於2019年1月1日生效。據悉,規則生效後,拼多多會根據商家的信用評價情況,採取相應的激勵或懲戒措施。拼多多方面表示,釋出該規則的主要目的就是為增強商家的誠信意識,鼓勵商家為消費者提供優質的商品或服務,保障消費者合法權益。 拼多多正在加

阿裏雲爬蟲風險管理產品商業化,雲端流量保駕護航

服務器 ant 溝通 路徑 f2c 查詢 新品發布 批量 技術幹貨 爬蟲風險管理產品是阿裏雲雲盾推出的新安全產品,1月底正式宣布商業化上線,提供可以覆蓋Web/H5/API/APP多種業務形態的爬蟲風險解決方案,對爬蟲風險進行有序管理。 惡意爬蟲引發高風險隨著傳統行業互聯網

支付寶“風險大腦”支付平臺保駕護航

ref ofo 網絡借貸 無法 系統 平臺 風險識別 借貸 其中 4月2日,溫州市金融辦和螞蟻金服共同宣布:溫州“金融大腦”系統正式上線,未來將對溫州地區的P2P網絡借貸平臺進行風險識別和預警。數據顯示,過去一年,支付寶開發的“風險大腦”套系統已經開始立功——協助各地金融監

圖文詳解:記憶體總是不夠,我靠HBase說服了Leader新專案保駕護航

​ ​ 大家好,我是小羽 最近在工作中用到了 Hbase 這個資料庫,也順便做了關於 Hbase 的知識記錄來分享給大家。其實 Hbase的內容體系真的很多很多,這裡介紹的是小羽認為在工作中會用到的一些技術點,希望可以幫助到大家。 可以這麼說網際網路都是建立在形形色色的資料庫之上的,現在主流的資料庫有這麼幾種

請牢記以上幾點,做到更多人願意與

打開 san 無限 你會 並發 span 交朋友 col 若有 請牢記以上幾點,做到讓更多人願意與你為友。若有下一點,你會吸住更多人才的。 第一:你有用。你能帶給人家實用價值。 第二:你有料。跟你相處能打開眼界,放大格局。 第三:你有量。你能傾聽別人的想法並發表有價值的見

【轉載】博客園背景音樂調用,音樂的博文加點料

mode com single data 一半 網易 支持 span 什麽 【轉載】博客園背景音樂調用,讓音樂為你的博文加點料   單調的文字怎麽行,讓音樂為你的博文加點料。什麽?你寫的是技術型博客不搞這麽多文藝,大叔,技術

智能公交電子站牌報告實時交通信息,出行更方便

智能交通 智慧城市 智能公交站牌 電子公交站牌 近幾年,城市公交大力推進信息化、電子化建設,如構建無人售票系統,實行IC卡收費。隨著經濟的發展,人民生活水平的提高,人民對公共交通出行的要求也越來越高,乘客關註的不僅僅是能否順利出行,而是更多地關心公交車對於到站時間、車輛運行狀況等信息的實時發布

(java web後端方向)如何的簡歷爭取到更多的面試機會,內容來自java web輕量級開發面試教程

java web輕量級開發面試教程 我們在做培訓時,會發現一個不合理的情況,一些程序員能力不錯,在公司裏也是技術牛人,但發出去的簡歷往往會石沈大海,沒有回復。對於剛畢業的大學生或工作年限在2年之內的程序員,這個情況會更嚴重。 這種情況下,其實不是你的能力有問題,而是簡歷篩選人(往往是人事

介紹一個神器:Chimee,一套可擴展的 H5 視頻播放器解決方案

包括 api 人員 保持 打包 需求 解耦 日常 開發 Chimee(讀“奇米”, [t??‘m?:])是由奇舞團開源的一套 H5 視頻播放器解決方案,由奇舞團視頻雲前端團隊結合在業務和視頻編解碼方向的沈澱積累傾心打造。 Chimee 支持 MP4、M3U8、FLV 等

字典和列表性能哪家強,我用一百萬隨機字符來揭曉!

tro 哈希表 並發 快速 random模塊 符號 基礎 運行時 散列表 Python中有兩個非常常用的數據結構,列表和字典。在做數據存儲的時候,到底二者哪家強,字典還是列表,還是差不多呢。與其猜測,不如我們用數據說話! 思路: 生成一個很大的文本文件分別用列表和字典來存儲

摩天都市裡,“她”遮蔽一切浮華!

這寸土寸金的城市裡,能擁有一套房子成了大部分人的一種奢望。摩天都市裡,唯有家,是遮蔽一切浮華的港灣。忙碌完回到家,一款舒適的沙發,能讓全身心都能得到放鬆。不管是休息、看電視、聽音樂還是閱讀,都需要舒服的姿勢。 沙發是家裡的第二張床,作為客廳的中心配置,已成為裝修設計的標配。市場上沙發品類繁多,想要挑到一款稱