자동차 모니터링을 위한 TorquePro 로그 서버 구축

자동차를 관리하다보면 궁금한 것이 자꾸 생긴다. 예를들어 내가 이번 년도에 몇 키로나 운행했지? 내가 낸 최고 속도는? 자동차의 오일 변화는? 내가 자주 운행하는 곳은?

이러한 궁금증이 쌓이다보니 이전부터 안드로이드나 OBD2를 가지고 차량 상태를 모니터링 하는 방법을 고심하기도 했었다.

아무튼 현재 상태는 넥서스7 2세대 WiFi + OBD2 + TorquePro(App) + Advanced PID for Hyundai(App)의 조합으로 현 상태를 모니터링 할 수 있게 되었다. 넥서스7 2세대의 경우 일부 개조를 통해 자동차 시동이 걸리면 자동 부팅되고, 후방 카메라와 연결되어 화면을 출력해주는 등 여러가지 기능을 수행한다. 뭐, 이건 다음에 시간이 되면 따로 다루도록 하겠다.

이 구조에서 현재 상태 모니터링은 아무 문제 없었다. 현재 제네시스 쿠페 380에서 가장 큰 문제는 냉각 문제였는데… TorquePro를 사용하면 왠만한 정보는 다 읽을 수 있고, 심지어 오류코드 삭제까지 되니 충분했다. 하지만… 로그를 남길 수가 없었다.

물론 인터넷에 연결되었을 때 메일로 로그를 자동으로 보낼 수 있게하는 기능이 있긴하지만… 메일로 받아서 그걸 정리하고 데이터 추출하고… 귀찮은 일이 너무 많아지게 된다. 그래서 옵션을 좀 뒤지다보니… WebServerURL을 입력하는 곳이 있다! 그래서 조금 더 구글을 열심히 뒤져보니 TorquePro에서 인터넷이 연결되어 있을 경우, 주기적으로(최소 1초 단위) 모니터링하고자 하는 값들을 웹서버로 보내는 기능이 들어 있었다.

실제로 해당 기능을 바탕으로 TorquePro 공식 홈페이지에서 로그를 저장하고 볼 수 있는 기능을 제공하고 있고, 심지어 개인 서버에서 돌릴 수 있도록 PHP 등으로 구현된 서버 프로그램도 있었다.

그런데… 그래도 역시… 삽질은 해야 재미아니겠는가? 그래서 해당 내용들을 조사하고 정리하여 아래와 같은 구조로 동작한다는 것을 확인했다.

위의 그림을 보면 1단계는 TorquePro 어플리케이션에서 사용자가 설정한 URL로 GET 방식으로 Request 하는 것으로 시작한다. 가끔 인터넷 서핑할 때 http://……./…..?some=thing&all=about 같은 형태를 본적이 있을텐데 이게 GET 방식으로 데이터를 전달 하는 것이다.

해당 데이터를 JSON 형태로 보면

{
        "eml" : [EMAIL Address],
        "time" : [UNIX TIMESTAMP],
        "kff1001" : ....,
        .
        .
        .
        [KEY] : [VALUE]
}

위의 형태로 표현할 수 있다. 이게 GET 방식으로 전달되면

http://[URL]?eml=[EMAIL Address]&time=[UNIX TIMESTAMP]&kff1001=.....&[KEY]=[VALUE]

와 같이 데이터 전달을 수행한다. 일단 그럼 데이터는 서버로 전달된다. 그럼 서버에서는 해당 데이터를 파싱하고 저장하면 된다. 몰론 이걸로 끝은 아니다. 서버에서는 해당 데이터를 잘 받았다고 “OK!” 문자열을 응답으로 보내면 된다.

현재 해당 내용을 바탕으로 Flask + Apache2 를 이용하여 서버를 구축해보았다. 실제 데이터베이스에 저장된 내용은 아래와 같았다.

6320|[email]|1551670913242|kff1007|96.9
6321|[email]|1551670913242|GPSLongitude|000.000000
6322|[email]|1551670913242|kff1001|4.5
6323|[email]|1551670913242|GPSAccuracy|10.0
6324|[email]|1551670913242|GPSSatellites|8.0
6325|[email]|1551670913242|EngineRPM|635.0
6326|[email]|1551670913242|GPSAltitude|00.000000
6327|[email]|1551670913242|GPSLatitude|00.000000
6328|[email]|1551670913242|k-2149|56.0
6329|[email]|1551670913242|Bank1CatalystTemp|680.0
6330|[email]|1551670913242|TransmissionTemp|86.0
6331|[email]|1551670913242|v|8.0

