NGINX App Protect DoS 배포 가이드

F5 NGINX App Protect DoS는 당신의 웹 애플리케이션을 위한 DoS 공격에 대해 행동 기반 보호를 제공합니다.
이 가이드는 NGINX App Protect DoS 의 배포 방법과 업그레이드 방법에 관해 설명합니다.

목차

1. NGINX App Protect DoS 배포 전제 조건
2. NGINX App Protect DoS 배포 시 플랫폼 보안 고려사항
3. CentOS 7.4+ 설치
4. RHEL 7.4+ 설치
5. RHEL 8+ / Rocky Linux 8 설치
6. RHEL 9+ 설치
7. Debian / Ubuntu 설치
8. Alpine 3.15.x / 3.17.x 설치
9. NGINX App Protect DoS Docker 배포
 9-1. NGINX App Protect DoS Docker 배포 지침
 9-2. CentOS 7.4 Docker 배포 예시
 9-3. UBI7 Docker 배포 예시
 9-4. RHEL 8 / Rocky Linux 8 Docker 배포 예시
 9-5. RHEL 9 Docker 배포 예시
 9-6. Debian 10 (Buster) / Debian 11 (Bullseye) / Debian 12 (Bookworm) Docker 배포 예시
 9-7. Ubuntu 18.04 (Bionic) / 20.04 (Focal) / 22.04 (Jammy) Docker 배포 예시
 9-8. Alpine Docker 배포 예시
10. NGINX App Proetct와 Docker 배포
 10-1. Docker 배포 지침
 10-2. CentOS 7.4 Docker 배포 예시
 10-3. RHEL 7.4 Docker 배포 예시
 10-4. Debian 10 (Buster) / Debian 11 (Bullseye) / Debian 12 (Bookworm) Docker 배포 예시
 10-5. Ubuntu 18.04 (Bionic) / 20.04 (Focal) / 22.04 (Jammy) Docker 배포 예시
11. NGINX App Protect DoS Arbitrator
 11-1. 개요
 11-2. NGINX App Protect DoS Arbitrator가 필수적인 이유
 11-3. NGINX App Protect DoS Arbitrator 배포
 11-4. NGINX App Protect DoS 다중 VM 배포
12. 설치 후 점검사항
 12-1. NGINX Plus Releases와의 호환성
13. App Protect Dos 업그레이드
14. SELinux
 14-1. 파일 레이블 수정
 14-2. 사용자 지정 포트로 Syslog
 14-3. Kuberenetes 배포 예시

1. NGINX App Protect DoS 배포 전제 조건

NGINX App Protect DoS는 추가 비용으로 다운로드 가능한 동적 모듈로 제공됩니다. 기존 NGINX Plus 구독에 NGINX App Protect DoS를 구매하거나 추가하려면 NGINX STORE에 문의하세요.

NGINX Plus Release 24와 이후의 release는 NGINX App Protect DoS를 지원합니다.

NGINX App Protect DoS는 다음 운영 체제를 지원합니다.

  • CentOS 7.4.x
  • RHEL 7.4.x
  • RHEL 8.1.x / Rocky Linux 8
  • RHEL 9
  • Debian 10 (Buster)
  • Debian 11 (Bullseye)
  • Debian 12 (Bookworm)
  • Ubuntu 18.04 (Bionic)
  • Ubuntu 20.04 (Focal)
  • Ubuntu 22.04 (Jammy)
  • Alpine 3.15
  • Alpine 3.17

NGINX App Protect DoS 패키지는 다음 의존성 패키지를 필요로 합니다:

  1. nginx-plus-module-appprotectdos – App Protect DoS 배포 를 위한 NGINX Plus 동적 모듈
  2. libcurl – HTTP 엑세스를 위한 소프트웨어 라이브러리
  3. sudo – 권한이 있는 사용자로 명령 실행
  4. zeromq3 – 빠른 메시지 기반 애플리케이션을 위한 소프트웨어 라이브러리
  5. boost – 전문가의 검토를 거친(peer-reviewed) 이식 가능한 무료 C++ 소스 라이브러리
  6. openssl – Transport Layer Security(TLS), Secure Sockets Layer(SSL) 프로토콜을 위한 툴킷
  7. libelf – ELF 엑세스를 위한 소프트웨어 라이브러리

더 자세한 내용은 NGINX Plus의 전체 전제 조건 목록을 참고하세요. NGINX App Protect DoS는 기존에 설치된 NGINX Plus에 모듈로 설치하거나, 깨끗한 환경에 App Protect DoS가 포함된 완전한 NGINX Plus로 설치하거나, 혹은 NGINX App Protect WAF와 함께 시스템에 설치될 수 있습니다.

Note:

– gRPC, HTTP/2, WebSocket 보호는 보호할 서비스의 active monitoring을 필요로 합니다.
– TLS fingerprint 기능은 오래된 OpenSSL 버전으로 인해 CentOS 7.4, RHEL 7, UBI 7에서 사용되지 않습니다. OpenSSL 1.1.1 혹은 그 이상의 버전을 필요로 합니다.
– Ubuntu 18.04에서는 proxy_protocol 매개변수를 사용하는 app_protect_dos_monitor 모니터 지시문을 구성할 수 없습니다. 결과적으로 proxy_protocol 구성에 대한 gRPC 및 HTTP/2 DoS 보호가 지원되지 않습니다.

2. NGINX App Protect DoS 배포 시 플랫폼 보안 고려사항

App Protect DoS를 NGINX Plus에 배포할 때, 플랫폼 보호를 위해 다음 지침을 따르십시오. 이를 통해 서비스 거부(Denial of Service) 상태를 초래하거나, 플랫폼 보안을 위협하는 상황을 방지할 수 있습니다.

  • NGINX App Protect DoS platform의 파일 권한을 nginx 사용자와 nginx 그룹으로 제한하십시오. (특히 설정이 포함된 민감한 영역의 경우)
  • 플랫폼에서 불필요한 원격 접근 서비스를 제거하십시오.
  • Syslog 목적지를  App Protect DoS와 동일한 서버(machine)에 구성하고, 외부 목적지로 프록시 하십시오. 이를 통해 Syslog 채널의 감청 및 중간자 공격(man in the middle attack)을 방지할 수 있습니다.

3. CentOS 7.4+ 설치

1. NGINX 패키지가 이미 설치된 경우, 설정과 로그를 백업합니다.

$ sudo cp -a /etc/nginx /etc/nginx-plus-backup
$ sudo cp -a /var/log/nginx /var/log/nginx-plus-backup

2. /etc/ssl/nginx/ 디렉토리를 생성합니다.

$ sudo mkdir -p /etc/ssl/nginx

3. NGINX 사용자 포털에 로그인하여 다음 두 파일을 다운로드합니다.

nginx-repo.key
nginx-repo.crt

4. 위 두 파일을 CentOS 서버의 /etc/ssl/nginx/ 디렉토리에 복사합니다. SCP 클라이언트나 다른 파일 전송 툴을 사용하여 이 작업을 수행합니다.

5. 의존성을 설치합니다.

$ sudo yum install ca-certificates epel-release wget

6. NGINX Plus와 NGINX App Protect DoS 저장소를 추가합니다.

$ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-7.4.repo
$ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-7.repo

7. 새로 설치하는 경우 저장소를 업데이트하고 가장 최근 버전의 NGINX Plus App Protect DoS 패키지(NGINX Plus를 포함하는)를 설치합니다.

$ sudo yum install app-protect-dos

다음 명령어를 사용하여 유효한 버전을 확인할 수 있습니다.

$ sudo yum --showduplicates list app-protect-dos

이후, 위 출력의 특정 버전을 설치하려면 다음과 같이 입력합니다.

$ sudo yum install app-protect-dos-27+2.4.0

8. 이전에 설치된 NGINX Plus App Protect DoS(NGINX Plus가 포함된) 패키지를 업그레이드 하는 경우:

$ sudo yum remove nginx-plus
$ sudo yum install app-protect-dos
$ sudo systemctl start nginx

Note:

/etc/nginx-plus-backup의 설정을 /etc/nginx-plus로 복구하는 것을 잊지 마세요.

9. NGINX 버전을 확인하여 NGINX Plus가 정상적으로 설치된 것을 확인합니다.

$ sudo nginx -v

10. NGINX App Protect DoS 버전을 확인하여 맞는 버전이 설치된 것을 확인합니다.

$ sudo admd -v

11. nginx.conf 파일의 메인 컨텍스트에 NGINX App Protect DoS 모듈을 로드합니다.

load_module modules/ngx_http_app_protect_dos_module.so;

12. nginx.conf 파일의 http/server/location 컨텍스트에 NGINX App Protect DoS를 활성화합니다.

app_protect_dos_enable on;
app_protect_dos_name "vs-example";
app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";
app_protect_dos_monitor "example.com/";

13. SELinux가 NGINX App Protect DoS를 허용하도록 설정합니다.

a. vi 에디터를 사용하여 파일을 생성합니다:

$ vi app-protect-dos.te

b. 위에서 생성한 파일에 아래 내용을 입력합니다.

module app-protect-dos 2.0;
require {
    type unconfined_t;
    type unconfined_service_t;
    type httpd_t;
    type tmpfs_t;
    type initrc_t;
    type initrc_state_t;
    class capability sys_resource;
    class shm { associate read unix_read unix_write write };
    class file { read write };
}
allow httpd_t initrc_state_t:file { read write };
allow httpd_t self:capability sys_resource;
allow httpd_t tmpfs_t:file { read write };
allow httpd_t unconfined_service_t:shm { associate read unix_read unix_write write };
allow httpd_t unconfined_t:shm { associate read write unix_read unix_write };
allow httpd_t initrc_t:shm { associate read unix_read unix_write write };

c. 다음 명령어들을 입력합니다.

$ sudo checkmodule -M -m -o app-protect-dos.mod app-protect-dos.te
$ sudo semodule_package -o app-protect-dos.pp -m app-protect-dos.mod
$ sudo semodule -i app-protect-dos.pp;

설치에 문제가 발생한다면, 문제 해결 가이드를 확인하세요.

Note:

NGINX Plus가 특정 네트워크 포트로 리스닝 하거나, upstream에 연결하거나, 원격 시스템으로 syslog 항목을 전송하기 위해 추가적인 SEinux 설정이 필요할 수 있습니다. 자세한 내용은 Using NGINX and NGINX Plus with SELinux 를 참고하세요.

14. NGINX/App-Protect-DoS 서비스가 부팅 시 시작되도록 설정하려면 다음 명령어를 사용합니다.

$ sudo systemctl enable nginx.service

15. NGINX 서비스를 시작합니다.

$ sudo systemctl start nginx

4. RHEL 7.4+ 설치

1. NGINX 패키지가 이미 설치된 경우, 설정과 로그를 백업합니다.

$ sudo cp -a /etc/nginx /etc/nginx-plus-backup
$ sudo cp -a /var/log/nginx /var/log/nginx-plus-backup

