콘텐츠로 이동

English · 한국어

pqcota 데모(OSS): 접근 준비 → 관측 → 인벤토리 → 전환물 생성

Docker만 있으면 한 줄로 설치하고, 실행하고, 스스로 지우는 종단 데모입니다. 가상 네트워크 하나에 묶인 노드들에서 pqcota가 전체 범위를 보여 줍니다. ① 사용자의 hosts 파일로 접근 준비 → ② Ansible/SSH로 OpenSSL, Java(JCA), 통신 핸드셰이크 관측 → ③ 중앙 인벤토리 → ④ 전환물 생성(플레이북 생성 → 적용 → 되돌림)입니다.

이 문서는 데모를 돌리는 사람을 위한 것입니다. 연결된 문서 중 한국어판이 없는 것은 영문입니다.

📊 실행하기 전에 볼 기대 결과: expected-output/에 콘솔 출력 샘플과 토폴로지 SVG가 있고, 실제 실행에서 달라질 수 있는 것(엣지 캡처 시점, 베이스 이미지 버전)도 적혀 있습니다.

요구 사항

  • Docker(Compose v2), 인터넷(처음 이미지를 빌드할 때), docker 그룹에 속한 사용자(root나 KVM은 필요 없음)
  • 다섯 리포를 나란히 클론해 둘 것(이 리포의 디렉터리 이름은 pqcota이고, 그 옆에 pqcota-common, pqcota-inventory, pqcota-discovery, pqcota-provisioning을 둡니다). 데모 이미지가 모두 빌드합니다. 빌드 안내를 보세요.

리포는 pqcota-ctl 컨테이너 안에서 빌드합니다. 빌드되는 것은 지금 체크아웃한 소스 그대로이며 커밋하지 않은 변경도 포함합니다.

빠른 시작

./demo/scripts/up.sh      # images → containers → build the repo on ctl → SSH keys → hosts.csv
./demo/scripts/demo.sh    # access prep → discovery → inventory → provisioning (generate, apply, roll back)
./demo/scripts/down.sh    # clean up (--rmi also removes images)

./demo/scripts/demo.sh --help는 조절할 수 있는 항목을 모두 보여 줍니다. 그중 하나가 아래의 선택 단계입니다.

처음이라면 scripts/의 이 스크립트 세 개면 충분합니다. 다른 폴더는 그 뒤에서 도는 장치입니다.

데모 환경은 파일 하나, demo/topology/topology.yaml로 정의됩니다. 처음 실행하면 샘플이 자동으로 복사됩니다(git은 무시합니다). 이 파일을 고치면 노드 수, 노드 종류, OpenSSL 버전, JCA provider, 네트워크 구간, 핸드셰이크가 모두 따라 바뀝니다. 그러니 사용자 환경에 더 가깝게 만들어 같은 종단 흐름을 돌려 볼 수 있습니다. 자세한 내용: topology/README(영문).

무엇이 보이나

demo.sh는 진행 상황을 ▶ N/6으로 보고합니다. 기본 토폴로지에는 노드가 셋 있고(web-gw(OpenSSL 3.x), pay-app(JVM), pay-db(OpenSSL 1.1.1, 레거시)), 컨트롤러 pqcota-ctl이 SSH로 이 노드들을 스캔합니다. 단계마다 보이는 것은 다음과 같습니다.

단계 보이는 것
0/6 접근 준비 hosts.csv로 Ansible 인벤토리를 만들고, 엔드포인트와 CMDB 프로파일을 등록합니다. 인벤토리 표에 접근 비밀이 몇 개인지 SQL로 세며 그 값은 0입니다
1/6 SSH 확인 컨트롤러에서 모든 노드로 Ansible ping을 보냅니다
2/6 관측 노드마다 OpenSSL 자산, JCA provider 체인(addProvider로 실행 중에 추가된 BouncyCastle 포함), TLS/SSH 핸드셰이크를 관측하고 결과를 가져옵니다. 실행이 끝나면 플레이북의 임시 디렉터리를 노드에서 지웁니다(Java 관측은 대상의 /tmp에 작은 파일을 남깁니다. FAQ를 보세요)
3/6 관측 보기 발견한 자산과 관측한 엣지의 등급입니다. 🟢 PQC/하이브리드, 🔴 고전(고전 알고리즘이 협상됨), ⚪ 등급 미정. 기본 토폴로지에서 web-gw → pay-app은 🟢이고 web-gw → pay-db는 🔴입니다(TLS와 SSH 모두)
4/6 토폴로지 관측한 것을 그림으로 그려 demo/.generated/topology.svg에 저장합니다
5/6 중앙 인벤토리 적재한 뒤 조회합니다. 엔드포인트와 프로파일 머리말, 모든 자산의 @app 라벨(pay-db가 공유하는 libssl.so.1.1은 payment-gw와 api-gw 둘 다에 귀속됩니다), 같은 결과를 두 번째로 적재해도 새 스냅샷이 생기지 않음(-history), 그 스냅샷의 자산과 엣지(-snapshot), 자산 범위(제외한 수를 보고함)와 그 범위를 가로지르는 -diff, 그리고 pqcota-prune 시험 실행
6/6 전환물 생성 확정된 계획에서 L2와 L3 플레이북과 되돌림 기록을 생성하고, 그것을 대상 노드(기본 설정에서는 pay-db)에 적용하며, /opt/pqcota/oqsprovider.so와 /etc/pqcota/openssl-pqc.cnf가 놓였는지 데모가 확인합니다. 그다음 되돌림 플레이북이 이를 취소하고 두 파일이 사라졌는지 데모가 확인합니다

