728x90

Redhat 계열(가령 CentOS)의 운영체제를 쓰면 패키지 매니저로 yum 을 기본적으로 사용합니다. 사전에 쉘 환경에 Path 가 잘 잡혀 있다면 면 yum 으로 설치한 패키지 실행에 큰 문제가 없지만, 간혹 다른 사람이 운영하던 환경의 서버에서 작업시, 패키지가 실행되지 않아 곤란하던 경험들이 다들 있으실 겁니다. 

이런 경우에는 Full Path 를 같이 사용하여 어플리케이션을 실행해야 합니다. 하지만, 어디에 설치되었는지 잘 모르겠다 싶은 경우에 패키지 설치 경로를 확인할 필요가 있겠죠? 몇 번 비슷한 상황을 겪을때마다 검색해서 찾았던 내용을 간단하게 정리해 봅니다. 


yum 으로 패키지 설치하기

yum 은 Redhat 계열의 운영체제에 기본적으로 탑재되어 있습니다. 설치 방법을 계정 권한에 따라 sudo 를 넣어야 하는가, 그렇지 않은가 정도의 차이만 있고 install [패키지명] 으로 대부분 해결이 됩니다. 

$ yum install mtr

혹은

$ sudo yum install mtr

 

설치된 패키지 확인하기

기존에 설치된 패키지가 있는 경우 install 명령을 이용했을 때, 이미 패키지가 설치되어 있다는 안내를 만나게 됩니다. 주의할 것은 어플리케이션에 따라 버전의 영향을 받는 경우가 종종 있기 때문에 설치된 패키지의 버전을 확인할 필요가 있습니다. 설치된 패키지를 확인하는 명령은 아래와 같습니다. 

// 설치된 모든 패키지를 확인
$ yum list | less
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
 * epel: d2lzkl7pfhq30w.cloudfront.net
Installed Packages
ConsoleKit.x86_64                         0.4.1-6.el6           @anaconda-CentOS-201703281317.x86_64/6.9
ConsoleKit-libs.x86_64                    0.4.1-6.el6           @anaconda-CentOS-201703281317.x86_64/6.9
ConsoleKit-x11.x86_64                     0.4.1-6.el6           @base
...

// 설치된 특정한 패키지를 확인
$ yum list | grep mtr
mtr.x86_64                                2:0.75-5.el6          @anaconda-CentOS-201703281317.x86_64/6.9
mtr-gtk.x86_64                            2:0.75-5.el6          base

 

패키지 설치 경로 확인하기

그런데 문제가 있습니다. 패키지가 설치된 것을 확인헀고 버전까지 알아볼 수 있었지만 실제 어느 경로에 설치되어 있는지는 yum 으로는 알기가 어렵습니다. 이때 사용하는 것이 또 다른 패키지 관련 명령인 rpm 입니다. rpm 은 -q 로 시작하는 명령을 통해 다양한 조회 기능을 제공합니다. 눈치 채셨을 것 같습니다만 -q 는 query 의 앞 글자입니다. 

// 설치한 패키지가 실행이 안된다...
$ mtr
-bash: mtr: command not found

// 설치된 모든 패키지를 조회
$ rpm -qa | less
ftp-0.17-54.el6.x86_64
fipscheck-1.2.0-7.el6.x86_64
strigi-libs-0.7.0-2.el6.x86_64
libgcc-4.4.7-23.el6.i686
...

// 특정 패키지로 한정하여 조회
$ rpm -qa | grep mtr
mtr-0.75-5.el6.x86_64

// 특정 문자열을 가진 패키지의 설치 경로를 조회
$ rpm -ql mtr
/usr/sbin/mtr
/usr/share/doc/mtr-0.75
...

// Full Path 로 실행!
$ sudo /usr/sbin/mtr -v
mtr 0.75

결과를 보니 mtr 이 /usr/sbin 경로에 위치한 것을 확인할 수 있었습니다. 보통 /usr/sbin 은 PATH 에 잡혀 있을 가능성이 높습니다만, 환경에 따라 다를 수 있는 부분입니다. 패키지를 설치했는데 실행되지 않는다면, 경로를 조회해서 실행하시기 바랍니다! 자주 써야 한다면 .bash_rc 나 .bash_profile 등에 PATH 환경 변수에 추가해 주면 되겠습니다!

#bash #터미널 #redhat #centos #yum #패키지관리자 #rpm #패키지설치경로 #설치경로조회 

728x90
728x90

CORS (Cross Origin Resource Sharing) 은 서로 다른 도메인 간에 리소스를 활용할 필요가 있을때, 어떤 규칙으로 누구에게 허용할 것인지를 정의하는 HTTP 표준의 일부입니다. 모던 브라우저들은 CORS 헤더에 대한 지원을 충실히 하고 있습니다만, 서버측에서는 어떤식의 구현이 필요한지, 그리고 커스텀 클라이언트를 사용하는 경우에는 어떤 요청을 보내는 것이 적절한지에 대해 오해도 많고 시행착오도 많습니다.

CORS 에 대한 기본적인 정의를 먼저 살펴보고 CORS 구현을 위한 RFC 규격을 살펴보면서 어떤 요청 헤더와 응답이 필요한지 살펴봄으로써, 혹시나 CORS 에 대하여 시행착오를 겪는 분들이 적어지기를 바라며 포스팅을 시작해 보도록 하겠습니다. 


CORS 란 무엇일까?

웹이 태동하고 급성장하던 시기에는 서로 다른 리소스를 가져다 쓰는 것에 대하여 큰 제약이 없었습니다. 하지만 리소스를 사용하는 것은 분명 서버측의 비용이 발생하는 일이고, 보안 관점에서도 접근하는 사용자를 적절히 통제할 필요가 생겼습니다. 이런 요구사항을 수용하기 위하여 정의된 것이 CORS (Cross Origin Resource Sharing, 서로 다른 원본 서버간의 리소스 공유에 관한 규칙) 입니다. 

2009년경에 출시된 파이어폭스 Firefox 3.5 와 사파리 Safari 4.0 에서부터 강화된 동일 오리진 정책 SOP (Same Origin Policy) 이 적용되기 시작했고 현재 시장에서 사용되는 대부분의 브라우저는 이 정책을 준수하고 있습니다. 이 즈음부터 XHR (XML Http Request) 을 이용해 서로 다른 원본 서버에서 리소스를 <비동기> 로 가져다 쓰는 것에 대한 혼란(?)이 시작되었다고 봐도 무방합니다. 

