게이트웨이 핑체크

Gateway ping 확인하는 스크립트

eth0 – 192.168.100.1
eth1 – 192.168.200.1

default gateway는  192.168.100.1 로 등록되어 있는 상태에서 192.168.100.1로 핑을 계속 보내면서 네트워크를 확인한다.

최대 실패횟수가 초과하면 현재 default gateway를 제거하고 eth1의 게이트웨이를 등록하고 관리자에게 이메일을 발송한다.

 

[code lang=”shell”]

#!/bin/sh

#####################################################################
# edit config
GW1="192.168.100.1"
GW2="192.168.200.1"
MAX_FAIL_COUNT=5
ERROR_MAILTO="me@jongwan.com"

#####################################################################
# path exec
EXEC_PING="/bin/ping"
EXEC_ROUTE="/sbin/route"
EXEC_MAIL="/usr/bin/mail"

#####################################################################
# prevent duplicate run
ME=`basename "$0"`
CHK_RUN=`pgrep -o $ME`
if [ $CHK_RUN -ne $$ ]; then
exit
fi

#####################################################################
# checking
FAIL_COUNT=0
while(true) do
# check ping
CHK=`$EXEC_PING -c1 $GW1 > /dev/null; echo $?`

# 0 is reachable, 2 is unreachable
if [ $CHK -ne "0" ]; then
FAIL_COUNT=$(($FAIL_COUNT+1))
else
FAIL_COUNT=0 # init fail_count if success ping
fi

# check fail count
if [ $FAIL_COUNT -ge $MAX_FAIL_COUNT ]; then
# add/del gateway
echo "Gateway connection failed : $GW1"
CMD1=`$EXEC_ROUTE del default gw $GW1`
CMD2=`$EXEC_ROUTE add default gw $GW2`

# send email
CMD3=`echo "Gateway connection failed : $GW1" | $EXEC_MAIL -s "Gateway connection failed : $GW1" $ERROR_MAILTO`

# exit shell
break
fi

sleep 1
done

[/code]

ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION

untitled-1

ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION

어느날 갑자기 다운로드가 되지 않고 이런 오류메시지가 나와서 알아보니 크롬 최신버전에서 헤더가 변경되었다한다.

아래처럼 변경 (PHP)

Header(“Content-Disposition: attachment; filename=$filename”);

Header(“Content-Disposition: attachment; filename=\”$filename\”“);

파일명을 쌍따옴표로 묶어준다.

PHP – HTML DOM 파서

Simple Html DOM Parser

http://sourceforge.net/projects/simplehtmldom/

C#의 Html Agility Pack(https://htmlagilitypack.codeplex.com/)같이 PHP에서 사용이 가능한 DOM 파서가 필요해 구글링을 해보니 Simplehtmldom 이라는 좋은 라이브러리가 있었다.

네이버 연합뉴스의 제목만 가져오기

