Feb 162017
 

PS4 Pro가 나온지 벌써 3개월이 지났지만 여전히 재고는 없고 검색을 조금만 해보면 가격을 높혀 파는 매물만 존재하는 듯 하다. 이에 몇몇 사람들은 포기하고 PS4 Slim을 구매하는 사람들도 있고 어떤 분들은 해외에서 직구를 하거나 윗돈을 주고 중고나라에서 구매하는 사람들도 존재하는 것 같다. 본인 같은 경우는 A/S가 확실치 않은 직구를 하고 싶진 않고 중고를 그다지 좋아지지 않는 나는 이 길을 택하지도 않을 것이고 급하지도 않기 때문에 매물이 있는 PS4 슬림을 구매하지는 않는다. 그러면 한국에서 일반적인 경로로 물건을 구매하게 될텐데 크게 두 가지 경로가 있을 것이다. 하나는 오프라인을 통해서 구매하는 방법이 있고 다른 한 가지 방법이 온라인을 통한 방법이다. 오프라인의 경우 회사 휴가를 쓸 수도 없고 구매하는 곳까지 가야하고 줄도 서야하고 너무 귀찮기 때문에 온라인을 노려보기로 했다. 그런데 재고가 들어왔을 때 알려주는 기능이 있다면 상관 없지만 그게 아니기 때문에 귀찮은 것을 싫어하는 개발자 입장에서 홈페이지에 주기적으로 접속해서 재고 여부를 확인하는 프로그램을 만들고자 하였다.

요구사항

  • 지금 사용하고 있는 개인 서버(리눅스)에서 쉽게 설정해서 쓸 수 있을 것
  • 만드는데 10분안에 뚝딱 만들 것
  • 최대한 로직 간단하게 하기

그 결과 쉘 스크립트가 가장 만만한 선택지였고 홈페이지에서 웹페이지를 다운로드 받아서 문자열 분석해서 구현하는 것으로 하였다. 쉘 스크립트는 가끔씩 만들어 본 적이 있어서 익숙하다는 점도 한 목 했다.

알고리듬

1) PS4 구매 페이지를 다운받는다.
2) "재고없음"이란 글자가 있는지 확인한다.
3) 만일 "재고없음"이 존재하면
  3-1) n초 기다린다
  3-2) 1로 돌아감
4) 만일 "재고없음"이 없으면
  4-1) 비프음을 울리고 이메일 전송
  4-2) 종료

한계점 : 네트워크가 안된다던지 하는 경우는 제외, 구매 페이지 자체의 형식이 바뀌는 부분은 제외 등

구현 준비

웹 페이지의 구성 확인

간단한 구현을 위해서 웹페이지의 소스의 문자열을 파악하는 방식으로 구현하는 것을 고려하였다. 이에 따라서 재고가 있는 페이지와 재고가 없는 페이지를 비교했다. 어떤 차이점이 있는지를 알아야 문자열 비교를 할 수 있기 때문이다. 제일 좋은 점은 재고 있는 경우 또는 재고 없는 경우에 특정한 문자열(단어)이 존재하는 것이 최고이다. 운이 좋게도 “재고없음”이라는 단어가 재고가 있는 경우는 등장하지 않는 것을 확인 가능했다.

아래는 이를 위해 이용한 url이다. 물론 이건 2017년 2월 15일 현재에 확인한 결과이니 나중에 재고 없는데 왜 있냐라거나와 같은 이야기가 안나오기를 바란다.

크롬에서 공식PS4판매 페이지 소스코드 보기

리눅스 명령어 조사

리눅스 명령어를 조합해서 만드는 것이 매우 직관적이고 불필요한 재개발을 줄일 수 있는 좋은 선택이기 때문에 최대한 사용해 보겠다.

| – 파이프라인 (pipeline)

쉘에서 파이프(|)는 파이프 좌측 명령의 stdout을 파이프 우측 명령의 stdin으로 입력해주는 역할을 한다.

지금까지 조사했던 내용을 조합해 보면 wget -qO- https://store.sony.co.kr/handler/ViewProduct-Start?productId=50150445 | grep -c '재고없음'을 입력하면 재고가 없을 때 1이상의 값이 되며, 재고가 있을 때 0이 출력되게 되는 코드가 만들어 진다.

명령어 치환 (Command Substitution, “)

