728x90

출처 :

https://elfinlas.github.io/nginx/230401_defense_attacker/

 

일단 nginx가 설치되어 있다는 것을 가정한다.
nginx의 기본 설정 파일을 vim이던 원하는 편집기로 연다.

보통은 경로가 /etc/nginx/nginx.conf 일거다.
물론 보안을 생각하면 다른 장소로 옮겨둔 사람도 있겠지만...

이 conf파일에 작성해도 좋지만 나 같은 경우 따로 빼뒀다.

http {
    ## Some Config

    ## 별도 경로로 빼둔 설정파일들
	include /home/mymy/nginx/ip-block-list.conf;  #ip block
  	include /home/mymy/nginx/hack_word.conf; #Hack word
  	include /home/mymy/nginx/ip-range-block-list.conf; #ip range block
}

 

저 설정파일들은 nginx에서 사용할 변수를 만들어 둔 파일들이다.
그리고 저 설정파일들은 아래서 더 자세하게 설명하겠다.

 

개별 IP 막기

위의 ip-block-list.conf 파일에는 다음과 같이 되어 있다.

geo $bad_ip {
    5.62.41.163 1;
    5.62.58.235 1;
    default 0;
}

상단에 geo를 적고 **$**표시가 변수 이름이다.
그리고 안에 값은 밴 시킬 ip는 1을 주고, 그 외는 허용하려 하기에 0을 줬다.

 

여기까지 하고 되면 참 좋겠지만...
이제 몇 가지 설정이 남았다.

다시 nginx.conf 파일을 열거나 자신의 서비스에 맞는 설정을 빼뒀으면 그 config를 열어준다.

server {
  #기본 설정
  listen 80;
  listen [::]:80;
  root /var/www/html;

  server_name bcow.world;

  #Ban black ip
  if ($bad_ip) { return 444; }

  #Ban ip range
  if ($bad_ip_range) { return 444;  }

  #특정 url 패턴을 거부
  if ($bad_word = 1) { return 444; }

  underscores_in_headers    on;  #1. 언더형식의 헤더를 허용 합니다.

  #실제 사용 처리
  location / {
    proxy_set_header Range $saferange;

    proxy_pass http://localhost:11122334;
    proxy_pass_request_headers	on; ## 요청 헤더 바로 전달
  }
}

 

설정을 저렇게 해주면 된다.
if ($bad_ip) { return 444; } 이 설정으로 인해,
해당 IP는 444응답... 즉 아무 응답도 못받고 죽은 서버라는 응답을 받게 된다.

만약 특정 Ip 영역대를 밴 시키고 싶다면?

 

IP Class로 막기

IP는 알다시피 A클래스, B클래스, C클래스 영역으로 나눠져있다.
그리고 서브넷 등등...

자세한 건 네트워크 쪽 찾아보거나 시스코의 CCNA 자격증 공부하면 줄기차게 나온다.
무튼...

이번엔 위에서 설명된 ip-range-block-list.conf 설정을 열람해보자

 

geo $bad_ip_range {
	# A
	103.0.0.0/8 1; #VN-21-11-29
  	185.0.0.0/8 1; #DE-21-12-27

    # B
  	5.161.0.0/16 1; #22-01-02
  	45.83.0.0/16 1; #log4j

    # C
  	77.111.247.0/24 1; #NO-21-12-16
  	167.172.62.0/24 1; #22-01-02

    default 0;
}

얘도 아까 단일 Ip랑 같은 설정을 가진다.
단지 A클래스일 경우 앞 대역 주소를 적고 나머진 0.0.0 즉 해당 네트워크 주소(시작 주소)를 적어둔다.

그리고 뒤에 서브넷을 입력한다.
A클래스니까 당연 서브넷은 8이다.

B랑 C는 A랑 같기에 설명은 생략한다.

 

무튼 이것도 변수를 선언하고 메인 설정에서 단일 Ip 밴시키듯 아래 설정을 두면 된다.

#Ban ip range
  if ($bad_ip_range) { return 444;  }

근데 이 블록 Ip는 잘보고 막자.
가끔 B클래스가 같은거 같아서 막 막다보면 엄한 영역도 막을 수 있다.