실제 저장된 데이터를 보면 정상적으로 데이터가 들어오는 것을 알 수 있다. 아, GPS 정보도 정확하게 들어온다. 0으로 매워둔 것은 아무래도 개인 정보다 보니 가렸다. 아무튼, 지금 저장된 데이터의 이름은 KEY 값을 사람이 알아볼 수 있는 값으로 저장한 것이다. 현재까지 사용한 KEY 값은 다음과 같다.

k3c = "Bank1CatalystTemp"
k3d = "Bank2CatalystTemp"
k2f = "FuelLevel"
kff1001 = "GPSSpeed"
kff1006 = "GPSLatitude"
kff1005 = "GPSLongitude"
kff1007 = "GPSBearing"
kff1010 = "GPSAltitude"
kff123a = "GPSSatellites"
kff1239 = "GPSAccuracy"
kc = "EngineRPM"
k5 = "EngineCoolantTemp"
kfe1805 = "TransmissionTemp"
kf = "IntakeAirTemp"

일부값은 코드가 노출이 안되는 것들이 있었다. 특히 Advanced PID for Hyundai 같은 유료 PID 어플 같은 경우에는 PID가 나타나지 않아 조금 더 모니터링이 필요할 것으로 보여진다.

이번 작업은 대략적으로 어떻게 데이터를 받아들일지에 대한 고민을 해보고 해결을 하기 위해 작업한 것으로 정리할 곳이 많다. 그래서 코드나 웹을 공개하긴 조…금… 부끄럽다. 뭐, 계속해서 업데이트 해서 최종판을 공개하는게 목표긴하지만… 허허허 앞으로 지속적인 업데이트를 수행할 예정이다.

Apache2 + Flask 환경 구성

Apache2 에서 wsgi 모듈을 이용하여 Flask 개발 환경을 구성하는 방법에 대해 간단히 기록한다.

일단, Apache2에서 wsgi 모듈을 설치해야 한다.

sudo apt-get install libapache2-mod-wsgi

그 후에 간단한 구조를 구성해준다. 나는 그냥 간단하게 /FLASK/flask_app 폴더에 __init__.py와 flask_app.wsgi 파일을 생성해두었다.

/FLASK/flask_app/
                /__init__.py
                /flask_app.wsgi

먼저 __init__.py 에 Flask를 이용한 화면 뷰를 구성해준다.

import flask

app = flask.Flask(__name__)

@app.route("/")
def ok_print():
    return "OK!"

if __name__ == '__main__':
    app.run()

간단하게 접속하면 “OK!”를 뿌려주는 뷰이다. 다음으로 flask_app.wsgi 파일을 생성해준다.

#!/usr/bin/python
import sys
sys.path.insert(0, "/FLASK/")
from flask_app import app as application

간단히 보면 현재 패스를 /FLASK로 변경하고 flask_app의 app을 application으로 할당하여 apache2 mod_wsgi 모듈을 통해 실행한다는 의미로 이해된다. 그리고 /FLASK 폴더의 권한을 www-data:www-data로 할당한다.

chown -R www-data:www-data /FLASK

마지막으로 VirtualHost 세팅을 아래을 위해 /etc/apache2/sites-available 폴더에 파일을 하나 생성한다. 나는 편리한 사용을 위해 ok.teshi.net.conf 라는 파일명으로 생성해주었다. 해당 파일 내용은 아래와 같다.

<VirtualHost *:80>
        ServerAdmin [Mail Address]
        ServerName ok.teshi.net
        ErrorLog ${APACHE_LOG_DIR}/ok/error.log
        CustomLog ${APACHE_LOG_DIR}/ok/access.log combined

        WSGIDaemonProcess flask_app user=www-data group=www-data threads=5
        WSGIProcessGroup flask_app
        WSGIScriptAlias / /FLASK/flask_app/flask_app.wsgi
        <Directory /FLASK/flask_app>
            Order deny,allow
            Allow from all
            Require all granted
        </Directory>
        <Files /FLASK/flask_app/flask_app.wsgi>
            Order deny,allow
            Allow from all
            Require all granted
        </Files>
</VirtualHost>

위의 파일을 생성한 후,

sudo a2ensite ok.teshi.net

명령어를 사용하여 사이트를 VirtualHost에 추가한다. 그 후 Apache를 다시 불러온다.

sudo systemctl reload apache2

위와 같이 실행한 후 웹페이지를 열어 접속해본다.

블로그 서버 유지 관리 비용