\`\을 이용하면 \`blah\라는 명령어를 실행하고 그에 따른 stdout텍스트로 치환하는 기능이다.
예를 들면 ls error.log.`date "+%Y%m%d"`라고 실행하면, ls error.log.20170216이 실제로 실행되게 된다.

wget – 웹페이지 다운로드

wget을 이용하면 웹 페이지의 내용을 가져올 수 있다. https나 http에 필요하면 로그인, 쿠키 등도 붙일 수 있고 옵션을 붙이면 stdout으로 결과를 뽑아볼 수 있기 때문에 다른 명령어와 연동하기에 편리하다.
여기서는 wget -qO- <<http location>>을 이용하여 웹 페이지(html)를 가져와서 stdout으로 출력한다.

grep – 문자열 검색

grep은 리눅스에서 잘 사용하면 많은 것을 할 수 있는 기능으로써 입력된 문자열에서 특정 문자열을 검색하는데 사용한다. 여기서 주목한건 -c옵션인데, 이를 이용하면 그 문자열이 입력된 문자열에서 몇 번 등장했는지 횟수를 stdout으로 출력할 수 있다.

예를 들어 echo "거북이 밥먹어 하하하" | grep -c '거북이'라는 코드를 입력하면 1을 출력하게 되는 것이다. 만약 echo "토끼 밥먹어 하하하" | grep -c '거북이'라는 코드를 입력하면 ‘거북이’라는 문자열이 없기 때문에 0이 리턴된다.

echo – 입력을 그대로 출력

셀 스크립트를 구현할 때, 현재 진행상황을 출력하기 위해서 사용되는 명령어이다. echo hello를 입력하면 stdout으로 hello가 출력된다.
-n 옵션 사용시 뒤에 개행을 하지 않는다. -e옵션 사용시 escape 문자열을 해석한다. ASCII에서 문자열 역할을 하지 않는 코드들을 생각하면 된다.
따라서 비프음을 쉘에서 울리고 싶다면, ASCII에서 비프를 의미하는 0x07 BEL을 이용한다. 응용해 보면 echo -ne '\007'을 입력하면 비프음이 울리게 된다.

sleep – 지정한 시간만큼 멈춤

sleep <<seconds>>명령어는 입력한 만큼의 숫자의 초만큼 프로그램을 정지시키는 명령어이다. 소수점도 이용 가능하다. 예를 들면, sleep 0.1이라고 입력하면 0.1초 동안 정지된다.

mail – 메일을 확인하거나 보내는 명령어

mail명령어를 전부 설명하면 범위를 벗어나기 때문에 보내는 방법에만 집중해보면, echo “PS4 Pro 재고가 있어요!!!” | mail -s “[알림]PS4Pro 재고 있음!!” blah@gmail.com과 같이 입력하면 제목을 [알림]PS4Pro 재고 있음!!으로, 내용은 PS4 Pro 재고가 있어요!!!, 보내는 주소는 blah@gmail.com이 되는 것이다. 혹시 전송이 안되거나 스팸메일함으로 전달 된다면, 믿을 수 있는 smtp 서버를 지정하면 되는데, 이 부분은 범위를 벗어나니 linux sendmail이란 키워드로 검색해 보는 것을 추천한다.

exit – 종료

쉘에서 나갈 때는 exit를 사용하면 종료되게 된다.

쉘 스크립트 언어

지금까지 위의 명령어를 이용하면 위의 알고리듬을 실행하기 위한 구성요소들은 거의 다 준비되었다고 볼 수 있다. 하지만 여기서 문제는 재고없으면 어떻게 다시 실행시킬 것인지 재고가 있는 경우 어떻게 알릴 것인지가 해결이 되지 않았다.
이 부분을 쉘 스크립트를 통해서 해결한다. 여기서는 많이 사용되고 있는 bash쉘을 이용하여 구현해 보겠다.

시작 부분

쉘 스크립트의 시작부분에는 #!/bin/bash를 입력한다. 그러면 이 쉘 스크립트의 내용을 실행할 때 /bin/bash를 통하여 동작시키게 된다. bash를 사용하지 않았으면 해당하는 언어를 적으면 된다. 파이썬이나 펄도 마찬가지 방법으로 이용할 수 있다.

변수대입

변수 대입은 변수명=대입할내용를 통해서 할 수 있다. 숫자 10abc란 변수에 넣고 싶으면 abc=10이라고 입력하면 된다.

변수사용

변수를 사용할 때는 변수명 앞에 $기호를 붙인다. 예를 들어서 abc란 변수를 사용할 떄는 $abc로 입력한다.

조건문

아래와 같은 형식으로 조건문을 사용할 수 있다.

if [<<조건>>]; then
   <<내용>>
fi

반복문

while 인 경우

while <<조건>>
do
   <<내용>>
done

for를 쓸 경우 (1~30까지 1씩 증가하면서 변수 i에 넣음)

for i in {1..30}
do
   <<내용>>
done

숫자계산

쉘 스크립트에서 숫자에 대한 사칙연산 등은 아래의 명령어를 사용한다.
$((<<expr>>))

예)
a=$((1+2+3)) => $a6입력
b=$((a+10)) => $a6이므로 $b16이 입력
c=$((b-1)) => $a6, $b16이므로 $c에는 10이 입력

주석처리

# 등장 후 개행까지는 전부 주석으로 취급함

실제 코드 구현

위에서 간단하게 배워본 쉘 스크립트를 통하여 실제 프로그램을 구현해 보았다.
알고리듬을 기준으로 구현한 코드는 아래와 같다.

#!/bin/bash

retry_count=0

while true
do
        # 50150247 : PS4 slim
        # 50150445 : PS4 Pro

        echo "try #$retry_count... "
        retry_count=$((retry_count + 1))

        result=`wget -qO- https://store.sony.co.kr/handler/ViewProduct-Start?productId=50150445 | grep -c '재고없음'`

        if [ $result == 0 ] ; then
                echo '재고 풀렸음!!!'

                # beep 음
                for i in {1..30}
                do
                        echo -ne '\007'
                        # 30fps
                        sleep 0.03
                done

                # 메일 전송
                echo “PS4 Pro 재고가 있어요!!!” | mail -s “[알림]PS4Pro 재고 있음!!” blah@gmail.com

                # 종료
                exit
        fi

        # retry each 60 seconds
        sleep 60
