Skip to content

Linux:Kernel:Security

Discretionary Access Control (Unix DAC)

UID, GID, Permission 등을 이용한 접근제어 기능을 의미한다. 리눅스 역시 UNIX 의 이 모델을 그대로 사용한다.

POSIX ACLs (Extended DAC)

Unix DAC 를 개선한 표준을 만들기 위한 여러 노력이 있었는데, 그 중 하나가 POSIX ACLs 이며, 리눅스에 적용되어 있다.

Unix DAC 와 같은 컨셉이지만, 더 디테일한 설정이 가능하다. 예를 들면, test.txt 파일에 대해, 소유자 이외의 사용자(other) 에게 아무런 권한이 없다고 하자. POSIX ACL 을 이용하면,, 다른 사용자 중 JB에게만 읽기 권한을 주는 것이 가능하다.

POSIX Capabilities

전통적인 super user (root) 기반의 시스템 관리 권한을 좀 더 세분화하는 것이다. 즉, 특정 실행 파일에 대해 root 가 가질 수 있는 능력을 제한할 수 있는 것이다.

예를 들면, a.out 파일은 root 권한으로 실행되더라도 ==> "UID, GID 변경 불가", "kill 시그널 전송 불가" 등의 제한을 둘 수 있는 것이다. 이 때, "UID, GID 변경 불가" ==> 이러한 각 항목을 "capability" 로 명칭한다.

Linux namespaces

프로세스로써 볼수 있는 것들을 제한. partitioning 혹은 isolation 을 가능하게 해주는 기능.

  • 보안을 위해 나온 기능은 아니지만, 보안을 위해 사용될 수 있다.
  • 네임스페이스는 여러 개를 만들어 낼 수 있으며,, 프로세스 하나가 네임스페이스 하나에 포함되는 형태이다.
  • 네임스페이스는 리눅스 컨테이너의 기반이 된다.
  • 현재 리눅스에서 하나의 프로세스에 할당된 네임스페이스는 다음과 같은 여러 타입의 네임스페이스를 포함한다.
    • UTS: uname 명령어(system call) 를 통해 얻어지는 nodename, domainname 을 네임스페이스 별로 가질 수 있게 해준다.
    • IPC: SystemV IPC, Posix Message Queue 에 대해,, 같은 이름의 IPC object 를 서로 다른 네임스페이스에서 가질 수 있게 해준다.
    • VFS: 프로세스마다 root path 를 다르게 인식 가능한 것. chroot() 활용.
    • PID: 다른 namespace 의 프로세스는 서로 같은 PID 를 가질수 있다.
    • NETWORK: 서로 다른 네트워킹 리소스를 가질 수 있다.
      • 즉, network device, IP 주소, IP 라우팅 테이블 등의 정보를 네임스페이스 별로 다르게 할당할 수 있다.
      • 컨테이너 구성 시 유용한데, 컨테이너 마다 각기 다른 network device, IP 주소, 라우팅 테이블을 가져서, 다른 컨테이너와 통신 시 네트워킹 활용할 수 있다.
    • USER: uid, gid 스페이스를 격리시킨다. 프로세스의 uid, gid 가 네임스페이스 안, 밖에서 달라질 수 있다.
      • 이렇게 되면, uid=user 인 프로세스가, 자신의 네임스페이스에선 uid=root 로 인식되고, 밖에선 uid=user 로 인식됨. sandboxing 구성이 가능해진다.

Network Security

Netfilter

패킷 필터링 기능 제공하는 프레임워크.

Labeled Networking

NetLabel, CIPSO, Labeled IPSec and SECMARK.

network access control 을 label 기반으로 하는 것. (smack 의 label 처럼)

  • 기존에 network access control 하려면, iptables 과 같은 별도의 솔루션 이용해야 했지만, label 기반으로 하면 LSM 에서 통합관리 가능.
  • SELinux, Smack 에서 이 기능 지원.

넷필터 룰에 따라 packet 에 라벨링 하거나, 소켓에 라벨링을 한다.

NuFW

  • https://lwn.net/Articles/146120/
  • 리눅스 커널에 공식 포함된 기능은 아님.
  • 넷필터를 활용한 방화벽 기능 제공. 인증 기능을 추가하여 좀 더 나은 방화벽 기능 제공한다. (기존에는 IP, Port 기반으로만 했기 때문에, user 에 대한 고려가 없었다)
  • IP, PORT 뿐만 아닌, User 에 대한 Accee control 이 가능하다. performance 를 떨어뜨리지 않기 위해서, TCP 의 경우, 초기 handshake 과정 (SYN 패킷) 만 인증한다.

