내 Mac / Linux 앱에 RoamSwitch의 진단 기능을 그대로
RoamSwitchKit(Mac)와 roamswitch-linux-kit(Linux)은 RoamSwitch 본체가 계산하는 보안 진단 결과를 Swift / Rust 코드에서 직접 참조할 수 있는 무료 오픈소스 클라이언트입니다. ARP 감시나 포트 스캔을 직접 구현하지 않고도 "지금 이 네트워크는 안전한가"를 자신의 앱에 통합할 수 있습니다.
🔒 왜 안전한가
- 읽기 전용: 잠금 전환, 포트 격리, 기기 배출 같은 조작계 API는 전혀 존재하지 않습니다. 이 패키지를 연결한 앱이 사용자 동의 없이 RoamSwitch의 설정을 변경할 수 없습니다.
- 완전 로컬: RoamSwitch 본체에 포함된 바이너리(macOS: RoamSwitchMCPServer / Linux: roamswitch-mcp)를 하위 프로세스로 실행하며 표준 입출력만으로 통신합니다. 텔레메트리는 전혀 전송하지 않습니다. 외부 호스트와 통신하는 도구는 옵트인(Mac에서는 Pro 전용)인 run_npm_audit_signatures(npm 레지스트리)뿐입니다. run_active_vuln_scan(기본값 비활성)은 127.0.0.1에 대한 프로브만 보내고, Mac의 get_exposed_ports는 노출된 포트마다 127.0.0.1로 HTTP GET을 1회 보내 헤더를 확인할 뿐입니다. 게이트웨이의 MAC 주소를 알아낼 때 Mac의 진단 계열 도구는 LAN 안의 게이트웨이에 ICMP ping을 보통 1회(MAC을 알아내지 못하면 몇 번까지) 보낼 수 있습니다. Linux의 get_security_report와 verify_security_findings는 LAN에 아무것도 보내지 않고 로컬 캐시에서 게이트웨이를 읽기만 합니다(get_guard_status처럼 게이트웨이의 MAC을 다시 알아내는 다른 도구는 ping을 1회 보낼 수 있습니다).
- 무료·오픈소스: MIT 라이선스로 공개되어 있어 누구나 소스 코드를 확인하고 자유롭게 통합할 수 있습니다.
패키지 매니저에 한 줄 추가
Package.swift의 dependencies에 추가하기만 하면 됩니다. macOS 12+, Swift 5.9+, RoamSwitch 1.3.0 이상 설치가 전제 조건입니다.
dependencies: [
.package(url: "https://github.com/lafine1211/RoamSwitchKit.git", from: "1.0.0")
]
Cargo.toml의 dependencies에 추가하기만 하면 됩니다. 안정판 Rust(2021 edition, tokio 비동기 런타임)와 roamswitch-mcp 바이너리를 포함한 RoamSwitch for Linux 설치가 전제 조건입니다.
[dependencies]
roamswitch-linux-kit = { git = "https://github.com/lafine1211/roamswitch-linux-kit", tag = "v0.1.0" }
간단한 메서드로 진단 결과 가져오기
import RoamSwitchKit
let client = try RoamSwitchClient()
let report = try await client.securityReport()
print(report.score, report.grade)
let ports = try await client.exposedPorts()
for port in ports.ports where port.overallRisk == "high" {
print(port.processName, port.port)
}
let status = try await client.guardStatus()
print(status.activeSecurityLevelLabel, status.isCurrentNetworkTrusted)
let urlReport = try await client.auditURLSafety(url: "https://apple.com.login-verify.xyz")
print(urlReport.score, urlReport.riskLevel) // e.g. 20, "dangerous"
use roamswitch_linux_kit::RoamSwitchClient;
let client = RoamSwitchClient::new(None, None)?;
let report = client.security_report().await?;
println!("{} ({})", report.score, report.grade);
let ports = client.exposed_ports(false).await?;
for port in ports.ports.iter().filter(|p| p.overall_risk.as_deref() == Some("high")) {
println!("{} {}", port.process_name, port.port);
}
let status = client.guard_status().await?;
println!("{} {}", status.active_security_level_label, status.is_current_network_trusted);
let url_report = client.audit_url_safety("https://apple.com.login-verify.xyz").await?;
println!("{} {}", url_report.score, url_report.risk_level); // e.g. 20, "dangerous"
읽기 전용 메서드
securityReport()
FileVault·SIP·Gatekeeper·방화벽·Wi-Fi 암호화 강도·ARP 스푸핑·외부 공개 포트 등 18개 항목을 종합 진단한 점수와 개선 권고를 가져옵니다.
exposedPorts(includeLocalOnly:)
현재 리스닝 중인 모든 포트를 나열하고, 외부에 공개된 포트는 알려진 위험 서비스(Redis/MongoDB 등) 판정을 포함한 상세 감사 결과를 가져옵니다. Mac에서는 노출된 포트마다 127.0.0.1로 HTTP GET을 1회 보내 헤더를 확인합니다.
guardStatus()
포트 가드, ARP 자동 대응, USB 가드, Bluetooth 가드, 웹/메일 다운로드 보호, DNS 위협 차단 상태 및 현재 보안 레벨을 조회합니다.
auditURLSafety(url:)
의심스러운 링크나 단축 URL을 분석하여 피싱, 유니코드 도메인 위장, 고위험 TLD를 기기 내에서 즉시 진단합니다 (Zero Telemetry).
기타 읽기 전용 메서드
| 메서드 | 개요 |
|---|---|
auditSecurityLogs(hours:) | 최근 보안 로그(Mac: Sudo 인증 실패, SSH 무차별 대입 시도, Gatekeeper 차단, XProtect 탐지 등 / Linux: Sudo 인증 실패, SSH 무차별 대입, 방화벽 차단, AppArmor 거부, ClamAV 탐지 등)를 집계하고 API 키나 토큰 등 민감 정보를 자동으로 마스킹한 뒤, 로그 패턴을 템플릿화한 신규 패턴 탐지 및 빈도 이상(통계적 스파이크) 탐지 결과도 반환합니다. Linux에서는 journal을 읽지 못한 경우(시간 초과 등) 집계의 0건을 '아무 일도 없었다'로 보지 않고 journalReadComplete가 false가 되며 journalError에 사유가 담깁니다. |
activeVulnScan() | 127.0.0.1 한정, 비파괴 방식의 실증형 취약점 검증입니다. 다른 호스트에는 연결하지 않지만 네트워크 요청을 보내는 도구이므로 기본값은 비활성이며 설정에서 옵트인해야 합니다. |
packageCveScan() | 설치된 패키지(Mac: Homebrew / Linux: dpkg・dnf・zypper・pacman)를 로컬 CVE 맵과 대조합니다. 네트워크 통신은 전혀 하지 않습니다. Linux에서는 패키지 목록을 가져오지 못했거나 시간 초과가 발생하면 '해당 없음'으로 처리하지 않고 complete가 false가 되며 incompleteReason에 사유가 담깁니다(끝내지 못한 결과는 이상 없음이 아닙니다). Ubuntu(20.04·22.04·24.04·26.04)에서는 Ubuntu 전용 데이터로 소스 패키지 이름과 소스 버전을 사용해, Ubuntu가 수정 버전을 이미 공개한 CVSS 7.0 이상의 CVE만 대조하므로 '해당 없음'이 알려진 CVE가 없다는 뜻은 아닙니다. 결과에는 ecosystem과 release가 추가되고 검출마다 binary(설치된 바이너리 패키지 이름)가 담기며, Ubuntu Pro로만 고칠 수 있는 수정에는 proOnly가 붙습니다. Ubuntu 파생판(Linux Mint, Pop!_OS 등)과 지원하지 않는 버전은 complete가 false가 되고 incompleteReason에 사유가 담기며 Debian 데이터로 바꾸지 않습니다. |
packageCveScanLanguages(watchedFolders:) | npm / PyPI / crates.io / RubyGems / Packagist / Go / Maven 등의 의존성 락파일을 동일한 로컬 CVE 맵과 대조합니다. 네트워크 통신은 전혀 하지 않습니다. |
canaryStatus() | 랜섬웨어 카나리아(미끼 파일) 배치 상태와 최근 50건까지의 탐지 인시던트를 반환합니다. |
portAnomalyIncidents() | 포트 이상 가드의 베이스라인 확보 상태, 현재 자동 차단 중인 포트, 최근 50건까지의 인시던트를 반환합니다. 현재 자동 차단 중인 포트는 타임스탬프가 없는 현재 상태의 스냅샷이며, 타임스탬프가 있는 인시던트 이력과는 다르다는 점을 응답 내 주석 필드로 명시하고 있습니다. |
runtimeThreatStatus() | XProtect의 악성코드 탐지로 이 Mac이 Air-Gap 격리되었는지와 그 발동 인시던트를 반환합니다. Air-Gap 원인을 파악하려면 가장 먼저 확인하세요. |
notificationHistory() | RoamSwitch가 보낸 알림(보안 로그 감사 이상, ClickFix 탐지 등)의 기록을 최근 1주일간, 최신순으로 반환합니다. |
각 반환 타입의 필드 정의는 GitHub의 README와 AGENTS.md에 Swift 타입 선언 그대로 실려 있습니다.
security_report()
LUKS/dm-crypt 디스크 암호화, UEFI Secure Boot, AppArmor/SELinux, sudo/SSH 설정, ARP 스푸핑, 외부 공개 포트 등 27개 항목을 종합 진단한 점수와 개선 조언을 가져옵니다.
exposed_ports(include_local_only)
현재 리스닝 중인 모든 포트를 나열하고, 외부에 공개된 포트는 알려진 위험 서비스(Redis/MongoDB 등) 판정을 포함한 상세 감사 결과를 가져옵니다. Mac에서는 노출된 포트마다 127.0.0.1로 HTTP GET을 1회 보내 헤더를 확인합니다.
guard_status()
포트 가드, ARP 자동 대응, USB 가드, Bluetooth 가드, 웹/메일 다운로드 보호, DNS 위협 차단 상태 및 현재 보안 레벨을 조회합니다.
audit_url_safety(url)
의심스러운 링크나 단축 URL을 분석하여 피싱, 유니코드 도메인 위장, 고위험 TLD를 기기 내에서 즉시 진단합니다 (Zero Telemetry).
기타 읽기 전용 메서드
| 메서드 | 개요 |
|---|---|
server_security_report() | Server Edition의 34개 항목 프로파일(커널 강화·컨테이너 격리·커널 CVE 노출·eBPF LSM)로 종합 진단합니다. |
run_active_vuln_scan() | 127.0.0.1 한정, 비파괴 방식의 실증형 취약점 검증입니다. 다른 호스트에는 연결하지 않지만 네트워크 요청을 보내는 도구이므로 기본값은 비활성이며 설정에서 옵트인해야 합니다. |
audit_secrets(text) | 텍스트·파일·디렉터리에서 API 키와 개인 키 유출을 탐지합니다(탐지된 값은 마스킹되어 출력). |
audit_security_logs(hours) | 최근 보안 로그(Mac: Sudo 인증 실패, SSH 무차별 대입 시도, Gatekeeper 차단, XProtect 탐지 등 / Linux: Sudo 인증 실패, SSH 무차별 대입, 방화벽 차단, AppArmor 거부, ClamAV 탐지 등)를 집계하고 API 키나 토큰 등 민감 정보를 자동으로 마스킹한 뒤, 로그 패턴을 템플릿화한 신규 패턴 탐지 및 빈도 이상(통계적 스파이크) 탐지 결과도 반환합니다. Linux에서는 journal을 읽지 못한 경우(시간 초과 등) 집계의 0건을 '아무 일도 없었다'로 보지 않고 journalReadComplete가 false가 되며 journalError에 사유가 담깁니다. |
get_app_help(query, topic) | RoamSwitch의 전체 기능 사양, 내부 동작, 모든 알림 메시지, 문제 해결을 망라한 공식 지식 베이스를 로컬에서 즉시 검색하여 정확한 설명과 권장 조치를 제공합니다. |
quarantine_status() | 악성코드 격리 Vault의 내용(원래 경로·탐지된 위협명·격리 일시·크기)을 반환합니다. |
canary_status() | 랜섬웨어 카나리아(미끼 파일) 배치 상태와 최근 50건까지의 탐지 인시던트를 반환합니다. |
package_cve_scan() | 설치된 패키지(Mac: Homebrew / Linux: dpkg・dnf・zypper・pacman)를 로컬 CVE 맵과 대조합니다. 네트워크 통신은 전혀 하지 않습니다. Linux에서는 패키지 목록을 가져오지 못했거나 시간 초과가 발생하면 '해당 없음'으로 처리하지 않고 complete가 false가 되며 incompleteReason에 사유가 담깁니다(끝내지 못한 결과는 이상 없음이 아닙니다). Ubuntu(20.04·22.04·24.04·26.04)에서는 Ubuntu 전용 데이터로 소스 패키지 이름과 소스 버전을 사용해, Ubuntu가 수정 버전을 이미 공개한 CVSS 7.0 이상의 CVE만 대조하므로 '해당 없음'이 알려진 CVE가 없다는 뜻은 아닙니다. 결과에는 ecosystem과 release가 추가되고 검출마다 binary(설치된 바이너리 패키지 이름)가 담기며, Ubuntu Pro로만 고칠 수 있는 수정에는 proOnly가 붙습니다. Ubuntu 파생판(Linux Mint, Pop!_OS 등)과 지원하지 않는 버전은 complete가 false가 되고 incompleteReason에 사유가 담기며 Debian 데이터로 바꾸지 않습니다. |
package_cve_scan_languages(watched_folders) | npm / PyPI / crates.io / RubyGems / Packagist / Go / Maven 등의 의존성 락파일을 동일한 로컬 CVE 맵과 대조합니다. 네트워크 통신은 전혀 하지 않습니다. |
verify_fim() | 약 150곳의 핵심 시스템 파일을 다시 해시하여 베이스라인과 비교해 변조를 검증합니다. root로 실행하면 결과에 추가 필드 recentIntrusionContext도 포함됩니다. 최근 변경마다 변경한 프로세스(계정·실행 파일·명령)와 그 프로세스가 속한 SSH 로그인(접속 출처·로그인 시각·인증 방식), 또는 확인하지 못한 이유가 들어갑니다. |
get_port_anomaly_incidents() | 포트 이상 가드의 베이스라인 확보 상태, 현재 자동 차단 중인 포트, 최근 50건까지의 인시던트를 반환합니다. 현재 자동 차단 중인 포트는 타임스탬프가 없는 현재 상태의 스냅샷이며, 타임스탬프가 있는 인시던트 이력과는 다르다는 점을 응답 내 주석 필드로 명시하고 있습니다. |
get_ebpf_incidents() | eBPF 런타임 가드의 현재 격리 상태와 발동 사유가 된 인시던트 이력을 반환합니다. Server Edition에서는 각 기록에 탐지부터 대응까지의 시간(밀리초. detect_to_receive_ms, receive_to_action_ms, detect_to_action_ms)이 더해지고, 결과에는 Falco 하트비트의 상태(heartbeat)도 포함됩니다. |
SSH 무차별 대입 가드(Server Edition과, sshd가 동작 중인 Client Edition)의 상태와 기록을 반환하는 get_ssh_guard_incidents()는 RoamSwitch 내부 크레이트(roamswitchkit)에는 있지만, 공개 중인 roamswitch-linux-kit에는 아직 반영되지 않았습니다.
각 반환 타입의 필드 정의는 GitHub의 README에 Rust 타입 선언 그대로 실려 있습니다.
이렇게 통합할 수 있습니다
아래는 Swift(Mac) 예시입니다. roamswitch-linux-kit(Linux)에서도 동일한 메서드(snake_case)로 똑같이 구현할 수 있습니다.
동기화·백업 앱
신뢰할 수 없는 네트워크에 연결되면 백그라운드 동기화를 일시 중지합니다.
let status = try await client.guardStatus()
if !status.isCurrentNetworkTrusted {
syncEngine.pauseBackgroundSync()
}
비밀번호 관리자
신뢰할 수 없는 네트워크에서는 자동 잠금 시간을 단축하는 등 보호 수준에 따라 동작을 바꿉니다.
let status = try await client.guardStatus() let lockTimeout: TimeInterval = status.isCurrentNetworkTrusted ? 300 : 30 vault.setAutoLockTimeout(lockTimeout)
개발자 도구·자동화
개발 서버가 0.0.0.0에서 대기를 시작할 때 경고하거나, Shortcuts 등으로 네트워크 신뢰도에 따른 워크플로를 구성합니다.
let ports = try await client.exposedPorts(includeLocalOnly: false)
for port in ports.ports where [3000, 5173, 8000, 11434, 1234].contains(port.port) {
print("⚠️ Dev/AI server exposed on port \(port.port)")
}
메일·채팅 앱에서의 링크 사전 확인
수신한 메시지 안의 링크를 표시 전에 자동으로 스캔하여, 위험한 것만 경고 표시합니다.
let result = try await client.auditURLSafety(url: link)
if result.riskLevel == "dangerous" || result.riskLevel == "suspicious" {
showWarningBanner(for: link, score: result.score)
}
우클릭 메뉴·단축어에서의 안전성 확인
Finder의 '서비스' 메뉴나 macOS 단축어(Shortcuts)에 넣어, 복사한 URL을 원액션으로 검사합니다.
// macOS Shortcuts(App Intent) 또는 서비스 메뉴 핸들러에서 호출
let report = try await client.auditURLSafety(url: pasteboardURL)
return "\(report.riskLevel.uppercased()) (\(report.score)/100)"
IT 자산 관리·MDM 대시보드
사내 여러 Mac에서 점수를 수집해, 관리자용 대시보드에서 목록화·경고 처리합니다.
let report = try await client.securityReport() try await mdmAPI.reportScore(deviceID: deviceID, score: report.score, grade: report.grade)
SDK 소개
Q. 무료로 사용할 수 있나요?
A. 예. RoamSwitchKit(Mac)과 roamswitch-linux-kit(Linux) 모두 MIT 라이선스로 무료 공개되어 있습니다. RoamSwitch 본체(진단 엔진)의 설치가 전제이지만, SDK 자체는 비용이 들지 않습니다.
Q. 사용자의 설정을 변경할 수 있나요?
A. 아니요. 읽기 전용이며, 잠금 전환이나 포트 격리 같은 조작계 API는 전혀 구현되어 있지 않습니다. 이 패키지를 내장한 앱이 사용자 동의 없이 RoamSwitch의 보호 설정을 변경할 수 없습니다.
Q. RoamSwitch가 설치되어 있지 않다면?
A. 해당 오류(Mac: RoamSwitchClientError.appNotInstalled / Linux: RoamSwitchClientError::AppNotInstalled)가 반환됩니다. 이 경우 기능을 숨기는 등 부드럽게 처리하는 것을 권장합니다.
Q. 자사 제품에 RoamSwitch 본체를 동봉·재배포하고 싶다면?
A. SDK 연동(본 페이지 내용)은 그대로 무료로 자유롭게 이용하실 수 있지만, RoamSwitch 본체의 동봉·재배포에는 OEM 라이선스가 필요합니다. OEM·파트너 제휴는 이쪽에서 상담해 주세요.