背景

前几天一个小伙伴发邮件问我,他在docker内部使用gdb调试时刻遇到了gdb如下报错信息
ptrace:Operation not permitted
当时我的答复是在docker create或者docker run时刻开启万精油--privileged参数。小伙伴的问题就此解决了。
但是事实并非如此简单

Docker上涉及到gdb调试权限的特性

capabilities

Docker借用了linux对进程设置capabilities,而其子进程继承父进程capabilites特性来完成对容器capacities的控制。Docker create和docker run参数中有下面两个参数可以对容器默认的capabilites进行修改:
--cap-add //添加某个capabilites属性 --cap-del //剔除某个默认的capabilites属性
cap-add和cap-del可以设置的参数可以通过下面链接查询到:
https://docs.docker.com/engine/reference/commandline/run/

  • Docker 将gdb调试需要SYS_PTRACE属性被禁止掉了,所以gdb在调试的时候会显示ptrace被禁止。所以想在docker内部调试gdb解决办法就是create和run的时候带上--cap-add sys_ptrace*
    例如:
docker run  -it --cap-add sys_ptrace centos:latest /bin/bash
root@7f5a2130e975>cd /home/
root@7fa2130e975> vi test.c
\#include <stdio.h>
int main(){int i = 0;printf(“Testing begin\n”);While(1){printf(“Loop cnt:%d\n”,i++);sleep(10);   }}root@7fa2130975>gcc -c -g -o test.o test.c
root@7fa2130975>gcc -o test -g test.o
root@7fa2130975>./test&
[1] 18
root@7fa2130975>gdb attach 18
//ok可以调试了

但是这并不是问题的全部,对于上述测试程序,如果执行下面命令gdb又有告警出来

root@7fa2130975>gdb ./test
(gdb) r
Warning:Error disabling address space randomization:Operation not permitted

虽然依然可以调试,但是我们还是需要搞清楚上述告警的意思。地址随机化是linux一项安全特性,它允许内核进程启动每次加载库的时候都在随机化的分布在进程虚拟内存地址空间上(早期固定的库要加载到固定地方,如果固定地方被占用才加载到别地方。会造成多次加载程序,其库地址都不变。如此有安全隐患)。在gdb调试中gdb默认需要关闭linux的地址随机化功能,可以通过gdb 命令set disable-randomization off关闭。如果在地址随机化下调试同一段程序,多次run时候可以看到它的运行地址和函数地址不一致,这没有什么太大的问题。问题可以结束了
关于gdb 设置地址随机化开关详情见下面链接:
http://visualgdb.com/gdbreference/commands/set_disable-randomization
当然上述告警其实也可以不通过gdb设置来完成,可以通过下面介绍的Docker参数可以达成。

seccomp

Docker默认情况下为每个容器都设置了一个默认的seccom profile。一般情况下无需修改。但是docker依然支持
docker create或者docker run时候通过--security-opt seccomp=xxx参数来设置docker容器的seccomp策略。
xxx可以是一个json格式文件,里面定义了docker容器每个具体的seccomp规则。也可以是字符unconfined表示关闭默认的docker seccomp 规则。
可以通过下面命令彻底关闭docker默认seccomp引入的任何限制
docker run -it --security-opt seccomp=unconfined centos:lastes
在运行上述gdb 调试命令run一个进程,告警信息终于彻底消失了。
Docker设置的seccomp 默认profile规则可以通过如下链接查询到:
https://docs.docker.com/engine/security/seccomp/
本文就不再做详细展开了。

Docker背后的实现技术

Docker实现seccomp控制

从Linux 2.6.23开始支持这种特性对进程能够使用的系统调用进行控制,如此可以进行一些安全性策略。sandbox就是依赖于此技术。docker梳理了Linux的系统调用,从300+个系统调用中屏蔽掉了44个系统调用,但是又最大程度的不影响正常的应用使用系统。

  • 在Docker engine上有一个叫seccomp模块提供了为docker提供默认seccomp规则(GetDefaultProfile()函数),而我们在命令行配置的seccomp属性会覆盖默认的seccomp规则(在setSeccomp()函数里)。最终规则在engine内部创建runc spec时刻函数createSpec生产。将seccomp传递到oci runtime spec的spec.linux.seccomp字段里。
  • 而runc通过seccomp库的InitSeccomp()函数,在Init一个容器时刻和exec触发的将一个进程setns到容器内部时刻调用此函数 将seccomp属性设置到容器的init进程或者exec进程里。
  • Linux进程属性里有seccomp属性,此属性也会父子继承,通过/proc/$pid/status里可以看到进程的seccomp属性。

Docker实现capabilities

从Linux 2.1开始支持的特性,将超级用户的权限划分为多个组,每个进程都有一个capabilities属性,子进程从自己的父进程中基础capacities。这个特性和sudo不一样,因为sudo控制粒度太粗;而capabilities控制粒度很精细。linux有一系列的调用可以设置、查看,清除和比较进程的capabilities。可以通过:
man cap_set_flag
来查看这一系列的系统调用。而具体进程的capacities可以通过/proc/$pid/status中:
Capxxx字段看到,本文就不再展开。感兴趣的朋友可以参考
https://www.cnblogs.com/iamfy/archive/2012/09/20/2694977.html

  • 在oci runtime spec里规定了spec.Process.Capabilities属性。runc中finializeNamespace()根据此属性对进程的capabilities进行设置。此函数会在init容器和exec加一个进程到容器时刻调用。