어제 아시는 분이 블로그 서버를 유지하는데 사용되는 비용에 대하여 질문을 하여, 간단하게 정리해본다.

먼저 환경은

Vultr 가상화

DNSEver 도메인 포워딩

이 두가지를 메인으로 사용하고 있다.

 

사실 DNSEver를 사용하지 않아도 Vultr 내부의 고정 아이피를 사용하면 되지만, 아무래도 해당 도메인을 블로그 서버에만 연결시켜 둔 것은 아니기 때문에 DNSEver를 사용하는 것이 좋은 방법이 되었다.

 

우선 Vultr 에 들어가는 비용은

 

 

달에 16.00$ 가 들어간다. 10.00$ 인스턴스 하나와 고정 IP 6$ 하나를 이용해서 나온 금액이다.

물론 접속자가 많다면 조금 더 가격이 올라 갈 수 있다. 하지만 현재까지는 많은 사람이 오지는 않기 때문에 16$ 로 충분히 유지가 가능하다. 16$ 는 16,000원으로 생각하도록 하고…

 

다음은 DNSEver에 들어가는 비용이다. 이것 역시 여러가지 모델이 있으니 자기한테 적절한 것을 선택하는 것이 좋을 것 같다. 우선 나 같은 경우는 이렇다… 정도로 이해하면 좋을 것 같다.

 

 

DNSEver는 미리 포인트를 구입해두고 포인트 차감 방식으로 동작한다. 1포인트는 1원으로 많은 양을 충전할 수록 보너스 포인트를 조금 챙겨준다. 내가 사용하는 요금제의 경우 한달에 1,500원을 사용한다. 여기서 조금 더 많은 사람이 들어오는 달에는 최대 2,000원을 사용하는 것을 볼 수 있었다.

 

그렇다면 한 달에 들어가는 비용은 18,000원, 맥시멈으로 20,000원 정도 잡으면 1년에 240,000원의 비용이 소요된다는 의미이다.

240,000원이라… 사실 이 돈이면 라즈베리파이나 그 유사한 무언가를 사고 유지관리를 하는 것이 더 저렴하게 먹히는 것을 알 수 있다.

하지만 최근 잦은 이사와 이동으로 고민을 해보면… 편의성이나 내가 관리를 할 필요가 없다는 사실이 더욱 좋게 다가오기는 한다.

rsync, 그리고 Encoding

회사에서 주로 음악을 다운로드 받다보니… 해당 데이터를 집에 있는 서버로 동기화 시킬 필요가 있었다.

음악은 사서 듣는 것이 좋습니다 ㅇㅅㅇ

동기화는 맥 미니 OSX 에서 Odroid 우분투로 진행해야 했다. 그래서 새로 프로그램을 짤까… 아니면 다른 프로그램을 설치할까 고민하다가… 역시 기본적인 툴이 좋겠거니 해서 rsync를 사용하기로 했다.

rsync -av [Music_Direcotry] [Server_ID]@[Server_Address]:[Server_Path]

 

너무 쉬운 명령어다. 물론 패스워드는 그전에 public 키로 자동 로그인 되도록 하였다.

 

아무튼… 이렇게 했는데 동기화가 잘된다. 그런데 살짝 이상한 점을 찾았다.

# ls
한글1 한글2 한글3
# cd 한글1
-bash: cd: 한글1 : No Such file or directory

위의 테스트 결과를 보면 ls 할 경우 정상적으로 디렉토리가 보인다. 한글이 깨지지도 않고 정상적이라는 것을 확인할 수 있다. 그런데… 디렉토리 이동을 할 경우 찾을 수 없는 디렉토리라고 한다.

 

멘탈이 살살 녹아내렸다. 그렇다고 디렉토리가 아에 없는 것은 아니었다.

ls */*
.
.
.

위와 같이 */* 로 검색을 하면 정상적으로 파일은 보였기 때문이다.

 

그래서 한참을 구글링하다 보니 rsync의 인코딩 문제가 아닐까 하는 의심이 생겼다. 그래서 rsync encoding 이란 내용으로 구글링 해보민 –iconv= 옵션을 사용하면 정상적으로 사용할 수 있다고 한다.

근데… OSX 기본 rsync는… –iconv 옵션이 없다. 그래서 먼저 brew로 설치를 다시 해주고 테스트 해보기로 한다.

brew install rsync

내 예상이 맞았는지 새로운 rsync가 설치된다. 새롭게 설치된 rsync의 주소는 아래와 같았다.

/usr/local/Cellar/rsync/[VERSION]/bin/rsync

