一.基礎知識
1.Docker容器的安全性,很大程度上依賴於Linux系統自身,評
估Docker的安全性時,主要考慮以下幾個方面:
- Linux內核的命名空間機制提供的容器隔離安全
- Linux控制組機制對容器資源的控制能力安全。
- Linux內核的能力機制所帶來的操作權限安全
- Docker程序(特別是服務端)本身的抗攻擊性。
- 其他安全增強機制對容器安全性的影響。
2.命名空間隔離的安全
- 當docker run啓動一個容器時,Docker將在後臺爲容器創建一個獨立的命 名空間。命名空間提供了最基礎也最直接的隔離。
- 與虛擬機方式相比,通過Linux namespace來實現的隔離不是那麼徹底。
- 容器只是運行在宿主機上的一種特殊的進程,那麼多個容器之間使用的就還是同一個宿主機的操作系統內核。
- 在 Linux 內核中,有很多資源和對象是不能被 Namespace 化的,比如:時 間。
3.控制組資源控制的安全
- 當docker run啓動一個容器時,Docker將在後臺爲容器創建一個獨 立的控制組策略集合。
- Linux Cgroups提供了很多有用的特性,確保各容器可以公平地分 享主機的內存、CPU、磁盤IO等資源。
- 確保當發生在容器內的資源壓力不會影響到本地主機系統和其他 容器,它在防止拒絕服務攻擊(DDoS)方面必不可少。
4.內核能力機制
- 能力機制(Capability)是Linux內核一個強大的特性,可以提供細 粒度的權限訪問控制。
- 大部分情況下,容器並不需要“真正的”root權限,容器只需要 少數的能力即可。
- 默認情況下,Docker採用“白名單”機制,禁用“必需功能”之外的其他權限。
5.Docker服務端防護
- 使用Docker容器的核心是Docker服務端,確保只有可信的用戶才 能訪問到Docker服務。
- 將容器的root用戶映射到本地主機上的非root用戶,減輕容器和 主機之間因權限提升而引起的安全問題。
- 允許Docker 服務端在非root權限下運行,利用安全可靠的子進程 來代理執行需要特權權限的操作。這些子進程只允許在特定範圍內進行操作。
6.其他安全特性
- 在內核中啓用GRSEC和PAX,這將增加更多的編譯和運行時的安 全檢查;並且通過地址隨機化機制來避免惡意探測等。啓用該特性不需要Docker進行任何配置。
- 使用一些有增強安全特性的容器模板。
- 用戶可以自定義更加嚴格的訪問控制機制來定製安全策略。
- 在文件系統掛載到容器內部時,可以通過配置只讀模式來避免容 器內的應用通過文件系統破壞外部環境,特別是一些系統運行狀 態相關的目錄。
二.系統基礎安全實驗
1.docker與系統共享內核並且會在宿主機上產生相應的進程
[root@server1 ~]# docker run -it --name vm1 ubuntu
root@f1c5528bcddb:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@f1c5528bcddb:/# free -m
total used free shared buffers cached
Mem: 992 442 550 12 0 257
-/+ buffers/cache: 184 808
Swap: 2047 0 2047
[root@server1 ~]# docker inspect vm1 | grep Pid
"Pid": 3435,
"PidMode": "",
"PidsLimit": 0,
[root@server1 ~]# cd /proc/3435
[root@server1 3435]# ls
attr environ mem pagemap stat
autogroup exe mountinfo personality statm
auxv fd mounts projid_map status
cgroup fdinfo mountstats root syscall
clear_refs gid_map net sched task
cmdline io ns schedstat timers
comm limits numa_maps sessionid uid_map
coredump_filter loginuid oom_adj setgroups wchan
cpuset map_files oom_score smaps
cwd maps oom_score_adj stack
[root@server1 3435]# cd ns/
[root@server1 ns]# ll
total 0
lrwxrwxrwx 1 root root 0 Aug 7 09:51 ipc -> ipc:[4026532227]
lrwxrwxrwx 1 root root 0 Aug 7 09:51 mnt -> mnt:[4026532225]
lrwxrwxrwx 1 root root 0 Aug 7 09:50 net -> net:[4026532230]
lrwxrwxrwx 1 root root 0 Aug 7 09:51 pid -> pid:[4026532228]
lrwxrwxrwx 1 root root 0 Aug 7 09:51 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 Aug 7 09:51 uts -
2.cgroup
查看cgroup服務路徑
[root@server1 ~]# mount -t cgroup
依次查看cpu,內存和容器的目錄下的文件
注意:cgroup目錄下有對容器進行相應的限制的參數,如cpu,memory等,新建的容器的id會出現在相應限額的docker的目錄下,在memory目錄下新建目錄時直接會從上級目錄繼承.
查看內存,發現沒有限制
在linux系統中可以通過修改/etc/security/limits.conf文件來限制cpu內存
[root@server1 ~]# cd /etc/security/limits.d/
[root@server1 limits.d]# ls
20-nproc.conf
[root@server1 limits.d]# vim /etc/security/limits.conf
三.對cpu進行資源限制
1.cpu獨佔
[root@server1 ~]# cd /sys/fs/cgroup/cpu
[root@server1 cpu]# mkdir x1
[root@server1 cpu]# cd x1/
[root@server1 x1]# ls
cgroup.clone_children cpu.cfs_quota_us
cgroup.event_control cpu.rt_period_us
cgroup.procs cpu.rt_runtime_us
cpuacct.stat cpu.shares
cpuacct.usage cpu.stat
cpuacct.usage_percpu notify_on_release
cpu.cfs_period_us tasks
[root@server1 x1]# cat cpu.cfs_period_us
100000 ##限制的長度
[root@server1 x1]# cat cpu.cfs_quota_us
-1 ##沒有時間限制
[root@server1 x1]# dd if=/dev/zero of=/dev/null & ##佔用cpu
[1] 3951
[root@server1 x1]# top ##查看cpu的佔有百分比(只有一個cpu)
若有兩個cpu需要按下列操作:
[root@server1 x1]# cd /sys/devices/system/cpu/
[root@server1 cpu]# ls
[root@server1 cpu]# cd cpu0/
[root@server1 cpu]# echo 0 > online
[root@server1 cpu]# lscpu
注意:
1.cpu.cfs_period_us:cpu分配的週期(微秒),默認爲100000。
2.cpu.cfs_quota_us:表示該control group限制佔用的時間(微秒),默認爲-1,表示不限制。如果設爲50000,表示佔用50000/100000=50%的CPU。
2.對cpu資源進行限制(docker容器)
1.清除之前創建的容器
[root@server1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7c111fe00da9 ubuntu "/bin/bash" About an hour ago Up About an hour vm1
[root@server1 ~]# docker rm -f vm1
vm1
[root@server1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
、
2.對容器暫停,和解除暫停
[root@server1 ~]# cd /sys/fs/cgroup/
[root@server1 cgroup]# ls
blkio cpu,cpuacct freezer net_cls perf_event
cpu cpuset hugetlb net_cls,net_prio pids
cpuacct devices memory net_prio systemd
[root@server1 cgroup]# cd freezer/
[root@server1 freezer]# ls
cgroup.clone_children cgroup.sane_behavior release_agent
cgroup.event_control docker tasks
cgroup.procs notify_on_release
[root@server1 freezer]# cd docker/
[root@server1 docker]# ls
cgroup.clone_children freezer.self_freezing
cgroup.event_control freezer.state
cgroup.procs notify_on_release
freezer.parent_freezing tasks
[root@server1 docker]# cat freezer.state
THAWED ##顯示開啓狀態
創建容器,並暫停
[root@server1 docker]# docker run -it --name vm1 ubuntu
root@797f2da104ec:/# [root@server1 docker]#
[root@server1 docker]# ls
797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5
cgroup.clone_children
cgroup.event_control
cgroup.procs
freezer.parent_freezing
freezer.self_freezing
freezer.state
notify_on_release
tasks
[root@server1 docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
797f2da104ec ubuntu "/bin/bash" 29 seconds ago Up 27 seconds vm1
[root@server1 docker]# docker container pause vm1 ##暫停容器vm1
vm1
[root@server1 docker]# cd 797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5
[root@server1 797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5]# ls
cgroup.clone_children freezer.self_freezing
cgroup.event_control freezer.state
cgroup.procs notify_on_release
[root@server1 797f2da104ecda43a84eb833d2ed49900e6c5216ad604978[root@server1 797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5]# cat freezer.state FROZEN ##暫停狀態
[root@server1 797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5]# cat tasks
4382 ##進程id
[root@server1 797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5]# ps ax ##進程4382顯示暫停
打開暫停容器進程
[root@server1 797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5]# docker container unpause vm1
vm1
[root@server1 797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5]# cat freezer.state
THAWED
[root@server1 797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
797f2da104ec ubuntu "/bin/bash" 7 minutes ago Up 7 minutes vm1
[root@server1 797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5]# cat tasks
4382
[root@server1 797f2da104ecda43a84eb833d2ed49900e6c5216ad60497865c5d269bce4faf5]# ps ax
設置swap和內存總共的大小(針對docker容器)
[root@server1 ~]# docker run -it --name vm1 --memory 300MB --memory-swap 300MB ubuntu
root@4057f95e93bf:/# free -m
total used free shared buffers cached
Mem: 992 442 550 12 0 261
-/+ buffers/cache: 179 813
Swap: 2047 0 2047
root@4057f95e93bf:/# [root@server1 ~]#
[root@server1 ~]# free -m
total used free shared buff/cache available
Mem: 992 133 558 12 300 695
Swap: 2047 0 204
安全加固
1.容器中的內存信息和主機中的內存信息
[root@server1 ~]# docker run -it --name vm1 --memory 300MB --memory-swap 300MB ubuntu
root@4057f95e93bf:/# free -m
total used free shared buffers cached
Mem: 992 442 550 12 0 261
-/+ buffers/cache: 179 813
Swap: 2047 0 2047
root@4057f95e93bf:/# [root@server1 ~]#
[root@server1 ~]# free -m
total used free shared buff/cache available
Mem: 992 133 558 12 300 695
Swap: 2047 0 2047
2.啓用lxcfs
1.安裝
[root@server1 ~]# ls
[root@server1 ~]# yum install lxcfs-2.0.5-3.el7.centos.x86_64.rpm -y
2.啓用(按enter)
[root@server1 ~]# cd /var/lib/lxcfs/
[root@server1 lxcfs]# ls
[root@server1 lxcfs]# lxcfs /var/lib/lxcfs/ &
[2] 4802
[root@server1 lxcfs]# hierarchies:
0: fd: 5: freezer
1: fd: 6: memory
2: fd: 7: net_prio,net_cls
3: fd: 8: devices
4: fd: 9: blkio
5: fd: 10: perf_event
6: fd: 11: hugetlb
7: fd: 12: cpuacct,cpu
8: fd: 13: cpuset
9: fd: 14: pids
10: fd: 15: name=systemd
[root@server1 lxcfs]#
3.啓動lxcfs之後,會在/var/lib/lxcfs目錄下生成兩個目錄
[root@server1 ~]# cd /var/lib/lxcfs/
[root@server1 lxcfs]# ls
cgroup proc
如果在/var/lib/lxcfs目錄下啓動的lxcfs,之後需要重新進入纔可以看到新生成的目錄
[root@server1 lxcfs]# ps ax | grep lxcfs
4802 pts/0 Sl 0:00 lxcfs /var/lib/lxcfs/
測試:
創建容器,限制內存發現限制成功
[root@server1 ~]# docker run -it --name vm1 --memory 300MB --memory-swap 300MB \
> -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \
> -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
> -v /var/lib/lxcfs/proc/stat:/proc/stat:rw \
> -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
> -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
> ubuntu