Skip to content

c5ln/SecureTL

 
 

Repository files navigation

SecureTL (TL : Traversal Learnings)

SecureTL은 더욱 안전한 TL이다.
Split Learning과 Secure Multi-Party Computation(MPC)을 결합하여 데이터 프라이버시를 보장하면서 협력 학습을 수행한다.
Orchestrator로 부터 받은 모델 Config 검증을 위해 WASM 샌드박스를 도입했다.
네트워크를 통한 원본 데이터 유출을 방지하기 위해 리눅스 커널 기능(namespace, seccomp-bpf)을 활용하여 프로세스 격리하고, 권한을 제어하였다.

Config 기반 동적 모델 생성

기존 TL++은 모델 아키텍처를 models.py에서 하드코딩하고 있다.
Secure TL은 모델 아키텍처를 하드코딩하지 않는다. JSON config 파일 하나로 모델 구조 전체를 정의하고, 런타임에 동적으로 PyTorch 모델을 생성한다.

Config 포맷

config/cnn_config.json에 레이어를 순서대로 정의한다.

[
  { "type": "conv2d", "args": [3, 64, 3], "kwargs": {"padding": 1} },
  { "type": "relu" },
  { "type": "maxpool2d", "args": [2, 2] },
  { "type": "flatten" },
  { "type": "linear", "args": [4096, 512] },
  { "type": "linear", "args": [512, 10] }
]

TLpp/dynamic_model.pyLayerBuilder클래스는 등록된 레이어 타입(conv2d, linear, relu, lstm, transformer_encoder_layer 등)을 args/kwargs로 인스턴스화한다. 코드 수정 없이 config만 바꾸면 다른 모델 아키텍처로 실험할 수 있다.

Config → Split Learning 모델 분할

Orchestrator가 config를 로드한 뒤 cut_layer 인덱스를 기준으로 분할한다.

config/cnn_config.json
        │
        ▼
  ┌─ node_config ──┐  ┌── orch_config ──┐
  │ Layer 0~4      │  │ Layer 5~end     │
  └────────────────┘  └─────────────────┘
        │                     │
  DynamicNodeNet       DynamicOrchestratorNet
  (각 Node에 전송)      (Orchestrator 보유)
  • Node 측: config[:cut_layer]DynamicNodeNet을 생성하여 로컬 데이터로 forward pass 수행
  • Orchestrator 측: config[cut_layer:]로 분류 레이어를 구성, activation을 받아 loss 계산 및 backward pass 수행

원본 데이터는 Node 밖으로 나가지 않으며, intermediate activation만 전송된다.

Config 검증 (WASM)

Orchestrator로부터 수신한 config JSON을 그대로 역직렬화하면 악의적 페이로드에 노출될 수 있다. 이를 방지하기 위해 Rust로 작성된 WebAssembly 모듈로 config를 사전 검증한다.

Orchestrator ──[JSON]──► Node
                          │
                    ┌─────▼──────────┐
                    │ WASM validator │  (Rust → wasm32 컴파일)
                    └─────┬──────────┘
                          │
                    검증 통과 시에만
                    모델 생성 진행

Node는 wasmtime 런타임 위에서 WASM 바이너리를 실행하고, 레이어 타입/인자 구조를 검증한 뒤에만 모델을 생성한다.
WASM 모듈은 샌드박스 내에서 실행되므로 검증 과정 자체가 호스트 시스템에 영향을 줄 수 없다.

프로세스 격리 (Namespace + Seccomp)

--isolated 플래그를 활성화하면 Node 하나가 3개의 격리된 프로세스로 분리된다.
각 프로세스는 Linux 커널 수준에서 서로 다른 보안 정책이 적용되어, 한 프로세스가 침해되더라도 다른 프로세스의 데이터에 접근하거나 외부로 유출할 수 없다.

아키텍처

┌─────────────────────────────────────────────────────────────────────┐
│                              Node                                   │
│                                                                     │
│  ┌───────────────────────┐  IPC (Queue) ┌────────────────────────┐  │
│  │      DataLoader       │◄────────────►│        Trainer         │  │
│  │                       │              │                        │  │
│  │  unshare(NEWNET)      │              │  unshare(NEWNET)       │  │
│  │  seccomp:             │              │  seccomp:              │  │
│  │   socket() ALL BLOCK  │              │   AF_INET/AF_INET6     │  │
│  │   execve()     BLOCK  │              │              BLOCK     │  │
│  │                       │              │   AF_UNIX    ALLOW     │  │
│  │  send as numpy array  │              │   (for torch IPC)      │  │
│  └───────────────────────┘              └───────────┬────────────┘  │
│                                                IPC  │  (Queue)      │
│                                      ┌──────────────┴────────────┐  │
│                                      │        Networker          │  │
│                                      │                           │  │
│                                      │  seccomp:                 │  │
│                                      │   AF_INET       ALLOW     │  │
│                                      │   other sockets BLOCK     │  │
│                                      │   execve()      BLOCK     │  │
│                                      │   PR_SET_NO_NEW_PRIVS     │  │
│                                      │                           │  │
│                                      │  Orchestrator/Helper comm │  │
│                                      └───────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