FileSystem

eCryptfs

Enterprise Cryptographic Filesystem. POSIX 의 file system 레벨 암호화 레이어에 맞게 구현되었다.

block device level 암호화와 file system level 암호화 (ecryptfs) 의 차이:

  • block device level 암호화 : FileSystem <-> Storage 로 read/write 과정에서 암복호화 된다. 즉, Storage 의 File Data 가 커널 메모리에 올라왔을 땐 복호화 된 상태인 것이다.
  • file system level 암호화 : FileSystem 자체에서 file, directory 각각을 암호화 하는 것이다. 이 방법의 장점은, file 이나 directory 별로 다른 key 로 암호화가 가능하다는 것이다.

Stackable file system 이다. lower (encrypted directory), upper (unencrypted directory). 이렇게 2개 Layer 로 나뉜다.

  • lower 는 main file system 을 말한다. 예를 들어 lower directory 가 ext4 마운트된 디렉토리 아래라면, ext4 파일 시스템인 것.
  • upper 가 실제 ecryptfs 파일 시스템이며, ecryptfs 파일시스템 코드에서 lower 와 암복호화를 통해 연결된다.

Storage

block device level 에 대한 보안 기능을 의미한다.

dm-verity

block device 의 integrity checking 을 담당한다. 검사하는 block device 는 read-only 여야만 한다.

  • Hash Tree (== group hash) 형태로 hash 를 한다.
  • VFS --> File System Driver --> Device Mapper --> dm-verity --> block devie --> physical disk
    • Storage 까지 저장되는 순서가 위와 같을 때, 리눅스 커널에선 Device Mapper 라는 Layer 가 있는데, 이 device mapper target 으로 dm-verity 가 구현된다.
    • (device mapper 에 대해선 잘 모름)

dm-crypt

block device 에 대한 encryption 기능을 제공한다.

Linux Security Module (LSM)

AppArmor, TOMOYO, Smack, SELinux, Yama : 리눅스 커널에 공식적으로 포함되어 있는 LSM 이다. (아래 나온 것들 중 다른 것들은 공식 포함되어 있지는 않음)

FBAC-LSM
http://schreuders.org/FBAC-LSM/
functionality-based application restrictions. 즉, application 이 할 수 있는 기능을 제한하는 것이다.
리눅스 커널에 공식 포함되어 있진 않다.
Yama
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/security/Yama.txt?id=HEAD
리눅스 커널에 공식 포함되어 있는 LSM.
adds restrictions to ptrace, providing a programmatic way to declare relationships between processes
ptrace 사용에 대한 접근제어를 가능하게 해준다. 즉, 악의적인 프로세스가 ptrace 를 통해 다른 process 에 개입하지 못하도록 하는 것이 목적이다.
/proc/sys/kernel/yama/ptrace_scope ==> 이 값에 따라 ptrace attach 관련 정책이 변경된다.
gresecurity
https://grsecurity.net/features.php
https://en.wikibooks.org/wiki/Grsecurity
extensive security enhancement patch for the Linux kernel (RBAC, chroot hardening, auditing, stack/heap protection randomization and more...)
리눅스 커널에 공식 포함되어 있지 않다.
단순 LSM 이라고 보긴 어려움. 단순 access contol 이 아니라, Linux Kernel Security 전반을 향상시키기 위한 솔루션임.
엄청나게 많은 보안 feature 를 제공함. LSM 과도 함께 사용 가능.
커널 패치가 필요하다. gcc plugin 을 통한 기능도 제공.
제공하는 기능을 크게 나누면 Memory Corruption Defenses (ROP defense, ASLR, stack overflow 등), FileSystem Hardening, Miscellaneous Protections, RBAC (=MAC), GCC Plugins
RSBAC (Rule Set Based Access Control)
https://en.wikipedia.org/wiki/RSBAC
https://www.acsa-admin.org/secshelf/book001/09.pdf
리눅스 커널에 공식 포함되어 있지 않다.
RSBAC == RBAC (Role Based Access Control). 2개는 같은 뜻으로 사용한다.
LSM 을 활용하지 않고, 자체 후킹 코드를 이용하여 General Framework 를 구현하고 있다.
기능은 SELinux 와 흡사함.