근래의 브라우저들에서는 Fetch 도 제공하기 시작했고 Fetch 역시 XHR 과 마찬가지로 CORS 의 영향권 아래에 있습니다. 따라서 CORS 에 대한 정확한 이해를 바탕으로 구현을 해야 커머셜 브라우저는 물론이고 커스텀 클라이언트 개발에 대응할 때도 불필요한 시행착오를 줄일 수 있습니다. 

브라우저보다 조금 늦게 (늘 그렇듯) 2010년에 Drafting 된 CORS

 

다른 Origin 에서 리소스를 가져오는 두가지 방법

JSONP 는 논외로 두고 다른 Origin 에서 리소스를 가져오는 방법은 앞서 이야기 한 것처럼 XHR 을 이용한 방식와 Fetch 를 이용한 방식으로 나뉘어 집니다. 많은 자바스크립트 프레임웍 (jquery, axios...) 도 이들을 래핑하고 있기 때문에 동일하게 CORS 규칙의 영향을 받게 됩니다. 

비동기로 리소스를 가져오는 방식은 다른 관점에서 보면 단순 요청 Simple Request 와 예비 요청 Pre-flight Request 로 다시 나뉘어 집니다. 이 두가지의 차이점은 간단합니다. 메소드와 헤더에 관한 규격들이 더 있지만, 일단 크게 아래의 구분이 있다는 점을 인식하는 것이 중요합니다. 

구분 내용
단순 요청 Simple Request - GET, POST, HEAD 메소드로 하나의 요청에 필요한 CORS 요청 헤더를 포함하여 전송
예비 요청 Pre-flight Request - OPTIONS 메소드를 이용하여 본 요청에 대한 스펙을 CORS 요청 헤더를 포함하여 전송
- 성공 응답을 받은 경우 본 요청을 전송

 

CORS 의 기본, Origin 요청 헤더

앞서 설명한 두 요청의 상세한 차이점은 다음 포스팅에서 소개할까 합니다. 절단 신공이라기 보다는... 두 요청의 공통 요소 중 하나인 Origin 헤더의 규격에 대해서 살펴보고 가는 것이 더 중요하기 때문입니다. 다른 Origin 으로 리소스를 요청하는 경우, 원래의 요청이 어떤 도메인에서 시작된 것인지를 다른 Origin 으로 알려주어야 할 필요가 있습니다. 이 때 사용하는 것이 Origin 요청 헤더입니다. 

가령 https://a-server.nopd-genius.com 이라는 도메인에서 XHR 혹은 자바스크립트 프레임워크를 이용하여 https://b-server.nopd-not.com 이라는 도메인으로 요청을 보내는 경우를 생각해 보겠습니다. 자바스크립트 코드는 첫번째 서버(a-server)에서 사용자 브라우저로 전달해 주었기 때문에, 이 코드가 만든 두번째 서버(b-server)로의 요청은 `Origin: https://a-server.nopd-genius.com` 이라는 헤더를 포함해야 합니다. 

이 요청을 받은 두번째 서버(b-server)는 Origin 값에 해당하는 정책을 확인하여 이를 CORS 응답 헤더로 내려주게 됩니다. 이 과정에서 Origin 헤더 값이 사전에 약속된 원본 도메인이 아니라면 에러 응답을 하거나 CORS 헤더 없이 응답하게 되어 결과적으로 브라우저에서는 응답을 사용하지 못하는 상황이 되게 됩니다. 

출처 : 모질라 CORS 문서 

 

그런데 말입니다, 모질라의 CORS 문서에서 발췌한 위의 내용은 한가지가 잘못되어 있습니다. RFC 의 규격 문서에 따르면 Origin 헤더의 값은 반드시 스킴 Scheme (http 혹은 https) 을 포함해야만 합니다. 위의 그림처럼 `Origin: foo.example` 로 던지면 규격에 대한 위반이 되게 됩니다. 왜냐하면 http://foo.example 과 https://foo.example 은 서로 다른 Origin 으로 활용될 수 있기 때문입니다. WHATWG 의 규격 문서를 보면 이 헤더의 규격은 아래와 같습니다. 

특정한 포트를 지정해주는 ":port" 는 필요 없는 경우 생략해 줄 수 있지만, 스킴은 생략 가능한 항목으로 명기되어 있지 않습니다. 따라서 Origin 요청 헤더는 위의 규격을 준수하여 전송할 필요가 있습니다. 모질라의 문서 그림도 업데이트가 되어야 하겠죠? ^^ 이렇게 Origin 헤더가 중요합니다. 

다행히도 근래의 모던 브라우저들은 CORS 요청을 하는 경우 항상 스킴을 포함한 Origin 요청 헤더를 보내주고 있습니다. 따라서 Origin 헤더 값은 상용 브라우저가 아닌 클라이언트를 사용하는 경우에 유의해 주시면 큰 문제는 발생하지 않을 것으로 생각됩니다. 다음 포스팅에서는 Simple Request 와 Pre-flight Request 의 요건에 대하여 보다 자세히 살펴보도록 하겠습니다. 


참고자료

 

교차 출처 리소스 공유 (CORS)

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라

developer.mozilla.org

 

 

Cross-Origin Resource Sharing

Must be deployable to IIS and Apache without requiring actions by the server administrator in a configuration where the user can upload static files, run serverside scripts (such as PHP, ASP, and CGI), control headers, and control authorization, but only d

www.w3.org

 

 

cross-site xmlhttprequest with CORS – Mozilla Hacks - the Web developer blog

Editor's Note: This article sure is a popular one! The Fetch API is now available in browsers and makes cross-origin requests easier than ever. Check out this Hacks post or ...

hacks.mozilla.org

 

 

Fetch Standard

 

fetch.spec.whatwg.org

 

728x90
728x90

Cloud Platform 을 사용할 때 가장 조심해야 하는 것 중 하나가, 각 플랫폼이 가지고 있는 QoS (Quality of Service) 수치를 넘지 않도록 해야 한다는 것입니다. 물론, 이 수치는 Support Ticket 등을 통해 늘리는 것이 가능하지만 시간이 소요될 수 있기 때문에 이벤트 등 대규모 사용자가 몰리는 이벤트가 준비중이라면 미리 체크를 해두어야 합니다. 

CDN 제품인 AWS CloudFront 도 마찬가지인데요, 적용되고 있는 여러가지 제한 중 이벤트 트레픽에 대한 고려사항은 크게 1) 대역폭에 대한 Limit 과 2) 요청수에 대한 Limit 이 있습니다. AWS 공식 문서에서는 `할당량` 또는 `Quotas` 로 제품 문서에서 확인할 수 있는 내용입니다. 


대역폭과 전송량 제한