2중 커널 레벨 방어

각 프로세스에는 두 계층의 커널 수준 보안이 적용된다.

Layer 1 — Network Namespace (unshare)

unshare(CLONE_NEWUSER | CLONE_NEWNET) 시스템 콜로 프로세스를 빈 네트워크 네임스페이스에 배치한다. 네트워크 인터페이스(lo, eth0 등)가 존재하지 않으므로 AF_INET/AF_INET6 소켓으로는 어떤 외부 연결도 성립할 수 없다. AF_UNIX 소켓은 파일시스템 기반이므로 네임스페이스 격리 후에도 정상 동작한다.

Layer 2 — Syscall 필터링 (seccomp-bpf)

prctl(PR_SET_SECCOMP) 로 BPF(Berkeley Packet Filter) 프로그램을 설치하여, 프로세스가 호출할 수 있는 시스템 콜 자체를 제한한다.
필터는 커널에서 실행되므로 사용자 공간에서 우회할 수 없다.

프로세스별 보안 정책

프로세스 unshare(NEWNET) socket 정책 execve 정책 역할
DataLoader O 전체 차단 (AF_INET, AF_INET6, AF_UNIX 모두) 차단 데이터 읽기 전용. numpy 배열로 변환 후 Queue 전송
Trainer O AF_INET/AF_INET6 차단, AF_UNIX 허용 허용 PyTorch 학습. AF_UNIX는 torch IPC/CUDA에 필요
Networker X AF_INET만 허용, 나머지 차단 차단 Orchestrator/Helper와의 IPv4 소켓 통신 전담

DataLoader에는 가장 엄격한 정책(DataLoaderPolicy)이 적용된다. 모든 소켓 생성과 execve 시스템 콜이 차단되어, 데이터를 읽고 numpy 배열로 변환하는 것 외에는 아무 작업도 수행할 수 없다. torch 텐서 공유는 AF_UNIX 소켓 기반 파일 디스크립터를 사용하므로, numpy 배열로 변환하여 전송함으로써 소켓 없이도 IPC가 가능하다.

Trainer에는 TrainerPolicy가 적용된다. 외부 네트워크(AF_INET/AF_INET6)는 차단하되, torch의 multiprocessing IPC와 CUDA 드라이버가 요구하는 AF_UNIX 소켓은 허용한다.

Networker에는 NetworkerPolicy가 적용된다. Orchestrator/Helper 통신에 필요한 AF_INET 소켓만 허용하고, AF_INET6/AF_UNIX 등 나머지 소켓 family와 execve를 차단한다. IPC는 multiprocessing.Queue가 내부적으로 os.pipe()(pipe syscall)을 사용하므로 소켓이 불필요하다. 네트워크 통신이 핵심 역할이므로 네임스페이스 격리(unshare)는 적용하지 않되, PR_SET_NO_NEW_PRIVS로 권한 상승을 방지한다.

seccomp-BPF 필터 구현

BPF 필터는 커널의 seccomp_data 구조체를 직접 검사하는 바이트코드로 구성된다.

seccomp_data {
    nr      (offset 0)  ← syscall 번호
    arch    (offset 4)  ← 아키텍처 (AUDIT_ARCH)
    args[0] (offset 16) ← 첫 번째 인자 (예: socket family)
}

AF_INET 차단 필터 동작 흐름:

[0] 아키텍처 로드 (AUDIT_ARCH 검증)
[1] 아키텍처 불일치 → 프로세스 종료
[2] syscall 번호 로드
[3] socket() 아닌 경우 → ALLOW
[4] args[0] (socket family) 로드
[5] AF_INET → BLOCK (EPERM)
[6] AF_INET6 → BLOCK (EPERM)
[7] 그 외 → ALLOW

멀티 아키텍처 지원

seccomp 필터는 아키텍처에 따라 syscall 번호가 다르다. ArchConfig 추상 클래스로 이를 분리하고, 런타임에 platform.machine()으로 자동 감지한다.

아키텍처 AUDIT_ARCH socket execve execveat
x86_64 0xC000003E 41 59 322
ARM64 (aarch64) 0xC00000B7 198 221 281

IPC 통신