2. /etc/ssl/nginx/ 디렉토리를 생성합니다.

$ sudo mkdir -p /etc/ssl/nginx

3. NGINX 사용자 포털에 로그인하여 다음 두 파일을 다운로드합니다.

nginx-repo.key
nginx-repo.crt

4. 위 두 파일을 RHEL 서버의 /etc/ssl/nginx/ 디렉토리에 복사합니다. SCP 클라이언트나 다른 파일 전송 툴을 사용하여 이 작업을 수행합니다.

5. 의존성을 설치합니다.

$ sudo yum install ca-certificates epel-release wget

6. Yum 저장소를 활성화하여 App Protect DoS 의존성을 설치합니다.

RHEL 구독이 있는 경우:

 $ sudo subscription-manager repos --enable rhel-*-optional-rpms \
                                 --enable rhel-*-extras-rpms \
                                 --enable rhel-ha-for-rhel-*-server-rpms
 $ yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

RHEL 구독이 없는 경우 CentOS 저장소에서 의존성을 설치할 수 있습니다. /etc/yum.repos.d/ 디렉토리에 다음 내용을 포함하는 centos.repo 저장소를 생성합니다.

[centos]
name=CentOS-7
baseurl=http://ftp.heanet.ie/pub/centos/7/os/x86_64/
enabled=1
gpgcheck=1
gpgkey=http://ftp.heanet.ie/pub/centos/7/os/x86_64/RPM-GPG-KEY-CentOS-7
[epel]
name=epel packages for CentOS/RHEL 7
baseurl=https://dl.fedoraproject.org/pub/epel/7/x86_64
enabled=1
gpgcheck=1
gpgkey=https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7
[extras]
name=extras packages for CentOS/RHEL 7
mirrorlist=http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=extras
enabled=1
gpgcheck=1
gpgkey=http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7

7. NGINX Plus와 NGINX App Protect DoS 저장소를 추가합니다.

$ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-7.4.repo
$ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-7.repo

8. 새로 설치하는 경우 저장소를 업데이트하고 가장 최근 버전의 NGINX Plus App Protect DoS 패키지(NGINX Plus를 포함하는)를 설치합니다.

$ sudo yum install app-protect-dos

다음 명령어를 사용하여 유효한 버전을 확인할 수 있습니다.

$ sudo yum --showduplicates list app-protect-dos

이후, 위 출력의 특정 버전을 설치하려면 다음과 같이 입력합니다.

$ sudo yum install app-protect-dos-27+2.4.0

9. 이전에 설치된 NGINX Plus App Protect DoS(NGINX Plus가 포함된) 패키지를 업그레이드 하는 경우:

$ sudo yum remove nginx-plus
$ sudo yum install app-protect-dos
$ sudo systemctl start nginx

Note:

/etc/nginx-plus-backup의 설정을 /etc/nginx-plus로 복구하는 것을 잊지 마세요.

10. NGINX 버전을 확인하여 NGINX Plus가 정상적으로 설치된 것을 확인합니다.

$ sudo nginx -v

11. NGINX App Protect DoS 버전을 확인하여 맞는 버전이 설치된 것을 확인합니다.

$ sudo admd -v

12. nginx.conf 파일의 메인 컨텍스트에 NGINX App Protect DoS 모듈을 로드합니다.

load_module modules/ngx_http_app_protect_dos_module.so;

13. nginx.conf 파일의 http/server/location 컨텍스트에 NGINX App Protect DoS를 활성화합니다.

app_protect_dos_enable on;
app_protect_dos_name "vs-example";
app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";
app_protect_dos_monitor "example.com/";

14. SELinux가 NGINX App Protect DoS를 허용하도록 설정합니다.

a. vi 에디터를 사용하여 파일을 생성합니다:

$ vi app-protect-dos.te

b. 위에서 생성한 파일에 아래 내용을 입력합니다.

module app-protect-dos 2.0;
require {
    type unconfined_t;
    type unconfined_service_t;
    type httpd_t;
    type tmpfs_t;
    type initrc_t;
    type initrc_state_t;
    class capability sys_resource;
    class shm { associate read unix_read unix_write write };
    class file { read write };
}
allow httpd_t initrc_state_t:file { read write };
allow httpd_t self:capability sys_resource;
allow httpd_t tmpfs_t:file { read write };
allow httpd_t unconfined_service_t:shm { associate read unix_read unix_write write };
allow httpd_t unconfined_t:shm { associate read write unix_read unix_write };
allow httpd_t initrc_t:shm { associate read unix_read unix_write write };

c. 다음 명령어들을 입력합니다.

$ sudo checkmodule -M -m -o app-protect-dos.mod app-protect-dos.te
$ sudo semodule_package -o app-protect-dos.pp -m app-protect-dos.mod
$ sudo semodule -i app-protect-dos.pp;

설치에 문제가 발생한다면, 문제 해결 가이드를 확인하세요.

Note:

NGINX Plus가 특정 네트워크 포트로 리스닝 하거나, upstream에 연결하거나, 원격 시스템으로 syslog 항목을 전송하기 위해 추가적인 SEinux 설정이 필요할 수 있습니다. 자세한 내용은 Using NGINX and NGINX Plus with SELinux 를 참고하세요.

15. NGINX/App-Protect-DoS 서비스가 부팅 시 시작되도록 설정하려면 다음 명령어를 사용합니다.

$ sudo systemctl enable nginx.service

16. NGINX 서비스를 시작합니다.

$ sudo systemctl start nginx

5. RHEL 8+ / Rocky Linux 8 설치

1. NGINX 패키지가 이미 설치된 경우, 설정과 로그를 백업합니다.

$ sudo cp -a /etc/nginx /etc/nginx-plus-backup
$ sudo cp -a /var/log/nginx /var/log/nginx-plus-backup

2. /etc/ssl/nginx/ 디렉토리를 생성합니다.

$ sudo mkdir -p /etc/ssl/nginx

3. NGINX 사용자 포털에 로그인하여 다음 두 파일을 다운로드합니다.

nginx-repo.key
nginx-repo.crt

4. 위 두 파일을 서버의 /etc/ssl/nginx/ 디렉토리에 복사합니다. SCP 클라이언트나 다른 파일 전송 툴을 사용하여 이 작업을 수행합니다.

5. 의존성을 설치합니다.

$ sudo dnf install ca-certificates wget

6. Yum 저장소를 활성화하여 App Protect DoS 의존성을 설치합니다.

RHEL 구독이 있는 경우:

$ sudo subscription-manager repos --enable=rhel-8-for-x86_64-baseos-rpms
$ sudo subscription-manager repos --enable=rhel-8-for-x86_64-appstream-rpms
$ sudo dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

7. NGINX Plus와 NGINX App Protect DoS 저장소를 추가합니다.

$ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-8.repo
$ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-8.repo

8. 새로 설치하는 경우 저장소를 업데이트하고 가장 최근 버전의 NGINX Plus App Protect DoS 패키지(NGINX Plus를 포함하는)를 설치합니다.

$ sudo dnf install app-protect-dos

 L4 accelerated mitigation 기능을 위한 명령어(RHEL 8.6+):

$ sudo dnf install app-protect-dos-ebpf

Note:

L4 accelerated mitigation 기능(RHEL 8.6+):
nginx-app-protect-dosnginx는 root 권한으로 동작해야합니다.
nginx-app-protect-dos가 다음 명령어를 실행합니다: ulimit -l unlimited

다음 명령어를 사용하여 유효한 버전을 확인할 수 있습니다.

$ sudo dnf --showduplicates list app-protect-dos

이후, 위 출력의 특정 버전을 설치하려면 다음과 같이 입력합니다.

$ sudo dnf install app-protect-dos-27+2.4.0

9. 이전에 설치된 NGINX Plus App Protect DoS(NGINX Plus가 포함된) 패키지를 업그레이드 하는 경우:

$ sudo dnf remove nginx-plus
$ sudo dnf install app-protect-dos
$ sudo systemctl start nginx

Note:

/etc/nginx-plus-backup의 설정을 /etc/nginx-plus로 복구하는 것을 잊지 마세요.

10. NGINX 버전을 확인하여 NGINX Plus가 정상적으로 설치된 것을 확인합니다.

$ sudo nginx -v

11. NGINX App Protect DoS 버전을 확인하여 맞는 버전이 설치된 것을 확인합니다.

$ sudo admd -v

12. nginx.conf 파일의 메인 컨텍스트에 NGINX App Protect DoS 모듈을 로드합니다.

load_module modules/ngx_http_app_protect_dos_module.so;

13. nginx.conf 파일의 http/server/location 컨텍스트에 NGINX App Protect DoS를 활성화합니다.

app_protect_dos_enable on;
app_protect_dos_name "vs-example";
app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";
app_protect_dos_monitor "example.com/";

14.  L4 accelerated mitigation 기능(RHEL 8.6+)을 nginx.conf 파일의 http 컨텍스트에서 활성화합니다.

app_protect_dos_accelerated_mitigation on;

15. SELinux가 NGINX App Protect DoS를 허용하도록 설정합니다.

a. vi 에디터를 사용하여 파일을 생성합니다:

$ vi app-protect-dos.te

b. 위에서 생성한 파일에 아래 내용을 입력합니다.

module app-protect-dos 2.0;
require {
    type unconfined_t;
    type unconfined_service_t;
    type httpd_t;
    type tmpfs_t;
    type initrc_t;
    type initrc_state_t;
    class capability sys_resource;
    class shm { associate read unix_read unix_write write };
    class file { read write };
}
allow httpd_t initrc_state_t:file { read write };
allow httpd_t self:capability sys_resource;
allow httpd_t tmpfs_t:file { read write };
allow httpd_t unconfined_service_t:shm { associate read unix_read unix_write write };
allow httpd_t unconfined_t:shm { associate read write unix_read unix_write };
allow httpd_t initrc_t:shm { associate read unix_read unix_write write };

c. 다음 명령어들을 입력합니다.

$ sudo checkmodule -M -m -o app-protect-dos.mod app-protect-dos.te &&  \
$ sudo semodule_package -o app-protect-dos.pp -m app-protect-dos.mod &&  \
$ sudo semodule -i app-protect-dos.pp;

L4 accelerated mitigation 기능의 경우:

a. vi에디터를 사용하여 파일을 생성합니다:

$ vi app-protect-dos.te

b. 위에서 생성한 파일에 아래 내용을 입력합니다.

module app-protect-dos-ebpf 2.0;
    require {
    type bpf_t;
    type httpd_t;
    type http_cache_port_t;
    type initrc_t;
    type initrc_var_run_t;
    class capability sys_admin;
    class process setrlimit;
    class tcp_socket name_connect;
    class file { append read write };
    class bpf { map_read map_write };
}
allow httpd_t bpf_t:file { read write };
allow httpd_t http_cache_port_t:tcp_socket name_connect;
allow httpd_t initrc_t:bpf { map_read map_write };
allow httpd_t initrc_var_run_t:file append;
allow httpd_t self:capability sys_admin;
allow httpd_t self:process setrlimit;