为什么在Docker里使用gdb调试器会报错相关推荐

  1. GDB调试器使用手册

    GDB调试器使用手册     使用GDB:     本文描述GDB,GNU的原代码调试器.(这是4.12版1994年一月,GDB版本4.16) * 目录: * 摘要:                  ...

  2. 使用GDB调试器(一)

    使用GDB调试器 GDB概要 ---- GDB是GNU开源组织公布的一个强大的UNIX下的程序调试工具.也许,各位比較喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但假设你是在UNIX平台下做 ...

  3. GDB调试器源代码分析系列--Inferior call的实现与分析(1)

    [转] GDB调试器源代码分析系列--Inferior call的实现与分析(1) (2011-10-11 20:41) 标签: 分析 分类: 调试器 先说说几个概念: (1)     什么是infe ...

  4. Linux调试——gdb调试器的简单使用调试coredump文件

    文章目录 一.背景 二.gdb的指令与使用 1.gdb的基本指令. 2.gdb指令的简单使用 1.进入gdb模式 2.实例说明 三.调试coredump文件 前提:本质上是在调试程序崩溃之后的内存镜像 ...

  5. GCC编译器和GDB调试器常用选项

    GCC编译器 gcc hello.c -o hello                   #将hello.c编译成hello可执行文件 gcc -E hello.c -o hello.i       ...

  6. [转载].gdb调试器快速入门

    调试在我们编写程序时占有重要的地位.在linux下如何使用gdb调试器?下面采用FQA的方式让你快速了解gdb调试器. 1.如何启动gdb调试器呢? 在终端输入 gdb 程序文件名 即可.注意gdb调 ...

  7. 【Linux学习】GDB调试器基本命令必知必会(一)

    本文介绍Linux下GDB调试器常用的基本命令. 测试均在Ubuntu12.10下完成. 先看看GDB调试的效果图: 对应的源代码: //插入排序,GDB调试测试代码 #include <std ...

  8. linux卸载gdb命令,【Linux学习】GDB调试器基本命令必知必会(一)

    本文介绍Linux下GDB调试器常用的基本命令. 测试均在Ubuntu12.10下完成. 先看看GDB调试的效果图: 对应的源代码: //插入排序,GDB调试测试代码 #include int x[1 ...

  9. ROS机器人程序设计(原书第2版)3.1.2 ROS节点启动时调用gdb调试器

    3.1.2 ROS节点启动时调用gdb调试器 我们需要一个启动文件(launch)去启动节点,如下: 想要在节点启动时调用gdb调试器,需要添加launch-prefix="xterm -e ...

最新文章

  1. sqlserver安装和简单的使用
  2. 微量元素与中医药 谋定·大健康医药-李喜贵:辩证研究病理变化
  3. 按住 ctrl 并滚动鼠标滚轮才可缩放地图_ZBrush自定义缩放快捷键
  4. [hls]m3u8视频如何处理成加密?
  5. 详细解释到底啥是共轭先验(用本科知识来解释)
  6. Android merge优化UI
  7. ios 怎么判断字符串的字节数_如何用IOS判断字符串是不是纯数字
  8. php把buffer转化为图片_干货:如何提升转化率?5个优化转化率的tips
  9. ibm服务器怎么收集日志信息,IBM X86 服务器Linux下收集DSA日志方法(包含BMC信息)...
  10. 50: 加密与解密 、 AIDE入侵检测系统 、 扫描与抓包 、 总结和答疑
  11. 网络安全等级保护概述
  12. dingo php,dingo/api 使用
  13. BuuCTF_crypto(2021.10.8新-->旧)
  14. 中国微团·国京酒业:白酒进入人体后
  15. input常见输入限制及金额转货币
  16. vue input 中文输入法回车
  17. ADB 安装、卸载apk、卸载系统应用、compileDebugJavaWithJavac问题、打印详细的log等
  18. 关于rx,tx或I2C串口不够的问题
  19. TCP及UDP首部各个字段
  20. 前端实现微信小程序 支付密码输入框

热门文章

  1. 全球及中国垃圾发电行业运营管理及十四五投资价值评估报告2021-2027年
  2. 中国脚轮行业现状调研及投资决策建议报告2021-2027年
  3. 位居全国第一- 丰收节交易会·内蒙古:名特优新农产品数量
  4. 菲律宾谋定农业大建特建构想 对话国际农民丰收节贸易会
  5. vuex-class用法
  6. 1. CMake 系列 - 从零构建动态库和静态库
  7. Mysql数据备份恢复及主从同步
  8. LeetCode(69):x 的平方根
  9. ajax原理及其优缺点
  10. 五千字详解消息通知!