격리된 프로세스 간 통신은 multiprocessing.Queue를 사용한다. 타입이 지정된 IPCMessage를 통해 데이터 요청, 배치 할당, forward/backward 결과 등을 교환한다.

보안 요약

TL++는 다중 계층 보안을 통해 데이터 프라이버시를 보장한다.

계층 기술 방어 대상
데이터 분리 Split Learning 원본 데이터 미전송, activation만 교환
암호학적 보호 Additive Secret Sharing (3-Party MPC) activation/gradient 도청 방지
네트워크 격리 Linux Network Namespace (unshare) 프로세스의 외부 네트워크 접근 차단
시스템 콜 제한 seccomp-BPF 위험한 시스템 콜 자체를 커널 수준에서 차단
권한 상승 방지 PR_SET_NO_NEW_PRIVS 프로세스 권한 상승 불가
Config 검증 WebAssembly (Rust) 역직렬화 공격 방지

프로젝트 구조

├── TLpp/
│   ├── orchestrator.py          # 학습 코디네이터
│   ├── node.py                  # SecureNode / IsolatedNode
│   ├── helper.py                # MPC share 교환 서버
│   ├── protocol.py              # 바이너리 소켓 프로토콜 + secret sharing
│   ├── dynamic_model.py         # JSON → PyTorch 모델 빌더
│   ├── data.py                  # 학습 데이터 로더
│   └── utils.py                 # BatchScheduler, GradientAggregator
├── isolation/
│   ├── dataloader.py            # DataLoaderProcess (격리)
│   ├── trainer.py               # TrainerProcess (격리)
│   ├── networker.py             # NetworkerProcess (격리)
│   └── common/
│       ├── ipc.py               # IPCChannel, IPCMessage
│       ├── warden.py            # seccomp-BPF 필터 빌더/설치
│       ├── process_policy.py    # 프로세스별 샌드박스 정책
│       └── architecture_config.py  # 아키텍처별 syscall 번호
├── validator/
│   ├── validator.py             # WASM 검증기 래퍼
│   └── config_validator/        # Rust 소스 + 컴파일된 .wasm
├── config/
│   └── cnn_config.json          # CNN 모델 아키텍처 정의
├── Dockerfile
├── docker_manager.py
├── gui.py                       # gui
└── requirements.txt

실행 방법

설치

pip install -r requirements.txt
pip install -e .

주요 의존성: torch, torchvision, wasmtime (WASM 런타임), pyseccomp

플랫폼별 동작 방식

  • Linux: 네이티브 실행. unshare, seccomp 등 커널 기능을 직접 사용한다.
  • macOS / Windows: Node 실행 시 docker_manager.py가 Docker를 자동 감지하여 Linux 컨테이너 내에서 실행한다. 이미지 빌드도 자동으로 처리되므로, Docker Desktop을 설치하고 실행한 상태에서 동일한 명령어를 사용하면 된다. Orchestrator와 Helper는 모든 플랫폼에서 네이티브로 실행된다.

Standard Mode

# Orchestrator
python -m TLpp.orchestrator \
  --host 192.168.0.4 --port 8080 \
  --n_nodes 1

# Node (별도 터미널에서 n_nodes 수만큼 실행)
python -m TLpp.node \
  --host 192.168.0.4 --port 8080

Secure Mode (MPC)

3-Party MPC를 활성화하여 activation과 gradient를 secret sharing으로 보호한다.

# Orchestrator
python -m TLpp.orchestrator \
  --host [Orchestrator_IP] --port [Orchestrator_Port] \
  --helper_host [Helper_IP] --helper_port [Helper_Port] \
  --n_nodes [number of nodes] \
  --secure

# Helper
python -m TLpp.helper \
  --orch_host [Orchestrator_IP] --orch_port [Orchestrator_Port]\
  --node_host [Helper_IP] --node_port [Helper_Port]\
  --n_nodes [number of nodes]

# Node
python -m TLpp.node \
  --orch_host [Orchestrator_IP] --orch_port [Orchestrator_Port]\
  --node_host [Helper_IP] --node_port [Helper_Port]\
  --secure

Isolated Mode (프로세스 격리 + MPC)

Node를 3개의 격리된 프로세스로 분리하여 커널 수준 보안을 적용한다.

# Orchestrator + Helper는 Secure Mode와 동일

# Node (--isolated 추가)
python -m TLpp.node \
  --orch_host [Orchestrator_IP] --orch_port [Orchestrator_Port]\
  --helper_host [Helper_IP] --helper_port [Helper_Port]\
  --secure \
  --isolated

About

DINA Lab Secure TL project

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 94.0%
  • Rust 5.9%
  • Dockerfile 0.1%