CloudFront 의 할당량 정책은 기본적으로 Distribution 당으로 적용됩니다. 참고로 시장 지배 사업자인 아카마이 Akamai 의 경우 Bucket 이라는 컨셉이 있고 CP Code 단위로 대역폭에 대한 관리만 하고 있습니다. 아카마이와 달리 CloudFront 의 경우 대역폭과 요청량의 두가지 제한이 있습니다. 

출처 : CloudFront 개발자 안내서

Distribution 을 `배포` 라고 표현하고 있는 부분은 늘 적응이 잘 안되네요. API 에서도 distid 등을 사용하니 Distribution 으로 인지하는 것이 편합니다. 공식 문서에 나온 것처럼 대역폭은 150Gbps 가 기본 제한이고 요청량은 250,000rps 가 기본 제한으로 들어가 있습니다. 바로 아래에 있는 `더 높은 할당량 요청`이 있는 이유는 조정이 가능하기 때문이겠죠? ^^

`더 높은 할당량 요청`을 누르면 Support 페이지로 넘어가고 `Service Limit Increase` 타입의 티켓을 열어 할당량을 높이는 방식입니다. 느낌이 오시겠지만 시간이 좀 걸릴 수 있는 부분이라 예측하지 못한 트레픽 Burst 가 아니고 계획된 이벤트라면 미리 할당량을 조정해 두시는 것이 정석입니다. 

 

할당량 초과는 어떻게 알 수 있을까?

CloudFront 에서는 위의 할당량이 초과 되었다 하더라도 알려주는 것은 없습니다. 요행히 CloudWatch 로 Distribution 의 에러 비율에 대한 알람을 걸어두었다면 메일을 통하여 한템포 늦게 인지할 수 있는 방법이 있긴 합니다. 다른 방법으로는 CloudFront 의 Monitoring 화면에서 사용자의 트레픽이 급격히 늘면서 5xx 에러가 증가했는지를 확인하는 방법이 있습니다.

후행적으로 확인하는 방법은 (이미 장애는 났고... 사용자는 영향을 받았고...) CloudFront 의 Access Log 를 통하는 방법이 있습니다. Access Log 의 필드중 2020년 12월 3일 기준으로 14번째 컬럼인 `x-edge-result-type` 이나 23번째 컬럼인 `x-edge-response-result-type` 의 값을 이용해서 확인할 수 있습니다. 

14번째 컬럼의 값
23번째 컬럼의 값

이 필드의 값으로 `LimitExceeded` 가 특히 할당량, Limit 초과에 대한 부분입니다. 문제는 LimitExceeded 가 어떤 Limit 을 초과한 것인지를 알려주지 않습니다. 알고 싶다면 <또> Support Ticket 을 열어야 합니다. 해보신 분들은 아시겠지만 Ticket 을 열면서 꼭 샘플 로그를 추출해서 제공해 주셔야 합니다. 


용량관리는 인프라에서 무척 중요한 부분입니다. 우리가 클라우드 서비스를 이용하는 이유중 하나는 그런 용량 관리로부터 조금이나마 자유롭고 싶어서 이지만, 결국 클라우드 서비스도 그들 입장에서는 용량관리를 해야만 합니다. 때문에 위와 같은 제한들이 존재하고 사용하고 있는 사업자의 숫자들을 기억해 둘 필요가 있습니다. 

> 참고 URL

 

할당량 - Amazon CloudFront

할당량 CloudFront에는 다음 할당량(이전에는 제한으로 지칭)이 적용됩니다. Lambda@Edge에는 기본 CloudFront 할당량에 추가하여 적용되는 특정한 할당량도 있습니다. 일반 할당량 엔터티 기본 할당량

docs.aws.amazon.com

 

표준 로그(액세스 로그) 구성 및 사용 - Amazon CloudFront

모든 이벤트에 대한 값이 있는 필드도 있고 재생, 중지, 일시 중지, 일시 중지 취소 및 탐색 이벤트에 대한 값만 있는 필드도 있습니다. 일반적으로 로그 파일에서 필드에 대해 하이픈(-)이 포함

docs.aws.amazon.com

 

728x90
728x90

VPN 과 관련한 여러가지 시험, 환경을 구축하다보니 로컬 라우팅 테이블이 꼬이는 현상이 발생하여 조사를 해보았습니다. 평소 사용하고 있던 IPv4 VPN 와 IPv6 VPN, 그리고 개별 과제로 만들고 있는 OpenVPN 기반의 IPv6 까지 아주 난장판이라 이런 문제가 생긴다고 생각해서 트러블슈팅 방법을 좀 정리해 보고자 합니다. (미래의 내가, 과거의 나를 찾을 것이 분명하니...)


지저분해지는 IPv6 라우팅 테이블

안그래도 복잡했던 로컬 IPv6 라우팅 테이블이 심하게 꼬인 것은 로컬 환경에서 OpenVPN Web UI 디버깅을 위해 OpenVPN 을 설치하고 구동하면서 부터였습니다. 오늘 아침 개발조직에 IPv6 접근 가이드를 해주기 위해 WIKI 를 정리하다보니 평소 사용하던 IPv6 VPN 에 연결하더라도 v6 웹 사이트 (가령 v6.google.com) 에 접근이 안되는 것을 확인했습니다. 

미처 캡쳐를 해두진 못했지만 netstat -nr 로 로컬의 라우팅 테이블을 살펴보니 스태틱으로 잡힌 테이블이 너무 많았습니다. VPN 연결시 생성되는 인터페이스인 utun 시리즈도 무려 6개나 존재하더군요. 인터페이스를 down 으로 하는 것과 라우팅 테이블은 별개라 한땀 한땀 삭제를 해주어야 했습니다. 사용한 명령들은 대략 아래의 패턴입니다. 

// 한 땀, 한 땀 삭제...
sudo route delete -inet6 ##v6주소##%utun0

// default 를 잠식한 utun 시리즈 삭제는 -ifscope 으로...
sudo route delete -inet6 default -ifscope utun1

이렇게 삭제를 하고나니 라우팅 테이블이 깔끔해졌습니다. 이제 라우팅 테이블을 지저분하게 만든 범인을 찾기 위해 간단한 스크립트로 리눅스 환경에서의 watch 를 구현하여 netstat -nr 명령을 반복하도록 해보았습니다. 우리가 기대하는 것은 VPN 연결시 필요한 라우팅 테이블이 추가 되었다가 VPN 연결을 종료하면 라우팅 테이블이 정리되는 것이겠죠!?

// Mac 환경에서 리눅스 watch 스타일로 명령 구동하기
while true; do clear; netstat -nr; sleep 2; done;

 

회사가 제공한 VPN 시험