c. 다음 명령어들을 입력합니다.

$ sudo checkmodule -M -m -o app-protect-dos-ebpf.mod app-protect-dos-ebpf.te &&  \
$ sudo semodule_package -o app-protect-dos-ebpf.pp -m app-protect-dos-ebpf.mod &&  \
$ sudo semodule -i app-protect-dos-ebpf.pp;

설치에 문제가 발생한다면, 문제 해결 가이드를 확인하세요.

Note:

NGINX Plus가 특정 네트워크 포트로 리스닝 하거나, upstream에 연결하거나, 원격 시스템으로 syslog 항목을 전송하기 위해 추가적인 SEinux 설정이 필요할 수 있습니다. 자세한 내용은 Using NGINX and NGINX Plus with SELinux 를 참고하세요.

16. NGINX/App-Protect-DoS 서비스가 부팅 시 시작되도록 설정하려면 다음 명령어를 사용합니다.

$ sudo systemctl enable nginx.service

17. NGINX 서비스를 시작합니다.

$ sudo systemctl start nginx

6. RHEL 9+ 설치

1. NGINX 패키지가 이미 설치된 경우, 설정과 로그를 백업합니다.

$ sudo cp -a /etc/nginx /etc/nginx-plus-backup
$ sudo cp -a /var/log/nginx /var/log/nginx-plus-backup

2. /etc/ssl/nginx/ 디렉토리를 생성합니다.

$ sudo mkdir -p /etc/ssl/nginx

3. NGINX 사용자 포털에 로그인하여 다음 두 파일을 다운로드합니다.

nginx-repo.key
nginx-repo.crt

4. 위 두 파일을 RHEL 서버의 /etc/ssl/nginx/ 디렉토리에 복사합니다. SCP 클라이언트나 다른 파일 전송 툴을 사용하여 이 작업을 수행합니다.

5. 의존성을 설치합니다.

$ sudo dnf install ca-certificates wget

6. Yum 저장소를 활성화하여 App Protect DoS 의존성을 설치합니다.

RHEL 구독이 있는 경우:

$ sudo subscription-manager repos --enable=rhel-9-for-x86_64-baseos-rpms
$ sudo subscription-manager repos --enable=rhel-9-for-x86_64-appstream-rpms
$ sudo dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm

7. NGINX Plus와 NGINX App Protect DoS 저장소를 추가합니다.

$ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/plus-9.repo
$ sudo wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-9.repo

8. 새로 설치하는 경우 저장소를 업데이트하고 가장 최근 버전의 NGINX Plus App Protect DoS 패키지(NGINX Plus를 포함하는)를 설치합니다.

$ sudo dnf install app-protect-dos

L4 accelerated mitigation 기능을 위한 명령어(RHEL 9):

$ sudo dnf install app-protect-dos-ebpf

Note:

L4 accelerated mitigation 기능(RHEL 9):
nginx-app-protect-dosnginx는 root 권한으로 동작해야합니다.
nginx-app-protect-dos가 다음 명령어를 실행합니다: ulimit -l unlimited

다음 명령어를 사용하여 유효한 버전을 확인할 수 있습니다.

$ sudo dnf --showduplicates list app-protect-dos

이후, 위 출력의 특정 버전을 설치하려면 다음과 같이 입력합니다.

$ sudo dnf install app-protect-dos-32+4.4.0

9. 이전에 설치된 NGINX Plus App Protect DoS(NGINX Plus가 포함된) 패키지를 업그레이드 하는 경우:

$ sudo dnf remove nginx-plus
$ sudo dnf install app-protect-dos
$ sudo systemctl start nginx

Note:

/etc/nginx-plus-backup의 설정을 /etc/nginx-plus로 복구하는 것을 잊지 마세요.

10. NGINX 버전을 확인하여 NGINX Plus가 정상적으로 설치된 것을 확인합니다.

$ sudo nginx -v

11. NGINX App Protect DoS 버전을 확인하여 맞는 버전이 설치된 것을 확인합니다.

$ sudo admd -v

12. nginx.conf 파일의 메인 컨텍스트에 NGINX App Protect DoS 모듈을 로드합니다.

load_module modules/ngx_http_app_protect_dos_module.so;

13. nginx.conf 파일의 http/server/location 컨텍스트에 NGINX App Protect DoS를 활성화합니다.

app_protect_dos_enable on;
app_protect_dos_name "vs-example";
app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";
app_protect_dos_monitor "example.com/";

14.  L4 accelerated mitigation 기능(RHEL 8.6+)을 nginx.conf 파일의 http 컨텍스트에서 활성화합니다.

app_protect_dos_accelerated_mitigation on;

15. SELinux가 NGINX App Protect DoS를 허용하도록 설정합니다.

a. vi 에디터를 사용하여 파일을 생성합니다:

$ vi app-protect-dos.te

b. 위에서 생성한 파일에 아래 내용을 입력합니다.

module app-protect-dos 2.0;
require {
    type unconfined_t;
    type unconfined_service_t;
    type httpd_t;
    type tmpfs_t;
    type initrc_t;
    type initrc_state_t;
    class capability sys_resource;
    class shm { associate read unix_read unix_write write };
    class file { read write };
}
allow httpd_t initrc_state_t:file { read write };
allow httpd_t self:capability sys_resource;
allow httpd_t tmpfs_t:file { read write };
allow httpd_t unconfined_service_t:shm { associate read unix_read unix_write write };
allow httpd_t unconfined_t:shm { associate read write unix_read unix_write };
allow httpd_t initrc_t:shm { associate read unix_read unix_write write };

c. 다음 명령어들을 입력합니다.

$ sudo checkmodule -M -m -o app-protect-dos.mod app-protect-dos.te &&  \
$ sudo semodule_package -o app-protect-dos.pp -m app-protect-dos.mod &&  \
$ sudo semodule -i app-protect-dos.pp;

L4 accelerated mitigation 기능의 경우:

a. vi에디터를 사용하여 파일을 생성합니다:

$ vi app-protect-dos.te

b. 위에서 생성한 파일에 아래 내용을 입력합니다.

module app-protect-dos-ebpf 2.0;
    require {
    type bpf_t;
    type httpd_t;
    type http_cache_port_t;
    type initrc_t;
    type initrc_var_run_t;
    class capability sys_admin;
    class process setrlimit;
    class tcp_socket name_connect;
    class file { append read write };
    class bpf { map_read map_write };
}
allow httpd_t bpf_t:file { read write };
allow httpd_t http_cache_port_t:tcp_socket name_connect;
allow httpd_t initrc_t:bpf { map_read map_write };
allow httpd_t initrc_var_run_t:file append;
allow httpd_t self:capability sys_admin;
allow httpd_t self:process setrlimit;

c. 다음 명령어들을 입력합니다.

$ sudo checkmodule -M -m -o app-protect-dos-ebpf.mod app-protect-dos-ebpf.te &&  \
$ sudo semodule_package -o app-protect-dos-ebpf.pp -m app-protect-dos-ebpf.mod &&  \
$ sudo semodule -i app-protect-dos-ebpf.pp;

설치에 문제가 발생한다면, 문제 해결 가이드를 확인하세요.

Note:

NGINX Plus가 특정 네트워크 포트로 리스닝 하거나, upstream에 연결하거나, 원격 시스템으로 syslog 항목을 전송하기 위해 추가적인 SEinux 설정이 필요할 수 있습니다. 자세한 내용은 Using NGINX and NGINX Plus with SELinux 를 참고하세요.

16. NGINX/App-Protect-DoS 서비스가 부팅 시 시작되도록 설정하려면 다음 명령어를 사용합니다.

$ sudo systemctl enable nginx.service

17. NGINX 서비스를 시작합니다.

$ sudo systemctl start nginx

7. Debian / Ubuntu 설치

1. NGINX 패키지가 이미 설치된 경우, 설정과 로그를 백업합니다.

$ sudo cp -a /etc/nginx /etc/nginx-plus-backup
$ sudo cp -a /var/log/nginx /var/log/nginx-plus-backup

2. /etc/ssl/nginx/ 디렉토리를 생성합니다.

$ sudo mkdir -p /etc/ssl/nginx

3. NGINX 사용자 포털에 로그인하여 다음 두 파일을 다운로드합니다.

nginx-repo.key
nginx-repo.crt

4. 위 두 파일을 Debian 서버의 /etc/ssl/nginx/ 디렉토리에 복사합니다. SCP 클라이언트나 다른 파일 전송 툴을 사용하여 이 작업을 수행합니다.

5. apt utils를 설치합니다:

Debian:

$ sudo apt-get install apt-transport-https lsb-release ca-certificates wget gnupg2 debian-archive-keyring

Ubuntu:

$ sudo apt-get install apt-transport-https lsb-release ca-certificates wget gnupg2 ubuntu-keyring

Note:

apt 설치 혹은 데이터베이스 업데이트가 release 정보 변경으로 인해 실패할 경우, 설치 전 아래 명령어를 입력하세요.
$ sudo apt-get update --allow-releaseinfo-change

6. NGINX 서명 키를 다운로드하고 추가합니다.

$ sudo wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | sudo gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

7. NGINX Plus와 NGINX App Protect DoS 저장소를 추가합니다:

Debian:

$ printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/plus/debian `lsb_release -cs` nginx-plus\n" | sudo tee /etc/apt/sources.list.d/nginx-plus.list
$ printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect-dos/debian `lsb_release -cs` nginx-plus\n" | sudo tee /etc/apt/sources.list.d/nginx-app-protect-dos.list

Ubuntu:

$ printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/plus/ubuntu `lsb_release -cs` nginx-plus\n" | sudo tee /etc/apt/sources.list.d/nginx-plus.list
$ printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect-dos/ubuntu `lsb_release -cs` nginx-plus\n" | sudo tee /etc/apt/sources.list.d/nginx-app-protect-dos.list

8. apt 설정을 /etc/apt/apt.conf.d에 다운로드합니다.

$ sudo wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx

9. 새로 설치하는 경우 저장소를 업데이트하고 가장 최근 버전의 NGINX Plus App Protect DoS 패키지(NGINX Plus를 포함하는)를 설치합니다.

$ sudo apt-get update
$ sudo apt-get install app-protect-dos

L4 accelerated mitigation 기능을 위한 명령어(Debian 11 / Debian 12 / Ubuntu 20.04 / Ubuntu 22.04):

$ sudo apt-get install app-protect-dos-ebpf

Note:

L4 accelerated mitigation 기능(Debian 11 / Debian 12 / Ubuntu 20.04 / Ubuntu 22.04):
nginx-app-protect-dosnginx는 root 권한으로 동작해야합니다.
nginx-app-protect-dos가 다음 명령어를 실행합니다: ulimit -l unlimited

