내 Mac / Linux 앱에 RoamSwitch의 진단 기능을 그대로
RoamSwitchKit(Mac)와 roamswitch-linux-kit(Linux)은 RoamSwitch 본체가 계산하는 보안 진단 결과를 Swift / Rust 코드에서 직접 참조할 수 있는 무료 오픈소스 클라이언트입니다. ARP 감시나 포트 스캔을 직접 구현하지 않고도 "지금 이 네트워크는 안전한가"를 자신의 앱에 통합할 수 있습니다.
🔒 왜 안전한가
- 읽기 전용: 잠금 전환, 포트 격리, 기기 배출 같은 조작계 API는 전혀 존재하지 않습니다. 이 패키지를 연결한 앱이 사용자 동의 없이 RoamSwitch의 설정을 변경할 수 없습니다.
- 완전 로컬: RoamSwitch 본체에 포함된 바이너리(macOS: RoamSwitchMCPServer / Linux: roamswitch-mcp)를 서브프로세스로 실행하여 표준 입출력으로만 통신합니다. 외부 서버로의 전송은 전혀 없습니다.
- 무료·오픈소스: 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 등) 판정을 포함한 상세 감사 결과를 가져옵니다.
guardStatus()
포트 가드, ARP 자동 대응, USB 가드, Bluetooth 가드, 웹/메일 다운로드 보호, DNS 위협 차단 상태 및 현재 보안 레벨을 조회합니다.
auditURLSafety(url:)
의심스러운 링크나 단축 URL을 분석하여 피싱, 유니코드 도메인 위장, 고위험 TLD를 기기 내에서 즉시 진단합니다 (Zero Telemetry).
기타 읽기 전용 메서드
| 메서드 | 개요 |
|---|---|
auditSecurityLogs(hours:) | 최근 보안 로그(Mac: Sudo 인증 실패, SSH 무차별 대입 시도, Gatekeeper 차단, XProtect 탐지 등 / Linux: Sudo 인증 실패, SSH 무차별 대입, 방화벽 차단, AppArmor 거부, ClamAV 탐지 등)를 집계하고 API 키나 토큰 등 민감 정보를 자동으로 마스킹한 뒤, 로그 패턴을 템플릿화한 신규 패턴 탐지 및 빈도 이상(통계적 스파이크) 탐지 결과도 반환합니다. |
activeVulnScan() | 127.0.0.1 한정·비파괴 실증형 취약점 검증. 유일하게 네트워크를 사용하는 도구이며 기본값은 비활성, 설정에서 옵트인이 필요합니다. |
packageCveScan() | 설치된 패키지(Mac: Homebrew / Linux: dpkg・dnf・zypper・pacman)를 로컬 CVE 맵과 대조합니다. 네트워크 통신은 전혀 하지 않습니다. |
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 스푸핑, 외부 공개 포트 등 24개 항목을 종합 진단한 점수와 개선 조언을 가져옵니다.
exposed_ports(include_local_only)
현재 리스닝 중인 모든 포트를 나열하고, 외부에 공개된 포트는 알려진 위험 서비스(Redis/MongoDB 등) 판정을 포함한 상세 감사 결과를 가져옵니다.
guard_status()
포트 가드, ARP 자동 대응, USB 가드, Bluetooth 가드, 웹/메일 다운로드 보호, DNS 위협 차단 상태 및 현재 보안 레벨을 조회합니다.
audit_url_safety(url)
의심스러운 링크나 단축 URL을 분석하여 피싱, 유니코드 도메인 위장, 고위험 TLD를 기기 내에서 즉시 진단합니다 (Zero Telemetry).
기타 읽기 전용 메서드
| 메서드 | 개요 |
|---|---|
server_security_report() | Server Edition의 30개 항목 프로파일(커널 강화·컨테이너 격리·커널 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 키나 토큰 등 민감 정보를 자동으로 마스킹한 뒤, 로그 패턴을 템플릿화한 신규 패턴 탐지 및 빈도 이상(통계적 스파이크) 탐지 결과도 반환합니다. |
get_app_help(query, topic) | RoamSwitch의 전체 기능 사양, 내부 동작, 모든 알림 메시지, 문제 해결을 망라한 공식 지식 베이스를 로컬에서 즉시 검색하여 정확한 설명과 권장 조치를 제공합니다. |
quarantine_status() | 악성코드 격리 Vault의 내용(원래 경로·탐지된 위협명·격리 일시·크기)을 반환합니다. |
canary_status() | 랜섬웨어 카나리아(미끼 파일) 배치 상태와 최근 50건까지의 탐지 인시던트를 반환합니다. |
package_cve_scan() | 설치된 패키지(Mac: Homebrew / Linux: dpkg・dnf・zypper・pacman)를 로컬 CVE 맵과 대조합니다. 네트워크 통신은 전혀 하지 않습니다. |
package_cve_scan_languages(watched_folders) | npm / PyPI / crates.io / RubyGems / Packagist / Go / Maven 등의 의존성 락파일을 동일한 로컬 CVE 맵과 대조합니다. 네트워크 통신은 전혀 하지 않습니다. |
verify_fim() | 약 150곳의 핵심 시스템 파일을 다시 해시하여 베이스라인과 비교해 변조를 검증합니다. |
get_port_anomaly_incidents() | 포트 이상 가드의 베이스라인 확보 상태, 현재 자동 차단 중인 포트, 최근 50건까지의 인시던트를 반환합니다. 현재 자동 차단 중인 포트는 타임스탬프가 없는 현재 상태의 스냅샷이며, 타임스탬프가 있는 인시던트 이력과는 다르다는 점을 응답 내 주석 필드로 명시하고 있습니다. |
get_ebpf_incidents() | eBPF 런타임 가드의 현재 격리 상태와 발동 사유가 된 인시던트 이력을 반환합니다. |
각 반환 타입의 필드 정의는 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·파트너 제휴는 이쪽에서 상담해 주세요.