done

vinano와 같은 텍스트 에디터를 열어서 ps4_checker.sh이라는 이름으로 만든다.
그 이후 쉘이 실행될 수 있도록 chmod u+x ps4_checker.sh을 실행하여 실행권한을 부여한다.

비프음의 경우 sleep으로 끊어서 처리하지 않으면 중첩되서 한 번 밖에 들리지 않게 된다.

실행방법

./ps4_checker.sh 을 실행한다. 그러면 60초마다 한 번 씩 재고유무를 체크하게 된다.
실제로 재고 있을 때 동작하는지 ‘PS4 Slim’웹페이지 주소를 이용하여 테스트 해보도록 하자.

재고 있는 경우

$ ./ps4_checker.sh
try #0...
재고 풀렸음!!!
$

성공적으로 이메일이 오는 것을 확인할 수 있다. 만약 안보이면 스팸메일함을 확인해 보자. 그래도 없으면 mail관련 리눅스 설정이 추가적으로 필요할 수도 있다.

재고가 있다는 이메일을 받은 화면

재고 없는 경우

$ ./ps4_checker.sh
try #0...
try #1...
try #2...
try #3...
try #4...
try #5...

강제 종료는 “Ctrl+C”를 하면 된다.

한계

“재고없음”이라는 글자가 없는 것을 판단하기 때문에, 인터넷이 끊기게 되면 재고있다고 오작동 하게 된다. 이 부분은 여러분이 수정해 보도록 하자! 🙂

결론

이 글은 어떻게 이 프로그램을 만들게 되었고 어떤 요구사항을 따르게 해야하는지 정리하였으며 구현 시작하기에 앞서 실제 PS4판매 페이지의 특성을 분석해보았으며 이에 알맞는 프로그램을 개발하기 위해서 쉘 스크립트 언어와 여러 리눅스 명령어를 조사하여 실제로 구현하여 잘 동작하는 것을 확인할 수 있었다. 물론 인터넷이 끊기거나 홈페이지가 변경되었을 때에 대응책에 대한 부분은 최대한 간단히 만들기 위해서 고려상황에서 제외하였다. 또한 대몬(daemon)화 시켜서 동작시키는 부분도 범위 밖이기 때문에 다루지 않았다. 이 글을 통해 꼭 C나 자바와 같은 프로그래밍 언어를 공부해야만 프로그램을 만들 수 있는게 아니라 리눅스에서 제공하는 유용한 명령어들을 조합하여 구현하는 것으로도 충분히 쓸만한 유용한 프로그램을 만들 수 있다는 것을 알 수 있었다. 이를 응용하면 꼭 이 상황뿐만 아니라 다른 홈페이지를 감시하는 경우에도 활용할 수 있을 것이다.