먼저 회사가 제공한 IPv6 VPN 을 살펴보았습니다. 심증은 <범인은 OpenVPN 이다!> 였지만 확실하게 하기 위해서죠. 개발팀도 분명 비슷한 증상을 겪을 수 있으니 FAQ 를 준비하는 목적도 있었습니다. 자, 우선 IPv6 VPN 연결전에는 아래와 같이 깔끔한 라우팅 테이블 목록을 볼 수 있습니다. 물론... 앞서 이야기 한 것처럼 한 땀, 한 땀 라우팅 테이블을 정리한 상태입니다 ㅜㅜ

회사에서 셋업한 IPv6 VPN 을 연결해 보니 utun 인터페이스로 다수의 라우팅 테이블이 추가되는 것을 확인할 수 있었습니다. 

다시 VPN 연결을 끊었을때 v4, v6 쪽으로 추가된 라우팅 테이블이 깔끔하게 정리되는 것을 확인할 수 있었습니다. 범인은 OpenVPN 일까요? 확인해 보았습니다.

 

AWS 에 구축한 IPv6 OpenVPN 시험

이번에는 AWS 에 구축해 둔 IPv6 OpenVPN 을 시험해 보았습니다. VPN 에 연결되면 이전의 다른 VPN 과 마찬가지로 다량의 라우팅 테이블이 추가되는 것을 확인할 수 있었습니다. 이번에도 동일하게 utun4 를 사용했군요. 터널 인터페이스가 만들어지고 삭제되는 과정도 좀 궁금하지만 따로 알아보기로 하고...

자 이제... 대망의 연결 종료의 시간이 되었습니다. OpenVPN 연결을 종료했을때 깔끔하게 라우팅 테이블이 정리되었으면 하는 바램을 갖고... 도전!

이런... 예상과 다르게 너무 깔끔하게 라우팅 테이블이 정리가 되었습니다. 문제가 생기길 기대(?)했는데 깔끔해진 걸 보니... 뭔가 OpenVPN 에 등록해 둔 Profile 들을 시험하는 과정에, 연결이 깔끔하지 못했거나 강제 종료된 경우 등 예외 상황에서 문제의 현상이 나오는 것일 가능성이 생겼습니다. 

AWS EC2 를 이용한 OpenVPN 구축 연재는 아래 글타래로... (2편은 아직 못쓴...)

 

AWS EC2 를 이용한 IPv6 지원 OpenVPN 구축 #1

코로나 바이러스의 두번째 웨이브가 한창입니다. 다행히 오늘(9/3) 기준으로 확진자 수가 200명 밑으로 내려오긴 했지만, 긴장의 끈을 놓기에는 여전히 확진자 수가 많습니다. 많은 기업들이 원격

ondemand.tistory.com

 

Mac 로컬 환경의 OpenVPN 시험

내친김에 로컬 환경의 시험도 해보았습니다. 조금 까리한 것은 로컬에서는 초기에 proto udp 로 시험하다보니 AF_INET6 로 서버가 구동되는 문제가 있어서 proto udp4 로 설정해둔 상태였습니다. 만약, 이 상태에서도 문제가 없다면 proto udp 일때 AF_INET6 로 구동되는 과정, 종료되는 과정의 문제라고 생각해도 될 것 같았습니다. 

참고로 utun4 는 로컬의 OpenVPN 서버가 점유하고 있는 터널이고, utun7 은 로컬의 Tunnelblick 이 연결을 맺으면서 생성한 인터페이스입니다. 자, 이제 연결을 끊어보겠습니다. 

오오... 찾은 것 같습니다. Tunnelblick 종료시 utun7 이 빠졌고, OpenVPN 서버 종료시 utun4 가 빠졌지만, Internet6 쪽에 추가된 스태틱 라우팅 하나가 빠지지 않은 것을 확인할 수 있었습니다. 설정의 문제인지는 조금 더 조사해 봐야하고 로컬 환경에서만 생기는 문제인지 명확하진 않습니다만, 최소한 FAQ 에 기술해두고 개발자 분들께 가이드 하는데는 문제 없을것 같습니다. 


뭔가 완전히 잘 알지 못하는 분야는 늘 시행착오가 생기는 것 같습니다. 오늘도 몇 가지 시행착오를 겪으면서 한 걸음, 한 걸음, 뚜벅 뚜벅 걸어나가 봅니다!

 

728x90
728x90

VPN 서버를 로컬에서 운영해야 하는 이유는 (굳이 찾자면) 여러가지가 있겠습니다만, 개인적으로는 OpenVPN Web UI 의 커스터마이징을 위하여 개발 환경이 필요했던 관계로 설치를 하게 되었습니다. 리눅스 환경에서의 설치는 종종 해왔지만 막상 로컬 Mac 환경에 설치하려니 적당한 가이드가 없는 것 같아 시행착오를 하며 내용을 정리해 봅니다. 


Homebrew 를 이용한 패키지 설치

OpenVPN 커뮤니티 버전의 소스를 다운로드 받아 빌드를 할까? 하는 생각을 0.1 초간 한 뒤에 바로 Homebrew 로 돌아섰습니다. 안그래도 지저분한 로컬 환경이라 (도커에 익숙치가 않네요) 더 지저분하게 하지 말자는 생각이 있었고, 빌드 환경 설정에 시간을 쓰지 말자는 생각이 들어 Homebrew 를 사용해 봤습니다. 

% brew install openvpn
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 3 taps (homebrew/core, homebrew/cask and homebrew/services).
...
...
==> Installing dependencies for openvpn: lz4, openssl@1.1 and pkcs11-helper
==> Installing openvpn dependency: lz4
==> Pouring lz4-1.9.3.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/lz4/1.9.3: 22 files, 657.6KB
==> Installing openvpn dependency: openssl@1.1
==> Pouring openssl@1.1-1.1.1h.catalina.bottle.tar.gz
==> Caveats
...
...

 

매번 느끼는 거지만 Homebrew 는 업데이트가 너무 많습니다. 따로 패키지만 올리고 싶어도 일단 필요한 것들을 다 업데이트 하고 시작하니 시간이 꽤 걸립니다. 한참을 지나 OpenVPN 설치를 위해 Dependency 가 있는 패키지들을 쭈욱~ 설치해 나갑니다. 중간에 몇 가지 심볼릭링크 작업이 에러가 나는게 보였지만... 잘 되리라 믿고 진행을 계속 했습니다. 한 15분정도 걸렸던 것 같네요.

 

OpenVPN 바이너리는 어디에!?

