티스토리 뷰

보안

Ubuntu Nginx 웹서버 기본 보안 설정

공허공자 2025. 6. 4. 00:49
"개발용으로 셋팅하는데 귀찮으니 안해야지"
라는 생각을 가지면 오만임.

운영레벨로 승격하지 않은 개발이나 스테이징 서버에서 
알수없는 트래픽과 CPU 스파이크를 경험하게 될 것이고 
웹서버 액세스 로그를 보면 
해킹 스캔 기록이 엄청나게 발생하는것을 목도하게 될 것.

Ubuntu OS 기반에 Nginx 웹서버 선택하여 진행함.

설정 요소들

Nginx 웹서버, WAF, UFW 방화벽, Fail2Ban, Ubuntu 자동 업데이트


Nginx 가상호스트 설정

http {
    #......

    # Declare 단일 클라이언트 ip 주소의 모든 페이지에 대해 1초에 5건의 요청 처리로 제한
    limit_req_zone $binary_remote_addr zone=badbot:10m rate=10r/s;
    limit_req_status 444;
  
    # Declare 각 클라이언트 IP 주소의 모든 페이지에 대해 동시 연결 제한
    ## 10m == 10MB의 메모리를 할당하여 대략 16만 개의 IP 주소 저장
    limit_conn_zone $binary_remote_addr zone=ddos:10m;

	server {
	  listen 80;
	  listen [::]:80;
	
	  server_name _;
	
      # https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker
      # 참고하여 include "nginx-ultimate-bad-bot-blocker.conf"      
	
      # request method 제한
	  add_header Allow "GET, POST, HEAD" always;
	  if ( $request_method !~ ^(GET|POST|HEAD|PUT|PATCH)$ ) { return 405; }
	
	  # Limit the size of POST requests
	  client_max_body_size 1M;
	
	  # Timeout settings defend Slowloris attack
	  client_body_timeout 12s;
	  client_header_timeout 12s;
	  keepalive_timeout 5s 5s;
	  send_timeout 10s;
	
		location / {
		    #......
		    
		    # limit_req_zone 선언 사용
		    ## burst: 초과 허용량 설정. 초과 요청이 즉시 거부되지 않고 대기열에 들어간 다음 지정된 요청 비율에 따라 처리될 수 있음을 의미
		    ## nodelay: 선언시 초과 요청들은 지정된 비율에 따라 대기열에 들어가지 않고 즉시 처리. burst 값 이내의 요청은 추가 지연 없이 처리
		    limit_req zone=badbot burst=5 nodelay;
		    
		    # 각 클라이언트 IP 주소의 모든 페이지에 대해 동시 10개 이하의 연결만 열도록 제한
		    limit_conn ddos 10;
        
            #......
		}
		
		location /admin {
			# 관리자 IP만 접속 허용
		    allow xxx.xxx.xxx.xxx/32;
            allow 192.168.1.0/24;
		    deny all;
		    
		    #......
		}
		
		#......
	}
}

Nginx ultimate bad bot blocker

https://github.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker

IP 차단 자동화

Fail2ban

  • 지정한 기간동안 IP 차단 자동화
  • 차단시 iptables 사용하니 셋팅 되어 있어야 함.
  • ubuntu는 ufw 사용하는게 제어가 쉬움
    • ufw는 명령어가 쉽도록 간략화한 iptables wrapper cli repl

Fail2ban 설치

sudo apt update && \
sudo apt install -y ufw fail2ban && \
sudo systemctl start fail2ban && \
sudo systemctl enable fail2ban && \
sudo systemctl status fail2ban --no-pager --full && \
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local && \
sudo vi /etc/fail2ban/jail.local
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 172.16.0.0/12 192.168.0.0/16 xxx.xxx.xxx.xxx/32
bantime = 7d
findtime = 1d
maxretry = 2
banaction = ufw
banaction_allports = ufw
sudo systemctl restart fail2ban && \
sudo fail2ban-client status
sudo ufw default deny incoming && \
sudo ufw default allow outgoing && \
sudo ufw allow in 80/tcp && \
sudo ufw allow in 443/tcp && \
sudo ufw allow out 80/tcp && \
sudo ufw allow out 443/tcp && \
sudo ufw allow in 22/tcp && \
sudo ufw limit 22/tcp comment 'Allow 6 connections over 30 seconds' && \
sudo ufw allow out 53/udp && \
sudo ufw allow out 25/tcp && \
sudo ufw enable && \
sudo ufw status verbose
sudo ufw delete allow in 22/tcp && \
sudo ufw allow from 192.168.0.0/16 to any port 22 proto tcp
sudo vi /etc/rsyslog.d/20-ufw.conf
# Log kernel generated UFW log messages to file
:msg,contains,"[UFW " /var/log/ufw.log