Sep 142016
 

VPN은 외부로부터 격리된 인트라넷을 구성하면 외부에서 접속이 불가능한데 이를 가능하게 해주는 서비스이다. 물리적으로 서로 떨어져 있는 회사 네트워크를 외부에 공개하지 않으면서 통신하기 위해 만들어 졌다. 물론 회사 네트워크에서 사용하면 이런용도로 사용하게 되겠지만, 집에서 공유기 뒤에 NAS를 쓰거나, 개인 서버를 사용하는 경우에도 동일한 방법으로 활용할 수 있다. 만약 NAS나 개인서버를 SMB(네트워크 공유 기능)통해 사용하기 위해서는 같은 네트워크에 있어야 한다. 하지만 외부에서는 이 방법을 사용할 수 없는데, 이는 ISP(네트워크 제공사)의 방화벽 문제가 있기 때문이며, 따라서 WebDAV등을 이용하여 구현하는 방법이 일반적이다. 이 경우에 외부에는 내부 서버를 공개하지 않으면서 안전(암호화된)하게 내부 네트워크에 접속된 것과 같은 상태를 만들 수 있는 방법이 바로 VPN인 것이다.

일반적인 공유기는 VPN 프로토콜 중에 하나인 PPTP를 지원하도록 구현되어 있다. 하지만 PPTP의 문제는 인증시스템이나 암호화 방식이 매우 오래되었으며 보안에 취약하다는 점이다[1]. 그래서인지 이번에 업데이트 되는 iOS 10, macOS Sierra부터는 보안상의 이유로 더 이상 PPTP프로토콜 기반의 VPN서비스를 이용할 수 없게 되었다[2]. 하지만 필자가 가지고 있는 공유기에서 PPTP를 지원하지 않기 때문에 다른 프로토콜을 사용하는 VPN이 필요하게 되었다. 하지만 굳이 공유기에서 PPTP가 아닌 다른 프로토콜을 지원하게 하려면 공유기의 펌웨어를 커스터마이징해야 한다는 것인데 그건 너무 시간이 많이 걸리며 공유기 공급사에서 소스코드를 공개하지 않는다는 점에서 어려움이 있다. 따라서 VPN서버를 공유기에서 내부 서버로 변경하면 여러종류의 VPN프로토콜이 사용 가능해 지기 때문에 홈 서버에 VPN서버를 설치 하게 되었다. 좀 더 큰 CPU파워를 사용할 수 있게 됨으로써 최신 VPN 프로토콜과 고급 암호화 기능도 사용할 수 있게 되었다.

자료 조사를 해보면서 여러 종류의 VPN 프로토콜이 존재함을 알 수 있었으며, VPN 프로토콜을 선택 기준이 필요해 졌는데 모바일이나 OS에서 추가적인 프로그램 설치 없이 사용할 수 있어야 한다는 조건을 걸었다. 이 조건을 만족하면 모바일로 외부에서 집에 있는 서버에 있는 동영상을 스트리밍으로 볼 수 있기 때문에다. 이에 추가 클라이언트 환경 설치가 필요한 OpenVPN은 제외되었다. 그렇게 되면 가능한 프로토콜이 L2TP/IPSec, IPSec, IKEv2 를 사용할 수 있음을 확인 가능하였다. 최초에는 L2TP/IPSec을 이용할 예정이였으나, 필자가 사용하는 OS에서는 기본 지원하며, 속도도 빠르고 높은 보안을 제공하는 IKEv2 프로토콜을 이용하여 구현하기로 하였다[3].