그래서 ip조회 서비스 등을 조회해서 대상 B클래스 주소가 같은 지역 같은 호스트,
비슷한 것 같으면 그 때 막는게 좋다.

이건 IP-API사이트에서 조회한 것인데 저렇게 밑에 hosting이라 되어 있으면 일단 막는게 좋다.
그리고 사진에 나온 것처럼 미국인데 asname이 텐센트...

물론 클라우드를 통해 접근해서 지역은 상관 없긴 하지만...
일단 중국은 다 막자.

다음은 url에 특정 키워드가 포함된 것을 잡는 것을 알아보자.

 

Url keyword

이것도 원리는 같다.
hack_word.conf 설정 파일을 보자.

#Request Bad Word
map $request_uri $bad_word {
	default 0;
	~*(wp-includes|wlwmanifest|xmlrpc|wordpress|administrator|wp-admin|wp-login|owa|a2billing) 1;
	~*(fgt_lang|flu|stalker_portal|streaming|system_api|exporttool|ecp|vendor|LogService|invoke|phpinfo) 1;
	~*(Autodiscover|console|eval-stdin|staging|magento|demo|rss|root|mifs|git|graphql|sidekiq|c99|GponForm) 1;
	~*(header-rollup-554|fckeditor|ajax|misc|plugins|execute-solution|wp-content|php|telescope) 1;
	~*(idx_config|DS_Store|nginx|wp-json|ads|humans|exec|level|monitoring|configprops|balancer|actuator) 1;
	~*(meta-data|web_shell_cmd|latest|remote|_asterisk|bash|Bind|binding|appxz|bankCheck|GetAllGameCategory) 1;
	~*(exchangerateuserconfig|exchange_article|kline_week|anquan|dns-query|nsepa_setup|java_script|gemini-iptv) 1;
	~*(j_spring_security_check|wps|cgi|asmx|HNAP1|sdk|evox) 1;
	~*(_ignition|alvzpxkr|ALFA_DATA|wp-plain) 1;
	~*(ldap|jndi|dns|securityscan|rmi|ldaps|iiop|corba|nds|nis) 1; # log4j
}

일단 내가 주로 막는 유형만 가져왔다.
저렇게 하면 url에 저 키워드가 들어가면 조건에 걸린다.

내가 집요하게 로그를 분석하며 취약점 찾으려 들어온 놈들 키워드를 분석했다.
이것도 메인 설정에 박아두면 된다.

if ($bad_word = 1) { return 444; }

이렇게 하면 어느정도 취약점 찾는 놈들은 막을 수 있을 것이다.

기타

또 막는 설정은 다양한게 있겠지만...

요새는 영악해서 가짜 UA 달고 오는게 예의지만...
UserAgent 공백으로 오는 무성의한 놈들도 있다. (아주 가끔...)

이런 놈들은 아래 설정으로 막을 수 있다.

#공백 UserAgent 차단
if (\$http_user_agent = "") { return 444; }

그리고 악의적인 행위로 유명한 봇들도 있다.
이건 아래 내용을 참고하자.

#Bot
map $http_user_agent $limit_bots {
        default 0;
        ~*(MJ12bot|ltx71|Adsbot/3.1/WordPress|BLEXBot|UCBrowser|Mb2345Browser) 1;
        ~*(MicroMessenger|LieBaoFast|Headless|netEstate|PetalBot) 1;
        ~*(bingbot|FeedDemon|GrapeshotCrawler|DuckDuckBot|MegaIndex) 1;
        ~*(VelenPublicWebCrawler|SimplePie|YandexBot|SCMGUARD|DotBot) 1;
        ~*(AhrefsBot|SemrushBot) 1;
	~*(wget|curl) 1;
    }

이걸 또 메인 설정(또는 개인 서비스 설정)에 아래와 같이 넣어준다.

#불필요 로봇 차단
if (\$limit_bots = 1) { return 444; }

이렇게하면 일단 가드를 완전히 올린 셋팅은 아니지만 어중이 떠중이는 못들어오게 막아준다.

 

nginx 책도 빌렸는데 공부를 좀 해서 더 견고하게 막아보도록 노오력해봐야겠다.
아래는 범위 ip 설정을 올려본다.

단일은 진짜 넘 커서...
이건 깃허브나 파일로 제공해야 할 듯 싶다.