특정 버전을 설치하기 위해 다음 명령어를 사용하여 업데이트 및 유효한 버전을 확인 할 수 있습니다.

$ sudo apt-get update
$ sudo apt-cache policy app-protect-dos

이후, 위 출력의 특정 버전을 설치합니다.

Debian 10의 예:

$ sudo apt-get install app-protect-dos=27+2.4.0-1~buster nginx-plus-module-appprotectdos=27+2.4.0-1~buster

Debian 11의 예:

$ sudo apt-get install app-protect-dos=27+2.4.0-1~bullseye nginx-plus-module-appprotectdos=27+2.4.0-1~bullseye

Debian 12의 예:

$ sudo apt-get install app-protect-dos=32+4.4.0-1~bookworm nginx-plus-module-appprotectdos=32+4.4.0-1~bookworm

Ubuntu 18.04의 예:

$ sudo apt-get install app-protect-dos=27+2.4.0-1~bionic nginx-plus-module-appprotectdos=27+2.4.0-1~bionic

Ubuntu 20.04의 예:

$ sudo apt-get install app-protect-dos=27+2.4.0-1~focal nginx-plus-module-appprotectdos=27+2.4.0-1~focal

Ubuntu 22.04의 예:

$ sudo apt-get install app-protect-dos=27+2.4.0-1~jammy nginx-plus-module-appprotectdos=27+2.4.0-1~jammy

10. 이전에 설치된 NGINX Plus App Protect DoS(NGINX Plus가 포함된) 패키지를 업그레이드 하는 경우:

$ sudo apt-get update
$ sudo apt-get remove nginx-plus
$ sudo apt-get install app-protect-dos
$ sudo service nginx start

11. NGINX 버전을 확인하여 NGINX Plus가 정상적으로 설치된 것을 확인합니다.

$ sudo nginx -v

12. NGINX App Protect DoS 버전을 확인하여 맞는 버전이 설치된 것을 확인합니다.

$ sudo admd -v

13. nginx.conf 파일의 메인 컨텍스트에 NGINX App Protect DoS 모듈을 로드합니다.

load_module modules/ngx_http_app_protect_dos_module.so;

14. nginx.conf 파일의 http/server/location 컨텍스트에 NGINX App Protect DoS를 활성화합니다.

app_protect_dos_enable on;
app_protect_dos_name "vs-example";
app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";
app_protect_dos_monitor "example.com/";

15.  L4 accelerated mitigation 기능(Debian 11 / Debian 12 / Ubuntu 20.04 / Ubuntu 22.04)을 nginx.conf 파일의 http 컨텍스트에서 활성화합니다.

app_protect_dos_accelerated_mitigation on;

16. NGINX 서비스를 시작합니다.

$ sudo service nginx start

8. Alpine 3.15.x / 3.17.x 설치

1. NGINX 패키지가 이미 설치된 경우, 설정과 로그를 백업합니다.

$ sudo cp -a /etc/nginx /etc/nginx-plus-backup
$ sudo cp -a /var/log/nginx /var/log/nginx-plus-backup

2. NGINX 사용자 포털에 로그인하여 다음 두 파일을 다운로드합니다.

nginx-repo.key
nginx-repo.crt

3. nginx-repo.key 파일을 /etc/apk/cert.key, nginx-repo.crt 파일을 /etc/apk/cert.pem로 업로드합니다. Alpine Linux는 서로 다른 저장소에 대한 클라이언트 인증서를 혼합하는 것을 지원하지 않으므로, 파일에 다른 인증서와 키가 포함되어 있지 않도록 합니다.

4. NGINX 공공 서명 키를 /etc/apk/keys디렉토리에 추가합니다.

$ sudo wget -O /etc/apk/keys/nginx_signing.rsa.pub  https://cs.nginx.com/static/keys/nginx_signing.rsa.pub

5. 이전에 설정된 NGINX Plus 저장소를 삭제합니다.

$ sed "/plus-pkgs.nginx.com/d" /etc/apk/repositories

6. NGINX Plus 저장소를 /etc/apk/repositories 파일에 추가합니다.

$ printf "https://pkgs.nginx.com/plus/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | sudo tee -a /etc/apk/repositories

7. NGINX App Protect DoS 저장소를 /etc/apk/repositories 파일에 추가합니다.

$ printf "https://pkgs.nginx.com/app-protect-dos/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | sudo tee -a /etc/apk/repositories

8. 모든 커뮤니티 지원 NGINX 패키지를 제거하는 것이 권장됩니다. 모든 NGINX 모듈도 함께 제거되니 주의하세요.

$ sudo apk del -r app-protect-dos
$ sudo apk del -r nginx

9. 저장소를 업데이트하고 가장 최신 버전의 NGINX Plus와 NGINX App Protect Dos를 설치하세요.

$ sudo apk update
$ sudo apk add nginx-plus app-protect-dos

L4 accelerated mitigation 기능을 위한 명령어:

$ sudo sudo apk add app-protect-dos-ebpf

Note:

L4 accelerated mitigation 기능:
nginx-app-protect-dosnginx는 root 권한으로 동작해야합니다.

특정 버전을 설치하기 위해 다음 명령어를 사용하여 업데이트 및 유효한 버전을 확인 할 수 있습니다.

$ sudo apk update
$ sudo apk info app-protect-dos

이후, 위 출력의 특정 버전을 설치합니다.

$ sudo apk add nginx-plus app-protect-dos=27+2.4.0-r1

10. 이전에 설치된 NGINX Plus App Protect DoS(NGINX Plus가 포함된) 패키지를 업그레이드 하는 경우:

$ sudo apk update
$ sudo apk del -r app-protect-dos
$ sudo apk del -r nginx-plus
$ sudo apk add nginx-plus app-protect-dos
$ rc-service nginx-app-protect-dos start

11. NGINX 버전을 확인하여 NGINX Plus가 정상적으로 설치된 것을 확인합니다.

$ sudo nginx -v

12. NGINX App Protect DoS 버전을 확인하여 맞는 버전이 설치된 것을 확인합니다.

$ sudo admd -v

13. nginx.conf 파일의 메인 컨텍스트에 NGINX App Protect DoS 모듈을 로드합니다.

load_module modules/ngx_http_app_protect_dos_module.so;

14. nginx.conf 파일의 http/server/location 컨텍스트에 NGINX App Protect DoS를 활성화합니다.

app_protect_dos_enable on;
app_protect_dos_name "vs-example";
app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";
app_protect_dos_monitor "example.com/";

15.  L4 accelerated mitigation 기능을 nginx.conf 파일의 http 컨텍스트에서 활성화합니다.

app_protect_dos_accelerated_mitigation on;

16. NGINX 서비스를 시작합니다.

$ sudo service nginx start

9. NGINX App Protect DoS Docker 배포

9-1. NGINX App Protect DoS Docker 배포 지침

다음 과정을 실행하기 위해서 root 권한이 필요합니다.

1. 다음 파일을 docker 이미지로 복사하는 Dockerfile을 생성합니다. (하단의 예제를 참고하세요)

  • nginx-repo.crt: NGINX 저장소 접근을 위한 인증서
  • nginx-repo.key: NGINX 저장소 접근을 위한 개인 키
  • nginx.conf: app-protect-dos가 활성화된 사용자 정의 nginx.conf 파일
  • entrypoint.sh: 모든 App Protect DoS 프로세스를 실행하는 Docker 시작 스크립트. 실행 권한이 있어야 합니다.

2. NGINX Plus 사용자 포털에 로그인하여 nginx-repo.crtnginx-repo.key 파일을 다운로드합니다.

3. 두 파일을 Docker파일이 위치한 경로에 복사합니다.

4. NGINX App Protect DoS를 nginx.conf파일에 추가합니다. 하단의 설정은 NGINX App Protect DoS가 활성화된 httpgrpc+tls 서버의 예제입니다. 모든 NGINX App Protect DoS와 연관된 지시문은 app_protect_dos_로 시작되는 것을 확인하세요.

nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log error;
worker_rlimit_nofile 65535;
working_directory /tmp/cores;

load_module modules/ngx_http_app_protect_dos_module.so; # NGINX App Protect DoS module

events {
    worker_connections  65535;
}

http {
    include         /etc/nginx/mime.types;

    log_format log_napd ', vs_name_al=$app_protect_dos_vs_name, ip=$remote_addr, tls_fp=$app_protect_dos_tls_fp, '
                        'outcome=$app_protect_dos_outcome, reason=$app_protect_dos_outcome_reason, '
                        'ip_tls=$remote_addr:$app_protect_dos_tls_fp, ';

    app_protect_dos_security_log_enable on; # Enable NGINX App Protect DoS's security logger
    app_protect_dos_security_log "/etc/app_protect_dos/log-default.json" /var/log/adm/logger.log; # Security logger outputs to a file
    # app_protect_dos_security_log "/etc/app_protect_dos/log-default.json" syslog:server=1.2.3.4:5261; # Security logger outputs to a syslog destination

    # HTTP/1 server
    server {
        default_type    application/octet-stream;
        listen          80 reuseport;
        server_name     serv80;

        set $loggable '0';
        access_log /var/log/nginx/access.log log_napd if=$loggable; # Access log with rate limiting and additional information
        # access_log syslog:server=1.1.1.1:5561 log_napd if=$loggable;

        app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json"; # Policy configuration for NGINX App Protect DoS

        location / {
            app_protect_dos_enable on; # Enable NGINX App Protect DoS in this block
            app_protect_dos_name "serv80"; # PO name
            app_protect_dos_monitor uri=http://serv80/; # Health monitoring
            proxy_pass http://1.2.3.4:80;
        }
    }

    # gRPC server with ssl
    server {
        default_type    application/grpc;
        listen          443 http2 ssl reuseport;
        server_name     serv_grpc;

        # TLS config
        ssl_certificate      /etc/ssl/certs/grpc.example.com.crt;
        ssl_certificate_key  /etc/ssl/private/grpc.example.com.key;
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  5m;
        ssl_ciphers          HIGH:!aNULL:!MD5;
        ssl_protocols        TLSv1.2 TLSv1.3;

        set $loggable '0';
        access_log /var/log/nginx/access.log log_napd if=$loggable;
        #access_log syslog:server=1.1.1.1:5561 log_napd if=$loggable;

        location / {
            app_protect_dos_enable on;
            app_protect_dos_name "serv_grpc";
            app_protect_dos_monitor uri=https://serv_grpc:443/service/method protocol=grpc; # mandatory for gRPC
            grpc_pass grpc://1.2.3.4:1001;
        }
    }

    sendfile            on;
    tcp_nopush          on;
    keepalive_timeout   65;
}

중요:

예시의 upstream, proxy pass 지시문을 관련 애플리케이션 백엔드 설정으로 교체하세요.

5. L4 accelerated mitigation 기능의 경우 nginx.conf 파일의

user nginx;