IKEv2 프로토콜을 사용할 때 ESP를 통하여 암호화된 패킷을 전송한다. 원래 ESP는 IP프로토콜에 바로 들어가기 때문에 공유기(NAT)뒤에 VPN서버가 있는 경우에는 DMZ설정 같은 것이 필요하며 공유기가 이 기능을 지원해야할 수도 있다. DMZ로 설정하면 VPN서버의 모든 부분이 인터넷으로 공개되기 때문에 내부를 숨기겠다는 목적이 달성되지 않는다. 하지만 선배 개발자들은 이런 문제를 해결하기 위해 NAT Passthrough라는 것을 제공하며 UDP프로토콜에 ESP를 담아서 보내도록 구현이 된다. 이 문제는 이를 설정함으로써 해결 된다.

준비물은 MITM(Man in the middle attack)방지를 위한 서버 인증을 위한 인증서가 필요하다. 이 글에서는 self-signed 인증서를 사용하여 IKEv2서버 구축하는 방법을 알려주지 않는다. 만약 self-signed 인증서를 사용하게 되면 클라이언트에서 추가적인 설정이 필요할 수도 있다.

이 글은 공유기의 IP주소로 DNS/DDNS 등의 방법으로 도메인이 할당되어 있으며, 이 도메인으로 정상적인 SSL 인증서를 발급받았다는 전제로 작성되어 있다.

SSL 인증서는 일반적으로 유료이지만 StartSSL이나 Let’s Encrypt 등을 통하여 무료로 발급 가능하다.

IKEv2를 동작시키기 위해서는 UDP/500과 UDP/4500을 열어 두어야 한다. UDP/500은 IKE프로토콜을 위해 필요하며, UDP/4500은 IPSec을 이용하기위해 필요하다. 이 두가지 포트를 공유기에서 포트포워딩 설정을 해두어야 한다.

IKEv2를 사용하기 위해서는 strongswan이라는 패키지 설치와 암호화 기능 등의 기능을 사용하기 위해다.

1. 패키지 설치
apt-get install strongswan libcharon-extra-plugins

2. 인증서 설정

2.1. root 인증서 복사
발급받은 인증서의 루트 인증서 및 채인 인증서 복사
복사시 한 파일당 하나의 인증서만 포함 시킬 것
/etc/ipsec.d/cacerts

2.2. 인증서 복사
발급받은 인증서 파일 복사(pem)
/etc/ipsec.d/certs

2.3 인증서의 비밀키 복사
발급받을 때 사용한 인증서 비밀키 복사 (키 패스워드 제거할 것)
/etc/ipsec.d/private

2.4 권한 설정
chmod 740 /etc/ipsec.d/cacerts
chmod 740 /etc/ipsec.d/certs
chmod 700 /etc/ipsec.d/private

3. /etc/ipsec.conf 파일 수정

config setup
  strictcrlpolicy=yes
  uniqueids = no

conn roadwarrior
  auto=add
  compress=no
  type=tunnel     # tunnel: network 계층(ip)부터 암호화, transport: 전송 계층(transport layer; TCP/UDP)부터 암호화
  keyexchange=ikev2
  rekey=no
  reauth=no
  fragmentation=yes
  forceencaps=yes
  dpdaction=clear
  dpddelay=35s
  dpdtimeout=2000s
  left=%any
  leftid=@example.com   # 아래 ipsec.secrets의 이름과 통일, 인증서에 도메인 포함되어 있을 것
  leftcert=example_com.pem   # 상기 certs 디렉토리에 복사한 인증서 파일명으로 변경 
  leftsendcert=always
  leftsubnet=0.0.0.0/0
  leftauth=pubkey
  right=%any
  rightid=%any
  rightauth=eap-mschapv2
  eap_identity=%identity
  rightdns=192.168.1.1           # 여기서 rightdns 의 주소를 VPN사용시 쓸 DNS서버 주소로 변경 필요하다. (예: 8.8.8.8)
  rightsourceip=10.8.10.0/24
  rightsendcert=never

4. /etc/ipsec.secrets

# 서버 도메인과 키 설정

# 예제 - 아래 도메인은 클라이언트 설정시 사용, 인증서에 아래 도메인이 포함되어 있어야 함, 상기 복사한 비밀키 파일명을 사용함
example.com : RSA “example_com.key"

{{VPN접속ID}} : EAP “{{VPN접속PASSWORD}}"
# 예제
admin : EAP “password"

5. 서버 재시작
ipsec restart

6. 공유기(NAT) 포트 포워딩
UDP 500 과 UDP 4500을 내부에 설치된 VPN서버로 포워딩