리눅스 환경에서는 패키지로 공급되는 프로그램들은 대부분 데몬 설정 파일도 같이 올려주고 systemctl 이나 services 명령으로 활성화, 비활성화를 쉽게 할 수 있습니다. 막상 Mac 환경에서는 그렇게 쓰는 경우가 잘 없다보니... 설치후에 무얼 해야하나 5분정도 멍을 때렸습니다. 이단 설치경로를 찾아보기로 했고 아래의 경로에서 OpenVPN 을 찾을 수 있었습니다. 

% pwd
/usr/local/opt/openvpn

% cd sbin
% ls -al
total 1440
drwxr-xr-x   3 xxx  yyy      96 10 28 16:25 .
drwxr-xr-x  17 xxx  yyy     544 12  1 12:36 ..
-r-xr-xr-x   1 xxx  yyy  735160 12  1 12:36 openvpn

그런데 설정 파일은 어디에 있는걸까요?

 

OpenVPN 설정파일은 여기에!!

OpenVPN 이 설치되고나면 설정파일은 아래의 경로에서 찾아볼 수 있습니다. client.conf 는 VPN 의 클라이언트가 될 머신에서 사용하는 파일이고 server.conf 는 VPN 서버에서 사용하는 파일입니다. 리눅스에서도 그랬었나 기억이 좀 가물거립니다만 친절한 안내 멘트가 같이 들어 있으니 익숙하지 않은 경우에는 내용을 하나씩 살펴보는 것을 추천드립니다. (라고 적으면서 저도 잘 모르는 내용이 많긴 합니다만... ㅎ)

% cd /usr/local/etc/openvpn
% ls -al
total 32
drwxr-xr-x   4 xxx  admin    128 12  1 12:36 .
drwxrwxr-x  20 xxx  admin    640 12  1 12:46 ..
-rw-r--r--   1 xxx  admin   3589 12  1 12:36 client.conf
-rw-r--r--   1 xxx  admin  10784 12  1 12:36 server.conf

 

우리는 성미가 급하니 OpenVPN 이 동작하는지 한번 보겠습니다. 느낌적 느낌으로 인지하셨겠지만 당연히 동작하지 않습니다 ㅎㅎ. 필요한 키생성 등을 해야 하지만 그래도 한번 실행해 보는 맛이 있어야겠죠?

% /usr/local/opt/openvpn/sbin/openvpn --config ./server.conf
2020-12-01 13:06:17 WARNING: --topology net30 support for server configs with IPv4 pools will be removed in a future release. Please migrate to --topology subnet as soon as possible.
2020-12-01 13:06:17 DEPRECATED OPTION: --cipher set to 'AES-256-CBC' but missing in --data-ciphers (AES-256-GCM:AES-128-GCM). Future OpenVPN version will ignore --cipher for cipher negotiations. Add 'AES-256-CBC' to --data-ciphers or change --cipher 'AES-256-CBC' to --data-ciphers-fallback 'AES-256-CBC' to silence this warning.
2020-12-01 13:06:17 Cannot pre-load tls-auth keyfile (ta.key)
2020-12-01 13:06:17 Exiting due to fatal error

네, 그렇습니다. 치명적인 에러가 있어서 실행이 안되었네요 ㅎㅎ DEPRECATED 로 표시된 부분은 server.conf 를 열어서 AES-256-CBC 로 된 부분을 AES-256-GCM 으로 변경해주시면 됩니다. 자, 그러면 tls-auth 를 위한 ta.key 파일을 생성해 보겠습니다

 

각종 Key 생성하기

우선 OpenVPN 용 Static Key 를 만들겠습니다. tls-auth 용 키이며 ta.key 파일을 만들어야 하는데요,  생성하는 것은 간단합니다. OpenVPN 바이너리에서 옵션을 지정하여 키를 생성할 수 있습니다. Configuration 파일이 위치한 경로에 ta.key 파일도 만들어 보도록 하겠습니다. 

% /usr/local/opt/openvpn/sbin/openvpn --genkey tls-auth ta.key
% cat ta.key
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
9b61ceee61da49815108d6703e722d22
3c0f98a075c5476a3189c394274bedb3
...
...
535613076cde018b76a098bd48fbde83
ba2a1259d8df458b15c6f521b7ae0c57
-----END OpenVPN Static key V1----

사용자와 PKI 연결 설정에 사용할 인증서 파일도 생성해 보도록 하겠습니다. 인증서 파일 생성을 하는 방법은 여러가지이지만 easyrsa 를 사용해 보도록 하겠습니다. Dependency 설치시에 같이 설치가 되지 않았던 것 같아 Homebrew 로 설치해 주었습니다. 

% brew install easy-rsa
...
% brew --prefix easy-rsa
/usr/local/opt/easy-rsa

이제 easyrsa 를 이용하여 PKI 를 구성하기 위한 루트 인증서, 비밀키, 공개키 등을 만들도록 하겠습니다. 참고로, easyrsa 는 기본 값으로 /usr/local/etc/pki 경로에 파일들을 생성하도록 되어 있으니 참고하시기 바랍니다. 

//===============================
// 초기화
//===============================
% /usr/local/opt/easy-rsa/bin/easyrsa init-pki

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /usr/local/etc/pki