출력에 그대로 나오지만 오류가 아닌 것이 둘 있습니다. - ⚠ duplicate: physical machine … → [pay-db web-gw]: Linux 호스트에서 나타납니다. 데모의 대상은 한 호스트의 컨테이너이고, Linux에서는 컨테이너 안에서 호스트의 머신 지문이 보여서 셋의 값이 같습니다. 한 머신을 여러 이름으로 등록했을 때 운영에서 보게 되는 것과 같습니다. Mac의 Docker Desktop에서는 지문이 다른 곳에서 오므로 이 줄이 나타나지 않습니다(까닭). - 전환물 생성이 놓는 oqsprovider.so는 빈 파일입니다. 데모가 보이는 것은 배포와 되돌릴 수 있음이지 암호 능력이 아닙니다(까닭). 실물로 확인하려면 아래 선택 단계를 켜세요.

선택 단계: 실물 provider로 마지막 한 걸음(DEMO_REAL_PROVIDER=1)

DEMO_REAL_PROVIDER=1 ./demo/scripts/demo.sh

빈 파일로는 보일 수 없는 것이 하나 있습니다. 도구가 만든 설정과 배치가 실제로 암호 능력을 만드는가입니다. 이 변수를 켜면 노드와 같은 베이스 위에서 실물 oqsprovider(liboqs와 oqs-provider)를 빌드해 그 마지막 한 걸음을 확인합니다. 처음 실행에는 빌드에 몇 분이 걸리고, 그 뒤로는 이미지를 재사용합니다.

대상은 pay-db가 아니라 인벤토리에서 OpenSSL 3.0–3.4로 관측된 노드입니다. provider는 OpenSSL 3의 개념이라 1.1.1 노드에는 놓을 곳이 없습니다. 같은 L2/L3 산출물이 그것을 배치하고 활성화한 다음 이렇게 됩니다.

보이는 것
능력 openssl list -kem-algorithms의 ML-KEM 계열이 0에서 14가 되고, list -providers에 oqsprovider … active가 보입니다
다시 관측 관측을 다시 돌려 적재합니다. provider 계층은 관측하지 않으므로 pqcota-inventory -diff에 그 노드의 변경이 나오지 않습니다(아래)
되돌림 L3→L2 순서로 취소하면 0으로 돌아갑니다. 같은 잣대로 잰 되돌릴 수 있음입니다

다시 관측해도 인벤토리는 바뀌지 않습니다. 오류가 아닙니다. OpenSSL에는 아직 provider 계층을 관측할 경로가 없고, 데모가 그 까닭을 함께 출력합니다.

출력이 놓이는 곳

대부분은 컨테이너 안에 있고, 리포에 놓이는 것은 demo/.generated/(git은 무시)뿐입니다. down.sh는 그 폴더를 통째로 지우고, 컨테이너 안에 있는 것은 컨테이너와 함께 사라집니다.