7. 테스트
iOS기기나 macOS에서 아래의 설정으로 만듦
내부망과 외부망에서 각각 수행하여 정상적으로 접속 되는지 확인한다.

  • VPN Type : IKEv2
  • Server Address(서버 주소) : VPN의 도메인 주소 (예: example.com)
  • Remote ID (리모트 ID) : 상기 적은 도메인 주소(예: example.com)
  • Local ID (로컬 ID) : 비워둘 것
  • Authentication Settings…(인증 설정) : 사용자 이름
    사용자 이름 : ipsec.secrets 에 설정한 아이디
    패스워드 : ipsec.secrets 에 설정한 패스워드
VPN 설정 예시

VPN 설정 예시

 

connected to VPN

VPN 접속 성공

8. 관련 접속 로그 확인
tail -f /var/log/syslog
tail -f /var/log/auth.log

이 글을 통해 우분투 서버에서 IKEv2를 사용한 서버 구축이 가능하였으며 이를 통해 어디에서나 모바일 디바이스, 데스크톱을 통하여 내부 네트워크에 접속할 수 있게 되었으며, 암호화가 되어 안전한 환경에서 내부서버의 데이터를 사용할 수 있게 되었다.

참고문헌

[1] B. Schneier, Mudge, “Cryptanalysis of Microsoft’s PPTP Authentication Extensions (MS-CHAPv2)”, CQRE ’99, Springer-Verlag, 1999, pp. 192-203.
[2] “Prepare for removal of PPTP VPN before you upgrade to iOS 10 and macOS Sierra”, Apple, https://support.apple.com/en-us/HT206844
[3]  https://hide.me/en/blog/2015/03/whats-the-difference-considering-pptp-vs-l2tp-vs-sstp-vs-ikev2/
[4] https://hub.zhovner.com/geek/universal-ikev2-server-configuration/

Sep 102016
 

우리는 ubuntu에서 패키지 인덱스를 업데이트 하기 위해 apt-get update 라는 명령을 사용하여 업데이트한다. 하지만 만약 커스텀 패키지를 이용하는 경우 (예: owncloud)에 keyexpired라는 문구를 볼 수 있다. 이는 패키지를 서명하는데 사용된 인증키가 시간이 지나 만료되었기 때문이다. 따라서 키를 다시 업데이트 해주는 작업이 필요하다. 아래의 절차를 따라 새로 받아보도록 하자.

1)  아래와 같은 메시지를  apt-get update 사용시 발견

Reading package lists... Done
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://download.opensuse.org  Release: The following signatures were invalid: KEYEXPIRED 1472205884

W: Failed to fetch http://download.opensuse.org/repositories/isv:/ownCloud:/community/xUbuntu_14.04/Release

W: Some index files failed to download. They have been ignored, or old ones used instead.

2) apt-key list 명령어를 통해 expired 키를 찾기

# apt-key list | grep "expired:"
pub 1024D/BA684223 2012-02-08 [expired: 2016-08-26]

3) 목록에 있는 내용을 통해 “BA684223″이란 키가 2016-08-26에 만료되었으며 업데이트 해야함을 확인 가능

4) apt-key 명령으로 새로 키(BA684223)를 업데이트 받음

# apt-key adv --recv-keys --keyserver keys.gnupg.net BA684223

# apt-key adv --recv-keys --keyserver keys.gnupg.net BA684223
Executing: gpg --ignore-time-conflict --no-options --no-default-keyring --homedir /tmp/tmp.DE4JfiHL45 --no-auto-check-trustdb --trust-model always --keyring /etc/apt/trusted.gpg --primary-keyring /etc/apt/trusted.gpg --keyring /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg --keyring /etc/apt/trusted.gpg.d/docker-maint-testing.gpg --keyring /etc/apt/trusted.gpg.d/openjdk-r-ppa.gpg --keyring /etc/apt/trusted.gpg.d/webupd8team-java.gpg --recv-keys --keyserver keys.gnupg.net BA684223
gpg: requesting key BA684223 from hkp server keys.gnupg.net
gpg: key BA684223: "isv:ownCloud OBS Project <isv:ownCloud@build.opensuse.org>" 5 new signatures
gpg: Total number processed: 1
gpg:         new signatures: 5

5) 다시 우분투 패키지 업데이트 작업을 진행한다.

