feat: [academy] Nginx 백과사전 SVG 일러스트 9~12번 추가

- 9.svg: 보안 필터 = 입장 불가 명단 (경비원/차단목록 비유)
- 10.svg: 정적 자산 캐싱 = 냉장고 보관 (캐시 히트 vs 미스 비교)
- 11.svg: 502/504/403/413 에러 카드 4종 (원인/해결 가이드)
- 12.svg: 핵심 정리 총괄 인포그래픽 (6대 기능 원형 배치)
This commit is contained in:
김보곤
2026-02-23 13:07:47 +09:00
parent 8bf5d10be7
commit 8780e89828
4 changed files with 611 additions and 0 deletions

View File

@@ -0,0 +1,163 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 500" font-family="sans-serif">
<defs>
<linearGradient id="bg10" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#0e3c4a"/>
<stop offset="100%" stop-color="#0f172a"/>
</linearGradient>
<linearGradient id="cacheBox" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#164e63"/>
<stop offset="100%" stop-color="#0e3c4a"/>
</linearGradient>
<linearGradient id="slowBox" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#3b1118"/>
<stop offset="100%" stop-color="#1e0a0e"/>
</linearGradient>
<linearGradient id="fastBox" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#0b3d1e"/>
<stop offset="100%" stop-color="#071f10"/>
</linearGradient>
</defs>
<rect width="800" height="500" fill="url(#bg10)"/>
<!-- Title -->
<text x="400" y="40" text-anchor="middle" fill="#22d3ee" font-size="24" font-weight="bold">정적 자산 캐싱 = 냉장고 보관</text>
<!-- LEFT SIDE: Slow path -->
<g transform="translate(40, 70)">
<rect x="0" y="0" width="230" height="340" rx="12" fill="url(#slowBox)" stroke="#f87171" stroke-width="2"/>
<text x="115" y="30" text-anchor="middle" fill="#f87171" font-size="16" font-weight="bold">매번 새로 가져오기</text>
<text x="115" y="50" text-anchor="middle" fill="#94a3b8" font-size="12">(캐시 없음)</text>
<!-- Slow clock icon -->
<circle cx="115" cy="90" r="24" fill="none" stroke="#f87171" stroke-width="2"/>
<line x1="115" y1="90" x2="115" y2="74" stroke="#f87171" stroke-width="2.5" stroke-linecap="round"/>
<line x1="115" y1="90" x2="128" y2="95" stroke="#f87171" stroke-width="2" stroke-linecap="round"/>
<text x="115" y="132" text-anchor="middle" fill="#f87171" font-size="11">응답 시간: 200ms+</text>
<!-- Step 1 -->
<rect x="20" y="150" width="190" height="32" rx="6" fill="#1e293b" stroke="#475569" stroke-width="1"/>
<text x="30" y="170" fill="#f87171" font-size="11">1. 클라이언트 요청</text>
<polygon points="115,185 110,192 120,192" fill="#f87171"/>
<!-- Step 2 -->
<rect x="20" y="196" width="190" height="32" rx="6" fill="#1e293b" stroke="#475569" stroke-width="1"/>
<text x="30" y="216" fill="#f87171" font-size="11">2. 서버에서 파일 읽기 (디스크 I/O)</text>
<polygon points="115,231 110,238 120,238" fill="#f87171"/>
<!-- Step 3 -->
<rect x="20" y="242" width="190" height="32" rx="6" fill="#1e293b" stroke="#475569" stroke-width="1"/>
<text x="30" y="262" fill="#f87171" font-size="11">3. 헤더 처리 + 압축</text>
<polygon points="115,277 110,284 120,284" fill="#f87171"/>
<!-- Step 4 -->
<rect x="20" y="288" width="190" height="32" rx="6" fill="#1e293b" stroke="#475569" stroke-width="1"/>
<text x="30" y="308" fill="#f87171" font-size="11">4. 응답 전송 (매번 반복!)</text>
</g>
<!-- CENTER: Cache storage -->
<g transform="translate(290, 80)">
<!-- Cache box / Refrigerator -->
<rect x="0" y="0" width="220" height="320" rx="14" fill="url(#cacheBox)" stroke="#22d3ee" stroke-width="2.5"/>
<!-- Refrigerator door handle -->
<rect x="190" y="80" width="8" height="50" rx="4" fill="#22d3ee" opacity="0.6"/>
<!-- Title area -->
<rect x="15" y="12" width="190" height="36" rx="8" fill="#22d3ee" fill-opacity="0.15"/>
<text x="110" y="36" text-anchor="middle" fill="#22d3ee" font-size="18" font-weight="bold">캐시 보관함</text>
<!-- Snowflake decorations -->
<text x="30" y="35" fill="#67e8f9" font-size="14" opacity="0.5">*</text>
<text x="185" y="30" fill="#67e8f9" font-size="14" opacity="0.5">*</text>
<!-- Cached items -->
<!-- JS file -->
<rect x="20" y="62" width="85" height="55" rx="6" fill="#1e293b" stroke="#fbbf24" stroke-width="1.5"/>
<text x="62" y="82" text-anchor="middle" fill="#fbbf24" font-size="22" font-weight="bold">.js</text>
<text x="62" y="102" text-anchor="middle" fill="#94a3b8" font-size="9">JavaScript</text>
<!-- CSS file -->
<rect x="115" y="62" width="85" height="55" rx="6" fill="#1e293b" stroke="#a78bfa" stroke-width="1.5"/>
<text x="157" y="82" text-anchor="middle" fill="#a78bfa" font-size="22" font-weight="bold">.css</text>
<text x="157" y="102" text-anchor="middle" fill="#94a3b8" font-size="9">Stylesheet</text>
<!-- PNG file -->
<rect x="20" y="128" width="85" height="55" rx="6" fill="#1e293b" stroke="#4ade80" stroke-width="1.5"/>
<text x="62" y="148" text-anchor="middle" fill="#4ade80" font-size="22" font-weight="bold">.png</text>
<text x="62" y="168" text-anchor="middle" fill="#94a3b8" font-size="9">Image</text>
<!-- SVG file -->
<rect x="115" y="128" width="85" height="55" rx="6" fill="#1e293b" stroke="#22d3ee" stroke-width="1.5"/>
<text x="157" y="148" text-anchor="middle" fill="#22d3ee" font-size="22" font-weight="bold">.svg</text>
<text x="157" y="168" text-anchor="middle" fill="#94a3b8" font-size="9">Vector</text>
<!-- Labels -->
<rect x="20" y="198" width="180" height="30" rx="6" fill="#0f172a" stroke="#22d3ee" stroke-width="1"/>
<text x="110" y="218" text-anchor="middle" fill="#22d3ee" font-size="13" font-weight="bold">expires 30d</text>
<rect x="20" y="238" width="180" height="30" rx="6" fill="#0f172a" stroke="#67e8f9" stroke-width="1"/>
<text x="110" y="258" text-anchor="middle" fill="#67e8f9" font-size="13" font-weight="bold">Cache-Control: public</text>
<!-- Freshness indicator -->
<rect x="20" y="278" width="180" height="28" rx="6" fill="#4ade80" fill-opacity="0.1" stroke="#4ade80" stroke-width="1"/>
<text x="110" y="297" text-anchor="middle" fill="#4ade80" font-size="12">30일간 신선 보관</text>
</g>
<!-- RIGHT SIDE: Fast path -->
<g transform="translate(530, 70)">
<rect x="0" y="0" width="230" height="340" rx="12" fill="url(#fastBox)" stroke="#4ade80" stroke-width="2"/>
<text x="115" y="30" text-anchor="middle" fill="#4ade80" font-size="16" font-weight="bold">캐시에서 바로 꺼내기</text>
<text x="115" y="50" text-anchor="middle" fill="#94a3b8" font-size="12">(캐시 히트!)</text>
<!-- Fast clock icon -->
<circle cx="115" cy="90" r="24" fill="none" stroke="#4ade80" stroke-width="2"/>
<line x1="115" y1="90" x2="115" y2="74" stroke="#4ade80" stroke-width="2.5" stroke-linecap="round"/>
<line x1="115" y1="90" x2="105" y2="82" stroke="#4ade80" stroke-width="2" stroke-linecap="round"/>
<!-- Speed lines -->
<line x1="148" y1="78" x2="158" y2="74" stroke="#4ade80" stroke-width="1.5" stroke-linecap="round"/>
<line x1="148" y1="90" x2="160" y2="90" stroke="#4ade80" stroke-width="1.5" stroke-linecap="round"/>
<line x1="148" y1="102" x2="158" y2="106" stroke="#4ade80" stroke-width="1.5" stroke-linecap="round"/>
<text x="115" y="132" text-anchor="middle" fill="#4ade80" font-size="11">응답 시간: 5ms</text>
<!-- Step 1 -->
<rect x="20" y="150" width="190" height="32" rx="6" fill="#1e293b" stroke="#475569" stroke-width="1"/>
<text x="30" y="170" fill="#4ade80" font-size="11">1. 클라이언트 요청</text>
<!-- Lightning bolt (skip) -->
<text x="115" y="196" text-anchor="middle" fill="#fbbf24" font-size="22">&#9889;</text>
<!-- Step 2 (direct) -->
<rect x="20" y="206" width="190" height="32" rx="6" fill="#1e293b" stroke="#4ade80" stroke-width="1.5"/>
<text x="30" y="226" fill="#4ade80" font-size="11">2. 캐시에서 즉시 반환!</text>
<!-- Result comparison -->
<rect x="20" y="260" width="190" height="56" rx="8" fill="#4ade80" fill-opacity="0.1" stroke="#4ade80" stroke-width="1"/>
<text x="115" y="282" text-anchor="middle" fill="#4ade80" font-size="13" font-weight="bold">304 Not Modified</text>
<text x="115" y="302" text-anchor="middle" fill="#94a3b8" font-size="11">서버 부하 없이 즉시 응답</text>
</g>
<!-- VS divider arrows -->
<text x="278" y="245" text-anchor="middle" fill="#475569" font-size="16" font-weight="bold">VS</text>
<text x="522" y="245" text-anchor="middle" fill="#475569" font-size="16" font-weight="bold">VS</text>
<!-- Arrows from cache to fast path -->
<line x1="512" y1="230" x2="528" y2="230" stroke="#4ade80" stroke-width="2" marker-end="none"/>
<polygon points="528,225 538,230 528,235" fill="#4ade80"/>
<!-- Bottom comparison bar -->
<g transform="translate(100, 430)">
<rect x="0" y="0" width="600" height="50" rx="10" fill="#1e293b" stroke="#22d3ee" stroke-width="1.5"/>
<!-- Slow bar -->
<rect x="20" y="12" width="200" height="10" rx="5" fill="#f87171" opacity="0.4"/>
<rect x="20" y="12" width="200" height="10" rx="5" fill="#f87171"/>
<text x="120" y="38" text-anchor="middle" fill="#f87171" font-size="11">캐시 없음: 200ms</text>
<!-- Fast bar -->
<rect x="350" y="12" width="5" height="10" rx="3" fill="#4ade80"/>
<text x="450" y="38" text-anchor="middle" fill="#4ade80" font-size="11">캐시 히트: 5ms (40x 빠름)</text>
<!-- Speed label -->
<text x="300" y="25" text-anchor="middle" fill="#fbbf24" font-size="14" font-weight="bold">40x</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

