InfraGuard

포트 연결 (PORT OVERVIEW)

감시 포트별로 서버 TCP 상태 분포·상위 소스 IP·연결 강도를 라이브 카드로 보여주는 플래그십 포트 관제 화면.

개요 — 무엇을 하나

포트 연결(Port Connections) 은 Infrastructure ▸ Connectivity & Traffic 의 플래그십 화면인 PORT OVERVIEW 다. 운영 정책에 등록된 감시 포트(예: 80·443·22·3306 …)마다 카드를 하나씩 띄우고, 각 카드 안에서 서버별로 그 포트에 붙은 TCP 세션을 상태별로 100% 스택바로 쪼개 보여줍니다. "지금 이 포트에 누가·얼마나·어떤 상태로 붙어 있는가"를 한 화면에서 훑는 것이 목적입니다.

원천은 레거시 트래픽 DB(legacy_glory 커넥션)의 traffic_session_ct 스냅샷 테이블이며, 수집기 check_ct.js 가 주기적으로 세션 스냅샷을 적재합니다. 앱은 읽기 전용입니다 — 이 화면은 아무것도 쓰지 않습니다.

각 서버 타일은 다음을 보여줍니다.

언제 쓰나

화면 구성

상단 컨트롤

요소 동작
타이머 1분 / 5분 / 1시간 세션 집계 창(window) 폭. 선택은 localStorage(infr:timer:traffic-ports)에 영속되어 다음 방문에도 유지.
포트 칩 감시 포트 목록(운영 정책). 칩을 눌러 카드를 켜고 끕니다. 전체 토글로 전부 선택/해제. 필터는 이번 세션에만 적용(영속 안 함) — 다음 방문 기본은 항상 전체.
스냅샷 시각 현재 창의 기준이 된 최신 스냅샷 시각(표시 시간대 보정 적용).
새로고침 / 폴링 30초마다 자동으로 /infra/traffic/ports/live 를 폴링해 카드를 갱신.

포트 카드 (masonry)

카드는 드래그로 순서 변경이 가능하고 그 순서는 localStorage(infr:order:traffic-ports)에 저장됩니다. 카드 높이가 제각각이라 row-span masonry(sortable_masonry 믹스인)로 빈틈 없이 배치됩니다. 한 카드 안의 서버 타일은 소스 IP 수 많은 순 → 총 세션 순 → 서버 인덱스 순으로 정렬됩니다.

TCP 상태 레전드

스택바의 색은 상태 의미별 CSS 토큰(var(--infr-state-*))입니다. 레전드가 색↔상태 매핑을 안내합니다.

토큰 표시 의미
established ESTABLISHED 정상 수립된 연결
listen LISTEN 수신 대기(서버 소켓)
syn_sent SYN SENT 연결 시도(클라이언트)
syn_recv SYN RECV SYN 수신·반쯤 열림 — 급증 시 SYN 플러드 의심
fin_wait FIN WAIT 종료 진행(FIN_WAIT1/2 통합)
close_wait CLOSE WAIT 상대가 닫음·앱이 미종료 — 누적 시 커넥션 누수
time_wait TIME WAIT 종료 후 대기
other 기타 위 7종 외 상태

사용법

  1. 타이머 선택 — 좁게 보려면 1분(가장 최신 스냅샷 배치), 완만한 추세는 5분·1시간.
  2. 포트 칩으로 관심 포트만 남기기 — 예: 웹만 보려면 80·443 만 켭니다.
  3. 스택바 읽기 — ESTABLISHED 비중이 낮고 SYN_RECV/TIME_WAIT 가 크면 이상 신호.
  4. SRC 서클 클릭 — 그 서버·포트의 소스 IP 목록 팝업(원격 IP·원격 포트·세션·최초/최종 관측)이 열립니다.
  5. IP 클릭 → 단일 IP 조사 — 그 IP 가 어느 서버·포트에·어떤 상태로 붙는지 분해, 지오/ASN, 기간 이력(5분·시간별·일별 롤업)을 확인. 여기서 평판 조회·차단으로 이어집니다.
  6. 카드 재정렬 — 자주 보는 포트를 위로 드래그하면 순서가 저장됩니다.

일별(1day) 이력은 롤업 특성상 개별 IP 가 아니라 그 IP 의 /24 대역(256 IP) 기준으로 집계됩니다. 팝업에 211.224.128.0/24 기준 같은 CIDR 라벨이 붙으면 이는 대역 전체의 합이라는 뜻입니다.

데이터 소스

모든 쿼리는 legacy_glory 커넥션에서 실행되며 파라미터 바인딩된 쿼리빌더로 App\Repositories\TrafficRepository 에 격리되어 있습니다(문자열 보간 금지).

창(window) 앵커링