# apt-get update

# apt-get upgrade

 

참고 자료

[1] http://superuser.com/questions/513609/how-to-apt-update-when-apt-is-not-accepting-the-repository

Oct 302014
 

1. 서론
  mysql 데이터베이스의 파티션이 커지면 데이터베이스 파일을 새로운 파티션에 옮기고 심볼릭 링크를 걸어서 용량을 확보하는 방법이 있다. 한편 우분투에서는 apparmor라고 하는 권한 관리 시스템이 존재하여서, 심볼릭 링크 후에 새로운 경로(파티션)에 대한 권한을 줄 필요가 있다.
  여기서 apparmor가 설치된 mysql 환경에서 어떻게 파티션을 만들고, 공간을 확장하는지 알아 본다.
 
2. 수행 방법
1) 추가할 디스크 마운팅 및 포멧
 # fdisk -l      // 파티션 할당 상태 확인
 # fdisk /dev/xvdb  // /dev/xvdb : 추가된 디스크 주소
    n 누루고 파티션 설정(primary partition, cylinder etc)
    w 눌러서 저장
 # mkfs.ext4 /dev/xvdb1     // ext4로 포멧
 # mount /dev/xvdb1 /mnt/mysql_disk1   // 마운팅
 
 # blkid     // 추가된 /dev/xvdb1 의 UUID 확인
 # vi /etc/fstab    // 재부팅시 바로 자동 마운팅을 위해 설정
  UUID=<> /mnt/mysql_disk1 ext4 rw 0 0     # 제일 아래줄에 추가
 # df -h     // 디스크 용량 확인
 