Integrity

승인된 (변조되지 않은) 프로그램만 실행해주는 것. TPM chip 을 이용하여 인증되지 않은 프로그램 실행되지 않게 해주고, good code 만 실행시켜줌.

EVM (Extended Verification Module)
특정 파일 데이터와 metadata 에 대하여 hash, 이 hash 값을 TPM 으로 서명하는 작업을 담당.
즉, 실행 파일 변조를 보호하는 것이 EVM 의 역할이다.
IMA (Integrity Measurement Architecture)
mmap() 사용 추적한다. 실행코드로서 매핑된 파일의 memory 영역을 hash 한다. 그리고 이 영역을 계속 tracking 한다. (이 영역을 TPM 으로 서명??)
즉, 현재 실행중인 실행파일의 실행코드를 인증하는 것이 IMA 의 역할이다.

EVM, IMA 를 함께 생각해보면,, offline file 변조는 EVM 이 막고,, running file 의 메모리 변조는 IMA 가 막는다.

LIM (Linux Integrity Module)
https://lwn.net/Articles/287790/
초기 EVM, IMA 는 LSM 을 사용하였다. 하지만 LSM Stacking 이 안되는 것과, side effect 의 존재로, LIM 의 하나로 들어간다. 이를 통해 LSM 과 함께 동작 가능하다.
LSM 이 access control 을 위한 주요 위치에 hook 을 설치한 것처럼, LIM 도 integrity 체크를 위한 주요 위치에 hook 을 설치.

근데 코드 상에는 LIM 이라는 명시가 없음. hook 설치했다는 개념만 남아있고, IMA 에 그냥 합쳐진 듯.

Audit

Audit 은 커널의 주요 이벤트나 주요 상황을 기록하기 위해서 사용된다. 즉, Audit 에서 여러 이벤트 타입을 제공 (uapi/linux/audit.h). 커널의 여러 코드에서 상황에 맞는 이벤트 타입으로 Audit API 호출하여, 이벤트 기록하는 것이다.

  • LSM 과 다른 보안 기능들에서 Audit API 를 많이 사용한다. (audit_log() 가 주요 public api)
  • auditd 라는 유저데몬이 있다. 이 데몬은 Audit record 들을 파일에 기록하는 역할을 한다. /etc/audit/auditd.conf 가 configure 파일이다.

Seccomp

secure computing mode 의 약자. 프로세스가 호출할 수 있는 system call 을 제한하는 것이다.

seccomp() system call 을 통해 기능을 활성화시키면, 이를 호출한 프로세스에 있는 모든 fd 들에 대해서, read(), write(), exit(), sigreturn() 을 제외한 모든 system call 호출이 불가능해진다. (호출할 경우 SIGKILL 됨)

seccomp 에 filtering 기능이 더해진 것이, seccomp-bfp 이다. 이는, 차단할 시스템 콜과, 시스템 콜 인자에 대한 필터링을 추가할 수 있는 기능이다. 이 역시 seccomp() 시스템 콜을 통해 필터링 룰 설정 가능하다.

필터링 룰은 BPF (berkely packet filter) 의 포맷을 따른다.

리눅스 커널 문서에서는, 샌드박싱 기능을 위해 seccomp 를 활용할 수 있다고 되어있다.

Hardening

hardening 이란, 공격자가 리눅스 커널을 해킹하기 더 어렵게 만드는 것을 의미한다. 이 기능은 다양한 레벨에서 적용 가능하다.

Address Space Layout Randomization (ASLR)
user level 실행파일의 로딩되는 메모리를 랜덤화하는 것이다. 최근에는 Linux Kernel 의 메모리 로딩도 랜덤화하는 기능이 포함되었다.

== Platform Security (=Hardware Security) == 리눅스 커널은 여러 Hardware Security Feature 들을 Support 한다.