위치 내용 정리
리포, demo/.generated/ 리포에 놓이는 모든 것: topology.svg와 topology.dot(관측한 토폴로지 그림), 그리고 토폴로지에서 생성한 docker-compose.yml, groups.ini, profiles.csv, manifest.env down.sh가 폴더를 지웁니다(git은 무시)
컨트롤러, pqcota-ctl:/work/ 빌드 산출물 dist/linux-<arch>/(수집기 셋)와 dist/collector.jar, 가져온 관측 results/*.json, 접속 정보 hosts.csv→ansible/targets.ini(0600, 비밀), nodes.json, profiles.csv, 확정된 계획 plan.json, 생성한 ansible/playbook{,-l3}.yml과 rollback{,-l3}.yml, 모듈 ansible/files/oqsprovider.so(빈 파일) 컨테이너와 함께 사라집니다
Postgres, pqcota-demo-pg 중앙 인벤토리: 스냅샷, 관측 기록, 엔드포인트, 프로파일, 전환물 생성 기록 down.sh가 볼륨도 지웁니다(-v)
대상 노드 적용 단계에서 /opt/pqcota/oqsprovider.so와 /etc/pqcota/openssl-pqc.cnf, 그리고 L3 활성화 지점 /etc/pqcota/service.env. 되돌림 단계에서 그 파일들을 지웁니다(/opt/pqcota·/etc/pqcota 디렉터리는 남습니다) 데모가 스스로 되돌립니다

안을 들여다보려면(데모를 내리기 전에):

docker exec pqcota-ctl ls -R /work           # everything on the controller
docker exec pqcota-ctl cat /work/ansible/provision.yml   # the generated playbook
docker exec pqcota-demo-pg psql -U postgres -d pqcota -c '\dt'  # the inventory tables

호스트 파일 시스템은 거의 건드리지 않습니다. 리포에 남는 것은 위의 그림과 생성 파일뿐이고, 그것들도 git이 무시합니다. 접속 키(/work/id_demo)와 targets.ini는 컨트롤러 안에만 있으며 인벤토리로 적재되지 않습니다.

사용자의 환경(실제 자산)에 적용하려면

데모는 컨테이너를 대신 띄워 줍니다. 실제 자산에서는 환경이 이미 있으므로 세 가지를 준비합니다. 머신의 역할은 데모와 같습니다. pqcota-ctl은 리포를 클론해 빌드하는 머신이고, 노드에는 미리 설치된 것이 없습니다. hosts.csv로 끝나지 않습니다.

# 준비할 것 필수? 무엇인가
1 hosts.csv 원격 다중 노드에서 필수 node_id, ip, port, 계정, 키 → pqcota-hosts가 Ansible 인벤토리(targets.ini, 0600, 저장하지 않음)를 생성합니다. --dsn을 주면 엔드포인트도 upsert합니다(비밀은 제외). 호스트 하나를 그 자리에서 스캔한다면 필요 없습니다
2 노드별 수집기 바이너리 필수 ctl에서 pqcota-nodescan, pqcota-jvmscan, pqcota-netcap을 빌드합니다. 데모의 플레이북은 이를 대신 배포합니다(discover.yml이 배포하고, 실행하고, 가져오고, 정리합니다). 빌드 명령은 빌드 안내에 있습니다(아키텍처별 미리 빌드된 바이너리가 이미 릴리스에 있고 SHA256SUMS로 무결성을 확인합니다. 이 리포에서 나왔음을 증명하는 서명만 아직 로드맵(영문)에 있습니다)
3 실행하는 방법 필수 Ansible이나 직접, 노드마다 수집기를 실행하고 결과 JSON을 가져옵니다. 데모의 discover.yml이 참조 구현입니다

그 뒤는 데모와 같습니다. 수집한 결과를 pqcota-ingest에 넘기면 정규화해 저장하고, pqcota-inventory로 봅니다.

✅ 데모의 수집기 배포를 그대로 복사해도 됩니다. 노드 이미지에는 수집기가 없고, discover.yml이 ctl에서 배포하고, 실행하고, 결과를 가져오고, 정리합니다(실행이 끝나면 /tmp의 작은 Java 파일을 빼고 노드에는 자기 것이 남지 않습니다). JVM 추가 구성요소는 -recon으로 JVM이 있는 노드에만 갑니다. 실제 환경으로 옮기려면 collector_bin_dir이 사용자의 빌드 산출물(아키텍처별)을 가리키게 하기만 하면 됩니다.

실환경으로 가져가지 않을 데모 전용 요소: - 트래픽 생성(groups.ini의 traffic=, pqcota-gen-traffic.sh): 데모에는 관측할 핸드셰이크가 없어서 일부러 만들어 냅니다. 실제 환경에는 실제 트래픽이 있으므로 pqcota-netcap <node> <iface> <window>로 관측하기만 하면 됩니다.

선택: 노드 등록 관문(pqcota-ingest <dir> <scope-file>), 자산 범위(-scope-assets), CMDB 프로파일(pqcota-profile), Postgres 저장(PQCOTA_DSN), 서명 검증(PQCOTA_VERIFY_KEY). 무엇이 필수이고 무엇이 선택인지는 pqcota-discovery cmd README(영문)를 보세요.

관측 너머

관측은 「실제로 협상된 것」(등급)까지 보여 줍니다. 「그것이 선언된 것과 얼마나 맞는가(CONFIRMED/UNDECLARED/UNOBSERVED)」와 거버넌스, 대조는 이 리포가 하지 않으므로 데모에도 없습니다.

English