2) Apparmor 설정파일 변경 [1]
 – 우분투는 접근관리를 좀 더 잘 하기 위해 파일에 권한을 사용자 단위로 지정하는 것이 아니라, 실행되어 있는 프로그램이 어디에 접근할 수 있는지를 설정함으로써 해결하고자 하였다. 이 편이 관리 측면에서 더 이득이 크다.
 
 # vi /etc/apparmor.d/user.sbin.mysqld
      # 제일 아래줄에 추가
      /mnt/mysql_disk1/mysql_data r,
      /mnt/mysql_disk1/mysql_data/** rwk,
 
3) sql 서버 종료
     # service mysql stop
4) 데이터파일을 새로 저장할 큰 용량의 디스크로 복사 (ubuntu mysql은 /var/lib/mysql 에 있음)
     # cd /var/lib/mysql
     # cp -R * /mnt/mysql_disk1/mysql_data
5) 기존 파일 백업
     # mv /var/lib/mysql /var/lib/mysql_bak
6) 심볼릭 링크 연결
     # cd /var/lib
     # ln -s /mnt/mysql_disk1/mysql_data mysql
7) sql 서버 다시 켜기
     # service mysql start
8) DB에 잘 접속되나 테스트
 
3. 정 리
 파일 복사하는데 꽤 시간이 걸리기 때문에 추후에는 mysql서버를 하나 더 준비하여 데이터를 옮기도록 작업하는 것이 더 좋을 것으로 예상된다. 그리고 데이터 베이스 파일을 하나로 하지 않고 여러개로 나누어서, 파일 단위로 심볼릭 링크를 걸어서 해결하는 방향이 더 좋을 것이라고 생각한다.
 
4. 관련 자료
[1] Recover an Innodb mysql database from an EBS on Ec2, Stack Exchange : http://dba.stackexchange.com/questions/57424/recover-an-innodb-mysql-database-from-an-ebs-on-ec2
[2] https://blogs.oracle.com/jsmyth/entry/running_out_of_physical_disk

Dec 312013
 

아래와 같은 에러를 내면서 “gem install rmagick”이 실패할 경우, 아래의 “checking for wand/MagickWand.h”를 주의깊게 보자. magickwand 라이브러리가 설치되어 있지 않기 때문에 발생하는 것이다.

root@wminserver:/home/redmine/redmine/redmine-2.4# gem install rmagick
Building native extensions.  This could take a while...
ERROR:  Error installing rmagick:
	ERROR: Failed to build gem native extension.

    /usr/local/rvm/rubies/ruby-2.1.0/bin/ruby extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for gcc... yes
checking for Magick-config... yes
checking for ImageMagick version >= 6.4.9... yes
checking for HDRI disabled version of ImageMagick... yes
checking for stdint.h... yes
checking for sys/types.h... yes
checking for wand/MagickWand.h... no

Can't install RMagick 2.13.2. Can't find MagickWand.h.
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/usr/local/rvm/rubies/ruby-2.1.0/bin/ruby

extconf failed, exit code 1

Gem files will remain installed in /usr/local/rvm/gems/ruby-2.1.0/gems/rmagick-2.13.2 for inspection.
Results logged to /usr/local/rvm/gems/ruby-2.1.0/extensions/x86_64-linux/2.1.0/rmagick-2.13.2/gem_make.out

 

해결방법

libmagickwand-dev를 설치해 줌으로써 해결이 된다. 아래의 명령을 실행시켜보도록 하자.

$ sudo apt-get install libmagickwand-dev
$ gem install rmagick

문제없이 잘 설치 될 것이다.

Reference

[1] Stack Overflow(Can’t install RMagick 2.13.1. Can’t find MagickWand.h), http://stackoverflow.com/questions/9050419/cant-install-rmagick-2-13-1-cant-find-magickwand-h

Nov 072013
 

2013년 11월 07일 현재 기준..

1. 최신 우분투버젼을 설치하고 있다는 가정하에 redmine을 apt-get install redmine 등의 방법으로 mysql을 이용하도록 설치하면 에러가 발생
-> /etc/redmine/default/database.yml 에서 adapter: 항목에 mysql을 mysql2로 변경

2. 성공적으로 설정이 끝나서 로그인 하려고 하면 에러 발생
-> “ruby-rack”의 버젼문제임 아래와 같이 해결(1.5.2 버젼의 경우 에러 발생)

2.1. /usr/share/redmine/Gemfile 의 마지막 줄에 아래 내용 추가

gem 'rack', '1.4.5'

2.2 다음과 같은 명령을 실행하여 1.4.5버젼의 rack를 설치
-> gem install rack –version 1.4.5
2.3 아래 명령을 실행하여 업데이트
-> bundle update

참조 : http://charles.lescampeurs.org/2013/11/01/redmine-on-ubuntu-13-10-with-apache2-and-passenger

May 302013
 

sar(System Activity Reporter)는 리눅스의 CPU 사용률, 메모리 사용률 따위의 정보를 알아내는대에 쓰이는 프로그램이다. 물론 모니터링에도 쓸 수 있다.

centos에서 이 프로그램은 ” yum install sysstat “를 통하여 설치할 수 있다.

사용법은 다음과 같다. /etc/cron.d/sysstat 에 등록된 정보에 따라서 로그를 지정된 파일에 저장시킨다.

처음 설치 후 실행을 위해서 ” service sysstat restart ” 명령을 통해 가능하다. ” chkconfig –add sysstat “를 통하여 재부팅 후에도 자동으로 실행되게 할 수 있다.

” sar -A -o <<파일명>>  <<반복|초>> <<반복횟수>> “을 통하여 파일에 로그를 저장한다. (-A는 모든 정보를 저장하는 옵션인데 자세한 것은 Oracle sar 설명[1]을 참조)

나중에 생성된 파일에서 정보를 다시 확인하는 방법은 ” sar -A -f <<파일명>> ” 을 통하여 가능하다.

 

[1] 시스템 작업 모니터링(sar) – Oracle(2013-05-30 01:56 KST 확인),  http://docs.oracle.com/cd/E24846_01/html/E23088/spmonitor-8.html

[2] http://www.welog.net/gbbs/bbs/board.php?bo_table=linux&wr_id=2

May 252013
 

2TB 이상의 하드디스크를 이용하여 리눅스에서 기존의 방법(fdisk)을 통해 파티션을 생성할 경우 무조건 2TB로만 만들어 지는 문제가 있다.

2TB이상의 파티션을 만들기 위해 아래의 방법을 이용하면 된다.

parted /dev/sdb     (/dev/sdb 는 상황에 맞추어 바꿀 것)
mklabel gpt
unit TB
mkpart primary 0.00TB 4.00TB
print
quit

cap_1

* 경고(책임의 한계) : 이 작업을 통하여 어떠한 일이 발생하더라도 책임을 지지 않습니다. 작업의 결과는 이 작업을 수행한 본인에게 책임이 있습니다.