user root;

로 교체하세요.

6. 동일한 디렉토리에 다음 내용을 포함하는 실행 권한이 있는 entrypoint.sh 파일을 생성하세요.

CentOS 7 / UBI 7:

#!/usr/bin/env bash

USER=nginx
LOGDIR=/var/log/adm

# prepare environment
mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rpm/lib64
export LD_LIBRARY_PATH

# run processes
/bin/su -s /bin/bash -c "/usr/bin/adminstall --daemons 1 --memory 200 > ${LOGDIR}/adminstall.log 2>&1" ${USER}
/usr/sbin/nginx -g 'daemon off;' &
/bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}

Alpine / Debian / Ubuntu / UBI 8/ UBI 9:

#!/usr/bin/env bash

USER=nginx
LOGDIR=/var/log/adm

# prepare environment
mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}

# run processes
/bin/su -s /bin/bash -c "/usr/bin/adminstall --daemons 1 --memory 200 > ${LOGDIR}/adminstall.log 2>&1" ${USER}
/usr/sbin/nginx -g 'daemon off;' &
/bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}

L4 accelerated mitigation 기능을 포함하는 Alpine / Debian / Ubuntu / UBI 8 / UBI 9

#!/usr/bin/env bash

LOGDIR=/var/log/adm

# prepare environment
mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}

# run processes
/bin/su -s /bin/bash -c "ulimit -l unlimited && /usr/bin/adminstall -e > ${LOGDIR}/admd.log 2>&1" ${USER}
/usr/sbin/nginx -g 'daemon off;' &
/bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}

7. Docker 이미지를 생성합니다.

$ docker build --no-cache -t app-protect-dos .

--no-cache 옵션은 Docker가 이미지를 처음부터 빌드하고, NGINX Plus와 NGINX App Protect DoS의 최신 버전을 설치하도록 합니다. 이전에 Dockerfile이 --no-cache 옵션 없이 이미지를 빌드했다면, 새로운 이미지는 Docker 캐시에서 이전에 빌드된 이미지의 버전을 사용합니다.

L4 accelerated mitigation 기능의 경우:

$ docker build --no-cache --privileged -t app-protect-dos .

--privileged 옵션은 Docker 컨테이너에 호스트 시스템의 모든 장치에 대한 루트 권한을 부여합니다.

8.  docker images 명령어로 app-protect-dos 이미지가 성공적으로 빌드된 것을 확인합니다.

$ docker images app-protect-dos

9. 생성한 이미지를 기반으로 컨테이너를 생성합니다. 예를 들어, my-app-protect-dos 컨테이너를 생성합니다.

$ docker run --name my-app-protect-dos -p 80:80 -d app-protect-dos

10. docker ps 명령어로 my-app-protect-dos 컨테이너의 생성 및 동작을 확인합니다.

$ docker ps

9-2. CentOS 7.4 Docker 배포 예시

# For CentOS 7:
FROM centos:7.4.1708

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Install prerequisite packages:
RUN yum -y install wget ca-certificates epel-release

# Add NGINX Plus and  NGINX App Protect DoS repo to Yum:
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-7.4.repo
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-7.repo

# Install NGINX App Protect DoS:
RUN yum -y install app-protect-dos \
    && yum clean all \
    && rm -rf /var/cache/yum \
    && rm -rf /etc/ssl/nginx

# Copy configuration files:
COPY nginx.conf /etc/nginx/
COPY entrypoint.sh  /root/

CMD /root/entrypoint.sh && tail -f /dev/null

9-3. UBI7 Docker 배포 예시

FROM registry.access.redhat.com/ubi7:ubi

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Setup the Redhat subscription
RUN subscription-manager register --force --org=${RHEL_ORG} --activationkey=${RHEL_ACTIVATION_KEY}
RUN subscription-manager refresh
RUN subscription-manager attach --auto

# Install prerequisite packages:
RUN yum -y install wget ca-certificates

# Install dependencies
RUN subscription-manager repos --enable rhel-*-optional-rpms \
                               --enable rhel-*-extras-rpms \
                               --enable rhel-ha-for-rhel-*-server-rpms
RUN yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

# Add NGINX Plus and NGINX App Protect DoS repo to Yum:
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-7.4.repo
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-7.repo

# Install NGINX App Protect DoS:
RUN yum -y install app-protect-dos \
    && yum clean all \
    && rm -rf /var/cache/yum \
    && rm -rf /etc/ssl/nginx

# Copy configuration files:
COPY nginx.conf /etc/nginx/
COPY entrypoint.sh  /root/

CMD /root/entrypoint.sh && tail -f /dev/null

 9-4. RHEL 8 / Rocky Linux 8 Docker 배포 예시

# For UBI 8
FROM registry.access.redhat.com/ubi8:ubi

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Setup the Redhat subscription
RUN subscription-manager register --force --org=${RHEL_ORG} --activationkey=${RHEL_ACTIVATION_KEY}
RUN subscription-manager refresh
RUN subscription-manager attach --auto

# Setup repos and Install dependencies
RUN subscription-manager repos --enable=rhel-8-for-x86_64-baseos-rpms
RUN subscription-manager repos --enable=rhel-8-for-x86_64-appstream-rpms
RUN dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

# Install prerequisite packages:
RUN dnf -y install wget ca-certificates

# Add NGINX Plus and NGINX App Protect DoS repo to Yum: https://cs.nginx.com/static/files/nginx-plus-8.4.repo
RUN wget -P /etc/yum.repos.d
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-8.repo

# Install NGINX App Protect DoS:
RUN dnf -y install app-protect-dos \
    && dnf clean all \
    && rm -rf /var/cache/yum \
    && rm -rf /etc/ssl/nginx

# Copy configuration files:
COPY nginx.conf /etc/nginx/
COPY entrypoint.sh  /root/

CMD /root/entrypoint.sh && tail -f /dev/null

9-5. RHEL 9 Docker 배포 예시

# For RHEL ubi9:
FROM registry.access.redhat.com/ubi9/ubi

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Setup the Redhat subscription
RUN subscription-manager register --force --org=${RHEL_ORG} --activationkey=${RHEL_ACTIVATION_KEY}
RUN subscription-manager refresh
RUN subscription-manager attach --auto

# Setup repos and Install dependencies
RUN subscription-manager repos --enable=rhel-9-for-x86_64-baseos-rpms
RUN subscription-manager repos --enable=rhel-9-for-x86_64-appstream-rpms
RUN dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm

# Install prerequisite packages:
RUN dnf -y install wget ca-certificates

# Add NGINX Plus repo to Yum:
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/plus-9.repo

# Add NGINX App-protect & dependencies repo to Yum:
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-9.repo
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/dependencies.repo \
    # You can use either of the dependencies or epel repo
    # && rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm \
    && dnf clean all

# Install NGINX App Protect DoS:
RUN dnf -y install app-protect-dos \
    && dnf clean all \
    && rm -rf /var/cache/yum \
    && rm -rf /etc/ssl/nginx

# Copy configuration files:
COPY nginx.conf /etc/nginx/
COPY entrypoint.sh  /root/

CMD /root/entrypoint.sh && tail -f /dev/null

9-6. Debian 10 (Buster) / Debian 11 (Bullseye) / Debian 12 (Bookworm) Docker 배포 예시


ARG OS_CODENAME
# Where OS_CODENAME can be: buster/bullseye/bookworm

FROM debian:${OS_CODENAME}

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Install prerequisite packages:
RUN apt-get update && apt-get install -y apt-transport-https lsb-release ca-certificates wget gnupg2 debian-archive-keyring

# Download and add the NGINX signing key:
RUN wget https://cs.nginx.com/static/keys/nginx_signing.key && apt-key add nginx_signing.key
RUN wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

# Add NGINX Plus and NGINX App Protect DoS repository:
RUN printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/plus/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-plus.list
RUN printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect-dos/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect-dos.list

# Download the apt configuration to `/etc/apt/apt.conf.d`:
RUN wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx

# Update the repository and install the most recent version of the NGINX App Protect package (which includes NGINX Plus):
RUN apt-get update && apt-get install -y app-protect-dos

# Remove nginx repository key/cert from docker
RUN rm -rf /etc/ssl/nginx

# Copy configuration files:
COPY nginx.conf /etc/nginx/
COPY entrypoint.sh  /root/

CMD /root/entrypoint.sh && tail -f /dev/null

9-7. Ubuntu 18.04 (Bionic) / 20.04 (Focal) / 22.04 (Jammy) Docker 배포 예시


ARG OS_CODENAME
# Where OS_CODENAME can be: bionic/focal/jammy

FROM ubuntu:${OS_CODENAME}

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Install prerequisite packages:
RUN apt-get update && apt-get install -y apt-transport-https lsb-release ca-certificates wget gnupg2 ubuntu-keyring

# Download and add the NGINX signing key:
RUN wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

