인터넷에 노출된 웹 애플리케이션은 SQL 인젝션, 자격 증명 악용, 알려진 취약점 패턴을 노린 탐색 공격을 상시로 받습니다. SafeLine은 GPL-3.0 셀프 호스팅 WAF 로, Docker Compose 스택으로 실행되며 허용된 요청을 오리진으로 전달하기 전에 HTTP/S 트래픽을 필터링합니다. 이 제품의 무료 Personal 요금제는 최대 10개의 애플리케이션을 지원합니다.
이 튜토리얼은 설치 과정과 특별히 주의해야 할 세 가지 영역을 다룹니다. 리버스 프록시 아키텍처 결정, SafeLine이 Nginx Proxy Manager 같은 기존 프록시 뒤에 위치할 때의 Docker 네트워크 구성, 그리고 설치 후 실행하여 WAF가 실제로 공격을 가로채는지 확인할 수 있는 검증 명령입니다.
요약
- Docker Compose로 Linux VPS에 SafeLine을 설치하세요. 한 줄 설치 프로그램을 사용하거나, 스택을 시작하기 전에 Compose 정의와 환경 구성을 직접 확인하려면 수동 Docker Compose 방식을 선택하세요.
- 설치하기 전에 리버스 프록시 아키텍처를 결정하세요. SafeLine이 유일한 프록시인 경우, 기존 Nginx Proxy Manager 뒤에 SafeLine을 두는 경우, 또는 SafeLine이 Caddy와 서버를 공유하는 경우가 있습니다. 각 구성마다 다른 포트 할당과 X-Forwarded-For 설정이 필요합니다.
- 설치 후에는 보호 대상 URL에 curl로 SQL 인젝션 탐색 요청을 보내 WAF를 검증하세요. Balanced 또는 Strict 모드에서는 403 응답과 함께 일치하는 Attack Events 항목이 차단을 확인해 줍니다. Monitor 모드에서는 응답이 성공 상태로 남더라도 일치하는 이벤트가 탐지를 확인해 줍니다.
- 무료 Personal 등급은 최대 10개의 애플리케이션과 핵심 탐지 엔진을 제공합니다. 지역 차단, 공격 로그 내보내기, 외부 알림은 Lite 등급이 필요하며, 더 강력한 공격 탐지와 로드 밸런싱은 Pro가 필요합니다.
시작하기 전에: 사전 요구 사항과 이 튜토리얼이 다루는 내용
이 튜토리얼은 root 또는 sudo 권한으로 SSH 접속할 수 있는 Linux VPS가 있고 Docker가 설치되어 있다고 가정합니다. 마무리 시점에는 최소 한 개의 사이트를 보호하는 작동하는 SafeLine 인스턴스와 언제든 다시 실행할 수 있는 검증 명령을 갖추게 됩니다.
필요한 것:
- Linux VPS. 아래 명령은 systemd를 사용하는 Debian 또는 Ubuntu 계열 시스템을 가정합니다. 다른 배포판에서는 패키지 및 서비스 이름을 확인하세요.
- 다음 문서에 따르면 최소 1 vCPU, 1 GB RAM, 5 GB 디스크가 필요합니다. 공식 배포 요구 사항. 실제 운영 환경의 여유를 확보하려면 이 가이드는 2 vCPU, 4 GB RAM, 20 GB 디스크를 권장합니다.
- Docker 20.10.14 이상 및 Docker Compose 2.0 이상.
- SSSE3를 지원하는 x86_64 CPU. 다음으로 확인하세요.
lscpu | grep ssse3명령어가 존재한다고 가정하지 말고 확인하세요. - 보호 대상 애플리케이션을 공개 HTTPS로 노출할 계획이라면 DNS가 VPS 공용 IP를 가리키는 도메인 또는 서브도메인.
- 선택한 토폴로지에 맞는 포트. 구성 A와 C는 보통 SafeLine에 포트 80과 443을 할당하고, 구성 B는 그 포트들을 Nginx Proxy Manager가 사용하도록 두고 SafeLine에는 10080 같은 다른 리스너를 할당합니다.
- root 또는 sudo 권한.
VPS 제공업체의 방화벽 또는 보안 그룹에서 선택한 토폴로지가 필요로 하는 공용 포트만 노출하세요. SSH와 TCP 9443은 신뢰할 수 있는 관리 출처로 제한하세요. 구성 B에서는 TCP 10080을 공용 IPv4 및 IPv6에 대해 닫아두고, 모든 토폴로지에서 8080 같은 백엔드 포트는 비공개로 유지하세요. 10080에 직접 접근하면 NPM을 우회하여 X-Forwarded-For 신뢰 경계가 무효화됩니다.
참고: 수동 ARM64 배포의 경우 다음을 설정하세요.
ARCH_SUFFIX=-arm. SafeLine의 공식 배포 문서 에 따르면 ARM에는 Pro 라이선스가 필요하며 Personal Edition은 ARM에서 지원되지 않습니다. Personal Edition에는 x86_64 VPS를 사용하세요.
시작하기 전에 Docker를 확인하세요.
docker --version
docker compose version
두 명령 모두 설치된 버전을 반환해야 합니다. Docker가 20.10.14 이상이고 Docker Compose가 2.0.0 이상인 경우에만 계속 진행하세요. 그렇지 않으면 SafeLine을 설치하기 전에 업그레이드하세요.
먼저 리버스 프록시 아키텍처를 선택하세요
새로 준비한 VPS라면 SafeLine이 포트 80과 443을 온전히 차지할 수 있습니다. 이미 Nginx Proxy Manager, Caddy, 또는 애플리케이션 자체 Nginx를 실행 중인 VPS는 그렇지 못하며, 아키텍처 결정이 원활한 설치와 첫 부팅 시 포트 충돌 사이의 차이를 만듭니다. 시작 시점에 이것을 한 번 제대로 정해두면 나머지 배포는 기계적으로 진행됩니다.
세 가지 구성:
- 구성 A, SafeLine이 유일한 리버스 프록시. SafeLine이 포트 80과 443을 차지하고 보호 대상 애플리케이션의 TLS를 관리합니다. 현재 CE 릴리스는 Free Cert 워크플로를 포함하며, 수동 인증서 업로드도 계속 사용할 수 있습니다. 설치된 릴리스에서 정확한 인증서 옵션을 확인하세요. 백엔드는 비공개 포트에서 실행되며 SafeLine이 그쪽으로 라우팅합니다.
- 구성 B, Nginx Proxy Manager(NPM) 뒤의 SafeLine. NPM이 포트 80과 443을 유지하며 SSL을 처리합니다. SafeLine은 포트 10080에서 수신합니다(NPM이 이미 TLS를 종료했으므로 HTTP만). NPM이 SafeLine으로 전달하고, SafeLine이 백엔드로 전달합니다. 이는 NPM이 이미 배포되어 있을 때 흔한 구성입니다.
- 구성 C, Caddy와 함께 있는 SafeLine. Caddy의 자동 HTTPS는 포트 443을 두고 SafeLine과 경쟁합니다. 실용적인 방식은 SafeLine에 포트 80과 443을 할당하고, SafeLine에서 Caddy를 거쳐 애플리케이션으로 넘어가는 경로를 위해 Caddy를 8080 같은 비공개 내부 HTTP 포트로 옮기는 것입니다.
| 구성 | 포트 443 소유 | SSL 관리 | 복잡성 | 추천 용도 |
|---|---|---|---|---|
| A, SafeLine 단독 | SafeLine | SafeLine 내부 | 낮음 | 새 VPS 또는 마이그레이션 의향이 있는 경우 |
| B, NPM 뒤 | NPM | NPM 내부 (Let's Encrypt) | 중간 | 기존 NPM 배포 |
| C, Caddy와 함께 | SafeLine | SafeLine 내부 | 중간에서 높음 | 유지하고 싶은 기존 Caddy |
핵심 요점: 구성 A는 새 VPS에 가장 간단하고, 구성 B는 NPM이 이미 실행 중일 때 적합하며, 구성 C는 Caddy 포트를 의도적으로 재할당해야 합니다.
VPS에 SafeLine 설치하기
설치 자체는 쉬운 부분입니다. SafeLine은 두 가지 설치 방식을 제공합니다. waf.chaitin.com에서 원격 스크립트를 가져오는 자동 설치 프로그램과, 실행 전에 모든 것을 직접 확인할 수 있는 수동 Docker Compose 방식입니다. 보안 정책에 맞는 것을 선택하세요.
1단계: Docker가 준비되었는지 확인
Docker 버전과 Docker 데몬이 실행 중인지 다시 확인하세요.
docker --version
docker compose version
sudo systemctl status docker
예상 출력에는 다음이 포함됩니다. active (running) Docker 데몬에 대한 것입니다. 실행 중이 아니라면 다음으로 시작하세요. sudo systemctl start docker 그리고 다음으로 부팅 시 활성화하세요. sudo systemctl enable docker.
2단계: SafeLine 설치 프로그램 실행
두 가지 하위 방식이 있습니다. 하나를 선택하세요.
2a단계, 자동 설치. root 권한으로 설치 프로그램을 실행하세요.
sudo bash -c "$(curl -fsSLk https://waf.chaitin.com/release/latest/manager.sh)" -- --en
스크립트는 SafeLine 데이터 디렉터리를 어디에 둘지 묻고, Docker 이미지를 가져온 뒤 스택을 시작합니다. 설치 후에는 다음을 실행하세요. sudo docker exec safeline-mgt resetadmin 관리자 자격 증명을 조회하거나 재설정하려면 다음 문서에 설명된 대로 하세요. 공식 배포 가이드. 생성된 자격 증명을 안전하게 보관하세요.
참고: 이 명령은 waf.chaitin.com에서 원격 셸 스크립트를 root로 다운로드하고 실행합니다. 공식 한 줄 명령에는 다음이 포함됩니다.
curl -k이는 TLS 인증서 검증을 비활성화합니다. 실행 전에 다운로드한 스크립트를 검토하거나, 그 위험이 허용되지 않는다면 2b단계를 사용하세요. SafeLine은 Cloudzy 원클릭 배포로도 제공되지만, 그 이미지는 다음을 사용합니다./opt/safeline,/opt/safeline/.env, 그리고/opt/safeline/docker-compose.yml. 이 가이드의/data/safeline경로를 Cloudzy 이미지에서 변경 없이 그대로 사용하지 마세요.
2b단계, 수동 Docker Compose 설치. 공식 Compose 파일을 다운로드하여 확인한 뒤 스택을 시작하세요.
sudo mkdir -p /data/safeline
cd /data/safeline
sudo wget -O /data/safeline/compose.yaml "https://waf.chaitin.com/release/latest/compose.yaml"
POSTGRES_PASSWORD="$(openssl rand -hex 32)"
sudo tee .env >/dev/null <<EOF
SAFELINE_DIR=/data/safeline
IMAGE_TAG=latest
MGT_PORT=9443
POSTGRES_PASSWORD=$POSTGRES_PASSWORD
SUBNET_PREFIX=172.22.222
IMAGE_PREFIX=chaitin
ARCH_SUFFIX=
RELEASE=
REGION=-g
MGT_PROXY=0
EOF
unset POSTGRES_PASSWORD
# Also adjust SUBNET_PREFIX if your VPS already uses 172.22.222.0/24.
sudo chmod 600 /data/safeline/.env
sudo docker compose up -d
후 after docker compose up -d 완료되면 실행 중인 컨테이너를 나열하여 확인하세요.
sudo docker compose ps
safeline-mgt, safeline-detector, safeline-tengine, safeline-pg, safeline-fvm, safeline-luigi, safeline-chaos 컨테이너가 보여야 합니다. 어떤 컨테이너가 다음을 표시하면 Exited가장 흔한 두 가지 원인은 3단계를 참조하세요.
3단계: 흔한 설치 오류 해결
두 가지 오류가 충분히 자주 발생하므로 별도의 단계로 다룰 만합니다.
서브넷 중복. 설치가 다음으로 실패하면 Pool overlaps with other one on this address space기본 SafeLine 서브넷이 기존 Docker 네트워크와 충돌하는 것입니다. 다음 문서에 설명된 대로 SafeLine 설치 문제 해결 안내다음을 편집하여 해결하세요. /data/safeline/.env:
sudo nano /data/safeline/.env
# Find the line:
# SUBNET_PREFIX=172.22.222
# Change to an unused range, for example:
# SUBNET_PREFIX=172.30.30
sudo docker compose -f /data/safeline/compose.yaml down
sudo docker compose -f /data/safeline/compose.yaml up -d
IPv6 리졸버 오류. safeline-tengine이 다음으로 충돌하면 nginx: [emerg] invalid IPv6 address in resolver먼저 리졸버 파일을 확인하고 누가 관리하는지 파악하세요.
readlink -f /etc/resolv.conf
cat /etc/resolv.conf
다음을 편집하지 마세요. /etc/resolv.conf systemd-resolved, NetworkManager, 또는 VPS 제공업체가 생성한 것이라면 직접 편집하지 마세요. 관리 서비스의 구성에서 잘못된 nameserver 값을 수정하고, 리졸버 파일을 다시 생성한 뒤 Tengine을 재시작하세요.
sudo docker restart safeline-tengine
4단계: 대시보드 접근
SafeLine의 관리 대시보드는 HTTPS를 통해 TCP 9443에서 수신합니다. 이 관리 포트를 인터넷 전체에 열어두지 마세요. 신뢰할 수 있는 출처 주소나 VPN으로 제한하거나, 공개 접근을 차단하고 SSH 터널을 사용하세요.
ssh -L 9443:127.0.0.1:9443 USER@SERVER_IP
열기 https://localhost:9443 터널을 통해 접근합니다. 첫 접근 시 자체 서명 인증서 경고가 나타나는 것이 정상입니다. 계속하기 전에 SSH 연결이 의도한 서버에 도달했는지 확인하세요.
초기 자격 증명을 잃어버렸다면 호스트에서 관리자 비밀번호를 재설정하세요.
sudo docker exec safeline-mgt resetadmin
이 명령은 다시 로그인하는 데 사용할 수 있는 관리자 자격 증명을 출력합니다.
아키텍처에 맞게 SafeLine 구성하기
이제 SafeLine이 실행 중이지만 아직 아무것도 보호하고 있지 않습니다. 대시보드의 Applications 페이지에서 SafeLine에게 어떤 사이트를 보호하고 정제된 트래픽을 어디로 전달할지 알려줍니다. 구성은 앞서 선택한 아키텍처에 따라 다르므로 각 구성마다 별도의 하위 섹션이 있습니다. 자신의 설정에 맞는 것만 진행하세요.
구성 A: 유일한 리버스 프록시로서의 SafeLine
구성 A에서는 SafeLine이 포트 80과 443에서 직접 수신하고 정제된 트래픽을 비공개 포트의 백엔드 애플리케이션으로 전달합니다. 대시보드에서:
- 로 이동 Applications, 그다음 Add Application.
- 수신 포트를 443으로 설정하고 SSL을 활성화하세요. 설치된 SafeLine 릴리스에서 사용할 수 있는 인증서 워크플로를 이용하세요. 현재 CE 릴리스는 Free Cert 발급 및 갱신 처리를 포함하며, 수동 인증서 업로드도 계속 사용할 수 있습니다.
- 업스트림을 다음으로 설정하세요.
http://127.0.0.1:8080. 백엔드가 Docker에서 실행된다면 해당 포트를 루프백에만 게시하세요. 예를 들어"127.0.0.1:8080:8080"서비스의 ports 섹션에서요. 다음과 같이 하드코딩된 컨테이너 IP는 피하세요.172.17.0.5컨테이너가 다시 생성될 때 바뀔 수 있기 때문입니다. - 애플리케이션을 저장하세요. SafeLine이 즉시 443에서 수신을 시작하고 정제된 트래픽을 백엔드로 전달합니다.
- 도메인의 DNS A 레코드가 VPS 공용 IP를 가리키고 포트 80과 443이 외부에서 접근 가능한지 확인하세요.
포트 443이 이미 다른 프로세스에 바인딩되어 있으면 SafeLine 컨테이너가 바인딩에 실패하고 대시보드에 해당 애플리케이션 오류가 표시됩니다. 애플리케이션을 추가하기 전에 충돌하는 프로세스를 중지하거나 다른 포트를 선택하세요.
구성 B: Nginx Proxy Manager 뒤의 SafeLine
구성 B는 NPM이 하던 일(포트 80과 443 소유, Let's Encrypt 처리)을 그대로 유지하고 그 뒤에 SafeLine을 전용 보안 계층으로 배치합니다. 트래픽 흐름은 클라이언트, NPM(포트 443, TLS 종료), SafeLine(포트 10080, HTTP), 백엔드 애플리케이션 순입니다.
SafeLine 대시보드 내부에서:
- Applications, 그다음 Add Application. 수신 포트를 10080으로 설정하고 SSL을 끈 상태로 두세요(NPM이 이미 TLS를 종료했습니다).
- 구성 A에서 설명한 대로 업스트림을 애플리케이션의 내부 주소로 설정하세요.
- 애플리케이션을 저장하세요.
Nginx Proxy Manager에서:
- Hosts, 그다음 Proxy Hosts, 그다음 Add Proxy Host.
- Details 탭: 도메인 이름과 스킴을 설정하세요.
http그리고 포워드 포트 10080을 설정하세요. NPM이 호스트에서 직접 실행된다면 다음을 사용하세요.127.0.0.1를 포워드 호스트명으로요. Linux의 Docker에서 NPM이 실행된다면127.0.0.1는 VPS 호스트가 아니라 NPM 컨테이너를 가리킵니다. Docker의 host-gateway 매핑을 추가하세요. 를 NPM Compose 서비스에 추가한 뒤 다음을 사용하세요.host.docker.internal를 포워드 호스트명으로요.
extra_hosts:
- "host.docker.internal:host-gateway"
NPM Compose 디렉터리에서 다음을 실행하세요. sudo docker compose up -d 그러면 컨테이너가 새 호스트 매핑으로 다시 생성됩니다.
- SSL 탭: Let's Encrypt 인증서를 요청하고, SSL을 강제하고, HTTP/2를 활성화하세요.
- X-Forwarded-For와 관련해 NPM의 Advanced 탭은 비워두세요. 다음 현재 NPM 템플릿에서는Advanced 내용이 server 범위에 삽입되며, 다음의 위치 수준에서 생성된 헤더를 덮어쓰지 않습니다. NGINX의 상속 규칙. 생성된 location은 다음을 전송합니다.
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
두 번째 지시어는 NPM이 관측한 주소를 헤더의 가장 오른쪽 값으로 추가합니다.
- Proxy Host를 저장하세요.
다시 SafeLine으로 돌아와, 실제 헤더 체인을 확인한 후에만 출발지 IP 추출을 구성하세요. SafeLine 9.3.1은 방향 및 인덱스 선택이 가능한 유연한 XFF 추출을 도입했습니다.
- Settings, 그다음 Advanced, 그다음 Real IP from Header. 헤더 이름을 다음으로 설정하세요.
X-Forwarded-For. - 헤더 끝에서 사용자 지정 추출을 사용하고 NPM이 추가한 가장 오른쪽 주소를 선택하세요. 정확한 인덱스 레이블은 버전마다 다르므로 Logs, 그다음 Access에서 결과를 확인하세요. 설치된 릴리스가 9.3.1 이전이라면 이 토폴로지를 따르기 전에 업데이트하세요.
- Cloudflare나 다른 CDN이 NPM 앞에 있다면, 먼저 NPM이 해당 제공업체가 공개한 프록시 범위만 신뢰하도록 구성하여 NPM이 추가한 주소가 신뢰할 수 있게 하세요. 실제 헤더 체인을 확인하고 테스트하기 전까지는 고정 위치를 선택하지 마세요.
- 애플리케이션을 저장하고 다시 로드하세요.
VPS 외부의 컴퓨터에서 구성을 테스트하세요.
curl -H "X-Forwarded-For: 1.2.3.4" "https://yourdomain.com/"
SafeLine 접근 로그에는 실제 공용 주소가 표시되어야 하며, 다음이 표시되면 안 됩니다. 1.2.3.4 또는 NPM의 브리지 주소.
백엔드 리스너를 비공개로 유지하여 사용자가 SafeLine을 우회하지 못하게 하세요. Docker Compose 백엔드의 경우 포트를 루프백에만 게시하세요.
ports:
- "127.0.0.1:8080:8080"
호스트에서 직접 실행되는 서비스의 경우 다음에서 수신하도록 구성하세요. 127.0.0.1:8080 다음 대신에 0.0.0.0:8080. VPS 외부의 컴퓨터에서 두 내부 포트를 모두 확인하세요.
curl --connect-timeout 5 "http://YOUR_VPS_PUBLIC_IP:10080"
curl --connect-timeout 5 "http://YOUR_VPS_PUBLIC_IP:8080"
TCP 연결이 거부되거나 시간 초과되어야 합니다. HTTP 오류나 "Empty reply from server"가 나오더라도 그 포트는 여전히 공개적으로 접근 가능하다는 뜻이므로 보안 조치가 필요합니다. 루프백 바인딩이 불가능하다면 일반적인 DOCKER-USER 규칙을 적용하는 대신 실제 인터페이스, Docker 네트워크, 대상 컨테이너에 맞춘 방화벽 규칙을 만드세요.
구성 C: Caddy와 함께하는 SafeLine
구성 C에서는 SafeLine이 포트 80과 443을 차지하고, Caddy는 비공개 내부 HTTP 포트로 옮깁니다. 트래픽 흐름은 클라이언트, SafeLine(443, TLS), Caddy(8080, 내부 HTTP), 애플리케이션 백엔드 순입니다.
편집 /etc/caddy/Caddyfile:
:8080 {
bind 127.0.0.1
reverse_proxy 127.0.0.1:3000
}
원격 :8080 사이트 블록이 중요한 부분입니다. 이제 Caddy는 443을 두고 SafeLine과 경쟁하는 대신 내부 HTTP 포트에서 수신합니다. 다음 bind 127.0.0.1 줄은 해당 리스너를 VPS 내부로 유지합니다. 다음으로 Caddy를 다시 로드하세요. sudo systemctl reload caddy 그리고 다음으로 확인하세요. sudo ss -ltnp | grep -E ':(443|8080)' Caddy가 443이 아니라 8080에 바인딩되었는지요.
SafeLine에서 SSL을 활성화한 상태로 443에서 수신하는 애플리케이션을 추가한 뒤, 업스트림을 다음으로 설정하세요. http://127.0.0.1:8080. Caddy는 SafeLine 앞이 아니라 뒤에 있으므로 X-Forwarded-For 설정은 기본 네트워크 연결 옵션으로 두어도 됩니다.
보호 모드를 선택하고 WAF가 공격을 차단하는지 검증하기
SafeLine에는 엔진이 요청을 악성으로 표시했을 때 무슨 일이 일어날지 결정하는 세 가지 보호 모드가 있습니다. 적합한 시작 모드는 애플리케이션에 따라 다르지만, 검증 단계는 어떤 모드에서든 동일합니다.
보호 모드: Monitor, Balanced, Strict
SafeLine의 각 애플리케이션은 자체 보호 모드 설정을 가지며, 다음에서 구성할 수 있습니다. Applications, 그다음 해당 앱, 그다음 Protection Mode:
- Monitor. SafeLine이 원래라면 차단했을 요청을 기록하지만 차단하지는 않습니다. 이는 풍부한 입력 폼을 갖춘 복잡한 운영 애플리케이션(포럼, WYSIWYG 필드가 있는 관리 패널, 자유 형식 JSON 페이로드를 받는 API)에 가장 안전한 시작점입니다. Monitor를 며칠간 실행하고 Attack Events 페이지를 검토하여 실제 사용자에 대한 오탐이 없는지 확인한 후 Balanced로 승격하세요.
- Balanced. 기본 모드입니다. SafeLine의 벤더가 공개한 GitHub 수치 는 Balanced 모드에 대해 탐지율 71.65%, 정확도 99.45%, 오탐률 0.07%를 보고합니다. Strict 모드는 탐지율 76.17%, 정확도 99.38%, 오탐률 0.22%로 보고됩니다. 이는 독립적인 벤치마크가 아니라 벤더가 보고한 결과이며, README는 데이터셋을 WAF-Eval로 명시하지 않습니다. 이를 보장된 운영 성능이 아니라 비교용 제품 수치로 받아들이세요.
- Strict. 더 엄격한 휴리스틱과 위에 나온 탐지율 대 오탐 사이의 절충을 갖춘 더 공격적인 규칙 집합입니다. 트래픽을 파악한 후, 문제없이 Balanced를 1~2주 운영한 뒤에 시도해 볼 만합니다.
권장 사항: 방해할 실제 트래픽이 없는 신규 배포에는 Balanced를 사용하세요. 기존 운영 애플리케이션이라면 며칠간 Monitor로 시작하여 Attack Events 로그에서 오탐을 찾고, 예외를 조정한 후 Balanced로 승격하세요. Strict는 트래픽을 파악한 후 Balanced를 1~2주 운영한 뒤에 시도해 볼 만합니다.
curl SQLi 테스트로 WAF 검증하기
설치가 완료되었다고 보기 전 마지막 단계는 WAF가 실제로 공격을 가로채는지 확인하는 것입니다. VPS 외부의 아무 컴퓨터에서 보호 대상 사이트를 향해 무해한 SQL 인젝션 탐색 요청을 실행하세요.
curl -i "https://yourdomain.com/?id=1%20and%201=2%20union%20select%201"
이것은 SafeLine이 공개한 SQL 인젝션 테스트 벡터입니다. Balanced 또는 Strict 모드에서는 403 상태와 SafeLine 차단 응답이 예상됩니다. Monitor 모드에서는 요청이 차단되지 않고 기록될 것으로 예상됩니다. HTTP 버전과 정확한 응답 본문은 다를 수 있으므로 Attack Events의 일치하는 항목으로 결과를 확인하세요.
그런 다음 4단계의 제한된 접근 방법을 통해 대시보드를 열고 Logs, 그다음 Attack Events로 이동하세요. 일치하는 타임스탬프, 공격 유형 SQL Injection, curl을 실행한 컴퓨터와 일치하는 출발지 IP, 그리고 요청 세부 정보에 문제의 쿼리 문자열이 담긴 새 항목이 보여야 합니다. 이벤트를 클릭하면 SafeLine이 캡처한 전체 요청과 응답을 볼 수 있습니다.
curl 요청이 200 OK를 반환했다면, Attack Events 로그와 함께 결과를 해석하세요.
- 일치하는 SQL Injection 이벤트가 있다면 애플리케이션이 아마도 Monitor 모드일 것입니다. 차단 없이 기록되는 것이 정상입니다.
- 일치하는 이벤트가 없다면, DNS가 의도한 VPS로 해석되는지 확인하고, SafeLine 리스너 및 업스트림 구성을 점검하고, 요청 시각을 SafeLine 접근 로그와 대조하세요.
- 또한 보호가 활성화되어 있고, IP 화이트리스트, 사용자 지정 허용 규칙, 경로 예외가 테스트 요청에 해당하지 않는지 확인하세요.
핵심 요점: curl 탐색 요청이 SafeLine 차단 페이지와 함께 403을 반환하고 Attack Events에 공격 유형 SQL Injection 항목이 나타나면, WAF가 트래픽을 올바르게 가로채고 있는 것입니다.
무료 등급이 제공하는 것과 유료 요금제가 필요한 것
무료 Personal 등급은 대부분의 단일 VPS 배포를 보호하기에 충분합니다. 유료 등급은 운영 기능(알림, 로그 내보내기, 지역 차단)이 필요하거나 10개 애플리케이션 한도를 넘어설 때부터 의미가 있습니다.
다음에서 가져온 세부 내역입니다. CyberServal 가격 페이지:
- Personal, 무료. 최대 10개의 애플리케이션. 시맨틱 탐지 엔진(SQLi, XSS, 명령어 인젝션, 경로 탐색, SSRF, XXE, CRLF), 속도 제한, 봇 CAPTCHA 챌린지, 자동화된 스크레이퍼를 막는 동적 HTML/JS 암호화, 웹 ACL 규칙, 인증서 관리를 포함합니다. 현재 CE 릴리스는 또한 Free Cert 발급 및 갱신 처리를 포함합니다.
- Lite, 월 $10 또는 연 $100. 지역 차단, 위협 인텔리전스 IP 데이터베이스, Discord 및 Telegram 알림 연동, 공격 로그 내보내기를 추가하고 애플리케이션 한도를 20개로 늘립니다.
- Pro, 월 $100 또는 연 $1,000. 더 강력한 공격 탐지, 서비스별 및 전역 구성, 사용자 지정 차단 페이지, 업스트림 로드 밸런싱, 마스터-슬레이브 노드 동기화, 무제한 애플리케이션을 추가합니다. 다음을 참조하세요. 현재 가격표 변경 사항은요.
- Ultimate, 맞춤 가격. 여러 채널에 걸친 1대1 지원과 맞춤 기능 개발을 갖춘 맞춤형 엔터프라이즈 조건.
SafeLine은 로컬 Compose 스택 내부에서 애플리케이션 데이터를 처리하고 저장합니다. 그러나 현재 CE 릴리스 노트는 위협 인텔리전스 공유(Threat Intelligence Sharing)를 언급하므로, 운영자는 배포를 완전 무유출(zero-egress)로 간주하기 전에 설치된 버전의 UEP, 개인정보, 공유 설정을 검토하고 아웃바운드 연결을 관찰해야 합니다.
여기서 더 나아가기
설치가 완료되었고 WAF가 검증되었습니다. 몇 가지 후속 작업이 배포를 건강하게 유지하는 데 도움이 됩니다.
- 풍부한 사용자 입력을 받는 운영 애플리케이션(포럼, 관리 패널, 자유 형식 API)의 경우 보호 모드를 다음으로 설정하세요. 모니터 3일에서 7일 동안 유지하고, Attack Events 페이지를 매일 검토하며, 오탐을 조정한 후 Balanced로 승격하세요.
- Lite 등급에서는 Discord 또는 Telegram 알림 연동을 설정하여 공격 알림이 대시보드 밖에서도 전달되도록 하세요.
- 월별 유지 관리 시간을 예약하세요. 업그레이드 전에 SafeLine의 데이터와 환경 구성을 백업하고 다음을 읽으세요. 현재 릴리스 노트그리고 설치된 버전에 지원되는 업그레이드 절차를 사용하세요. 다음에만 의존하지 마세요.
docker compose pull다음으로docker compose up -d릴리스 간에 Compose 정의나 필요한 환경 변수가 바뀔 수 있기 때문입니다. Cloudzy 원클릭 사용자는 다음에서 작업해야 합니다./opt/safeline그리고 마켓플레이스 이미지의 지침을 따르세요. - 다음을 구독하세요. SafeLine 릴리스 페이지 보안 패치 알림을 위해서요. 그리고 다음도요. 프로젝트 저장소 이슈 추적을 위해서요.
이 배포를 위한 VPS가 아직 없다면, SafeLine은 다음에서 원클릭 배포로 제공됩니다. Cloudzy 마켓플레이스. 4 GB RAM 플랜은 이 가이드에서 권장하는 실용적인 여유 공간을 제공합니다. 다음을 다시 확인하세요: 현재 가격표 게시 시점에 Cloudzy에서, 플랜 사양은 변경될 수 있기 때문입니다. 원클릭 이미지는 다음을 사용합니다: /opt/safeline 와 /opt/safeline/docker-compose.yml따라서 아키텍처 및 대시보드 지침은 적용되지만, 이 가이드의 /data/safeline 명령은 동일하게 적용되지 않습니다.
자주 묻는 질문
SafeLine WAF가 Nginx Proxy Manager를 대체하나요, 아니면 둘 다 실행하나요?
SafeLine은 유일한 리버스 프록시로 배포될 때 Nginx Proxy Manager를 대체할 수 있습니다. 그러나 NPM을 반드시 대체할 필요는 없습니다. 흔한 구성은 SSL과 라우팅을 위해 NPM을 앞에 두고 그 뒤에 SafeLine을 전용 보안 계층으로 배치하는 것입니다. 둘 다 잘 작동합니다. 선택은 하나의 도구가 두 가지 일을 하기를 원하는지, 아니면 두 도구가 각각 한 가지 일을 잘하기를 원하는지에 달려 있습니다.
무료 등급이 단일 WordPress 사이트나 소규모 SaaS에 충분한가요?
보호 측면에서는 충분합니다. 무료 Personal 등급은 시맨틱 탐지 엔진, 속도 제한, 봇 CAPTCHA 챌린지, 동적 HTML/JS 암호화를 포함하며, 이는 단일 사이트의 핵심 방어 수단입니다. 유료 등급은 지역 차단, 공격 로그 내보내기, 외부 알림, 더 높은 애플리케이션 한도, 더 강력한 탐지, 로드 밸런싱 같은 운영 기능을 추가합니다. 유료 등급이 필요한지는 트래픽 양만이 아니라 필요한 기능과 애플리케이션 수에 달려 있습니다.
SafeLine이 1 GB RAM VPS에서 작동하나요?
SafeLine의 공식 최소 사양은 1 GB RAM입니다. 이는 테스트나 매우 가벼운 워크로드에는 충분할 수 있지만, 운영 용량은 트래픽, 활성화된 기능, 로그 보존에 따라 달라집니다. 소규모 운영 배포의 경우 2 vCPU와 4 GB RAM이 보수적인 시작점입니다. 메모리 사용량을 모니터링하고 측정된 부하에 따라 확장하세요.
왜 ARM64에는 유료 라이선스가 필요한가요?
SafeLine의 공식 배포 문서 에 따르면 ARM 배포에는 Pro 라이선스가 필요하며 Personal Edition은 ARM에서 지원되지 않습니다. Personal Edition을 원한다면 x86_64 VPS를 선택하세요. ARM이 필요하다면 Pro 라이선스를 준비하세요.
Chaitin Tech가 내 SafeLine 인스턴스에서 무엇을 받나요?
정확한 아웃바운드 데이터는 릴리스와 활성화된 기능에 따라 달라질 수 있습니다. 현재 CE 릴리스 노트는 위협 인텔리전스 공유(Threat Intelligence Sharing)를 언급하며, 설치된 버전은 UEP나 기타 공유 설정도 노출할 수 있습니다. 그러한 설정과 설치된 버전의 릴리스 노트를 검토한 뒤 네트워크 수준에서 아웃바운드를 확인하세요. SafeLine의 로컬 컨테이너가 애플리케이션 데이터를 처리하지만, 그 사실만으로 UEP를 거부하면 모든 아웃바운드 요청이 중단된다는 것이 증명되지는 않습니다.