해외 서비스 하는 분은 잘 알아보고 적용하고,
국내나 국외 크게 신경 안쓰시는 분은 아래 내용을 참고하자.

geo $bad_ip_range {
	# A
    #34.0.0.0/8 1; #22-07-01 => Google Bot 있을 수 있음
	103.0.0.0/8 1; #VN-21-11-29
  	185.0.0.0/8 1; #DE-21-12-27
	159.0.0.0/8 1; #22-04-17
	20.0.0.0/8 1; #22-04-30
	15.0.0.0/8 1; #22-06-10
	51.0.0.0/8 1; #22-06-27
	35.0.0.0/8 1; #22-07-01

  	# B
    # 66.249.0.0/16 1; #US_21-11-15 => Google Bot 있을 수 있음
  	5.161.0.0/16 1; #22-01-02
  	45.83.0.0/16 1; #log4j
  	51.159.0.0/16 1; #FR-21-11-17
  	137.184.0.0/16 1; #22-01-02
  	167.71.0.0/16 1; #US(NE)-21-11-25
  	185.220.0.0/16 1; #log4j
	20.119.0.0/16 1; #22-02-02
	92.223.0.0/16 1; #22-04-05
	46.101.0.0/16 1; #22-06-09
	163.172.0.0/16 1; #22-06-10
	198.235.0.0/16 1; #22-06-28
	5.62.0.0/16 1;
	178.62.0.0/16 1;
	146.70.0.0/16 1;
	14.116.0.0/16 1;
	144.168.0.0/16 1;
	144.126.0.0/16 1;
	143.198.0.0/16 1;
	128.199.0.0/16 1;
	18.118.0.0/16 1;
	18.234.0.0/16 1;
	159.65.0.0/16 1;
	159.65.0.0/16 1;
	34.240.0.0/16 1;
	157.245.0.0/16 1;
	170.247.0.0/16 1;
	159.223.0.0/16 1;
	165.232.0.0/16 1;
	168.119.0.0/16 1;
	188.166.0.0/16 1;
	198.244.0.0/16 1;
	35.86.0.0/16 1;
	35.89.0.0/16 1;
	106.75.0.0/16 1;
	205.185.0.0/16 1;
	209.141.0.0/16 1;
	209.127.0.0/16 1;
	43.130.0.0/16 1;
	35.93.0.0/16 1;

  	# C
  	77.111.247.0/24 1; #NO-21-12-16
  	167.172.62.0/24 1; #22-01-02
  	171.25.193.0/24 1; #log4j
	92.118.160.0/24 1; #22-04-10
	220.181.51.0/24 1; #22-04-12
	95.142.120.0/24 1; #22-04-25
	5.188.62.0/24 1; #22-05-10
	116.179.33.0/24 1; #22-06-10

	92.223.85.0/24 1;
	93.158.91.0/24 1;
	93.158.90.0/24 1;
	36.99.136.0/24 1;
	111.7.100.0/24 1;
	117.187.173.0/24 1;
	156.146.35.0/24 1;
	185.54.229.0/24 1;
	185.27.99.0/24 1;
	185.181.60.0/24 1;
	198.235.24.0/24 1;
	205.169.39.0/24 1;
	205.210.31.0/24 1;
	208.80.194.0/24 1;
	111.7.100.0/24 1;
	205.210.31.0/24 1;
	51.222.253.0/24 1;
	89.187.163.0/24 1;
	95.142.120.0/24 1;
	42.83.147.0/24 1;
	54.36.148.0/24 1;
	64.43.117.0/24 1;
	191.102.179.0/24 1;
	199.244.88.0/24 1;

  	default 0;
}
 
반응형

'WEB & WAS > nginx' 카테고리의 다른 글

NginX를 이용한 static 컨텐츠 서비스 와 캐시 설정  (0) 2022.08.09
nginx와 Tomcat 구성  (0) 2016.08.22
728x90

특정 서버나 장비의 작동여부를 외부에서 확인하기 위해서 ping 테스트를 많이 합니다.

ip 혹은 hostname만으로 간단하게 확인할 수 있어서 편리한 도구입니다.

하지만 보안상 icmp를 활성화 하지 않아 확인이 불가능할 수 있고, ping 테스트 성공이 특정 서비스의 정상작동 여부를 확인해줄 수 없는 단점도 존재합니다.