# Add NGINX Plus and NGINX App Protect DoS repository:
RUN printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg]https://pkgs.nginx.com/plus/ubuntu `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-plus.list
RUN printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect-dos/ubuntu `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect-dos.list

# Download the apt configuration to `/etc/apt/apt.conf.d`:
RUN wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx

# Update the repository and install the most recent version of the NGINX App Protect DoS package (which includes NGINX Plus):
RUN apt-get update && apt-get install -y app-protect-dos

# Remove nginx repository key/cert from docker
RUN rm -rf /etc/ssl/nginx

# Copy configuration files:
COPY nginx.conf /etc/nginx/
COPY entrypoint.sh /root/

CMD /root/entrypoint.sh && tail -f /dev/null

9-8. Alpine Docker 배포 예시

# For Alpine 3.15 / 3.17:
ARG OS_CODENAME
# Where OS_CODENAME can be: 3.15 / 3.17
FROM alpine:${OS_CODENAME}

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Download and add the NGINX signing key:
RUN wget -O /etc/apk/keys/nginx_signing.rsa.pub https://cs.nginx.com/static/keys/nginx_signing.rsa.pub

# Add NGINX Plus repository:
RUN printf "https://pkgs.nginx.com/plus/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | tee -a /etc/apk/repositories

# Add NGINX App Protect DoS repository:
RUN printf "https://pkgs.nginx.com/app-protect-dos/alpine/v`egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release`/main\n" | tee -a /etc/apk/repositories

# Add prerequisite packages
RUN apk update && apk add bash

# Update the repository and install the most recent version of the NGINX App Protect DoS package (which includes NGINX Plus):
RUN --mount=type=secret,id=nginx-crt,dst=/etc/apk/cert.pem,mode=0644 \
    --mount=type=secret,id=nginx-key,dst=/etc/apk/cert.key,mode=0644 \
    apk update && apk add nginx-plus app-protect-dos

# Copy configuration files:
COPY nginx.conf /etc/nginx/
COPY entrypoint.sh /root/

CMD ["sh", "/root/entrypoint.sh"]

10. NGINX App Proetct와 Docker 배포

10-1. Docker 배포 지침

다음 과정을 실행하기 위해서 root 권한이 필요합니다.

1. 다음 파일을 docker 이미지로 복사하는 Dockerfile을 생성합니다. (하단의 예제를 참고하세요)

  • nginx-repo.crt: NGINX 저장소 접근을 위한 인증서
  • nginx-repo.key: NGINX 저장소 접근을 위한 개인 키
  • nginx.conf: app-protect-dos가 활성화된 사용자 정의 nginx.conf 파일
  • entrypoint.sh: 모든 App Protect DoS 프로세스를 실행하는 Docker 시작 스크립트. 실행 권한이 있어야 합니다.

2. NGINX Plus 사용자 포털에 로그인하여 nginx-repo.crtnginx-repo.key 파일을 다운로드합니다.

3. 두 파일을 Docker파일이 위치한 경로에 복사합니다.

4. 동일한 디렉토리에 다음 내용을 포함하는 nginx.conf파일을 생성합니다.

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log error;
worker_rlimit_nofile 65535;
working_directory /tmp/cores;

load_module modules/ngx_http_app_protect_module.so;
load_module modules/ngx_http_app_protect_dos_module.so;

events {
    worker_connections 65535;

}

http {
    include         /etc/nginx/mime.types;

    log_format log_napd ', vs_name_al=$app_protect_dos_vs_name, ip=$remote_addr, tls_fp=$app_protect_dos_tls_fp, '
                        'outcome=$app_protect_dos_outcome, reason=$app_protect_dos_outcome_reason, '
                        'ip_tls=$remote_addr:$app_protect_dos_tls_fp, ';

    app_protect_dos_security_log_enable on;
    app_protect_dos_security_log "/etc/app_protect_dos/log-default.json" /var/log/adm/logger.log;
    #app_protect_dos_security_log "/etc/app_protect_dos/log-default.json" syslog:server=1.2.3.4:5261;

    # HTTP/1 server
    server {
        default_type        application/octet-stream;
        listen              80 reuseport;
        server_name         serv80;
        proxy_http_version  1.1;

        app_protect_policy_file "/etc/app_protect/conf/NginxDefaultPolicy.json";
        app_protect_security_log_enable on;

        set $loggable '0';
        access_log /var/log/nginx/access.log log_napd if=$loggable;
        #access_log syslog:server=1.1.1.1:5561 log_napd if=$loggable;
        app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";

        location / {
            app_protect_enable on;
            app_protect_name "serv80";
            client_max_body_size 0;

            app_protect_dos_enable on;
            app_protect_dos_name "serv80";
            app_protect_dos_monitor uri=http://serv80/;

            proxy_pass http://1.2.3.4:80;
        }
    }

    # gRPC server with ssl
    server {
        default_type    application/grpc;
        listen          443 http2 ssl reuseport;
        server_name     serv_grpc;

        # TLS config
        ssl_certificate      /etc/ssl/certs/grpc.example.com.crt;
        ssl_certificate_key  /etc/ssl/private/grpc.example.com.key;
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  5m;
        ssl_ciphers          HIGH:!aNULL:!MD5;
        ssl_protocols        TLSv1.2 TLSv1.3;

        set $loggable '0';
        access_log /var/log/nginx/access.log log_napd if=$loggable;
        #access_log syslog:server=1.1.1.1:5561 log_napd if=$loggable;

        location / {
            app_protect_dos_enable on;
            app_protect_dos_name "serv_grpc";
            app_protect_dos_monitor uri=https://serv_grpc:443/service/method protocol=grpc; # mandatory for gRPC
            grpc_pass grpc://1.2.3.4:1001;
        }
    }

    sendfile            on;
    tcp_nopush          on;
    keepalive_timeout   65;
}

중요:

예시의 upstream, proxy pass 지시문을 관련 애플리케이션 백엔드 설정으로 교체하세요.

5. L4 accelerated mitigation 기능의 경우 nginx.conf 파일의

user nginx;

user root;

로 교체하세요.

6. 동일한 디렉토리에 다음 내용을 포함하는 실행 권한이 있는 entrypoint.sh 파일을 생성하세요.

CentOS 7 / UBI 7:

#!/usr/bin/env bash
USER=nginx
LOGDIR=/var/log/adm

# prepare environment
mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/rpm/lib64
export LD_LIBRARY_PATH

# run processes
/bin/su -s /bin/bash -c "/usr/bin/adminstall > ${LOGDIR}/adminstall.log 2>&1" ${USER}/bin/su -s /bin/bash -c '/opt/app_protect/bin/bd_agent &' ${USER}
/bin/su -s /bin/bash -c "/usr/share/ts/bin/bd-socket-plugin tmm_count 4 proc_cpuinfo_cpu_mhz 2000000 total_xml_memory 307200000 total_umu_max_size 3129344 sys_max_account_id 1024 no_static_config 2>&1 > /var/log/app_protect/bd-socket-plugin.log &" ${USER}
/usr/sbin/nginx -g 'daemon off;' &
/bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}

Alpine / Debian / Ubuntu / UBI 8/ UBI 9:

#!/usr/bin/env bash
USER=nginx
LOGDIR=/var/log/adm

# prepare environment
mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}

# run processes
/bin/su -s /bin/bash -c "/usr/bin/adminstall > ${LOGDIR}/adminstall.log 2>&1" ${USER}/bin/su -s /bin/bash -c '/opt/app_protect/bin/bd_agent &' ${USER}
/bin/su -s /bin/bash -c "/usr/share/ts/bin/bd-socket-plugin tmm_count 4 proc_cpuinfo_cpu_mhz 2000000 total_xml_memory 307200000 total_umu_max_size 3129344 sys_max_account_id 1024 no_static_config 2>&1 > /var/log/app_protect/bd-socket-plugin.log &" ${USER}
/usr/sbin/nginx -g 'daemon off;' &
/bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}

L4 accelerated mitigation 기능을 포함하는 Alpine / Debian / Ubuntu / UBI 8 / UBI 9

#!/usr/bin/env bash
LOGDIR=/var/log/adm

# prepare environment
mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}

# run processes
/bin/su -s /bin/bash -c "ulimit -l unlimited && /usr/bin/adminstall -e > ${LOGDIR}/admd.log 2>&1" ${USER}
/bin/su -s /bin/bash -c "/usr/share/ts/bin/bd-socket-plugin tmm_count 4 proc_cpuinfo_cpu_mhz 2000000 total_xml_memory 307200000 total_umu_max_size 3129344 sys_max_account_id 1024 no_static_config 2>&1 > /var/log/app_protect/bd-socket-plugin.log &" ${USER}
/usr/sbin/nginx -g 'daemon off;' &
/bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}

7. Docker 이미지를 생성합니다.

CentOS:

$ docker build --no-cache -t app-protect-dos .

RHEL:

$ docker build --build-arg RHEL_ORGANIZATION=${RHEL_ORGANIZATION} --build-arg RHEL_ACTIVATION_KEY=${RHEL_ACTIVATION_KEY} --no-cache -t app-protect-dos .

--no-cache 옵션은 Docker가 이미지를 처음부터 빌드하고, NGINX Plus와 NGINX App Protect DoS의 최신 버전을 설치하도록 합니다. 이전에 Dockerfile이 --no-cache 옵션 없이 이미지를 빌드했다면, 새로운 이미지는 Docker 캐시에서 이전에 빌드된 이미지의 버전을 사용합니다.

L4 accelerated mitigation 기능의 경우:

$ docker build --build-arg RHEL_ORGANIZATION=${RHEL_ORGANIZATION} --build-arg RHEL_ACTIVATION_KEY=${RHEL_ACTIVATION_KEY} --no-cache --privileged -t app-protect-dos .±

--privileged 옵션은 Docker 컨테이너에 호스트 시스템의 모든 장치에 대한 루트 권한을 부여합니다.

8.  docker images 명령어로 app-protect-dos 이미지가 성공적으로 빌드된 것을 확인합니다.

$ docker images app-protect-dos

9. 생성한 이미지를 기반으로 컨테이너를 생성합니다. 예를 들어, my-app-protect-dos 컨테이너를 생성합니다.

$ docker run --name my-app-protect-dos -p 80:80 -d app-protect-dos

10. docker ps 명령어로 my-app-protect-dos 컨테이너의 생성 및 동작을 확인합니다.

$ docker ps

10-2. CentOS 7.4 Docker 배포 예시

# For CentOS 7:
FROM centos:7.4.1708

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Install prerequisite packages:
RUN yum -y install wget ca-certificates epel-release

# Add NGINX Plus, NGINX App Protect DoS and NGINX App Protect repo to Yum:
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-7.4.repo
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-7.repo
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-7.repo

# Install NGINX App Protect DoS and NGINX App Protect:
RUN yum -y install app-protect-dos app-protect\
    && yum clean all \
    && rm -rf /var/cache/yum \
    && rm -rf /etc/ssl/nginx


# Copy configuration files:
COPY nginx.conf custom_log_format.json /etc/nginx/
COPY entrypoint.sh  /root/

CMD /root/entrypoint.sh && tail -f /dev/null

10-3. RHEL 7.4 Docker 배포 예시

# For Red Hat 7.4+:
FROM registry.access.redhat.com/rhel7:7.4

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Setup the Red Hat subscription
RUN subscription-manager register --force --org=${RHEL_ORG} --activationkey=${RHEL_ACTIVATION_KEY}
RUN subscription-manager refresh
RUN subscription-manager attach --auto

# Install prerequisite packages
RUN yum -y install wget ca-certificates

# Install dependencies
RUN subscription-manager repos --enable rhel-*-optional-rpms \
                               --enable rhel-*-extras-rpms \
                               --enable rhel-ha-for-rhel-*-server-rpms
RUN yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

# Add NGINX Plus, NGINX App Protect DoS and NGINX App Protect repo to Yum:
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/nginx-plus-7.4.repo
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-dos-7.repo
RUN wget -P /etc/yum.repos.d https://cs.nginx.com/static/files/app-protect-7.repo

# Install NGINX App Protect DoS and NGINX App Protect:
RUN yum -y install app-protect-dos app-protect\
    && yum clean all \
    && rm -rf /var/cache/yum \
    && rm -rf /etc/ssl/nginx

# Copy configuration files:
COPY nginx.conf custom_log_format.json /etc/nginx/
COPY entrypoint.sh  /root/

CMD /root/entrypoint.sh && tail -f /dev/null

10-4. Debian 10 (Buster) / Debian 11 (Bullseye) / Debian 12 (Bookworm) Docker 배포 예시


ARG OS_CODENAME
# Where OS_CODENAME can be: buster/bullseye/bookworm

FROM debian:${OS_CODENAME}

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Install prerequisite packages:
RUN apt-get update && apt-get install -y apt-transport-https lsb-release ca-certificates wget gnupg2 debian-archive-keyring

# Download and add the NGINX signing key:
RUN wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

# Add NGINX Plus, NGINX App Protect and NGINX App Protect DoS repository:
RUN printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/plus/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-plus.list
RUN printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect-dos/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect-dos.list
RUN printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect/debian `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect.list