표시 창은 앱의 now() 가 아니라 데이터의 최신 스냅샷(MAX(snapshot_ts))을 기준으로 잡습니다. 수집기 저장 시계와 앱 시계가 몇 시간씩 어긋날 수 있어, now() 로 창을 잡으면 데이터를 벗어나 빈 화면이 되기 때문입니다.

타이머 SQL 경계(snapshot_ts)
1분 최신 스냅샷 분의 startOfMinute ~ endOfMinute
5분 최신 스냅샷 − 4분의 startOfMinute ~ 최신 endOfMinute
1시간 최신 스냅샷 − 59분의 startOfMinute ~ 최신 endOfMinute

snapshot_ts 의 WHERE 경계는 레거시 저장 시각을 그대로 씁니다. 화면에 보이는 스냅샷 시각만 운영 정책의 표시 시간대 보정(traffic_tz_offset_hours)이 더해져 표시됩니다.

핵심 쿼리 — portOverview()

SELECT a.local_port, a.server_name, a.server_index, a.remote_ip,
       a.state_code, b.state_name,
       SUM(a.session_count) AS total_sessions
FROM traffic_session_ct AS a
LEFT JOIN protocol_state AS b ON a.state_code = b.state_code
WHERE a.snapshot_ts BETWEEN :min AND :max
  AND a.local_port IN (:ports)          -- 운영 정책 감시 포트
GROUP BY a.local_port, a.server_name, a.server_index,
         a.remote_ip, a.state_code, b.state_name;

관련 테이블

테이블 커넥션 역할 공급
traffic_session_ct legacy_glory 세션 스냅샷(host/remote/state/count) check_ct.js
protocol_state legacy_glory TCP state 코드 → 상태명 룩업 —
traffic_session_ct_5min/_1hour/_1day legacy_glory IP 조사 팝업의 기간 이력 롤업 aggregate.js
ip_info_loop legacy_glory IP 조사 팝업의 지오/ASN/ISP 인리치 —

서버 응답 형태(요약)

{
  "ports": [80, 443, 22],
  "timer": 1,
  "snapshot": "2026-08-13 10:24:00",
  "ports_data": [
    { "port": 443, "server_data": [
      { "alias": "web1", "idx": 12, "host_count": 84,
        "top_req": [ { "remote_ip": "203.0.113.10", "session_count": 61 } ],
        "connections": [ { "state": "established", "count": 420, "pct": 78 } ],
        "total": 538 }
    ] }
  ]
}

portsData() 는 20초 캐시(타이머 + 포트 목록 해시별)로 원격 왕복을 억제합니다.

권한

Infrastructure 역할 영역은 최소 user_level 1(뷰어)로 열람 가능합니다. 포트 연결 화면은 읽기 전용이라 별도 쓰기 게이트가 없습니다 — 데모(1)·스태프(5)·관리자(10) 모두 조회할 수 있습니다. 라우트는 infr.auth 세션 인증만 요구합니다.

작업 필요 레벨
포트 연결 조회·폴링·IP 조사 팝업 1 (인증된 모든 사용자)
감시 포트 목록 편집(운영 정책) 10 (Administration) — 운영 정책

IP 조사 팝업에서 이어지는 차단은 Security ▸ 차단 목록으로 넘어가며 그쪽은 쓰기 user_level 2 이상 + 감사 로그를 요구합니다. 이 화면 자체는 차단을 수행하지 않습니다.

문제해결 · FAQ

카드는 뜨는데 서버 데이터가 비어 있어요. 해당 창에 그 포트로 붙은 세션이 없다는 뜻입니다. 타이머를 5분/1시간으로 넓히거나, 실제로 그 포트가 열려 트래픽이 있는지 확인합니다.

모든 카드가 비어 있고 "연결 스냅샷이 없습니다"가 떠요. legacy_glory 의 traffic_session_ct 에 최근 스냅샷이 없습니다(수집기 check_ct.js 중단 또는 DB 연결 실패). 최신 스냅샷 시각이 표시되지 않으면 수집기 상태를 점검합니다.

포트가 안 보여요. 감시 포트 목록(infra_monitored_ports)에 없으면 카드가 생성되지 않습니다. Administration ▸ 운영 정책에서 CSV 로 추가합니다(1~65535, 최대 30개, 입력 순서 보존). 기본값:

infra_monitored_ports = 80,443,22,3306,25,465,27017,21,53,3030,8080,6379,6001

스냅샷 시각이 실제 시각과 몇 시간 달라요. 레거시 DB 저장 시계와 표시 시간대가 다르면 운영 정책의 traffic_tz_offset_hours(±14h)로 표시 시각을 보정합니다. 쿼리 경계에는 적용되지 않고 표시에만 반영됩니다.

일별 이력이 비어 있어요. _1day 롤업은 하루 지연될 수 있고 /24 대역 기준으로 집계됩니다. 5분·시간별 grain 으로 확인합니다.

관련 항목

포트 연결 — PORT OVERVIEW
포트 연결 — PORT OVERVIEW