파워쉘에서는 이러한 ping 테스트를 보완할 수 있는 Test-NetConnection이라는 cmdlet을 제공합니다.

Test-NetConnection cmdlet을 사용하면 ping 테스트 뿐 아니라 TraceRoute도 할 수 있고, ip(혹은 DNS명)와 특정 TCP 포트를 지정하여 해당 포트로 연결이 정상적인지의 여부도 확인 할 수 있습니다.

Test-NetConnection 파워쉘 명령 작성

우선 기본적으로 아무런 옵션을 입력하지 않고 명령을 실행하면 "internetbeacon.msedge.net"이라는 기본사이트로 ping 테스트를 수행합니다. 아마도 Microsoft의 서버 같네요.

만약 어떤 특정서버의 연결상태를 확인하려면 아래와 같이 수행하여 ping 테스트와 같은 효과를 볼 수 있습니다.

Test-NetConnection -ComputerName remoteserver

아래 예는 Test-NetConnection cmdlet을 사용하여 google.com으로 ping 테스트 한 효과를 볼 수 있습니다.

ping 테스트 외 특정 서버의 포트가 활성화 되어 있는지 여부를 확인하기 위해서는 port 옵션을 추가하여 확인하고자 하는 포트를 지정할 수 있습니다.

Test-NetConnection -ComputerName remoteserver -Port port​

 

google.com의 웹서비스인 80 포트로 테스트 해본 결과이며,

구글은 81 포트는 서비스 하지 않아 fail이 발생하는 것을 확인할 수 있습니다. 실패하더라도 친절하게 ping 테스트는 성공했다는 것도 보여주네요.

 

파워쉘 스크립트 작성

파워쉘 커맨드 창에서 직접 확인만 한다면 여기까지만 할 수 있어도 문제는 없을것 같습니다만,

저희의 목적은 파워쉘을 통해 관리업무를 자동화시켜 수작업을 최대한 줄이는 것입니다.

서버가 수십대가 있고, 서버마다 확인이 필요한 포트가 여러 개가 있을 경우 모든 포트마다 이 명령을 수행하는 것은 비 효율적일테니까요.

이를 위해서는 하나의 명령을 사용하는 파워쉘 커맨드에서 파워쉘 스크립트를 작성할 줄 알아야 합니다.

제 개인적으로도 파워쉘을 사용해서 Windows 계열의 서버를 잘 관리하려면 스크립트를 작성할 수 있어야 많은 도움이 된다고 생각합니다.

단순히 파워쉘 명령(cmdlet)만으로 충분하고 자동화까지 할 필요가 없다면 아래 내용은 읽지 않으셔도 됩니다.

관리할 서버가 여러 대라고 가정하면 각 서버들의 ip 혹은 DNS 명을 미리 다른 파일에 등록해 두는 것이 좋습니다.

관리대상 서버가 추가 혹은 삭제되면 이 목록만 변경해주면 되니까요....저는 그렇게 사용합니다.

아래 처럼 2대의 서버와 포트를 ";"(구분자는 다른 것으로 해도 무방합니다.)로 구분한 쌍으로 묶어 서버 목록 파일을 만들어서 별도의 serverlist.txt 파일로 저장합니다. (추후 파워쉘 스크립트 파일에서 이 목록파일(serverlist.txt)을 읽어 올 예정입니다.)

www.google.com;80 www.google.com;81 www.microsoft.com;80

 

이제 파워쉘 스크립트를 작성하기 위해서 Windows Powershell ISE를 오픈합니다. (문서편집기 아무거나 사용하여 작성하셔도 됩니다만, 실행까지 시켜보기 위해서는 Powershell ISE가 편리하겠죠?)

빈 파워쉘 스크립트 파일에 위에서 Get-Content cmdlet을 사용하여 작성한 서버 목록 파일(serverlist.txt)을 읽어오는 스크립트를 작성합니다.

$ServerList = Get-Content .\serverlist.txt

serverlist.txt 파일에는 총 3개의 행이 존재하고 각각의 목록은 ip와 port를 ";"로 구분해 놓았으니, loop를 돌면서 각각의 행을 ip와 port로 구분하도록 $arrSvr라는 배열에 저장합니다.