# Download the apt configuration to `/etc/apt/apt.conf.d`:
RUN wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx

# Update the repository and install the most recent version of the NGINX App Protect DoS and NGINX App Protect package (which includes NGINX Plus):
RUN apt-get update && apt-get install -y app-protect-dos app-protect

# Remove nginx repository key/cert from docker
RUN rm -rf /etc/ssl/nginx

# Copy configuration files:
COPY nginx.conf custom_log_format.json /etc/nginx/
COPY entrypoint.sh  /root/

CMD /root/entrypoint.sh && tail -f /dev/null

10-5. Ubuntu 18.04 (Bionic) / 20.04 (Focal) / 22.04 (Jammy) Docker 배포 예시


ARG OS_CODENAME
# Where OS_CODENAME can be: bionic/focal/jammy

FROM ubuntu:${OS_CODENAME}

ARG DEBIAN_FRONTEND=noninteractive

# Download certificate and key from the customer portal (https://my.f5.com)
# and copy to the build context:
COPY nginx-repo.crt nginx-repo.key /etc/ssl/nginx/

# Install prerequisite packages:
RUN apt-get update && apt-get install -y apt-transport-https lsb-release ca-certificates wget gnupg2 ubuntu-keyring

# Download and add the NGINX signing key:
RUN wget -qO - https://cs.nginx.com/static/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

# Add NGINX Plus, NGINX App Protect and NGINX App Protect DoS repository:
RUN printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/plus/ubuntu `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-plus.list
RUN printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect-dos/ubuntu `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect-dos.list
RUN printf "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://pkgs.nginx.com/app-protect/ubuntu `lsb_release -cs` nginx-plus\n" | tee /etc/apt/sources.list.d/nginx-app-protect.list

# Download the apt configuration to `/etc/apt/apt.conf.d`:
RUN wget -P /etc/apt/apt.conf.d https://cs.nginx.com/static/files/90pkgs-nginx

# Update the repository and install the most recent version of the NGINX App Protect DoS and NGINX App Protect package (which includes NGINX Plus):
RUN apt-get update && apt-get install -y app-protect-dos app-protect

# Remove nginx repository key/cert from docker
RUN rm -rf /etc/ssl/nginx

# Copy configuration files:
COPY nginx.conf custom_log_format.json /etc/nginx/
COPY entrypoint.sh /root/

CMD /root/entrypoint.sh && tail -f /dev/null

11. NGINX App Protect DoS Arbitrator

11-1. 개요

NGINX App Protect DoS arbitrator는 실행 중인 모든 NGINX App Protect DoS 인스턴스를 조율하여 로컬/글로벌 공격의 시작/중지를 동기화합니다.

NGINX App Protect DoS arbitrator는 네트워크 내의 여러 App Protect DoS 인스턴스를 관리하는 중앙 조정 구성 요소 역할을 합니다. NGINX App Protect DoS arbitrator는 둘 이상의 NGINX App Protect DoS 인스턴스가 존재할 때 필요합니다. NGINX App Protect DoS의 주요 기능은 모든 인스턴스가 각 보호 대상에 대해 동일한 상태를 인식하고 공유하도록 보장하는 것입니다. NGINX App Protect DoS arbitrator의 동작 방식과 필수적인 이유는 다음과 같습니다.

NGINX App Protect DoS arbitrator 동작 방식:

  • 주기적인 상태 수집: arbitrator는 일반적으로 동작 중인 모든 App Protect DoS 인스턴스로부터 상태 정보를 수집합니다. 수집은 설정된 주기마다 실행됩니다, 일반적으로 10초의 주기를 가집니다.
  • 새로운 인스턴스의 상태 초기화: 새로운 App Protect DoS 인스턴스가 생성되면, 보호 대상에 대해 빈 상태나 초기화된 상태로 시작하지 않습니다. 대신, arbitrator로부터 초기 상태를 가져옵니다.
  • 공격 발생 시 업데이트: 하나의 App Protect DoS 인스턴스로부터 공격이 감지되면, 해당 인스턴스는 arbitrator에 공격 알림을 전송합니다. 이후 arbitrator는 공격받은 보호 대상의 상태를 업데이트하여 공격을 받고 있음을 나타냅니다. 중요한 점은, 이 업데이트된 상태는 다른 모든 인스턴스에 전파됩니다.

11-2. NGINX App Protect DoS Arbitrator가 필수적인 이유

NGINX App Protect DoS Arbitrator는 여러 이유로 필수적입니다.

  • 글로벌 상태 관리: Arbitrator가 없을 경우, 각 App Protect DoS 인스턴스는 각 보호 대상에 대해 독립적으로 상태를 관리합니다. 이러한 상태는 일관성 문제를 초래할 수 있습니다. 예를 들어, 만약 인스턴스 A가 “PO-Example”이라는 보호 대상에 대한 공격을 감지해도, 인스턴스 B는 이 공격을 인지하지 못하여 보호 대상을 취약한 상태로 방치할 수 있습니다.
  • 균일한 공격 탐지: Arbitrator가 존재할 경우, 인스턴스 A가 “PO-Example” 공격을 감지하고 arbitrator에게 보고하면, “PO-Example”의 상태가 즉시 갱신되어 공격임을 나타냅니다. 이는 인스턴스 B를 포함한 모든 인스턴스가 공격을 인식하고 이를 완화하기 위한 적절한 조치를 취할 수 있습니다.

요약하면, NGINX App Protect DoS Arbitrator는 여러 App Protect DoS 인스턴스에서 보호 대상에 대한 일관되고 최신화된 상태를 유지하기 위한 중앙 조정자 역할을 합니다. 이 조정은 공격이 적절히 감지되고 완화되도록 하며, 한 인스턴스에서 얻은 정보를 다른 인스턴스와 효율적으로 공유하여 네트워크의 전체적인 보안을 강화합니다.

11-3. NGINX App Protect DoS Arbitrator 배포

1. 명령어를 통해 공식 NGINX App Protect DoS Arbitrator 이미지를 pull 합니다.

$ docker pull docker-registry.nginx.com/nap-dos/app_protect_dos_arb:latest

2. 해당 이미지를 기만으로 컨테이너를 생성합니다. 예를 들어 app-protect-dos-arb 컨테이너를 생성합니다.

$ docker run --name app_protect_dos_arb -p 3000:3000 -d docker-registry.nginx.com/nap-dos/app_protect_dos_arb

3. docker ps 명령어로 app-protect-dos-arb 컨테이너가 생성되고, 실행중임을 확인합니다.

4. NGINX App Protect DoS Arbitrator가 올바르게 동작하고, NGINX App Protect DoS 서버에 접근 하려면 DNS 레코드가 필요합니다. svc-appprotect-dos-arb 또는 구성된 Arbitrator FQDN(app_protect_dos_arb_fqdn 지시문이 포함된)가 유효한 DNS resolution을 갖추고 있는지 확인하세요. 이 과정은 Arbitrator를 사용하는 VM/Docker 배포에서만 필요합니다. Arbitrator가 NGINX App Protect DoS와 같은 Kubernetes 네임스페이스에 존재할 경우 이 과정은 필요하지 않습니다.

11-4. NGINX App Protect DoS Arbitrator 다중 VM 배포

Arbitrator 서비스는 standalone 형태입니다. 다운되어도 원활하게 다시 시작할 수 있습니다. 10초마다 통신하는 NGINX App Protect DoS 인스턴스에서 필요한 모든 정보를 즉시 복구합니다. 다운타임은 약 10~20초로 NGINX App Protect DoS 작동에 영향을 미치지 않습니다.

NGINX App Protect DoS Arbitrator 서비스는 3000번 포트를 통해 연결되고, App Protect DoS 인스턴스에서 볼 수 있습니다. 모든 모듈은 이 서비스에 자동으로 연결을 시도합니다. 액세스할 수 없는 경우 각 인스턴스는 standalone 모드로 작동합니다.

NGINX App Protect DoS 서버와 Arbitrator service 사이의 인증을 위한 MTLS, 비밀번호와 같은 옵션은 없습니다. 현재 Arbitrator service는 네임스페이스 외부로 노출되지 않습니다. 외부로부터의 격리는 고객의 책임입니다. 이는 Arbitrator의 모든 배포에 적용되며, 다중 VM 배포에만 해당되는 것은 아닙니다.

12. 설치 후 점검사항

다음 명령어를 통해 NGINX App Protect DoS 배포 후 enforcement가 정상적으로 동작하는지 확인할 수 있습니다.

1. ps aux 명령어를 통해 NGINX App Protect DoS에 필요한 세 프로세스가 동작중인지 확인합니다.

  • admd
  • nginx: master process
  • nginx: worker process
USER       PID   %CPU   %MEM    VSZ    RSS TTY      STAT  START     TIME  COMMAND
nginx      7759   0.0    0.0   113120  1200 ?       Ss    Sep06     0:00  /bin/sh -c /usr/bin/admd -d --log info > /var/log/adm/admd.log 2>&1
root       7765   0.0    0.0   87964   1464 ?       Ss    Sep06     0:00  nginx: master process /usr/sbin/nginx -g daemon off;
nginx      7767   0.0    0.1   615868  8188 ?       Sl    Sep06     0:04  nginx: worker process

2. /var/log/nginx/error.log 에 NGINX 에러가 없고 정책이 성공적으로 컴파일 되었는지 확인합니다.

2020/09/07 15:33:44 [notice] 9307#9307: using the "epoll" event method
2020/09/07 15:33:44 [notice] 9307#9307: nginx/1.19.0 (nginx-plus-r22)
2020/09/07 15:33:44 [notice] 9307#9307: built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
2020/09/07 15:33:44 [notice] 9307#9307: OS: Linux 3.10.0-327.28.3.el7.x86_64
2020/09/07 15:33:44 [notice] 9307#9307: getrlimit(RLIMIT_NOFILE): 1024:4096
2020/09/07 15:33:44 [notice] 9310#9310: start worker processes
2020/09/07 15:33:44 [notice] 9310#9310: start worker process 9311
PID <9311>, WORKER <0>, Function adm_ngx_init_process, line 684, version: 22+1.19.4-1.el7.ngx

3. 공격을 시도하여 공격자의 IP 주소는 차단되고, 정상적인 트래픽은 통과하는 것을 확인합니다.

a. 정상 트래픽 시뮬레이션

echo "Start Good Traffic 2"
while true; do
  curl ${VS}/good1 &
  curl ${VS}/good2 &
  curl ${VS}/good3 &
  curl ${VS}/good4
  sleep 0.1
  done &

b. 7분 경과 후 공격 시작