[code lang=”php”]
$html = file_get_html(‘http://news.naver.com/main/list.nhn?mode=LPOD&mid=sec&oid=422&listType=title’);
foreach($html->find(‘.list_body .type02 a’) as $e) {
echo $e->innertext;
}
[/code]

다음 연령별 뉴스의 모든 노드를 출력

[code lang=”php”]
$html = file_get_html(‘http://media.daum.net/ranking/age/’);
$dump = dump_html_tree($html);
echo "<xmp style=’text-align: left;’>";
print_r($dump);
echo "</xmp>";
[/code]

Google reCAPTCHA PHP (CURL/Snoopy) Sample

logo_recaptcha_color_24dp Google reCAPTCHA

입력폼

[code lang=”html”]
<form onsubmit="return check_form()">
<input type="hidden" id="recaptcha_response" name="recaptcha_response" value="" />
<div id="recaptcha1"></div>
<button type="submit">확인</button>
</form>
[/code]

[code lang=”javascript”]
<script type="text/javascript">
var recaptchaWidger1;
var onloadCallback = function() {
recaptchaWidger1 = grecaptcha.render(‘recaptcha1’, {
‘sitekey’ : ‘{Site key}’
});
};
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>

<script>
function check_form() {
var recaptch_response = grecaptcha.getResponse(recaptchaWidger1);
if (!recaptch_response) {
alert("자동가입방지 문자를 확인해 주세요");
return false;
}

document.getElementById("recaptcha_response").value = recaptch_response;

return true;
}
</script>
[/code]

폼데이터 처리(1) – Snoopy.lib.php

[code lang=”php”]
include_once ‘Snoopy.class.php’;
$snoopy = new Snoopy;
$data = array(
"secret" => "Secret key",
"response" => $_POST[‘recaptcha_response’]
);
$snoopy->submit(‘https://www.google.com/recaptcha/api/siteverify’, $data);
$response = json_decode($snoopy->results);
if (!$response->success) {
exit("fail message");
}
[/code]

폼데이터 처리(2) – CURL

[code lang=”php”]
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/recaptcha/api/siteverify");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, "secret={Secret key}&response=".$_POST[‘recaptcha_response’]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$output = curl_exec ($ch);
curl_close ($ch);
$response = json_decode($output);
if (!$response->success) {
exit("fail message");
}
[/code]

find 명령으로 오래된 파일찾기

find 명령으로 오래된 파일을 찾아본다

현재위치에서 *.txt파일중 30일이 지난 파일을 출력

# find . -name “*.txt” -type f  -ctime +30 -print

현재위치에서 30일이 지난 모든 파일을 삭제

# find . -type f -ctime +30 | xargs rm

현재위치에서 30일이 지난 모든 디렉토리를 삭제

# find . -type d -ctime +30 | xargs rm -rf

현재 위치에서 7일안에 생성된 파일을 출력

# find . -type f -ctime -7 -print

현재 위치에서 1일안에 수정된 파일을 출력

# find . -type f -mtime -1 -print

옵션설명

-type f(파일) d(디렉토리) l(링크)

-ctime : 생성시간

-mtime : 수정시간

-atime : 접근시간

100kb이상인 파일을 출력

# find . type f -size +100k -print

fail2ban – 워드프레스 로그인 차단 (wp-login.php)

워드프레스 악의적인 로그인 차단

fail2ban 을 이용하여 워드프레스(https://wordpress.org/) 로그인 페이지를 안전하게 해보자

1

어느날 갑자기 무차별대입공격(brute force attack)으로 로그가 엄청나게 늘어나 버렸다.

워드프레스에 Wordfence 플러그인이 설치되어 있었지만 차단해주지는 못했다.

때문에 로그파일을 읽어 방화벽(iptables)에 등록해주는 fail2ban 을 이용하여 직접 방어해본다.

 

기본환경

ubuntu 14.04에 apache2가 설치되어 있다.

 

fail2ban 설치하기

fail2ban은 지정된 로그파일을 모니터링하면서 정규식을 이용, 특정패턴을 읽는다. 패턴이 일정이상 반복되면 bantime (초) 만큼 방화벽에 아이피를 등록하여 차단한다.

우분투 패키지매니저를 통한 설치

#sudo apt-get install fail2ban

소스설치

https://github.com/fail2ban/fail2ban 에서 소스파일을 다운로드한다.

로그파일 확인

워드프레스의 로그인 파일(wp-login.php)에 접근한 로그를 확인하기 위해 아파치 로그폴더를 확인해 본다

# cat /var/log/apache2/access.log | grep wp-login.php

91.200.12.42 – – [12/Sep/2016:02:02:49 +0900] “POST /wp-login.php HTTP/1.1” 200 5527 “http://jongwan.com/wp-login.php” “Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)”
91.200.12.42 – – [12/Sep/2016:02:03:07 +0900] “POST /wp-login.php HTTP/1.1” 200 5527 “http://jongwan.com/wp-login.php” “Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)”
91.200.12.42 – – [12/Sep/2016:02:03:14 +0900] “POST /wp-login.php HTTP/1.1” 200 5527 “http://jongwan.com/wp-login.php” “Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)”
91.200.12.42 – – [12/Sep/2016:02:03:25 +0900] “POST /wp-login.php HTTP/1.1” 200 5527 “http://jongwan.com/wp-login.php” “Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)”
91.200.12.42 – – [12/Sep/2016:02:03:37 +0900] “POST /wp-login.php HTTP/1.1” 200 5527 “http://jongwan.com/wp-login.php” “Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1; 125LA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)”

wp-login.php 파일에 수초간격으로 계속 접근을 시도한 것을 확인할 수 있다.

 

fail2ban 룰 작성

fail2ban에서 사용하는 failregex 라는 룰을 작성한다. 로그파일을 확인해 보면 아래와 같이 작성할 수 있다.

^<HOST> .* “POST /wp-login.php

 

룰 파일을 생성

fail2ban 은 기본적으로 /etc/fail2ban 에 설치된다.

# vim /etc/fail2ban/filter.d/wordpress-login.php

파일 내용은 아래와 같다

[bash]

[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
ignoreregex =

[/bash]

 

jail.conf 에 룰을 등록

룰을 생성했드면 jail.conf 에 해당 룰을 등록해 줄 수 있다. /etc/fail2ban/jail.conf 파일을 열어 마지막줄에 아래 내용을 추가해준다.

# vim /etc/fail2ban/jail.conf

[bash]

[wp-auth]
enabled = true
filter = wordpress-login
action = iptables-multiport[name=NoAuthFailures, port="http,https"]
logpath = /var/log/apache2/*access*.log
bantime = 1200
maxretry = 8

[/bash]

fail2ban 룰 테스트

fail2ban은 아래와 같은 명령을 이용해서 룰을 확인할 수 있다.

#fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/wordpress-login.conf

 

fail2ban 재시작

#service fail2ban restart