소속별 접근 통제 랩같은 업무망, 소속마다 다른 문
한눈에 보기
로그인한 «소속»에 따라 같은 주소가 열리기도, 막히기도 합니다. 그 차이를 PC와 휴대폰에서 눈으로 확인하는 랩입니다.
서버는 하나도 바꾸지 않았습니다. 문을 여닫는 것은 서버 앞의 Cloudflare 입니다.
이 랩에서는 무엇을 보나요?
소속마다 열리는 서버가 다른 것을 봅니다. WARP? 앱으로 로그인한 사람의 소속을 보고 서버마다 허용할 소속을 정해 둡니다.
등장인물 6명과 서버 5대
체험 계정 6개는 모두 가짜 회사(항공 지상조업 시나리오)이며 실제 고객과 관계없습니다.
| 소속 | 하는 일 | 로그인 버튼 |
|---|---|---|
| 본사 임직원 | 거의 모든 업무 | 사내 AD FS (랩) · 2단계 인증 필수 |
| 그룹 IT 총괄 | 전체 + 서버 관리(SSH) | 사내 AD FS (랩) · 2단계 인증 필수 |
| 협력사 A (조업) | 운영 업무 + 협력사 포털 | 협력사 IdP (랩) |
| 협력사 B (정비) | 협력사 포털만 | 협력사 IdP (랩) |
| 고객 항공사 X | 자기 회사 전용 포털만 | 협력사 IdP (랩) |
| 고객 항공사 Y | 자기 회사 전용 포털만 | 협력사 IdP (랩) |
서버 5대의 이름과 주소는 «어떤 순서로 해 보나요?»의 표에 있습니다.
체험 계정 비밀번호는 메가존클라우드 담당 SE에게 요청하시면 드립니다.
무엇을 준비하면 되나요?
둘 중 하나입니다. 랩 단말 화면을 웹으로 열거나(팀원), 내 단말에 앱을 깔고 체험 계정으로 로그인합니다.
어느 단말로 해 보나
랩 단말(팀원용): 늘 켜진 Windows와 Android 에뮬레이터 화면을 팀 로그인 뒤 noVNC?로 엽니다. 내 단말은 아래처럼 앱을 깝니다.
- Windows, macOS: Cloudflare One Client 설치 파일을 내려받아 설치
- Android: Google Play에서 «Cloudflare One Agent» 검색 후 설치
- iPhone: App Store에서 «Cloudflare One Agent» 검색 후 설치
팀 이름을 물으면: mzccfteam
다른 VPN이나 보안 에이전트가 깔린 회사 PC는 충돌할 수 있어, 개인 기기나 시험용 기기를 권합니다.
어떤 순서로 해 보나요?
앱에서 로그인하고 서버 주소 5개를 차례로 엽니다. 열리면 서버 색깔 화면, 막히면 Cloudflare 차단 화면이 뜹니다.
다섯 단계: 로그인 → 주소 열기 → 결과 읽기
- 앱에서 로그인을 누르고 팀 이름
mzccfteam을 넣습니다. - 소속 버튼을 고릅니다. 본사와 그룹 IT는 «사내 AD FS (랩)», 협력사와 고객사는 «협력사 IdP (랩)»입니다.
- 체험 계정 이메일과 비밀번호를 넣습니다. 본사와 그룹 IT는 6자리 2단계 인증(MFA?)을 한 번 더 묻습니다.
- 앱이 Connected(연결됨)로 바뀌면 아래 주소를 브라우저에서 하나씩 엽니다.
- 소속을 바꾸려면 앱 설정에서 로그아웃(계정 해제)한 뒤 1번부터 다시 합니다.
| 서버 | 주소 |
|---|---|
| 운영 업무시스템 | http://ops.ghlab.nxlab.cflare.kr |
| 정산·ERP | http://erp.ghlab.nxlab.cflare.kr |
| 협력사 포털 | http://partner.ghlab.nxlab.cflare.kr |
| 고객사 X 전용 포털 | http://airline-x.ghlab.nxlab.cflare.kr |
| 고객사 Y 전용 포털 | http://airline-y.ghlab.nxlab.cflare.kr |
앱이 꺼져 있으면(Disconnected) 어느 주소도 열리지 않습니다. 이름을 알아도 밖에서는 닿지 않는 것이 이 구조의 핵심입니다.
누가 어느 서버에 들어가나요?
아래 정답표와 같으면 정책이 제대로 동작하는 것입니다.
정답표: 소속 × 서버
| 서버 | 본사 | 그룹 IT | 협력사 A | 협력사 B | 고객 X | 고객 Y |
|---|---|---|---|---|---|---|
| 운영 업무시스템 | ✅ | ✅ | ✅ | ⛔ | ⛔ | ⛔ |
| 정산·ERP | ✅※ | ✅※ | ⛔ | ⛔ | ⛔ | ⛔ |
| 협력사 포털 | ✅ | ✅ | ✅ | ✅ | ⛔ | ⛔ |
| 고객사 X 포털 | ✅ | ✅ | ⛔ | ⛔ | ✅ | ⛔ |
| 고객사 Y 포털 | ✅ | ✅ | ⛔ | ⛔ | ⛔ | ✅ |
| 서버 관리(SSH) | ⛔ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
| 카카오톡 | ⛔ | ✅ | ⛔ | ⛔ | ⛔ | ⛔ |
※ 정산·ERP는 소속이 맞아도 단말 기준(OS 버전, 방화벽)을 통과해야 열립니다.
고객사 X와 Y가 서로의 포털을 못 보는 것이 «고객별 통제», 협력사 A와 B가 다른 범위를 받는 것이 «협력사별 통제»입니다.
휴대폰에서도 똑같이 갈리나요?
똑같이 갈립니다. 정책이 기기가 아니라 «사람과 소속»에 붙어 있어서입니다.
모바일에서 달라지는 것과 같은 것
- 같은 것: 소속별로 열리고 막히는 서버, 차단 화면, 카카오톡 차단
- 다른 것: 휴대폰은 posture? 검사 항목이 적어 Android는 OS 버전과 앱 연결 여부 정도입니다. 백신과 루팅은 기기 관리(MDM) 연동으로 봅니다.
랩 Android는 OS 14라 «OS 13 이상» 기준을 통과합니다. 기준을 15로 올리면 같은 사람도 정산·ERP에서 막힙니다.
막히면 어떤 화면이 보이나요?
«이 소속은 이 서버에 권한이 없습니다»처럼 사유가 적힌 Cloudflare 차단 화면이 뜹니다. 화면이 아예 안 뜨면 앱 연결부터 봅니다.
증상별로 먼저 볼 것
| 보이는 것 | 뜻 |
|---|---|
| 서버 색깔 화면 «접속에 성공했습니다» | 허용 |
| Cloudflare 차단 화면(사유 문구 있음) | 정책이 막음(정답표대로면 정상) |
| 한참 뒤 «연결할 수 없음» | 앱이 꺼져 있거나 로그인 전, 또는 서버 관리(SSH)처럼 화면 없는 차단 |
| 카카오톡 접속 불가 | 업무 단말 메신저 차단(그룹 IT만 예외) |
관리자는 Zero Trust? 로그에서 «누가, 어느 단말로, 무엇을, 왜 막혔나»를 한 줄씩 봅니다.
함정: 자주 하는 실수: 계정을 안 바꾸고 결과가 이상하다고 느끼는 것
다른 소속으로 바꿀 때 로그아웃을 빼먹으면 앞사람 소속으로 계속 판정됩니다.
앱은 로그인한 사람을 기억해, 브라우저나 탭을 바꿔도 소속은 그대로입니다.
앱 설정 › 계정 › 로그아웃(또는 Re-authenticate) 뒤 다시 로그인합니다.
단말 하나를 여럿이 번갈아 쓰는 랩이라 생기는 일입니다. 실제 회사에서는 사람마다 자기 단말이 있습니다.
한눈에 보기
사람은 «소속 리스트»에 넣고, 정책은 리스트만 봅니다. 서버마다 허용 한 줄, 맨 끝에 전체 차단 한 줄을 두면 소속이 늘어도 정책을 다시 짜지 않습니다.
네트워크 정책의 «허용»은 끝이 아닙니다. 웹 트래픽은 HTTP 정책을 한 번 더 지납니다.
소속은 정책에 어떻게 넣나요?
소속마다 이메일 리스트를 만들고, 조건은 «이메일이 리스트 안에 있음»으로 씁니다. 사람을 더할 때 정책은 고치지 않습니다.
리스트 구성: 사람은 리스트에, 정책은 리스트만
Zero Trust › Reusable components › Lists
- 이메일 리스트: 소속 6개와 «전체 페르소나» 1개(정책 적용 범위)
- IP 리스트: 서버마다 1개씩 5개
회사 IdP 밖 계정(협력사, 고객사)이 섞이면 IdP? 그룹보다 이메일 리스트가 단순합니다. IdP 그룹이 잘 관리되면 «User Group Names» 조건으로 바꿉니다.
Gateway 정책은 어떤 순서로 두나요?
서버마다 «IP 리스트와 허용 소속 리스트면 허용» 한 줄, 맨 끝에 All Block? 한 줄입니다.
정책 순서(위에서부터 평가)
Zero Trust › Traffic policies › Firewall policies
| 종류 | 정책 | 동작 |
|---|---|---|
| DNS | 메신저 도메인 + 그룹 IT 외 소속 | 차단 |
| 네트워크 | 운영 서버 22번 + 그룹 IT | 허용 |
| 네트워크 | 랩 대역 80번 + 전체 페르소나 | 허용(판정은 HTTP에서) |
| 네트워크 | 랩 대역 전체 | 차단(All Block?) |
| HTTP | 정산·ERP + 단말 기준 미통과 | 차단 |
| HTTP | 서버별 허용 소속 | 허용 × 5 |
| HTTP | 랩 대역 전체 | 차단(사유 문구) |
평문 HTTP(80)라 TLS 복호화 없이도 차단 화면이 뜹니다. HTTPS 서버면 복호화를 켜거나 네트워크 정책으로만 막습니다(화면 없이 연결 실패).
단말 프로필은 소속별로 어떻게 나누나요?
단말 프로필?을 소속으로 가릅니다. 본사와 그룹 IT는 인터넷 전체를(Exclude 모드), 협력사와 고객사는 업무 대역만(Include 모드) Cloudflare로 보냅니다.
왜 나누나
- 본사: 회사 보안 정책(메신저 차단, 위협 차단)을 인터넷 전체에 겁니다.
- 외부 계정: 자기 회사 인터넷은 두고 우리 업무 서버로 가는 길만 줍니다. 개인정보와 회선 간섭 민원이 줄어듭니다.
DNS 정책은 Include 모드에서도 걸립니다(앱의 DNS 프록시를 지나기 때문).
기본 Split Tunnel? 제외 목록에 사설 대역(10으로 시작하는 대역 등)이 통째로 있어, 업무 서버가 사설 대역이면 그 부분을 빼야 터널을 탑니다.
소속이 맞아도 막힐 수 있나요?
단말이 단말 기준(posture)?에 못 미치면 막힙니다. 이 랩은 정산·ERP에만 기준을 붙여, 미달 단말은 소속과 상관없이 차단 화면을 봅니다.
OS 별로 볼 수 있는 것
Zero Trust › Reusable components › Posture checks
| OS | 이 랩에서 거는 것 | 참고 |
|---|---|---|
| Windows | OS 버전, 방화벽 | 백신 상태는 Windows 10·11의 보안 센터 기준(서버 OS에는 없음) |
| Android | OS 버전 | 루팅·백신은 MDM 연동으로 |
함정: 놓치기 쉬운 것: 등록 권한(Device enrollment)
단말 등록 권한에 외부 계정을 안 넣으면 협력사와 고객사는 앱 로그인 단계에서 막힙니다.
한눈에 보기
이번 구축에서 실제로 걸린 것은 셋입니다. 식(expression)의 자료형과 리스트 참조 문법, 서버 OS의 클라이언트 설치 의존성, 에뮬레이터의 가상화 조건입니다.
단말 화면을 보는 경로(noVNC)는 별도 계정의 Access 뒤에 둬, 실습이 정책을 만져도 화면 접근이 흔들리지 않게 했습니다.
HTTP 정책의 목적지 IP는 어떻게 쓰나요?
배열이라 any(...[*] in ...)로 감쌉니다. http.conn.dst_ip in {…}는 «Array(Ip)» 파싱 오류로 거부되고, 네트워크 정책의 net.dst.ip와는 자료형이 다릅니다.
식 예시
# 네트워크 정책: 단일 값
net.dst.ip in $<IP 리스트 ID> and net.dst.port == 22
# HTTP 정책: 배열
any(http.conn.dst_ip[*] in $<IP 리스트 ID>)
# 신원: 리스트 참조
identity.email in $<이메일 리스트 ID>리스트 참조는 $ 바로 뒤에 리스트 ID(하이픈 포함)를 씁니다. $가 빠지면 «expected literal {» 오류가 납니다.
문자열 치환으로 식을 만들면 $$가 $로 줄어드는 함정(JavaScript String.replace 등)에 이번에 실제로 걸렸습니다.
Windows Server에 클라이언트가 안 깔리면?
무선 LAN 서비스(wlansvc)를 설치하고 재부팅합니다. 설치가 1603으로 롤백되고 이벤트 로그에 «서비스가 응답하지 않음»과 «의존 서비스 시작 실패»가 남는 경우입니다.
해결 순서
Install-WindowsFeature Wireless-Networking # 재부팅 필요
Restart-Computer
msiexec /i <설치 파일>.msi /qn ORGANIZATION=<팀 이름>설치 로그(/l*v)에 sc.exe config CloudflareWARP depend= "wlansvc" 줄이 보이면 확정입니다.
Windows Server는 공식 지원 OS가 아니라(공식: Windows 10, 11) 검증 결과에 이 단서를 붙입니다.
클라우드에서 Android 에뮬레이터를 돌리려면?
중첩 가상화가 되는 인스턴스가 필요합니다. AWS는 8세대 Intel(c8i, m8i, r8i)에서 이를 켜야 에뮬레이터 속도에 필요한 /dev/kvm이 생깁니다.
구성 요점
- 중첩 가상화(nested virtualization)는 인스턴스를 만들 때 CPU 옵션에서 켭니다.
- Play 스토어가 든 시스템 이미지를 씁니다(모바일 클라이언트 공식 배포가 Google Play뿐).
- 화면은 가상 디스플레이와 VNC, noVNC로 웹에 내보내고 그 앞에 Access를 둡니다.
Zero Trust › Access › Applications › Add an application › Self-hosted

셸 스크립트에서 set -o pipefail과 yes | sdkmanager --licenses를 함께 쓰면 yes의 SIGPIPE(141)로 멈춥니다.
왜 막혔는지는 어디서 보나요?
Gateway 로그 한 줄에 사용자 이메일, 단말, 정책 이름, 결과가 남습니다.
판정 근거는 로그 한 줄: 사용자·단말·정책
화면: Zero Trust › Insights › Logs › Gateway
- DNS, Network, HTTP 탭이 따로 있습니다.
- 정책 이름에 랩 접두어를 붙이면 필터 한 번으로 랩 판정만 모입니다.
- 장기 보관과 외부 분석은 Logpush로 보냅니다.
함정: 공유 계정의 함정: 정책은 계정 전체에 걸린다
한 계정에서 여러 실습을 돌리면 정책이 남의 사용자에게 걸리지 않게 «적용 범위 리스트»로 묶어야 합니다.
Gateway 정책과 단말 프로필은 계정 단위라, 신원 조건 없는 실습 정책은 같은 계정의 다른 사용자도 막습니다.
이 랩은 모든 정책에 «전체 페르소나»나 소속 리스트 조건을 걸고, 대역 전체 차단은 랩 전용 사설 대역에만 겁니다.
이 문서의 용어
- 단말 프로필
- Device profile · 소속·OS 마다 WARP 동작(어떤 트래픽을 터널로 보낼지)을 다르게 주는 설정
- All Block
- 맨 끝 전체 차단 정책 · 위에서 허용되지 않은 나머지를 전부 막는 마지막 줄
- IdP
- Identity Provider(신원 제공자) · 회사 로그인 시스템(AD FS·Google·Okta 등)
- MFA
- Multi-Factor Authentication(2단계 인증) · 비밀번호 다음에 휴대폰 6자리 등을 한 번 더 묻는 것
- noVNC
- 브라우저로 원격 화면을 보는 도구 · 이 랩의 PC·휴대폰 화면을 웹으로 보여 줍니다
- posture
- Device posture(단말 상태 검사) · OS 버전·방화벽 같은 단말 조건을 통과한 기기만 허용하는 검사
- Split Tunnel
- 분할 터널 · 어떤 주소는 Cloudflare 로, 어떤 주소는 그냥 인터넷으로 보낼지 정하는 목록
- WARP
- Cloudflare One Client(WARP) · PC·휴대폰에 까는 앱. 켜 두면 업무 트래픽이 Cloudflare 를 거쳐 갑니다
- Zero Trust
- 제로 트러스트 · «회사 안이라도 믿지 않고 매번 누구인지 확인한다»는 접근 방식