//===============================
// CA Certificate 생성
//===============================
% /usr/local/opt/easy-rsa/bin/easyrsa build-ca nopass
Using SSL: /usr/local/opt/openssl@1.1/bin/openssl OpenSSL 1.1.1h  22 Sep 2020
Generating RSA private key, 2048 bit long modulus (2 primes)
..........................................................................................................................................+++++
..............................................................................................+++++
e is 65537 (0x010001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:MyLocalPKI

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/usr/local/etc/pki/ca.crt

//===============================
// 서버인증서 생성
//===============================
% /usr/local/opt/easy-rsa/bin/easyrsa build-server-full server nopass
Using SSL: /usr/local/opt/openssl@1.1/bin/openssl OpenSSL 1.1.1h  22 Sep 2020
Generating a RSA private key
..............................................................+++++
...................................................................................................................................+++++
writing new private key to '/usr/local/etc/pki/easy-rsa-38744.0yXv0x/tmp.Xb7eac'
-----
Using configuration from /usr/local/etc/pki/easy-rsa-38744.0yXv0x/tmp.VwN7Lb
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until Mar  6 04:45:50 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

//===============================
// 키 교환 알고리즘용 DH 파라메터 생성
//===============================
% /usr/local/opt/easy-rsa/bin/easyrsa gen-dh
Using SSL: /usr/local/opt/openssl@1.1/bin/openssl OpenSSL 1.1.1h  22 Sep 2020
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
...............................................................................+....................................+......................................
DH parameters of size 2048 created at /usr/local/etc/pki/dh.pem


//===============================
// Client 용 Credential 생성
//===============================
% /usr/local/opt/easy-rsa/bin/easyrsa build-client-full mylocalclient nopass
Using SSL: /usr/local/opt/openssl@1.1/bin/openssl OpenSSL 1.1.1h  22 Sep 2020
Generating a RSA private key
...................................................................................................................................................................+++++
..+++++
writing new private key to '/usr/local/etc/pki/easy-rsa-65143.eROtDW/tmp.haeAUt'
-----
Using configuration from /usr/local/etc/pki/easy-rsa-65143.eROtDW/tmp.EOABaH
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'mylocalclient'
Certificate is to be certified until Mar  6 05:03:20 2023 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

뭔가 번잡하니 많네요. 하지만 늘 하던 일이었다고 생각하시고 하나씩 따라오셨으면 특별히 문제 없었을 겁니다. 이제 생성된 파일들이 어디에 있는지 체크해 볼까요?

// 서버 인증서와 클라이언트 인증서
% pwd
/usr/local/etc/pki/issued
% ls
mylocalclient.crt	server.crt

// 서버 비밀키와 클라이언트 비밀키, CA 비밀키
% pwd
/usr/local/etc/pki/private
% ls
ca.key			mylocalclient.key	server.key

// CA 인증서와 DH 파라메터 파일
% pwd
/usr/local/etc/pki
% ls ca.crt dh.pem
ca.crt	dh.pem

3가지 경로에 각 파일이 나뉘어져 있습니다. easyrsa 는 마치 내가 CA (Certificate Authority) 가 된 것처럼 인증서를 발급해주고 만들어주는 역할을 한 것이고, 각각 필요한 키들이 생성되어 적절한 위치에 나뉘어져 있다고 생각하시면 됩니다. 

 

OpenVPN 서버를 다시 시작해보자

간결한 관리를 위하여 앞서 작업했던 /usr/local/etc/openvpn 경로로 서버에서 필요한 파일들을 복사해 오도록 하겠습니다. 파일명은 server.conf 에 기술된 파일명을 기준으로 하고 있으니, 다른 이름으로 생성했다면 이름을 변경해 주셔도 무방합니다. 파일이 복사되었다면 sudo 권한으로 OpenVPN 서버를 실행하도록 하겠습니다. 

% pwd
/usr/local/etc/openvpn
% cp /usr/local/etc/pki/ca.crt .
% cp /usr/local/etc/pki/dh.pem ./dh2048.pem
% cp /usr/local/etc/pki/private/server.key .
% cp /usr/local/etc/pki/issued/server.crt .

% sudo /usr/local/opt/openvpn/sbin/openvpn --config ./server.conf
% sudo /usr/local/opt/openvpn/sbin/openvpn --config ./server.conf
2020-12-01 14:17:01 WARNING: --topology net30 support for server configs with IPv4 pools will be removed in a future release. Please migrate to --topology subnet as soon as possible.
2020-12-01 14:17:01 OpenVPN 2.5.0 x86_64-apple-darwin19.6.0 [SSL (OpenSSL)] [LZO] [LZ4] [PKCS11] [MH/RECVDA] [AEAD] built on Nov 13 2020
2020-12-01 14:17:01 library versions: OpenSSL 1.1.1h  22 Sep 2020, LZO 2.10
2020-12-01 14:17:01 NOTE: your local LAN uses the extremely common subnet address 192.168.0.x or 192.168.1.x.  Be aware that this might create routing conflicts if you connect to the VPN server from public locations such as internet cafes that use the same subnet.
2020-12-01 14:17:01 Diffie-Hellman initialized with 2048 bit key
2020-12-01 14:17:01 Outgoing Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
2020-12-01 14:17:01 Incoming Control Channel Authentication: Using 160 bit message hash 'SHA1' for HMAC authentication
2020-12-01 14:17:01 Opened utun device utun7
2020-12-01 14:17:01 /sbin/ifconfig utun7 delete
ifconfig: ioctl (SIOCDIFADDR): Can't assign requested address
2020-12-01 14:17:01 NOTE: Tried to delete pre-existing tun/tap instance -- No Problem if failure
2020-12-01 14:17:01 /sbin/ifconfig utun7 10.8.0.1 10.8.0.2 mtu 1500 netmask 255.255.255.255 up
2020-12-01 14:17:01 /sbin/route add -net 10.8.0.0 10.8.0.2 255.255.255.0
add net 10.8.0.0: gateway 10.8.0.2
2020-12-01 14:17:01 Could not determine IPv4/IPv6 protocol. Using AF_INET6
2020-12-01 14:17:01 Socket Buffers: R=[786896->786896] S=[9216->9216]
2020-12-01 14:17:01 setsockopt(IPV6_V6ONLY=0)
2020-12-01 14:17:01 UDPv6 link local (bound): [AF_INET6][undef]:1194
2020-12-01 14:17:01 UDPv6 link remote: [AF_UNSPEC]
2020-12-01 14:17:01 MULTI: multi_init called, r=256 v=256
2020-12-01 14:17:01 IFCONFIG POOL IPv4: base=10.8.0.4 size=62
2020-12-01 14:17:01 IFCONFIG POOL LIST
2020-12-01 14:17:01 Initialization Sequence Completed

이렇게 대략 로컬 설치가 끝났습니다. 사실 이후에 udp4 만 사용하도록 변경, tls-auth 가 생각처럼 동작하지 않아 제외하는 작업등을 진행한 후에 정상적인 기동, 클라이언트의 연결이 가능했습니다. 이 부분은 다음 포스팅에서 정리해 보도록 하겠습니다. 

 

[ NordVPN 크리스마스 할인행사 > bit.ly/39unoRx ]

 

NordVPN: Best VPN Service Provider | #1 Editors' Choice

온라인에서 개인정보를 보호하고 지리적 위치 제약 없이 콘텐츠에 액세스하세요. 60개국 이상에서 1000개 이상의 서버를 사용할 수 있으며, 강력한 암호화와 로그 삭제 정책을 갖추고 있습니다.

nordvpn.com

 

본 포스팅은 제휴마케팅을 통해 소정의 수수료를 받을 수 있습니다.

728x90
728x90

오늘은 go 입니다. <못 먹어도 go> 라는 말이 있지만 golang 은 참 가까이 하기에 쉽지 않은 물건인 느낌입니다. OpenVPN 관련하여 오픈소스로 공개되어 있는 Web UI 가 go X beego 로 구성되어 있어서 간만에 go 환경을 맞추느라 고생을 했습니다.


오늘의 에러를 소개합니다.

beego 환경을 준비하기 위해서는 아래의 두가지 패키지를 설치해야 합니다. 

% go get -u github.com/astaxie/beego
% go get -u github.com/beego/bee

하지만 잘 되었을리가 없겠죠? beego 패키지를 설치하는 동안은 문제가 없었지만 개발도구인 bee 를 올리는 동안 묘한 에러가 발생했습니다. 

% go get -u github.com/beego/bee
# golang.org/x/sys/unix
go/src/golang.org/x/sys/unix/fcntl_darwin.go:11:9: undefined: fcntl
go/src/golang.org/x/sys/unix/fcntl_darwin.go:16:12: undefined: fcntl
go/src/golang.org/x/sys/unix/fcntl_darwin.go:22:12: undefined: fcntl
go/src/golang.org/x/sys/unix/ioctl.go:20:9: undefined: ioctl
go/src/golang.org/x/sys/unix/ioctl.go:29:9: undefined: ioctl
go/src/golang.org/x/sys/unix/ioctl.go:38:9: undefined: ioctl
go/src/golang.org/x/sys/unix/ioctl.go:48:9: undefined: ioctl
go/src/golang.org/x/sys/unix/ioctl.go:60:9: undefined: ioctl
go/src/golang.org/x/sys/unix/syscall_bsd.go:645:10: undefined: mmap
go/src/golang.org/x/sys/unix/syscall_bsd.go:646:10: undefined: munmap
go/src/golang.org/x/sys/unix/ioctl.go:60:9: too many errors

% bee
zsh: command not found: bee

 

문제는 golang 의 버전

여기저기 검색을 해보았지만 딱히 상황에 걸맞는(?) 해결책을 찾기가 어려웠습니다. 그러다 중국어로 된 커뮤니티 한 곳에서 같은 질문을 한 스레드를 찾았고 답변으로 "go 업그레이드 하니까 되던데?" 를 찾았습니다. 네, 재빨리 버전을 확인하니 근래의 버전과 꽤 차이가 나고 있었습니다. 

// 업데이트 전
% go version
go version go1.10.3 darwin/amd64

// 업데이트 후
% go version
go version go1.15.5 darwin/amd64

1.10.3 에서 나던 오류가 1.15.5 로 업그레이드 한 이후에는 깨끗히 사라졌습니다. go get 을 하는 과정에 뭔가 조금 더 친절한 에러 메세지가 나왔다면 좋겠을텐데 하는 생각이 들더군요. 사실 go 로 큰 규모의 개발을 하고 있지는 않아 쉽게 업데이트 했지만, go binary 를 업데이트하면서 다른 문제가 생길수도 있지 않을까? 하는 생각도 들었습니다. 

 

잘 동작하는 bee!

이제 다시 bee 를 설치하고 bee 를 실행해 보았습니다. 네, 잘 돌아가네요! 그런데 bee는 2.0.0 에서 1.12.3 으로 다운그레이드 하라고... 허허... 천천히 해보기로 하고... 포스팅을 마무리 해봅니다. 

% go get -u github.com/beego/bee
lineplus@AL01249083 ~ %
lineplus@AL01249083 ~ % bee
2020/11/30 19:59:33 INFO     ▶ 0001 Getting bee latest version...
2020/11/30 19:59:33 WARN     ▶ 0002 Update available 2.0.0 ==> 1.12.3
2020/11/30 19:59:33 WARN     ▶ 0003 Run `bee update` to update
2020/11/30 19:59:33 INFO     ▶ 0004 Your bee are up to date
Bee is a Fast and Flexible tool for managing your Beego Web Application.

You are using bee for beego v2.x. If you are working on beego v1.x, please downgrade version to bee v1.12.0

USAGE
    bee command [arguments]

AVAILABLE COMMANDS
...
728x90
728x90

 

지난 포스팅에 이어 이번 포스팅에서는 백업한 데이터를 복원하는 방법에 대하여 확인해 보도록 하겠습니다. 백업을 위한 파라메터가 `backup` 이었다면 반대로 복원을 위한 파라메터는 `restore` 입니다. 기억하기 쉽죠? 옵션도 비슷합니다. 백업시 사용한 포맷에 따라 다르겠습니다만 InfluxDB 에서는 신규 포맷을 권장하기 때문에 `-portable` 옵션은 항상 붙인다고 기억하면 편합니다. 


새로운 데이터베이스로 복원하기

백업 파일이 가지고 있는 데이터베이스명, 즉 원본 데이터베이스를 `-db` 옵션에 지정하고 복원시 사용할 데이터베이스의 이름을 `-newdb` 로 지정해 주어야 합니다. 원래의 데이터베이스로 바로 복원하는 것은 제공되지 않고, 약간의 우회 방법을 사용해야 합니다. 우선 새로운 데이터베이스로 복원을 해보겠습니다. 

$ influxd restore -portable -db myreport -newdb myreport_new ./
2020/11/20 15:29:03 Restoring shard 16 live from backup 20201120T062805Z.s16.tar.gz
2020/11/20 15:29:03 Restoring shard 25 live from backup 20201120T062805Z.s25.tar.gz
2020/11/20 15:29:03 Restoring shard 2 live from backup 20201120T062805Z.s2.tar.gz
2020/11/20 15:29:03 Restoring shard 41 live from backup 20201120T062805Z.s41.tar.gz
2020/11/20 15:29:03 Restoring shard 10 live from backup 20201120T062805Z.s10.tar.gz
2020/11/20 15:29:03 Restoring shard 8 live from backup 20201120T062805Z.s8.tar.gz
...
...
2020/11/20 15:29:03 Restoring shard 13 live from backup 20201120T062805Z.s13.tar.gz
2020/11/20 15:29:03 Restoring shard 21 live from backup 20201120T062805Z.s21.tar.gz
2020/11/20 15:29:03 Restoring shard 26 live from backup 20201120T062805Z.s26.tar.gz
2020/11/20 15:29:03 Restoring shard 73 live from backup 20201120T062805Z.s73.tar.gz
2020/11/20 15:29:03 Restoring shard 7 live from backup 20201120T062805Z.s7.tar.gz
$

명령 마지막에 지정된 경로에서 백업에 대한 meta 파일과 manifest 파일을 확인한 뒤 복원 작업이 진행됩니다. meta 파일은 바이너리로 되어 있어 어떤 내용이 들어 있는지 확인하기 어렵습니다만 manifest 파일을 열어보면 백업 폴더에 있는 여러 tar.gz 파일들이 어떤 데이터베이스에 대하여 어떤 리텐션 정책으로 백업되었고 각 파일의 Shard ID 를 확인해볼 수 있습니다. 

$ cat 20201120T062805Z.manifest | head -n 20
{
  "meta": {
    "fileName": "20201120T062805Z.meta",
    "size": 1902
  },
  "limited": false,
  "files": [
    {
      "database": "myreport",
      "policy": "autogen",
      "shardID": 3,
      "fileName": "20201120T062805Z.s3.tar.gz",
      "size": 1024,
      "lastModified": 0
    },
    ...
    ...

 

복원한 데이터베이스 확인하기

InfluxDB CLI 를 이용하여 데이터베이스가 잘 복원되었는지 확인해 보겠습니다. 원본 데이터베이스의 Measurement 에 저장된 데이터포인트 수를 확인하고, 복원된 데이터베이스의 Measurement 에 저장된 데이터포인트 수를 확인하면 되겠죠? 터미널에서 `influx` 를 입력하여 CLI 에 진입하고 각 데이터베이스에 대하여 간단한 쿼리를 수행했습니다. 

$ influx
Connected to http://localhost:8086 version 1.8.3
InfluxDB shell version: 1.8.3
> use myreport
Using database myreport
> select count(*) from mydata
name: mydata
time count_ratio
---- -----------
0    1063148
> use myreport_new
Using database myreport_new
> select count(*) from mydata
name: mydata
time count_ratio
---- -----------
0    1063148
>

 

 

원래의 데이터베이스로 복원하는 방법

그런데 원래의 데이터베이스로 복원을 해야할 경우에는 어떻게 해야 할까요? 우선 아무 생각 없이 원래의 데이터베이스로 복원하도록 앞서 살펴본 복원 명령의 `-newdb` 값을 원래의 데이터베이스 이름으로 지정해 보았습니다. 무슨 에러가 나는지 확인해 보시죠. 

$ influxd restore -portable -db myreport -newdb myreport ./
2020/11/20 15:45:18 error updating meta: DB metadata not changed. database may already exist
restore: DB metadata not changed. database may already exist

원래의 데이터베이스로 복원하는 방법도 어렵지 않습니다. 앞서 살펴본 것처럼 우선 1) 새로운 데이터베이스로 복원을 먼저 한 뒤, 2) 새로운 데이터베이스에서 원래의 데이터베이스로 데이터를 옮기는 방법을 써야 합니다. 굳이 이렇게 해야 할 경우가 많이 생기지 않도록 하는 것이 좋겠지만, 방법은 알아두면 피가되고 살이될 것 같습니다. 

$ influxd restore -portable -db myreport -newdb myreport_temp ./

$ influx
> USE myreport_temp
> SELECT * INTO myreport..:MEASUREMENT FROM /.*/ GROUP BY *
> DROP DATABASE myreport_temp

간단한 구문입니다만 한번 설명을 하면 1) 임시 데이터베이스(myreport_temp)를 사용하도록 명령을 하고, 2) select~into 구문을 사용하여 모든 measurement 의 값을 원래의 데이터베이스(myreport) 로 넣습니다. 이 작업은 데이터포인트의 수에 따라 시간이 많이 소요될 수 있습니다. 마지막으로 3) 임시 데이터베이스는 삭제해 줍니다. 