while [ true ]
do
ab -B ${BAD_IP1} -l -r -n 1000000 -c 150 -d -H "Host: evil.net" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: WireXBot" -H "x-requested-with:" -H "Referer: http://10.0.2.1/none.html" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: en-US" http://${VS}/ &
ab -B ${BAD_IP2} -l -r -n 1000000 -c 150 -d -H "Host: evil.net" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: WireXBot" -H "x-requested-with:" -H "Referer: http://10.0.2.1/none.html" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: en-US" http://${VS}/ &
ab -B ${BAD_IP3} -l -r -n 1000000 -c 150 -d -s 10 -H "Host: evil.net" -H "Pragma: no-cache" -H "Cache-Control: no-cache" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Upgrade-Insecure-Requests: 1" -H "User-Agent: WireXBot" -H "x-requested-with:" -H "Referer: http://10.0.2.1/none.html" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: en-US" http://${VS}/

 killall ab
 done

c. 공격자는 서비스가 차단되는 동안, 정상 트래픽은 지속적으로 통과하는 것을 확인합니다.

12-1. NGINX Plus Releases와의 호환성

위협 캠페인 패키지는 위협 캠페인 패키지가 출시된 당시 지원된 NGINX Plus release와 그 시점부터의 모든 향후 releases와 호환됩니다. 즉 이전의 App Protect DoS releases와는 호환되지 않습니다. 이러한 이전 releases는 현재 지원되지 않으므로 위협 캠페인 업데이트를 포함한 지원의 이점을 얻으려면 App Protect DoS를 업그레이드해야 합니다.

13. App Protect Dos 업그레이드

최신 NGINX App Protect DoS 패키지를 다운로드하고 설치하여 NGINX Plus와 App Protect DoS를 최신 버전으로 업그레이드할 수 있습니다. 해당 패키지를 통해 업그레이드를 진행하면 App Protect DoS는 삭제 후 재설치됩니다. 이전의 기본 보안 정책은 삭제되고, 새로운 기본 보안 정책 설치됩니다. 만약 사용자 지정 보안 정책을 생성한 경우, 해당 정책은 유지되며 json 파일을 사용하여 전체 경로를 사용하여 사용자 지정 보안 정책을 참조하도록 nginx.conf파일을 업데이트해야 합니다.

만약 NGINX 버전을 App Protect DoS 모듈 외부에서 업그레이드하면, App Protect DoS는 삭제되고 재설치 해야 합니다. 업그레이드 이후 NGINX를 재 시작해야 합니다.

14. SELinux

최신 Red Hat Enterprise Linux (RHEL) 및 관련 Linux 배포판에서 Security-Enhanced Linux (SELinux)의 기본 설정은 매우 엄격하며, 편의성보다 보안을 우선시하는 경향이 있습니다.

App Protect DoS는 설치 시 SELinux 정책 모듈을 적용하지만, 정책을 조정하거나 파일 레이블을 수정하지 않으면 특정 구성은 차단될 수 있습니다.

14-1. 파일 레이블 수정

예를 들어, 로그 설정 파일을 /etc/logs에 저장하려 한다면, 해당 디렉토리의 기본 SELinux 파일 컨텍스트를 변경해야 합니다.

semanage fcontext -a -t httpd_config_t /etc/logs
restorecon -Rv /etc/logs

14-2. 사용자 지정 포트로 Syslog

예약되지 않은 포트로 로그를 전송하려면, semanage를 사용하여 원하는 포트(예의 경우 35514)를 syslogd_port_t 타입에 추가할 수 있습니다.

semanage port -a -t syslogd_port_t -p tcp 35514

다음 명령어를 사용하여 syslog 포트를 확인합니다.

semanage port -l | grep syslog

14-3. Kuberenetes 배포 예시

App Protect DoS

appprotect-dos.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: appprotect-dos
  namespace: appprotect-dos-wp-diff
  labels:
    app: appprotect-dos
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: appprotect-dos
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: appprotect-dos
    spec:
    containers:
    - name: centos-bados
      image: example.com/centos_app_protect_dos_r24:latest
      imagePullPolicy: Always
      resources:
        requests:
            cpu: "200m"
            memory: "500Mi"
        limits:
            cpu:  "900m"
            memory: "800Mi"
      ports:
        - containerPort: 80
          name: web
        - containerPort: 8090
          name: probe
        - containerPort: 8091
          name: probe500
        livenessProbe:
          httpGet:
            path: /app_protect_dos_liveness
            port: 8090
          initialDelaySeconds: 0
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /app_protect_dos_readiness
            port: 8090
          initialDelaySeconds: 0
          periodSeconds: 10
        volumeMounts:
        - name: shared
          mountPath: /shared/
        - name: conf
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
        - name: root-script
          mountPath: /root/entrypoint.sh
          subPath: entrypoint.sh
        - name: log-default
          mountPath: /etc/app_protect_dos/log-default.json
          subPath: log-default.json
    volumes:
    - name: shared
      persistentVolumeClaim:
        claimName: pvc-appprotect-dos-shared
    - name: conf
      configMap:
        name: cm-appprotect-dos-nginx
        items:
        - key: nginx.conf
            path: nginx.conf
    - name: root-script
      configMap:
          name: cm-appprotect-dos-entry
          defaultMode: 0755
          items:
          - key: entrypoint.sh
            path: entrypoint.sh
    - name: log-default
      configMap:
        name: cm-appprotect-dos-log-default
        defaultMode: 0755
        items:
        - key: log-default.json
          path: log-default.json

svc-appprotect-dos.yaml:

apiVersion: v1
kind: Service
metadata:
  name: svc-appprotect-dos
  namespace: appprotect-dos-wp-diff
  labels:
    app: appprotect-dos
spec:
  ports:
    - name: app
      port: 80
      protocol: TCP
      nodePort: 80
  selector:
    app: appprotect-dos
  type: NodePort

log-default.json:

{
    "filter": {
        "traffic-mitigation-stats": "all",
        "bad-actors": "all",
        "attack-signatures": "all"
    }
}

entrypoint.sh:

#!/usr/bin/env bash
USER=nginx
LOGDIR=/var/log/adm

# prepare environment
mkdir -p /var/run/adm /tmp/cores ${LOGDIR}
chmod 755 /var/run/adm /tmp/cores ${LOGDIR}
chown ${USER}:${USER} /var/run/adm /tmp/cores ${LOGDIR}

# run processes
/bin/su -s /bin/bash -c "/usr/bin/adminstall --daemons 1 --memory 200 > ${LOGDIR}/adminstall.log 2>&1" ${USER}
/usr/sbin/nginx -g 'daemon off;' &
/bin/su -s /bin/bash -c "/usr/bin/admd -d --log info > ${LOGDIR}/admd.log 2>&1 &" ${USER}

install.sh:

#!/bin/bash
set -ex
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
kubectl -n appprotect-dos-wp-diff create cm cm-appprotect-dos-nginx --from-file ${DIR}/nginx.conf
kubectl -n appprotect-dos-wp-diff create cm cm-appprotect-dos-entry --from-file ${DIR}/entrypoint.sh
kubectl -n appprotect-dos-wp-diff create cm cm-appprotect-dos-log-default --from-file ${DIR}/log-default.json
kubectl create -f ${DIR}/appprotect-dos.yaml
#kubectl create -f ${DIR}/svc-appprotect-dos.yaml

nginx.conf:

user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log debug;
worker_rlimit_nofile 65535;
working_directory /tmp/cores;

load_module modules/ngx_http_app_protect_dos_module.so;

events {
    worker_connections  65535;
}
http {
    include         /etc/nginx/mime.types;
    default_type    application/octet-stream;

    log_format log_napd ', vs_name_al=$app_protect_dos_vs_name, ip=$remote_addr, tls_fp=$app_protect_dos_tls_fp, '
                        'outcome=$app_protect_dos_outcome, reason=$app_protect_dos_outcome_reason, '
                        'ip_tls=$remote_addr:$app_protect_dos_tls_fp, ';

    app_protect_dos_security_log_enable on;
    app_protect_dos_security_log "/etc/app_protect_dos/log-default.json" /var/log/adm/logger.log;
    # app_protect_dos_security_log "/etc/app_protect_dos/log-default.json" syslog:server=1.2.3.4:5261;

    server {
        listen 80 reuseport;
        server_name serv;

        set $loggable '0';
        access_log /var/log/nginx/access.log log_napd if=$loggable;
        # access_log syslog:server=1.1.1.1:5561 log_napd if=$loggable;

        app_protect_dos_policy_file "/etc/app_protect_dos/BADOSDefaultPolicy.json";

        location / {
            app_protect_dos_enable on;
            app_protect_dos_name "serv";
            app_protect_dos_monitor uri=http://serv:80/ protocol=http1;
            proxy_pass http://1.2.3.4:80;
        }
    }

    server {
        listen 8090;
        server_name probe;

        app_protect_dos_liveness on;    # uri:/app_protect_dos_liveness port:8090
        app_protect_dos_readiness on;   # uri:/app_protect_dos_readiness port:8090

        location / {
            proxy_pass http://localhost:8091;
        }
    }

    server {
        listen 8091;
        return 503;
    }

    sendfile            on;
    tcp_nopush          on;
    keepalive_timeout   65;
}
App Protect DoS arb

Arbitrator(arb)는 확장 시나리오에 필수적인 내부 서비스입니다. Arbitrator 서비스는 NGINX App Protect DoS 와 동일한 네임스페이스에 배포 되어야 합니다.

appprotect-dos-arb.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: appprotect-dos-arb
  namespace: appprotect-dos-wp-diff
spec:
  replicas: 1
  selector:
    matchLabels:
      app: appprotect-dos-arb
  template:
    metadata:
      labels:
        app: appprotect-dos-arb
    spec:
      containers:
      - name: arb-svc
        image: example.com/app_protect_dos_arb:latest
        resources:
          requests:
            cpu: "200m"
            memory: "500Mi"
          limits:
            cpu:  "900m"
            memory: "800Mi"
        ports:
        - containerPort: 3000

svc-appprotect-dos-arb.yaml:

apiVersion: v1
kind: Service
metadata:
  name: svc-appprotect-dos-arb
  namespace: appprotect-dos-wp-diff
spec:
  selector:
    app: appprotect-dos-arb
  ports:
    - name: arb
      port: 3000
      protocol: TCP
      targetPort: 3000
  clusterIP: None

install_appprotect-arb.sh:

#!/bin/bash

set -ex
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
kubectl -n appprotect-dos-wp-diff apply -f ${DIR}/appprotect-dos-arb.yaml
kubectl -n appprotect-dos-wp-diff apply -f ${DIR}/svc-appprotect-dos-arb.yaml

install NGINX App Protect DoS with ARB service:

#!/bin/bash

set -ex
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
kubectl create ns appprotect-dos-wp-diff
${DIR}/appprotect-dos/install.sh
${DIR}/appprotect-dos-arb/install_appprotect-dos-arb.sh

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required