기존 명령어를 새로운 명령어로 대치할 수 있지만 추후 문제가 될 수도 있다는 생각이 들어 해당 버젼은 그대로 두고 아래와 같이 명령어를 작성해주었다.

/usr/local/Cellar/rsync/3.1.2/bin/rsync -av --iconv=utf-8-mac,utf-8 [Source] [Destination]

위의 명령어 사용 후 정상적으로 디렉토리에 접근 가능함을 확인하였다.

 

Fail2Ban 재설정 기념 로그 살펴보기

Fail2Ban을 재설정하고 차단을 활성화 시킨 후 문득 궁금해졌다.

대략 하루에 몇번의 접속 시도가 있을 것인가에 대한 것이었다.

 

사실 이 블로그 조차 찾아오는 이가 너—–어무 적은데 들어와 봤자 얼마나 오겠어라는 생각에 조회를 해보았다.

 

그런데 생각보다 많다.

2017년 09월 21일 기준 : 로그인 시도 ( 단순 메시지 기준으로 ) 979회

왜? 도대체 여기에 뭐가 있다고?

그렇다면 시도한 IP 주소는 어떻게 될까?

2017년 09월 21일 기준 : 로그인 시도 IP 수는 27개

무려 27 곳에서 내 서버를 탐내고 있다.

 

 

…. 이해가 안된다. 물론 좀비로 쓰려고 하면 할 수 있겠지만 이거참…. 주기적으로 패스워드를 바꿔 주는게 좋을듯 하긴 하다.

 

아무튼 해당 데이터가 어떤지 보려고…. 파이썬을 조금 이용해 보았다.

 

파이썬 + freegeoip 라고 생각하면 좋을 듯 하다.

 

import json
import requests


if __name__ == '__main__':
    country_ip_dict = {}
    for line in open("cut", "r"):
        res = requests.get("http://freegeoip.net/json/" + line.strip()).text
        res_json = json.loads(res)
        if res_json['country_name'] not in country_ip_dict: c
            ountry_ip_dict[res_json['country_name']] = []
        country_ip_dict[res_json['country_name']].append(line.strip())

    key_list = country_ip_dict.keys()
    key_list.sort()

    for _key in key_list:
        print _key, ":", len(country_ip_dict[_key])
        for item in country_ip_dict[_key]:
            print "    -", item

 

그래서 목록을 만들어 보았더니…

 

Australia : 1
– 203.27.138.60
China : 7
– 117.78.34.221
– 123.183.209.135
– 123.59.199.40
– 124.93.247.99
– 182.61.21.98
– 218.28.238.162
– 58.30.96.138
Croatia : 2
– 5.188.10.179
– 5.188.10.182
France : 2
– 212.129.23.96
– 90.41.191.181
Indonesia : 1
– 103.71.255.27
Israel : 1
– 62.219.209.70
Italy : 1
– 212.237.11.114
Netherlands : 1
– 95.211.230.94
Poland : 1
– 62.21.48.119
Republic of Korea : 4
– 1.209.148.74
– 1.221.187.110
– 14.58.118.69
– 180.70.170.34
Russia : 1
– 185.110.132.49
Seychelles : 1
– 93.174.90.30
Singapore : 1
– 139.59.110.43
Sweden : 1
– 85.230.149.52
Ukraine : 1
– 193.201.224.236
United States : 1
– 74.208.169.251

역시 부동의 1위는 중국이다. 아… 진짜… 그리고 2위는 한국이다…

 

가끔은 진짜 궁금해진다. 도대체 무슨 용도로 내 서버에 그리 접속하려는 걸까? 단순히 경유지로 쓰려고? 흠… 뭐… 아무튼… 일하기 싫은 금요일 오후 약간의 삽질을 해보았다.

 

 

Fail2Ban 무시할 IP 설정하기

아무생각 없이 SSH 관련된 프로그램을 짜고 서버에서 테스트를 하기 위해서 돌렸더니 심각한 문제가 발생하였다.

 

SSH 접속 불가

 

처음에는

 

응? 왜? 뭐지?

 

라고 멘붕이 왔다가 웹 페이지를 열어 서버는 정상 동작 중인 것을 확인하였고….. 그렇다면 SSH 데몬이 문제인데 라고 생각하다가 얼마전에 중국발 접속 시도가 너무 많아서 설치했던 fail2ban을 기억해냈다.

 

이렇게 된 것이다. SSH 관련 프로그램을 실행 했더니 이 녀석이 이상 동작을 하게 되고 결론적으로 재접속 시도가 늘고 fail2ban 동작!! 이라는 상황…

 