사실 백업과 복원은 지난 포스팅에서 처럼 풀 백업만 하는 것 보다는 증분 백업을 섞어서 해주는 것이 좋습니다. InfluxDB 는 시작과 끝 Timestamp 지정을 통해 일정 기간의 데이터포인트를 백업하는 방법을 제공하고 있습니다. 물론 저장 방식으로 인해 정확히 시작과 끝 시간 구간 내의 데이터만 추출되지는 않습니다. 

그럼에도 불구하고 데이터포인트가 많아지면 처리 속도가 영향을 받을 수 있으니 공식 문서를 참고하여 지정된 시간 범위의 데이터를 백업하고 복원하는 시도, 도전도 해보시기 바라겠습니다! (공식 문서 : docs.influxdata.com/influxdb/v1.8/administration/backup_and_restore/)


>> 지난 포스팅을 안보았다면...

 

InfluxDB, 데이터의 백업과 복원 #1 / 백업의 두가지 방법

InfluxDB 도 데이터베이스이기 때문에 만일의 상황을 대비하여 백업과 복원 방법에 대하여 알아둘 필요가 있습니다. 근래에 클라우드 기반으로 서비스를 제공하고 있다보니 공식 문서에서 설치형

ondemand.tistory.com

 

728x90
728x90

Amazon Linux 를 쓰는 EC2 인스턴스에서 yum 으로 docker-compose 의 설치가 원활하지 않아 github 에서 릴리즈된 버전을 설치해 보기로 했습니다. 구글링을 통해 잘 정리된 명령어를 찾을 수 있었고 다시 한 번 구글님께 감사의 절을 올리고 설치를 진행해 보았습니다.


