- 函数介绍
seccomp 是Linux系统调用过滤机制,用于限制进程可以执行的系统调用。它通过Berkeley Packet Filter (BPF) 程序来定义哪些系统调用是允许的,哪些是禁止的。seccomp 是构建沙箱环境、提高应用程序安全性的重要工具,可以有效防止恶意代码执行危险的系统调用。
- 函数原型
1 | #include <linux/seccomp.h> |
- 功能
seccomp 提供了系统调用级别的安全控制,可以:
限制进程可执行的系统调用集合
定义系统调用的执行策略(允许、错误、终止)
使用BPF程序实现复杂的过滤逻辑
构建安全的沙箱环境
- 参数
prctl方式:
int option: 控制选项(如PR_SET_SECCOMP)
unsigned long arg2: seccomp模式(SECCOMP_MODE_STRICT/SECCOMP_MODE_FILTER)
其他参数: 根据选项而定
seccomp系统调用:
unsigned int operation: 操作类型(SECCOMP_SET_MODE_STRICT/SECCOMP_SET_MODE_FILTER)
unsigned int flags: 标志位(通常为0)
*void args: 操作参数(BPF程序指针等)
- 返回值
成功: 返回0
失败: 返回-1,并设置errno
- 相似函数,或关联函数
prctl: 进程控制接口
personality: 设置进程执行特性
chroot: 改变根目录
capset: 设置进程权限
- 示例代码
示例1:基础seccomp使用
1 | #define _GNU_SOURCE |
示例2:自定义BPF过滤器
1 | #define _GNU_SOURCE |
示例3:只读沙箱环境
1 | #define _GNU_SOURCE |
示例4:进程监控和日志
1 | #define _GNU_SOURCE |
示例5:安全沙箱应用
1 | #define _GNU_SOURCE |
seccomp 使用注意事项
系统要求:
内核版本: 需要Linux 3.5或更高版本
data-ad-format="fluid" data-ad-layout-key="-7k+ex-4a-9w+4a">架构支持: 支持多种CPU架构
编译选项: 需要内核编译时启用CONFIG_SECCOMP
权限要求:
- CAP_SYS_ADMIN: 通常需要管理员权限2. 无特权进程: 可以使用SECCOMP_MODE_STRICT3. 容器环境: Docker等容器可能有限制
安全考虑:
- 策略不可逆: 一旦应用,seccomp策略不能放松2. 调试困难: 被阻止的系统调用可能难以调试3. 兼容性: 可能影响程序的正常功能4. 性能影响: BPF过滤会增加系统调用开销
最佳实践:
渐进式应用: 从宽松策略开始,逐步收紧
充分测试: 在生产环境前充分测试
错误处理: 妥善处理被阻止的系统调用
日志记录: 记录安全相关事件
备份方案: 提供策略失效时的处理方案
seccomp 模式详解
SECCOMP_MODE_STRICT (模式1):
特点: 最简单的模式,只允许read/write/exit/exit_group
优点: 简单、高效、安全
缺点: 功能极其有限
适用: 极度安全要求的简单程序
SECCOMP_MODE_FILTER (模式2):
特点: 使用BPF程序定义复杂过滤规则
优点: 灵活、功能强大
缺点: 配置复杂
适用: 大多数实际应用场景
常见系统调用编号
x86_64架构:
SYS_read = 0
SYS_write = 1
SYS_open = 2
SYS_close = 3
SYS_stat = 4
SYS_fstat = 5
SYS_lstat = 6
SYS_poll = 7
SYS_lseek = 8
SYS_mmap = 9
SYS_mprotect = 10
SYS_munmap = 11
SYS_brk = 12
SYS_rt_sigaction = 13
SYS_rt_sigprocmask = 14
SYS_rt_sigreturn = 15
SYS_ioctl = 16
SYS_pread64 = 17
SYS_pwrite64 = 18
SYS_readv = 19
SYS_writev = 20
SYS_access = 21
SYS_pipe = 22
SYS_select = 23
SYS_sched_yield = 24
SYS_mremap = 25
SYS_msync = 26
SYS_mincore = 27
SYS_madvise = 28
SYS_shmget = 29
SYS_shmat = 30
SYS_shmctl = 31
SYS_dup = 32
SYS_dup2 = 33
SYS_pause = 34
SYS_nanosleep = 35
SYS_getitimer = 36
SYS_alarm = 37
SYS_setitimer = 38
SYS_getpid = 39
SYS_sendfile = 40
SYS_socket = 41
SYS_connect = 42
SYS_accept = 43
SYS_sendto = 44
SYS_recvfrom = 45
SYS_sendmsg = 46
SYS_recvmsg = 47
SYS_shutdown = 48
SYS_bind = 49
SYS_listen = 50
SYS_getsockname = 51
SYS_getpeername = 52
SYS_socketpair = 53
SYS_setsockopt = 54
SYS_getsockopt = 55
SYS_clone = 56
SYS_fork = 57
SYS_vfork = 58
SYS_execve = 59
SYS_exit = 60
SYS_wait4 = 61
SYS_kill = 62
SYS_uname = 63
SYS_semget = 64
SYS_semop = 65
SYS_semctl = 66
SYS_shmdt = 67
SYS_msgget = 68
SYS_msgsnd = 69
SYS_msgrcv = 70
SYS_msgctl = 71
SYS_fcntl = 72
SYS_flock = 73
SYS_fsync = 74
SYS_fdatasync = 75
SYS_truncate = 76
SYS_ftruncate = 77
SYS_getdents = 78
SYS_getcwd = 79
SYS_chdir = 80
SYS_fchdir = 81
SYS_rename = 82
SYS_mkdir = 83
SYS_rmdir = 84
SYS_creat = 85
SYS_link = 86
SYS_unlink = 87
SYS_symlink = 88
SYS_readlink = 89
SYS_chmod = 90
SYS_fchmod = 91
SYS_chown = 92
SYS_fchown = 93
SYS_lchown = 94
SYS_umask = 95
SYS_gettimeofday = 96
SYS_getrlimit = 97
SYS_getrusage = 98
SYS_sysinfo = 99
SYS_times = 100
SYS_ptrace = 101
SYS_getuid = 102
SYS_syslog = 103
SYS_getgid = 104
SYS_setuid = 105
SYS_setgid = 106
SYS_geteuid = 107
SYS_getegid = 108
SYS_setpgid = 109
SYS_getppid = 110
SYS_getpgrp = 111
SYS_setsid = 112
SYS_setreuid = 113
SYS_setregid = 114
SYS_getgroups = 115
SYS_setgroups = 116
SYS_setresuid = 117
SYS_getresuid = 118
SYS_setresgid = 119
SYS_getresgid = 120
SYS_getpgid = 121
SYS_setfsuid = 122
SYS_setfsgid = 123
SYS_getsid = 124
SYS_capget = 125
SYS_capset = 126
SYS_rt_sigpending = 127
SYS_rt_sigtimedwait = 128
SYS_rt_sigqueueinfo = 129
SYS_rt_sigsuspend = 130
SYS_sigaltstack = 131
SYS_utime = 132
SYS_mknod = 133
SYS_uselib = 134
SYS_personality = 135
SYS_ustat = 136
SYS_statfs = 137
SYS_fstatfs = 138
SYS_sysfs = 139
SYS_getpriority = 140
SYS_setpriority = 141
SYS_sched_setparam = 142
SYS_sched_getparam = 143
SYS_sched_setscheduler = 144
SYS_sched_getscheduler = 145
SYS_sched_get_priority_max = 146
SYS_sched_get_priority_min = 147
SYS_sched_rr_get_interval = 148
SYS_mlock = 149
SYS_munlock = 150
SYS_mlockall = 151
SYS_munlockall = 152
SYS_vhangup = 153
SYS_modify_ldt = 154
SYS_pivot_root = 155
SYS__sysctl = 156
SYS_prctl = 157
SYS_arch_prctl = 158
SYS_adjtimex = 159
SYS_setrlimit = 160
SYS_chroot = 161
SYS_sync = 162
SYS_acct = 163
SYS_settimeofday = 164
SYS_mount = 165
SYS_umount2 = 166
SYS_swapon = 167
SYS_swapoff = 168
SYS_reboot = 169
SYS_sethostname = 170
SYS_setdomainname = 171
SYS_iopl = 172
SYS_ioperm = 173
SYS_create_module = 174
SYS_init_module = 175
SYS_delete_module = 176
SYS_get_kernel_syms = 177
SYS_query_module = 178
SYS_quotactl = 179
SYS_nfsservctl = 180
SYS_getpmsg = 181
SYS_putpmsg = 182
SYS_afs_syscall = 183
SYS_tuxcall = 184
SYS_security = 185
SYS_gettid = 186
SYS_readahead = 187
SYS_setxattr = 188
SYS_lsetxattr = 189
SYS_fsetxattr = 190
SYS_getxattr = 191
SYS_lgetxattr = 192
SYS_fgetxattr = 193
SYS_listxattr = 194
SYS_llistxattr = 195
SYS_flistxattr = 196
SYS_removexattr = 197
SYS_lremovexattr = 198
SYS_fremovexattr = 199
SYS_tkill = 200
SYS_time = 201
SYS_futex = 202
SYS_sched_setaffinity = 203
SYS_sched_getaffinity = 204
SYS_set_thread_area = 205
SYS_io_setup = 206
SYS_io_destroy = 207
SYS_io_getevents = 208
SYS_io_submit = 209
SYS_io_cancel = 210
SYS_get_thread_area = 211
SYS_lookup_dcookie = 212
SYS_epoll_create = 213
SYS_epoll_ctl_old = 214
SYS_epoll_wait_old = 215
SYS_remap_file_pages = 216
SYS_getdents64 = 217
SYS_set_tid_address = 218
SYS_restart_syscall = 219
SYS_semtimedop = 220
SYS_fadvise64 = 221
SYS_timer_create = 222
SYS_timer_settime = 223
SYS_timer_gettime = 224
SYS_timer_getoverrun = 225
SYS_timer_delete = 226
SYS_clock_settime = 227
SYS_clock_gettime = 228
SYS_clock_getres = 229
SYS_clock_nanosleep = 230
SYS_exit_group = 231
SYS_epoll_wait = 232
SYS_epoll_ctl = 233
SYS_tgkill = 234
SYS_utimes = 235
SYS_vserver = 236
SYS_mbind = 237
SYS_set_mempolicy = 238
SYS_get_mempolicy = 239
SYS_mq_open = 240
SYS_mq_unlink = 241
SYS_mq_timedsend = 242
SYS_mq_timedreceive = 243
SYS_mq_notify = 244
SYS_mq_getsetattr = 245
SYS_kexec_load = 246
SYS_waitid = 247
SYS_add_key = 248
SYS_request_key = 249
SYS_keyctl = 250
SYS_ioprio_set = 251
SYS_ioprio_get = 252
SYS_inotify_init = 253
SYS_inotify_add_watch = 254
SYS_inotify_rm_watch = 255
SYS_migrate_pages = 256
SYS_openat = 257
SYS_mkdirat = 258
SYS_mknodat = 259
SYS_fchownat = 260
SYS_futimesat = 261
SYS_newfstatat = 262
SYS_unlinkat = 263
SYS_renameat = 264
SYS_linkat = 265
SYS_symlinkat = 266
SYS_readlinkat = 267
SYS_fchmodat = 268
SYS_faccessat = 269
SYS_pselect6 = 270
SYS_ppoll = 271
SYS_unshare = 272
SYS_set_robust_list = 273
SYS_get_robust_list = 274
SYS_splice = 275
SYS_tee = 276
SYS_sync_file_range = 277
SYS_vmsplice = 278
SYS_move_pages = 279
SYS_utimensat = 280
SYS_epoll_pwait = 281
SYS_signalfd = 282
SYS_timerfd_create = 283
SYS_eventfd = 284
SYS_fallocate = 285
SYS_timerfd_settime = 286
SYS_timerfd_gettime = 287
SYS_accept4 = 288
SYS_signalfd4 = 289
SYS_eventfd2 = 290
SYS_epoll_create1 = 291
SYS_dup3 = 292
SYS_pipe2 = 293
SYS_inotify_init1 = 294
SYS_preadv = 295
SYS_pwritev = 296
SYS_rt_tgsigqueueinfo = 297
SYS_perf_event_open = 298
SYS_recvmmsg = 299
SYS_fanotify_init = 300
SYS_fanotify_mark = 301
SYS_prlimit64 = 302
SYS_name_to_handle_at = 303
SYS_open_by_handle_at = 304
SYS_clock_adjtime = 305
SYS_syncfs = 306
SYS_sendmmsg = 307
SYS_setns = 308
SYS_getcpu = 309
SYS_process_vm_readv = 310
SYS_process_vm_writev = 311
SYS_kcmp = 312
SYS_finit_module = 313
SYS_sched_setattr = 314
SYS_sched_getattr = 315
SYS_renameat2 = 316
SYS_seccomp = 317
SYS_getrandom = 318
SYS_memfd_create = 319
SYS_kexec_file_load = 320
SYS_bpf = 321
SYS_execveat = 322
SYS_userfaultfd = 323
SYS_membarrier = 324
SYS_mlock2 = 325
SYS_copy_file_range = 326
SYS_preadv2 = 327
SYS_pwritev2 = 328
SYS_pkey_mprotect = 329
SYS_pkey_alloc = 330
SYS_pkey_free = 331
SYS_statx = 332
SYS_io_pgetevents = 333
SYS_rseq = 334
总结
seccomp 是Linux系统中强大的安全机制,提供了:
- 系统调用级别的访问控制: 精确控制进程可以执行的操作2. 灵活的策略定义: 通过BPF程序实现复杂过滤逻辑3. 高效的执行: 内核级别的过滤,性能开销小4. 广泛的应用场景: 适用于沙箱、容器、安全审计等
通过合理使用seccomp,可以显著提高应用程序的安全性,构建更加安全可靠的计算环境。在实际应用中,需要仔细设计过滤策略,充分测试,并考虑错误处理和调试需求。