Foreach ($Server in $ServerList) { $arrSvr = $Server -split ';' }

Test-NetConnection cmdlet을 실행시킬때 ComputerName, Port 옵션에 각각 ip와 port를 지정하고,

저희가 얻고자하는 결과는 특정 포트 연결의 성공여부이기 때문에 TcpTextSucceeded 필드만 추출하여 $ConnState 변수에 저장합니다.

$ConnState = (Test-NetConnection -ComputerName $arrSvr[0] -Port $arrSvr[1]).TcpTestSucceeded;

그 후 Write-Host cmdlet을 사용하여 결과에 따라 테스트 결과를 화면에 출력합니다.

If ($ConnState -eq $False) {
	Write-host $Server "test fail.";
} else {
	Write-host $Server "test succeed.";
}

지금까지의 파워쉘 스크립트를 하나의 파일로 요약하면 아래와 같습니다.

# 서버목록 파일을 읽어서 저장
$ServerList = Get-Content E:\temp\powershell\serverlist.txt;
Foreach ($Server in $ServerList) {
	# ip;port쌍을 구분자 ';'로 구분하여 배열에 저장
	$arrSvr = $Server -split ';'
	
    # Test-NetConnection cmdlet 실행하여 결과를 $ConnState 변수에 저장
 	$ConnState = (Test-NetConnection -ComputerName $arrSvr[0] -Port $arrSvr[1]).TcpTestSucceeded
    If ($ConnState -eq $False) {
        Write-host $Server "test fail.";
    } else {
        Write-host $Server "test succeed.";
    }
}

위와 같은 스크립트를 작성하고 스케쥴을 등록하여 주기적으로 실행시키면 포트의 활성화 여부를 테스트 할 수 있겠죠?

테스트 실패 시 "test fail"이라고 출력하지 않고 등록된 관리자에게 메일을 발송하면 더 편리하겠네요.

 

지금까지 말씀드린 Test-NetConnection 기능 외 자세한 기능을 알고 싶으시다면, Microsoft 매뉴얼을 참고하세요.

Test-NetConnection (nettcpip)

Use this topic to help manage Windows and Windows Server technologies with Windows PowerShell.

docs.microsoft.com

 
반응형
728x90

AIX tcping 설치 위치 정보

IBM freeSoftware RPM : https://public.dhe.ibm.com/aix/freeSoftware/aixtoolbox/RPMS/ppc-6.1/tcping/

RPMS 폴더 아래의 버전별로 tcping 확인해서 설치 하면됩니다. 

 

tcping 버전 정보 확인

tcping --version

tcping 명령어의 기본 구문

Usage: tcping [-q] [-t timeout_sec] [-u timeout_usec] <host> <port>

 

사용 예시

tcping을 사용하여 호스트와 포트에 대한 연결을 테스트할 수 있습니다.

 

  • 호스트와 포트에 대한 기본적인 테스트
tcping example.com 80

이 명령어는 example.com의 80번 포트에 대한 연결을 시도하고 응답 시간을 표시합니다.

 

  • 특정 응답 시간 제한과 함께 테스트
tcping -t 5 example.com 80

이 명령어는 최대 응답 시간이 5초로 제한된 example.com의 80번 포트에 대한 연결을 테스트합니다.

 

  • 특정 포트 범위에 대한 테스트
tcping -p 22-80 example.com

이 명령어는 example.com 호스트에 대한 22부터 80까지의 포트 범위에 대한 연결을 시도하고 응답 시간을 표시합니다.

 

  • 특정 포트만 테스트
tcping -p 443 example.com

이 명령어는 example.com 호스트의 443번 포트에 대한 연결을 시도하고 응답 시간을 표시합니다.

 

  • closed
tcping sangchul.kr 80
$ tcping sangchul.kr 80
sangchul.kr port 80 closed.
  • open
tcping sangchul.kr 80
$ tcping sangchul.kr 80
sangchul.kr port 80 open.
tcping sangchul.kr 443
$ tcping sangchul.kr 443
sangchul.kr port 443 open.

 

tcping은 호스트와 포트에 대한 연결 상태를 확인하는 데 유용한 도구입니다.

반응형

+ Recent posts