Github 저장소에서 최신 릴리즈 태그 찾기

먼저 할일은 Github 의 Docker 프로젝트를 들르는 일입니다. 하위에 만들어져 있는 저장소들 중 compose 저장소가 docker-compose 를 만드는 공장입니다. 해당 저장소에 들어간 뒤 우측 사이드바에서 최신 릴리즈 정보를 확인할 수 있습니다. 

compose 저장소를 선택합니다
1.27.4 버전이 최신이군요!

 

 

docker/compose

Define and run multi-container applications with Docker - docker/compose

github.com

 

릴리즈 파일 전송받기

<Releases> 텍스트를 누르면 빌드되어 릴리즈 된 파일들의 목록을 볼 수 있습니다. 플랫폼과 운영체제에 따라 서로 다른 빌드를 사용하게 되는데요, Linux 버전을 받으면 되겠습니다. 구글링으로 찾은 curl 명령 예제는 uname -s 와 uname -m 으로 플랫폼 정보를 가져와서 쓰도록 되어 있어 유용했습니다! 

리눅스 버전을 받아 봅시다

// 최신 릴리즈 버전에 맞게 "1.27.4" 부분을 바꿔줍니다
// Root 권한이 아니라면 sudo 를 사용해야겠죠?
// 보통 기본 Path 로 잡혀 있는 /usr/local/bin 에 파일을 저장했습니다
//
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   651  100   651    0     0  27125      0 --:--:-- --:--:-- --:--:-- 27125
100 11.6M  100 11.6M    0     0  3053k      0  0:00:03  0:00:03 --:--:-- 3630k

// 받은 파일의 퍼미션을 변경하여 실행 가능하게 바꿉니다
//
$ sudo chmod +x /usr/local/bin/docker-compose

// 설치된 docker-compose 의 버전을 확인합니다. 
//
$ docker-compose --version
docker-compose version 1.27.4, build 40524192

 

728x90

+ Recent posts