# Uncomment the following to stop logging anything that matches the last rule.
# Doing this will stop logging kernel generated UFW log messages to the file
# normally containing kern.* messages (eg, /var/log/kern.log)
& stop
sudo touch /var/log/ufw.log && \
sudo chown syslog:adm /var/log/ufw.log && \
sudo chmod o-r /var/log/ufw.log && \
sudo systemctl restart rsyslog
sudo ls -alt /etc/fail2ban/filter.d/nginx*
sudo bash -c 'cat > /etc/fail2ban/filter.d/nginx-sslerror.conf <<EOF
[Definition]
failregex = SSL_do_handshake\(\) failed .+ while SSL handshaking, client: <HOST>, server: .+

ignoreregex =

datepattern = {^LN-BEG}%%ExY(?P<_sep>[-/.])%%m(?P=_sep)%%d[T ]%%H:%%M:%%S(?:[.,]%%f)?(?:\s*%%z)?
^[^\[]*\[({DATE})
{^LN-BEG}
EOF' && \
sudo bash -c 'cat > /etc/fail2ban/filter.d/nginx-4xx.conf <<EOF
[Definition]
failregex = ^<HOST>.*"(GET|POST).*" (404|444|403|400) .*$

ignoreregex = .*(robots.txt|favicon.ico|jpg|png)
EOF' && \
sudo bash -c 'cat > /etc/fail2ban/filter.d/nginx-forbidden.conf <<EOF
[Definition]
failregex = directory index of .+ is forbidden, client: <HOST>, server: .+
ignoreregex =

EOF' && \
sudo bash -c 'cat > /etc/fail2ban/filter.d/ufw.conf <<EOF
[Definition]
failregex = [UFW BLOCK].+SRC=<HOST> DST
ignoreregex =
EOF'
sudo bash -c 'cat > /etc/fail2ban/jail.d/custom.conf <<EOF
[sshd]
enabled = true

[nginx-4xx]
enabled = true
port     = http,https
filter   = nginx-4xx
logpath  = %(nginx_access_log)s

[nginx-http-auth]
enabled = true
port     = http,https
filter   = nginx-http-auth
logpath  = %(nginx_access_log)s

[nginx-botsearch]
enabled = true
port     = http,https
filter   = nginx-botsearch
logpath  = %(nginx_access_log)s

[nginx-forbidden]
enabled = true
port    = http,https
filter  = nginx-forbidden
logpath = %(nginx_access_log)s

[nginx-sslerror]
enabled = false
port    = http,https
filter  = nginx-sslerror
logpath = %(nginx_access_log)s

[ufw]
enabled = true
filter  = ufw
logpath = /var/log/ufw.log
EOF'
sudo systemctl restart fail2ban && \
sudo systemctl status fail2ban --no-pager --full && \
sudo fail2ban-client status
cd ~ && \
vi fail2ban-status.sh
#!/usr/bin/env bash

for jail in $(sudo fail2ban-client status | grep 'Jail list:' | sed 's/.*://;s/,//g'); do
  echo "Jail: $jail";
  sudo fail2ban-client status $jail | grep 'Banned IP';
done
chmod +x fail2ban-status.sh && \
./fail2ban-status.sh

리눅스 자동 업데이트

sudo apt install -y unattended-upgrades && \
sudo dpkg-reconfigure --priority=low unattended-upgrades && \
sudo systemctl status unattended-upgrades --no-pager --full

Confirm 선택 화면 뜨면 YES 선택

 

참고자료

  1. https://scalastic.io/en/ufw-fail2ban-nginx/
  2. https://mytory.net/archives/13142
  3. https://linuxhandbook.com/ufw-logs/
  4. https://blog.fernvenue.com/archives/ufw-with-fail2ban/
    1. /var/log/ufw.log 나중에 생기는 문제 예방 가이드
    2. /etc/fail2ban/filter.d/ufw.conf 없어서 발생하는 경고 해결 가이드
  5. https://gist.github.com/bartosjiri/f7e2e6a6c8890be7f5992470ac4c9350
  6. https://webdock.io/en/docs/how-guides/security-guides/configuring-ufw-and-fail2ban-mitigate-basic-ddos-attacks
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함