SMAP (supervisor mode access prevention)
https://lwn.net/Articles/517475/
intel cpu 의 security feature 이다. 리눅스 커널에서 이를 지원하기 위해 2012년에 추가되었다.
user --> kernel 접근 시 page fault 가 발생한다. 하지만 그 반대의 경우 kernel --> user. 이 시나리오에 대해선 접근 제어를 하지 않는다. 하지만 kernel 은 user 의 모든 부분을 접근 가능하기 때문에, 이는 위험할 수 있다. 따라서, kernel privilege 에서 user memory 접근을 막는 것. 이것이 SMAP 의 역할이다.
CR4 레지스터에 SMAP 을 위한 특정 비트를 추가. SMAP enable 이면, kernel 에서 user memory 접근 시 page fault 가 발생한다. STAC, CLAC 이라는 명령어도 새로 추가되어, 이게 SMAP enable/disable 해준다. (copy_to_user 등의 접근은 allow 되어야 한다)
SMAP 의 장점은 다음과 같다.
  • kernel 이 잘못된 user memory 를 읽거나 씀으로써 생기는 expolit 을 예방한다.
  • kernel 개발자의 실수 (user memory 접근에 관한) 를 쉽게 발견할 수 있다.
TPM (Trusted Platform Module)
암호화 키 저장, 암호화 연산이 가능한 Hardware Chip 규격을 의미한다.
2006년 이후의 많은 PC, 노트북들은 TPM 이 포함되어 출시되었다.
IOMMU (Input Output Memory Management Unit)
https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit
IOMMU 란 CPU<->MMU<->Physical Memory 의 컨셉을 DMA 가능한 버스에 적용한 것이다. 즉, 주변 기기<->IOMMU<->Physical Memory 형태가 된다.
  • 즉, DMA 를 할 때, 물리 메모리에 직접 접근하지 않고, 디바이스는 가상 메모리로 접근 -> IOMMU 에서 물리주소로 재매핑 하는 것이다.
  • 이를 통해 IOMMU 에서 memory protection 이 가능하다.
Intel ==> VT-d / ARM ==> SMMU 라는 이름으로 이 기능을 지원한다.
NX (Never Execute)
코드와 데이터 영역을 구분하여, 데이터 영역이 실행되지 않도록 하는 기술이다. 페이지 테이블의 특정 비트를 이용해서, 실행영역 메모리만 실행 가능하도록 해준다.
ARM 에서는 xn bit 로 사용된다.

Key (Key Retention Service)

key, 인증 토큰, cross-domain user mapping(??) 등을 커널에 보관하고, 요청 시 이를 제공해주는 서비스이다.

  • keyring: key 들의 집합.
  • user: user 에서도 access 가능한 키.
  • logon: kernel 에서만 access 가능한 키. (생성은 user 에서. access 는 kernel 에서만) 즉, user space 사용자가 자신의 데이터를 kernel 에 숨기고 싶을 때. 이럴 때 주로 사용한다.
  • Trusted Keys : TPM 에서 생성되고, TPM 에서 보관되는 키.
  • Encrypted Keys : 커널에서 생성되는 AES 키. master key 를 이용하여 보호된다. (master key == Trusted Key or user)
    • (user, logon 의 경우 모두, user-space 에서 key 를 kernel 에 전달하고, kernel 이 이를 보관하는 방식이다)

/proc/keys, /proc/key-users 를 통해 현재 커널에서 관리 중인 key 를 확인할 수 있다.

Kernel Self Protection

잘못된 커널 코드로 인해서 발생하는 버그들은 계속해서 생기고 있다. kernel self protection 이란, 이러한 결함을 해결하는 것을 말한다.

static checker (smatch, coverity, ..), dynamic checker (kernel configs, trinity, KASAN, ...),

Linux Containers

Linux Kernel 이 제공하는 기능을 이용하여 OS-Level 가상화 방법. (namespace, cgroup 등의 커널 기능을 이용하여 container 기능 제공)

LXC, LXD, (LXCFS) ==> canonical 에서 만든 컨테이너. LXC 는 2008년에 만들어진 컨테이너이며, LXD 는 2014년에 발표되어 현재 개발중인 발전된 컨테이너이다.

Docker ==> 현재 가장 Hot 한 컨테이너(?) 를 활용한 기술. LXC 가 컨테이너라고 한다면, Docker 는 컨테이너 기반의 App 을 배포하는 것에 초점이 맞춰진 오픈소스 프로젝트. Docker 는 libcontainer (자체 컨테이너 기술), libvirt, LXC, systemd-nspawn 등을 이용하여 컨테이너 동작 수행 가능하다.

See also

Favorite site