@@ -0,0 +1,146 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 500" font-family="sans-serif">
<defs>
<linearGradient id="bg11" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#0e3c4a"/>
<stop offset="100%" stop-color="#0f172a"/>
</linearGradient>
<linearGradient id="card502" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#3b1118"/>
<stop offset="100%" stop-color="#1a0a0e"/>
</linearGradient>
<linearGradient id="card504" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#3b2506"/>
<stop offset="100%" stop-color="#1a1203"/>
</linearGradient>
<linearGradient id="card403" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#2d1b54"/>
<stop offset="100%" stop-color="#150d2a"/>
</linearGradient>
<linearGradient id="card413" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#0e3c4a"/>
<stop offset="100%" stop-color="#071e27"/>
</linearGradient>
</defs>
<rect width="800" height="500" fill="url(#bg11)"/>
<!-- Title -->
<text x="400" y="40" text-anchor="middle" fill="#22d3ee" font-size="24" font-weight="bold">Nginx 주요 에러 코드 가이드</text>
<!-- Card 1: 502 Bad Gateway (top-left) -->
<g transform="translate(30, 65)">
<rect x="0" y="0" width="360" height="190" rx="14" fill="url(#card502)" stroke="#f87171" stroke-width="2"/>
<!-- Error code -->
<text x="180" y="40" text-anchor="middle" fill="#f87171" font-size="42" font-weight="bold">502</text>
<text x="180" y="62" text-anchor="middle" fill="#f87171" font-size="14">Bad Gateway</text>
<!-- Icon: broken connection -->
<g transform="translate(55, 80)">
<circle cx="0" cy="15" r="12" fill="none" stroke="#f87171" stroke-width="2"/>
<text x="0" y="20" text-anchor="middle" fill="#f87171" font-size="14">S</text>
<line x1="14" y1="15" x2="35" y2="15" stroke="#f87171" stroke-width="2" stroke-dasharray="4,3"/>
<!-- Break mark -->
<text x="50" y="22" fill="#f87171" font-size="20" font-weight="bold">/</text>
<line x1="63" y1="15" x2="84" y2="15" stroke="#f87171" stroke-width="2" stroke-dasharray="4,3"/>
<circle cx="98" cy="15" r="12" fill="none" stroke="#f87171" stroke-width="2"/>
<text x="98" y="20" text-anchor="middle" fill="#f87171" font-size="14">P</text>
</g>
<!-- Description -->
<rect x="15" y="115" width="330" height="28" rx="6" fill="#0f172a" fill-opacity="0.6"/>
<text x="180" y="134" text-anchor="middle" fill="#fca5a5" font-size="13">PHP-FPM이 응답하지 않음</text>
<!-- Solution -->
<rect x="15" y="152" width="330" height="28" rx="6" fill="#4ade80" fill-opacity="0.1" stroke="#4ade80" stroke-width="1"/>
<text x="30" y="170" fill="#4ade80" font-size="12" font-weight="bold">해결:</text>
<text x="72" y="170" fill="#94a3b8" font-size="12">PHP-FPM 상태 확인 후 재시작</text>
</g>
<!-- Card 2: 504 Gateway Timeout (top-right) -->
<g transform="translate(410, 65)">
<rect x="0" y="0" width="360" height="190" rx="14" fill="url(#card504)" stroke="#fbbf24" stroke-width="2"/>
<!-- Error code -->
<text x="180" y="40" text-anchor="middle" fill="#fbbf24" font-size="42" font-weight="bold">504</text>
<text x="180" y="62" text-anchor="middle" fill="#fbbf24" font-size="14">Gateway Timeout</text>
<!-- Icon: hourglass -->
<g transform="translate(150, 72)">
<!-- Hourglass shape -->
<rect x="0" y="0" width="60" height="6" rx="2" fill="#fbbf24"/>
<rect x="0" y="44" width="60" height="6" rx="2" fill="#fbbf24"/>
<line x1="5" y1="6" x2="25" y2="25" stroke="#fbbf24" stroke-width="2"/>
<line x1="55" y1="6" x2="35" y2="25" stroke="#fbbf24" stroke-width="2"/>
<line x1="25" y1="25" x2="5" y2="44" stroke="#fbbf24" stroke-width="2"/>
<line x1="35" y1="25" x2="55" y2="44" stroke="#fbbf24" stroke-width="2"/>
<!-- Sand -->
<circle cx="30" cy="36" r="4" fill="#fbbf24" opacity="0.5"/>
</g>
<!-- Description -->
<rect x="15" y="115" width="330" height="28" rx="6" fill="#0f172a" fill-opacity="0.6"/>
<text x="180" y="134" text-anchor="middle" fill="#fde68a" font-size="13">처리 시간 초과 (느린 쿼리 등)</text>
<!-- Solution -->
<rect x="15" y="152" width="330" height="28" rx="6" fill="#4ade80" fill-opacity="0.1" stroke="#4ade80" stroke-width="1"/>
<text x="30" y="170" fill="#4ade80" font-size="12" font-weight="bold">해결:</text>
<text x="72" y="170" fill="#94a3b8" font-size="12">proxy_read_timeout 타임아웃 설정 확인</text>
</g>
<!-- Card 3: 403 Forbidden (bottom-left) -->
<g transform="translate(30, 275)">
<rect x="0" y="0" width="360" height="190" rx="14" fill="url(#card403)" stroke="#a78bfa" stroke-width="2"/>
<!-- Error code -->
<text x="180" y="40" text-anchor="middle" fill="#a78bfa" font-size="42" font-weight="bold">403</text>
<text x="180" y="62" text-anchor="middle" fill="#a78bfa" font-size="14">Forbidden</text>
<!-- Icon: lock -->
<g transform="translate(150, 72)">
<rect x="10" y="18" width="40" height="30" rx="5" fill="none" stroke="#a78bfa" stroke-width="2.5"/>
<path d="M18,18 V10 a12,12 0 0,1 24,0 V18" fill="none" stroke="#a78bfa" stroke-width="2.5"/>
<circle cx="30" cy="32" r="4" fill="#a78bfa"/>
<line x1="30" y1="36" x2="30" y2="42" stroke="#a78bfa" stroke-width="2"/>
</g>
<!-- Description -->
<rect x="15" y="115" width="330" height="28" rx="6" fill="#0f172a" fill-opacity="0.6"/>
<text x="180" y="134" text-anchor="middle" fill="#c4b5fd" font-size="13">접근 권한 없음 (파일 퍼미션 문제)</text>
<!-- Solution -->
<rect x="15" y="152" width="330" height="28" rx="6" fill="#4ade80" fill-opacity="0.1" stroke="#4ade80" stroke-width="1"/>
<text x="30" y="170" fill="#4ade80" font-size="12" font-weight="bold">해결:</text>
<text x="72" y="170" fill="#94a3b8" font-size="12">chmod/chown 파일 권한 및 소유자 확인</text>
</g>
<!-- Card 4: 413 Too Large (bottom-right) -->
<g transform="translate(410, 275)">
<rect x="0" y="0" width="360" height="190" rx="14" fill="url(#card413)" stroke="#22d3ee" stroke-width="2"/>
<!-- Error code -->
<text x="180" y="40" text-anchor="middle" fill="#22d3ee" font-size="42" font-weight="bold">413</text>
<text x="180" y="62" text-anchor="middle" fill="#22d3ee" font-size="14">Request Entity Too Large</text>
<!-- Icon: oversized file -->
<g transform="translate(140, 68)">
<!-- Small box trying to hold big file -->
<rect x="0" y="10" width="30" height="36" rx="3" fill="none" stroke="#22d3ee" stroke-width="2" stroke-dasharray="3,2"/>
<!-- Big file overflowing -->
<rect x="5" y="-2" width="60" height="44" rx="5" fill="none" stroke="#22d3ee" stroke-width="2.5"/>
<text x="35" y="22" text-anchor="middle" fill="#22d3ee" font-size="18" font-weight="bold">50MB</text>
<text x="35" y="36" text-anchor="middle" fill="#67e8f9" font-size="9">upload.zip</text>
<!-- Overflow arrows -->
<line x1="65" y1="8" x2="72" y2="2" stroke="#f87171" stroke-width="1.5"/>
<line x1="65" y1="36" x2="72" y2="42" stroke="#f87171" stroke-width="1.5"/>
</g>
<!-- Description -->
<rect x="15" y="115" width="330" height="28" rx="6" fill="#0f172a" fill-opacity="0.6"/>
<text x="180" y="134" text-anchor="middle" fill="#67e8f9" font-size="13">업로드 파일 크기가 제한 초과</text>
<!-- Solution -->
<rect x="15" y="152" width="330" height="28" rx="6" fill="#4ade80" fill-opacity="0.1" stroke="#4ade80" stroke-width="1"/>
<text x="30" y="170" fill="#4ade80" font-size="12" font-weight="bold">해결:</text>
<text x="72" y="170" fill="#94a3b8" font-size="12">client_max_body_size 값 증가</text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -0,0 +1,147 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 500" font-family="sans-serif">
<defs>
<linearGradient id="bg12" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#0e3c4a"/>
<stop offset="100%" stop-color="#0f172a"/>
</linearGradient>
<radialGradient id="glow" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#22d3ee" stop-opacity="0.15"/>
<stop offset="100%" stop-color="#22d3ee" stop-opacity="0"/>
</radialGradient>
<linearGradient id="nodeGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#164e63"/>
<stop offset="100%" stop-color="#0e3c4a"/>
</linearGradient>
</defs>
<rect width="800" height="500" fill="url(#bg12)"/>
<!-- Title -->
<text x="400" y="38" text-anchor="middle" fill="#22d3ee" font-size="24" font-weight="bold">Nginx 핵심 기능 총정리</text>
<!-- Central glow -->
<circle cx="400" cy="240" r="180" fill="url(#glow)"/>
<!-- Connection lines (drawn first, behind nodes) -->
<!-- To Reverse Proxy (top-left, ~135deg) -->
<line x1="370" y1="210" x2="175" y2="105" stroke="#22d3ee" stroke-width="1.5" opacity="0.4"/>
<!-- To SSL/TLS (top-right, ~45deg) -->
<line x1="430" y1="210" x2="625" y2="105" stroke="#22d3ee" stroke-width="1.5" opacity="0.4"/>
<!-- To Security Filter (left, 180deg) -->
<line x1="350" y1="240" x2="150" y2="270" stroke="#22d3ee" stroke-width="1.5" opacity="0.4"/>
<!-- To Static Cache (right, 0deg) -->
<line x1="450" y1="240" x2="650" y2="270" stroke="#22d3ee" stroke-width="1.5" opacity="0.4"/>
<!-- To Load Balancing (bottom-left, ~225deg) -->
<line x1="370" y1="270" x2="175" y2="395" stroke="#22d3ee" stroke-width="1.5" opacity="0.4"/>
<!-- To Log Monitoring (bottom-right, ~315deg) -->
<line x1="430" y1="270" x2="625" y2="395" stroke="#22d3ee" stroke-width="1.5" opacity="0.4"/>
<!-- Animated pulse dots on lines -->
<circle r="3" fill="#22d3ee" opacity="0.8">
<animateMotion dur="3s" repeatCount="indefinite" path="M370,210 L175,105"/>
</circle>
<circle r="3" fill="#22d3ee" opacity="0.8">
<animateMotion dur="3s" repeatCount="indefinite" path="M430,210 L625,105"/>
</circle>
<circle r="3" fill="#22d3ee" opacity="0.8">
<animateMotion dur="3.5s" repeatCount="indefinite" path="M350,240 L150,270"/>
</circle>
<circle r="3" fill="#22d3ee" opacity="0.8">
<animateMotion dur="3.5s" repeatCount="indefinite" path="M450,240 L650,270"/>
</circle>
<circle r="3" fill="#22d3ee" opacity="0.8">
<animateMotion dur="4s" repeatCount="indefinite" path="M370,270 L175,395"/>
</circle>
<circle r="3" fill="#22d3ee" opacity="0.8">
<animateMotion dur="4s" repeatCount="indefinite" path="M430,270 L625,395"/>
</circle>
<!-- CENTER: Nginx logo/icon -->
<g transform="translate(400, 240)">
<circle cx="0" cy="0" r="55" fill="#0f172a" stroke="#22d3ee" stroke-width="3"/>
<circle cx="0" cy="0" r="48" fill="url(#nodeGrad)" stroke="#22d3ee" stroke-width="1.5"/>
<!-- N letter for Nginx -->
<text x="0" y="-5" text-anchor="middle" fill="#22d3ee" font-size="36" font-weight="bold">N</text>
<text x="0" y="18" text-anchor="middle" fill="#67e8f9" font-size="13" font-weight="bold">Nginx</text>
</g>
<!-- Node 1: Reverse Proxy (top-left) -->
<g transform="translate(135, 82)">
<rect x="-60" y="-30" width="120" height="72" rx="12" fill="url(#nodeGrad)" stroke="#22d3ee" stroke-width="2"/>
<!-- Arrow icon -->
<g transform="translate(-12, -18)">
<rect x="0" y="0" width="24" height="16" rx="3" fill="none" stroke="#22d3ee" stroke-width="1.5"/>
<line x1="5" y1="8" x2="15" y2="8" stroke="#22d3ee" stroke-width="1.5"/>
<polygon points="15,4 21,8 15,12" fill="#22d3ee"/>
</g>
<text x="0" y="14" text-anchor="middle" fill="#22d3ee" font-size="13" font-weight="bold">리버스 프록시</text>
<text x="0" y="32" text-anchor="middle" fill="#94a3b8" font-size="10">요청 중계/분배</text>
</g>
<!-- Node 2: SSL/TLS (top-right) -->
<g transform="translate(665, 82)">
<rect x="-60" y="-30" width="120" height="72" rx="12" fill="url(#nodeGrad)" stroke="#fbbf24" stroke-width="2"/>
<!-- Lock icon -->
<g transform="translate(-10, -22)">
<rect x="2" y="10" width="16" height="12" rx="2" fill="none" stroke="#fbbf24" stroke-width="1.5"/>
<path d="M5,10 V6 a5,5 0 0,1 10,0 V10" fill="none" stroke="#fbbf24" stroke-width="1.5"/>
</g>
<text x="0" y="14" text-anchor="middle" fill="#fbbf24" font-size="13" font-weight="bold">SSL/TLS</text>
<text x="0" y="32" text-anchor="middle" fill="#94a3b8" font-size="10">암호화 통신</text>
</g>
<!-- Node 3: Security Filter (middle-left) -->
<g transform="translate(110, 270)">
<rect x="-60" y="-30" width="120" height="72" rx="12" fill="url(#nodeGrad)" stroke="#f87171" stroke-width="2"/>
<!-- Shield icon -->
<g transform="translate(-8, -22)">
<path d="M8,0 L16,4 L16,12 C16,18 8,22 8,22 C8,22 0,18 0,12 L0,4 Z" fill="none" stroke="#f87171" stroke-width="1.5"/>
<polyline points="4,11 7,14 12,8" fill="none" stroke="#f87171" stroke-width="1.5"/>
</g>
<text x="0" y="14" text-anchor="middle" fill="#f87171" font-size="13" font-weight="bold">보안 필터</text>
<text x="0" y="32" text-anchor="middle" fill="#94a3b8" font-size="10">악성 요청 차단</text>
</g>
<!-- Node 4: Static Cache (middle-right) -->
<g transform="translate(690, 270)">
<rect x="-60" y="-30" width="120" height="72" rx="12" fill="url(#nodeGrad)" stroke="#4ade80" stroke-width="2"/>
<!-- Lightning icon -->
<g transform="translate(-6, -22)">
<polygon points="8,0 2,10 6,10 4,18 14,7 9,7 12,0" fill="none" stroke="#4ade80" stroke-width="1.5"/>
</g>
<text x="0" y="14" text-anchor="middle" fill="#4ade80" font-size="13" font-weight="bold">정적 캐싱</text>
<text x="0" y="32" text-anchor="middle" fill="#94a3b8" font-size="10">빠른 자산 제공</text>
</g>
<!-- Node 5: Load Balancing (bottom-left) -->
<g transform="translate(135, 395)">
<rect x="-60" y="-30" width="120" height="72" rx="12" fill="url(#nodeGrad)" stroke="#a78bfa" stroke-width="2"/>
<!-- Scale/balance icon -->
<g transform="translate(-12, -22)">
<line x1="12" y1="2" x2="12" y2="16" stroke="#a78bfa" stroke-width="1.5"/>
<line x1="2" y1="6" x2="22" y2="6" stroke="#a78bfa" stroke-width="1.5"/>
<line x1="2" y1="6" x2="0" y2="14" stroke="#a78bfa" stroke-width="1.5"/>
<line x1="22" y1="6" x2="24" y2="14" stroke="#a78bfa" stroke-width="1.5"/>
<path d="M-3,14 Q0,18 3,14" fill="none" stroke="#a78bfa" stroke-width="1.5"/>
<path d="M21,14 Q24,18 27,14" fill="none" stroke="#a78bfa" stroke-width="1.5"/>
<rect x="7" y="16" width="10" height="3" rx="1" fill="#a78bfa"/>
</g>
<text x="0" y="14" text-anchor="middle" fill="#a78bfa" font-size="13" font-weight="bold">로드 밸런싱</text>
<text x="0" y="32" text-anchor="middle" fill="#94a3b8" font-size="10">트래픽 분산</text>
</g>
<!-- Node 6: Log Monitoring (bottom-right) -->
<g transform="translate(665, 395)">
<rect x="-60" y="-30" width="120" height="72" rx="12" fill="url(#nodeGrad)" stroke="#67e8f9" stroke-width="2"/>
<!-- Magnifying glass icon -->
<g transform="translate(-8, -22)">
<circle cx="8" cy="8" r="7" fill="none" stroke="#67e8f9" stroke-width="1.5"/>
<line x1="13" y1="13" x2="19" y2="19" stroke="#67e8f9" stroke-width="2" stroke-linecap="round"/>
</g>
<text x="0" y="14" text-anchor="middle" fill="#67e8f9" font-size="13" font-weight="bold">로그 모니터링</text>
<text x="0" y="32" text-anchor="middle" fill="#94a3b8" font-size="10">접근/에러 추적</text>
</g>
<!-- Bottom tagline -->
<rect x="225" y="458" width="350" height="34" rx="17" fill="#22d3ee" fill-opacity="0.12" stroke="#22d3ee" stroke-width="1.5"/>
<text x="400" y="481" text-anchor="middle" fill="#22d3ee" font-size="18" font-weight="bold">SAM 프로젝트의 수문장</text>
</svg>

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@@ -0,0 +1,155 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 500" font-family="sans-serif">
<defs>
<linearGradient id="bg9" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#0e3c4a"/>
<stop offset="100%" stop-color="#0f172a"/>
</linearGradient>
<linearGradient id="boardGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#1e293b"/>
<stop offset="100%" stop-color="#0f172a"/>
</linearGradient>
</defs>
<rect width="800" height="500" fill="url(#bg9)"/>
<!-- Title -->
<text x="400" y="42" text-anchor="middle" fill="#22d3ee" font-size="24" font-weight="bold">보안 필터 = 입장 불가 명단</text>
<!-- Guard figure -->
<g transform="translate(400, 200)">
<!-- Guard body -->
<circle cx="0" cy="-60" r="22" fill="#334155" stroke="#22d3ee" stroke-width="2"/>
<!-- Sunglasses -->
<rect x="-14" y="-66" width="11" height="7" rx="2" fill="#0f172a" stroke="#67e8f9" stroke-width="1"/>
<rect x="3" y="-66" width="11" height="7" rx="2" fill="#0f172a" stroke="#67e8f9" stroke-width="1"/>
<line x1="-3" y1="-62" x2="3" y2="-62" stroke="#67e8f9" stroke-width="1"/>
<!-- Mouth -->
<line x1="-5" y1="-52" x2="5" y2="-52" stroke="#94a3b8" stroke-width="1.5" stroke-linecap="round"/>
<!-- Hat -->
<rect x="-18" y="-85" width="36" height="8" rx="2" fill="#1e293b" stroke="#22d3ee" stroke-width="1.5"/>
<rect x="-12" y="-95" width="24" height="12" rx="2" fill="#1e293b" stroke="#22d3ee" stroke-width="1.5"/>
<text x="0" y="-86" text-anchor="middle" fill="#22d3ee" font-size="7" font-weight="bold">GUARD</text>
<!-- Body -->
<rect x="-20" y="-36" width="40" height="50" rx="6" fill="#334155" stroke="#22d3ee" stroke-width="2"/>
<text x="0" y="-8" text-anchor="middle" fill="#22d3ee" font-size="10" font-weight="bold">NGINX</text>
<!-- Arms -->
<line x1="-20" y1="-25" x2="-38" y2="-5" stroke="#334155" stroke-width="8" stroke-linecap="round"/>
<line x1="20" y1="-25" x2="38" y2="-5" stroke="#334155" stroke-width="8" stroke-linecap="round"/>
<line x1="-20" y1="-25" x2="-38" y2="-5" stroke="#22d3ee" stroke-width="2" stroke-linecap="round"/>
<line x1="20" y1="-25" x2="38" y2="-5" stroke="#22d3ee" stroke-width="2" stroke-linecap="round"/>
<!-- Legs -->
<line x1="-8" y1="14" x2="-10" y2="40" stroke="#334155" stroke-width="8" stroke-linecap="round"/>
<line x1="8" y1="14" x2="10" y2="40" stroke="#334155" stroke-width="8" stroke-linecap="round"/>
<line x1="-8" y1="14" x2="-10" y2="40" stroke="#22d3ee" stroke-width="2" stroke-linecap="round"/>
<line x1="8" y1="14" x2="10" y2="40" stroke="#22d3ee" stroke-width="2" stroke-linecap="round"/>
</g>
<!-- Blacklist Board (center) -->
<g transform="translate(320, 255)">
<rect x="0" y="0" width="160" height="180" rx="8" fill="url(#boardGrad)" stroke="#22d3ee" stroke-width="2"/>
<rect x="55" y="-10" width="50" height="20" rx="4" fill="#22d3ee"/>
<text x="80" y="5" text-anchor="middle" fill="#0f172a" font-size="11" font-weight="bold">차단 목록</text>
<!-- List items -->
<text x="18" y="38" fill="#f87171" font-size="13" font-weight="bold">../</text>
<text x="65" y="38" fill="#94a3b8" font-size="11">경로 트래버설</text>
<text x="142" y="38" fill="#f87171" font-size="14" font-weight="bold">X</text>
<text x="18" y="65" fill="#f87171" font-size="13" font-weight="bold">.env</text>
<text x="65" y="65" fill="#94a3b8" font-size="11">환경 파일</text>
<text x="142" y="65" fill="#f87171" font-size="14" font-weight="bold">X</text>
<text x="18" y="92" fill="#f87171" font-size="13" font-weight="bold">.git</text>
<text x="65" y="92" fill="#94a3b8" font-size="11">소스코드</text>
<text x="142" y="92" fill="#f87171" font-size="14" font-weight="bold">X</text>
<text x="18" y="119" fill="#f87171" font-size="13" font-weight="bold">sqlmap</text>
<text x="80" y="119" fill="#94a3b8" font-size="11">해킹 도구</text>
<text x="142" y="119" fill="#f87171" font-size="14" font-weight="bold">X</text>
<text x="18" y="146" fill="#f87171" font-size="13" font-weight="bold">nikto</text>
<text x="72" y="146" fill="#94a3b8" font-size="11">스캐너</text>
<text x="142" y="146" fill="#f87171" font-size="14" font-weight="bold">X</text>
<!-- Separator lines -->
<line x1="10" y1="47" x2="150" y2="47" stroke="#1e293b" stroke-width="1"/>
<line x1="10" y1="74" x2="150" y2="74" stroke="#1e293b" stroke-width="1"/>
<line x1="10" y1="101" x2="150" y2="101" stroke="#1e293b" stroke-width="1"/>
<line x1="10" y1="128" x2="150" y2="128" stroke="#1e293b" stroke-width="1"/>
</g>
<!-- Left side: Blocked requests -->
<g transform="translate(30, 100)">
<text x="80" y="0" text-anchor="middle" fill="#f87171" font-size="16" font-weight="bold">차단된 요청</text>
<!-- Blocked request 1 -->
<rect x="0" y="18" width="165" height="36" rx="6" fill="#1e293b" stroke="#f87171" stroke-width="1.5" stroke-dasharray="4,2"/>
<text x="12" y="40" fill="#f87171" font-size="12">GET /../../etc/passwd</text>
<circle cx="152" cy="36" r="10" fill="none" stroke="#f87171" stroke-width="2"/>
<line x1="145" y1="29" x2="159" y2="43" stroke="#f87171" stroke-width="2"/>
<line x1="159" y1="29" x2="145" y2="43" stroke="#f87171" stroke-width="2"/>
<!-- Blocked request 2 -->
<rect x="0" y="66" width="165" height="36" rx="6" fill="#1e293b" stroke="#f87171" stroke-width="1.5" stroke-dasharray="4,2"/>
<text x="12" y="88" fill="#f87171" font-size="12">GET /.env</text>
<circle cx="152" cy="84" r="10" fill="none" stroke="#f87171" stroke-width="2"/>
<line x1="145" y1="77" x2="159" y2="91" stroke="#f87171" stroke-width="2"/>
<line x1="159" y1="77" x2="145" y2="91" stroke="#f87171" stroke-width="2"/>
<!-- Blocked request 3 -->
<rect x="0" y="114" width="165" height="36" rx="6" fill="#1e293b" stroke="#f87171" stroke-width="1.5" stroke-dasharray="4,2"/>
<text x="12" y="136" fill="#f87171" font-size="12">GET /.git/config</text>
<circle cx="152" cy="132" r="10" fill="none" stroke="#f87171" stroke-width="2"/>
<line x1="145" y1="125" x2="159" y2="139" stroke="#f87171" stroke-width="2"/>
<line x1="159" y1="125" x2="145" y2="139" stroke="#f87171" stroke-width="2"/>
<!-- Blocked request 4 -->
<rect x="0" y="162" width="165" height="36" rx="6" fill="#1e293b" stroke="#f87171" stroke-width="1.5" stroke-dasharray="4,2"/>
<text x="12" y="184" fill="#f87171" font-size="12">UA: sqlmap/1.5</text>
<circle cx="152" cy="180" r="10" fill="none" stroke="#f87171" stroke-width="2"/>
<line x1="145" y1="173" x2="159" y2="187" stroke="#f87171" stroke-width="2"/>
<line x1="159" y1="173" x2="145" y2="187" stroke="#f87171" stroke-width="2"/>
<!-- Arrow blocked -->
<line x1="170" y1="110" x2="220" y2="110" stroke="#f87171" stroke-width="2" stroke-dasharray="6,3"/>
<polygon points="220,105 230,110 220,115" fill="#f87171"/>
<text x="200" y="130" text-anchor="middle" fill="#f87171" font-size="10">403</text>
</g>
<!-- Right side: Passed requests -->
<g transform="translate(590, 100)">
<text x="90" y="0" text-anchor="middle" fill="#4ade80" font-size="16" font-weight="bold">통과된 요청</text>
<!-- Passed request 1 -->
<rect x="10" y="18" width="175" height="36" rx="6" fill="#1e293b" stroke="#4ade80" stroke-width="1.5"/>
<text x="22" y="40" fill="#4ade80" font-size="12">GET /dashboard</text>
<circle cx="168" cy="36" r="10" fill="none" stroke="#4ade80" stroke-width="2"/>
<polyline points="161,36 165,40 175,30" fill="none" stroke="#4ade80" stroke-width="2"/>
<!-- Passed request 2 -->
<rect x="10" y="66" width="175" height="36" rx="6" fill="#1e293b" stroke="#4ade80" stroke-width="1.5"/>
<text x="22" y="88" fill="#4ade80" font-size="12">POST /api/orders</text>
<circle cx="168" cy="84" r="10" fill="none" stroke="#4ade80" stroke-width="2"/>
<polyline points="161,84 165,88 175,78" fill="none" stroke="#4ade80" stroke-width="2"/>
<!-- Passed request 3 -->
<rect x="10" y="114" width="175" height="36" rx="6" fill="#1e293b" stroke="#4ade80" stroke-width="1.5"/>
<text x="22" y="136" fill="#4ade80" font-size="12">GET /images/logo.png</text>
<circle cx="168" cy="132" r="10" fill="none" stroke="#4ade80" stroke-width="2"/>
<polyline points="161,132 165,136 175,126" fill="none" stroke="#4ade80" stroke-width="2"/>
<!-- Passed request 4 -->
<rect x="10" y="162" width="175" height="36" rx="6" fill="#1e293b" stroke="#4ade80" stroke-width="1.5"/>
<text x="22" y="184" fill="#4ade80" font-size="12">GET /api/products</text>
<circle cx="168" cy="180" r="10" fill="none" stroke="#4ade80" stroke-width="2"/>
<polyline points="161,180 165,184 175,174" fill="none" stroke="#4ade80" stroke-width="2"/>
<!-- Arrow passed -->
<line x1="-30" y1="110" x2="-5" y2="110" stroke="#4ade80" stroke-width="2"/>
<polygon points="-5,105 5,110 -5,115" fill="#4ade80"/>
<text x="-12" y="130" text-anchor="middle" fill="#4ade80" font-size="10">200</text>
</g>
<!-- Bottom label -->
<rect x="250" y="455" width="300" height="36" rx="18" fill="#22d3ee" fill-opacity="0.15" stroke="#22d3ee" stroke-width="1.5"/>
<text x="400" y="479" text-anchor="middle" fill="#22d3ee" font-size="18" font-weight="bold">Nginx 보안 필터링</text>
</svg>

After

Width:  |  Height:  |  Size: 9.2 KiB