아무튼 해당 문제를 해결하기 위해서는 아래와 같이 수정해주면 된다.

 

vim /etc/fail2ban/jail.conf

에서 ignoreip 옵션을 찾은 후

ignoreip = [원하는 무시할 IP 주소]/24

저장하고 종료 후,

 

fail2ban-client reload

내가 설정한 보안이 날 막다니…. 이런…

 

[PredictionIO] Prediction IO redeploy (Prediction IO 에서 다시 deploy 하기)

Prediction IO 를 테스트 삼아 이런저런 작업을 수행중이다.

그러던 중 가장 큰 의문 중 하나가

train 시키고 다시 deploy 시키려면 껏다 다시 켜야 하나?

였다.

 

테스트를 해보니 그냥 deploy 하면 된다. 그럼 새로운 서버가 동작하게 되고 자연 스럽게 이전 서버는 죽는다.

[Vultr] 워드 프레스, 클라우드 컴퓨팅 서버로 이전기 -1-

이전 글에서 적었듯이 갑작스러운 서버 정리를 위해서 선택한 방법은 기존 서버에서 클라우드 컴퓨팅 서버로 이전하는 것이었다. 그러면서 적용한 방식에 대해서 정리를 해보고자 이전기를 작성한다.

먼저 사용한 클라우드 컴퓨팅 서비스에 대해서 설명하고자 한다.

가장 널리 알려진 클라우드 컴퓨팅 서비스는 바로 아마존 AWS 의 EC2 서비스이다. 이와 유사한 서비스로는 국내에 KT uCloud 같은 것들이 있는데 문제는… 가격이다.

기본적으로 아마존이나 KT에서 하면 기본적으로 제일 작은 인스턴스

인스턴스 : 하나의 컴퓨터로 생각하면 편하다.

로 생성을 하더라도 기본적으로 한달에 2만원에서 3만원 정도의 비용을 지불해야 한다. 그래서 조금 더 저렴한 곳이 없을까 하여 여기저기 뒤져보다가 Vultr 를 찾을 수 있었다.

사실, 나무 위키라는 좋은 곳에서 정보를 얻을 수 있었다.

가격은 최소 한달에 5달러부터, 일단 최소로 신청을 하고 모자랄 경우 업그레이드도 가능하다고 하니 일단은 최소 금액으로 투자를 하려고 하다가… 그래도 웹서버에 메모리 2기가는 되어야지라는 생각에 10달러 짜리를 신청하였다. 신청하는 과정은 아래와 같았다. 먼저 아래 링크로 가서 가입을 진행한다.

일단 위의 링크는 추천인이 포함된 링크임을 이실직고 한다. 만약 추천인을 적기 싫다면, 아래 링크로 들어가면 된다.

이미지는 동일하지만 클릭해보면 주소가 다르다는 것을 바로 알 수 있을 것이다.

아무튼 위의 링크로 접속하게 되면 홈페이지로 접속된다. 이 부분만 살펴보면된다.

위의 그림을 보면 이메일 적는 곳과 패스워드 적는 곳이 있다. 저 곳에 사용을 원하는 이메일 주소와 패스워드를 입력 한다. 만약 패스워드가 약하다고 판단되면 다시 한번 확인하는 창이 나타나고 아니라면 다음 단계로 진행된다. 다음 화면은 결제 정보를 입력하는 곳이다. 적는다고 바로 결제 되는 것은 아니니 입력하고 진행한다.

신용카드로 사용할 경우, 위의 정보를 입력한다. 일단 이름, 주소를 입력하고 아래 ‘Credit Card Details’ 를 입력한다. 그리고 Link Only로 할경우 충전없이 진행된다. ‘Summary’ 쪽은 코드를 검색해서 가져갈 경우 추가 금액을 넣어준다고 하는데 구글에서 찾을 수 있다고 하였으나…

귀차니즘으로 포기하였다.

그 이후 메일 인증을 하라고 할것이다. 메일을 확인하여 인증을 수행하면 된다.

자, 여기까지 하였다면 일단 Vultr 가입은 끝나게 된다.

사실 가입부터 적었지만… 어려운 부분이 없다. 귀찮은 부분은 주소를 적는 부분? 그 외에는 쉽게 진행할 수 있었다. 이후 부터가 조금 어려워 질 수도 있는 부분인데 해당 부분은 후에 따로 정리해서 작성하고자 한다.

일단 가입부터 해보고 이것저것 건드리면서 0.0x 달러를 소비해보는 것도 나쁜 방법은 아니라…. 고 생각한다.